diff --git a/Decay/General/FFSDecayer.cc b/Decay/General/FFSDecayer.cc
--- a/Decay/General/FFSDecayer.cc
+++ b/Decay/General/FFSDecayer.cc
@@ -1,444 +1,463 @@
 // -*- C++ -*-
 //
 // FFSDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FFSDecayer class.
 //
 
 #include "FFSDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr FFSDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FFSDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void FFSDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
-			      VertexBasePtr vertex,
+			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> ) {
   decayInfo(incoming,outgoing);
-  vertex_             = dynamic_ptr_cast<AbstractFFSVertexPtr>(vertex);
-  perturbativeVertex_ = dynamic_ptr_cast<FFSVertexPtr>        (vertex);
+  for(auto vert : vertex) {
+    vertex_             .push_back(dynamic_ptr_cast<AbstractFFSVertexPtr>(vert));
+    perturbativeVertex_ .push_back(dynamic_ptr_cast<FFSVertexPtr>        (vert));
+  }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(inV.at(inter));
     outgoingVertexF_[inter] = AbstractFFVVertexPtr();
     outgoingVertexS_[inter] = AbstractVSSVertexPtr();
     if(outV[0].at(inter)) {
       if (outV[0].at(inter)->getName()==VertexType::FFV)
 	outgoingVertexF_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(outV[0].at(inter));
       else
 	outgoingVertexS_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[0].at(inter));
     }
     if(outV[1].at(inter)) {
       if (outV[1].at(inter)->getName()==VertexType::FFV)
 	outgoingVertexF_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(outV[1].at(inter));
       else
 	outgoingVertexS_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[1].at(inter));
     }
   }
 }
 
 void FFSDecayer::persistentOutput(PersistentOStream & os) const {
   os << perturbativeVertex_       << vertex_
      << incomingVertex_   << outgoingVertexF_
      << outgoingVertexS_;
 }
 
 void FFSDecayer::persistentInput(PersistentIStream & is, int) {
   is >> perturbativeVertex_       >> vertex_
      >> incomingVertex_   >> outgoingVertexF_
      >> outgoingVertexS_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<FFSDecayer,GeneralTwoBodyDecayer>
 describeHerwigFFSDecayer("Herwig::FFSDecayer", "Herwig.so");
 
 void FFSDecayer::Init() {
 
   static ClassDocumentation<FFSDecayer> documentation
     ("The FFSDecayer class implements the decay of a fermion to "
      "a fermion and a scalar.");
 
 }
 
 double FFSDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay,
 		       MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin0)));
   //Need to use different barred or unbarred spinors depending on 
   //whether particle is cc or not.
   int itype[2];
   if(inpart.dataPtr()->CC())        itype[0] = inpart.id()    > 0? 0:1;
   else                              itype[0] = 2;
   if(decay[0]->dataPtr()->CC())     itype[1] = decay[0]->id() > 0? 0:1;
   else                              itype[1] = 2;
   bool ferm(itype[0] == 0 || itype[1] == 0 || (itype[0] == 2 && itype[1] == 2));
 
   if(meopt==Initialize) {
     // spinors and rho
     if(ferm) {
       SpinorWaveFunction   ::calculateWaveFunctions(wave_,rho_,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
       if(wave_[0].wave().Type() != SpinorType::u)
 	for(unsigned int ix = 0; ix < 2; ++ix) wave_   [ix].conjugate();
     }
     else {
       SpinorBarWaveFunction::calculateWaveFunctions(wavebar_,rho_,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
       if(wavebar_[0].wave().Type() != SpinorType::v)
 	for(unsigned int ix = 0; ix < 2; ++ix) wavebar_[ix].conjugate();
     }
   }
   // setup spin info when needed
   if(meopt==Terminate) {
     // for the decaying particle
     if(ferm) {
       SpinorWaveFunction::
 	constructSpinInfo(wave_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorBarWaveFunction::constructSpinInfo(wavebar_,decay[0],outgoing,true);
     }
     else {
       SpinorBarWaveFunction::
 	constructSpinInfo(wavebar_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorWaveFunction::constructSpinInfo(wave_,decay[0],outgoing,true);
     }
     ScalarWaveFunction::constructSpinInfo(decay[1],outgoing,true);
   }
   if(ferm)
     SpinorBarWaveFunction::
       calculateWaveFunctions(wavebar_,decay[0],outgoing);
   else
     SpinorWaveFunction::
       calculateWaveFunctions(wave_   ,decay[0],outgoing);
   ScalarWaveFunction scal(decay[1]->momentum(),decay[1]->dataPtr(),outgoing);
   Energy2 scale(sqr(inpart.mass()));
   for(unsigned int if1 = 0; if1 < 2; ++if1) {
     for(unsigned int if2 = 0; if2 < 2; ++if2) {
-      if(ferm) (*ME())(if1, if2, 0) = 
-	vertex_->evaluate(scale,wave_[if1],wavebar_[if2],scal);
-      else     (*ME())(if2, if1, 0) = 
-	vertex_->evaluate(scale,wave_[if1],wavebar_[if2],scal);
+      if(ferm) (*ME())(if1, if2, 0) = 0.;
+      else     (*ME())(if2, if1, 0) = 0.;
+      for(auto vert : vertex_) {
+	if(ferm) (*ME())(if1, if2, 0) += 
+		   vert->evaluate(scale,wave_[if1],wavebar_[if2],scal);
+	else     (*ME())(if2, if1, 0) += 
+		   vert->evaluate(scale,wave_[if1],wavebar_[if2],scal);
+      }
     }
   }
   double output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy FFSDecayer::partialWidth(PMPair inpart, PMPair outa,
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
-  if(perturbativeVertex_) {
+  if(perturbativeVertex_.size()==1 &&
+     perturbativeVertex_[0]) {
     double mu1(0.),mu2(0.);
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     if(outa.first->iSpin() == PDT::Spin1Half) {
       mu1 = outa.second/inpart.second;
       mu2 = outb.second/inpart.second;
-      perturbativeVertex_->setCoupling(sqr(inpart.second), in, outa.first, outb.first);
+      perturbativeVertex_[0]->setCoupling(sqr(inpart.second), in, outa.first, outb.first);
     }
     else {
       mu1 = outb.second/inpart.second;
       mu2 = outa.second/inpart.second;
-      perturbativeVertex_->setCoupling(sqr(inpart.second), in, outb.first, outa.first);
+      perturbativeVertex_[0]->setCoupling(sqr(inpart.second), in, outb.first, outa.first);
       
     }
-    double c2 = norm(perturbativeVertex_->norm());
-    Complex cl = perturbativeVertex_->left();
-    Complex cr = perturbativeVertex_->right();
+    double c2 = norm(perturbativeVertex_[0]->norm());
+    Complex cl = perturbativeVertex_[0]->left();
+    Complex cr = perturbativeVertex_[0]->right();
     double me2 = c2*( (norm(cl) + norm(cr))*(1. + sqr(mu1) - sqr(mu2))
 		      + 2.*mu1*(conj(cl)*cr + conj(cr)*cl).real() );
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second, outa.second,
 					outb.second);
     Energy output = me2*pcm/16./Constants::pi;
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 
 double FFSDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   int iscal (0), iferm (1), iglu (2);
   // get location of outgoing fermion/scalar
   if(decay[1]->dataPtr()->iSpin()==PDT::Spin0) swap(iscal,iferm);
   // work out whether inpart is a fermion or antifermion
   int itype[2];
   if(inpart.dataPtr()->CC())        itype[0] = inpart.id() > 0 ? 0 : 1;
   else                              itype[0] = 2;
   if(decay[iferm]->dataPtr()->CC()) itype[1] = decay[iferm]->id() > 0 ? 0 : 1;
   else                              itype[1] = 2;
 
   bool ferm(false);
   if(itype[0] == itype[1] ) {
     ferm = itype[0]==0 || (itype[0]==2 && decay[iscal]->id() < 0);
   }
   else if(itype[0] == 2) {
     ferm = itype[1]==0;
   }
   else if(itype[1] == 2) {
     ferm = itype[0]==0;
   }
   else if((itype[0] == 1 && itype[1] == 0) ||
 	  (itype[0] == 0 && itype[1] == 1)) {
     if(abs(inpart.id())<=16) {
       ferm = itype[0]==0;
     }
     else if(abs(decay[iferm]->id())<=16) {
       ferm = itype[1]==0;
     }
     else {
       ferm = true;
     }
   }
   else
     assert(false);
   if(meopt==Initialize) {
     // create spinor (bar) for decaying particle
     if(ferm) {
       SpinorWaveFunction::calculateWaveFunctions(wave3_, rho3_, const_ptr_cast<tPPtr>(&inpart), 
 						 incoming);
       if(wave3_[0].wave().Type() != SpinorType::u)
    	for(unsigned int ix = 0; ix < 2; ++ix) wave3_[ix].conjugate();
     }
     else {
       SpinorBarWaveFunction::calculateWaveFunctions(wavebar3_,rho3_, const_ptr_cast<tPPtr>(&inpart), 
 						    incoming);
       if(wavebar3_[0].wave().Type() != SpinorType::v)
    	for(unsigned int ix = 0; ix < 2; ++ix) wavebar3_[ix].conjugate();
     }
   }
   // setup spin information when needed 
   if(meopt==Terminate) {
     if(ferm) {
       SpinorWaveFunction::
 	constructSpinInfo(wave3_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorBarWaveFunction::constructSpinInfo(wavebar3_,decay[iferm],outgoing,true);
     }
     else {
       SpinorBarWaveFunction::
 	constructSpinInfo(wavebar3_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorWaveFunction::constructSpinInfo(wave3_,decay[iferm],outgoing,true);
     }
     ScalarWaveFunction::constructSpinInfo(        decay[iscal],outgoing,true);
     VectorWaveFunction::constructSpinInfo(gluon_, decay[iglu ],outgoing,true,false);
     return 0.;
   }
 
   // calulate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
 
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half, PDT::Spin0,
 								       PDT::Spin1Half, PDT::Spin1)));
   // create wavefunctions
   if (ferm)  SpinorBarWaveFunction::calculateWaveFunctions(wavebar3_, decay[iferm],outgoing);
   else       SpinorWaveFunction::   calculateWaveFunctions(wave3_   , decay[iferm],outgoing);
   
   ScalarWaveFunction swave3_(decay[iscal]->momentum(), decay[iscal]->dataPtr(),outgoing);
   VectorWaveFunction::calculateWaveFunctions(gluon_,   decay[iglu ],outgoing,true);
 
   // gauge invariance test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[iglu ]->momentum(),decay[iglu ]->dataPtr(),10,
 					  outgoing));
     }
   }
 #endif
   
   if (! ((incomingVertex_[inter]  && (outgoingVertexF_[inter] || outgoingVertexS_[inter])) ||
 	 (outgoingVertexF_[inter] &&  outgoingVertexS_[inter])))
     throw Exception()
       << "Invalid vertices for radiation in FFS decay in FFSDecayer::threeBodyME"
       << Exception::runerror;
 
 
   // sort out colour flows
   int F(1), S(2);
   if (decay[iscal]->dataPtr()->iColour()==PDT::Colour3 && 
       decay[iferm]->dataPtr()->iColour()==PDT::Colour8)
     swap(F,S);
   else if (decay[iferm]->dataPtr()->iColour()==PDT::Colour3bar && 
 	   decay[iscal]->dataPtr()->iColour()==PDT::Colour8)
     swap(F,S);
 
 
   Complex diag;
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
   for(unsigned int ifi = 0; ifi < 2; ++ifi) {
     for(unsigned int ifo = 0; ifo < 2; ++ifo) {
       for(unsigned int ig = 0; ig < 2; ++ig) {
    	// radiation from the incoming fermion
    	if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	   (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
    	  assert(incomingVertex_[inter]);
 	  if (ferm) {
 	    SpinorWaveFunction spinorInter =
 	      incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),wave3_[ifi],
 					       gluon_[2*ig],inpart.mass());
 
 	    assert(wave3_[ifi].particle()->id()==spinorInter.particle()->id());
-	    diag = vertex_->evaluate(scale,spinorInter,wavebar3_[ifo],swave3_);
+	    diag = 0.;
+	    for(auto vertex : vertex_)
+	      diag += vertex->evaluate(scale,spinorInter,wavebar3_[ifo],swave3_);
 	  }
 	  else {
 	    SpinorBarWaveFunction spinorBarInter = 
 	      incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),wavebar3_[ifi],
 					       gluon_[2*ig],inpart.mass());
 
 	    assert(wavebar3_[ifi].particle()->id()==spinorBarInter.particle()->id());
-	    diag = vertex_->evaluate(scale,wave3_[ifo], spinorBarInter,swave3_);
+	    diag = 0.;
+	    for(auto vertex :vertex_)
+	      diag+= vertex->evaluate(scale,wave3_[ifo], spinorBarInter,swave3_);
 	  }
 	  if(!couplingSet) {
 	    gs = abs(incomingVertex_[inter]->norm());
 	    couplingSet = true;
 	  }
 	  for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	    (*ME[colourFlow[0][ix].first])(ifi, 0, ifo, ig) += 
 	       colourFlow[0][ix].second*diag;
 	  }
 #ifdef GAUGE_CHECK
 	  total+=norm(diag);
 #endif
 	}
 	  
   	// radiation from outgoing fermion
    	if((decay[iferm]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	   (decay[iferm]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
   	  assert(outgoingVertexF_[inter]);
 	  // ensure you get correct outgoing particle from first vertex
 	  tcPDPtr off = decay[iferm]->dataPtr();
 	  if(off->CC()) off = off->CC();  	  
 	  if (ferm) {	    
 	    SpinorBarWaveFunction spinorBarInter = 
 	      outgoingVertexF_[inter]->evaluate(scale,3,off,wavebar3_[ifo],
 						gluon_[2*ig],decay[iferm]->mass());
 	    
 	    assert(wavebar3_[ifo].particle()->id()==spinorBarInter.particle()->id());
-	    diag = vertex_->evaluate(scale,wave3_[ifi],spinorBarInter,swave3_);
+	    diag = 0.;
+	    for(auto vertex :vertex_)
+	      diag+= vertex->evaluate(scale,wave3_[ifi],spinorBarInter,swave3_);
 	  }
 	  else {
 	    SpinorWaveFunction spinorInter = 
 	      outgoingVertexF_[inter]->evaluate(scale,3,off,wave3_[ifo],
 						gluon_[2*ig],decay[iferm]->mass());
 	      
 	    assert(wave3_[ifo].particle()->id()==spinorInter.particle()->id());
-	    diag = vertex_->evaluate(scale,spinorInter,wavebar3_[ifi],swave3_);
+	    diag = 0.;
+	    for(auto vertex :vertex_)
+	      diag+= vertex->evaluate(scale,spinorInter,wavebar3_[ifi],swave3_);
 	  }
 	  if(!couplingSet) {
 	    gs = abs(outgoingVertexF_[inter]->norm());
 	    couplingSet = true;
 	  }
 	  for(unsigned int ix=0;ix<colourFlow[F].size();++ix) {
 	    (*ME[colourFlow[F][ix].first])(ifi, 0, ifo, ig) += 
 	      colourFlow[F][ix].second*diag;
 	  }
 #ifdef GAUGE_CHECK
 	  total+=norm(diag);
 #endif
   	}
 
   	// radiation from outgoing scalar
    	if((decay[iscal]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	   (decay[iscal]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
   	  assert(outgoingVertexS_[inter]);
 	  // ensure you get correct ougoing particle from first vertex
 	  tcPDPtr off = decay[iscal]->dataPtr();
 	  if(off->CC()) off = off->CC();
 	  ScalarWaveFunction  scalarInter = 
 	    outgoingVertexS_[inter]->evaluate(scale,3,off,gluon_[2*ig],
 					      swave3_,decay[iscal]->mass());
 	    
 	  assert(swave3_.particle()->id()==scalarInter.particle()->id());
 	  if (ferm){
-	    diag = vertex_->evaluate(scale,wave3_[ifi],wavebar3_[ifo],scalarInter);
+	    diag = 0.;
+	    for(auto vertex :vertex_)
+	      diag += vertex->evaluate(scale,wave3_[ifi],wavebar3_[ifo],scalarInter);
 	  }
 	  else {
-	    diag = vertex_->evaluate(scale,wave3_[ifo],wavebar3_[ifi],scalarInter);
+	    diag = 0.;
+	    for(auto vertex :vertex_)
+	      diag += vertex->evaluate(scale,wave3_[ifo],wavebar3_[ifi],scalarInter);
 	  }
 	  if(!couplingSet) {
 	    gs = abs(outgoingVertexS_[inter]->norm());
 	    couplingSet = true;
 	  }
 	  for(unsigned int ix=0;ix<colourFlow[S].size();++ix) {
   	    (*ME[colourFlow[S][ix].first])(ifi, 0, ifo, ig) += 
 	      colourFlow[S][ix].second*diag;
 	  }
 #ifdef GAUGE_CHECK
 	  total+=norm(diag);
 #endif
   	}
       }
     }
   }
 
   // contract matrices
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha(S,EM)
   output*=(4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
 
   // return the answer
   return output;
 }
diff --git a/Decay/General/FFSDecayer.h b/Decay/General/FFSDecayer.h
--- a/Decay/General/FFSDecayer.h
+++ b/Decay/General/FFSDecayer.h
@@ -1,210 +1,218 @@
 // -*- C++ -*-
 //
 // FFSDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_FFSDecayer_H
 #define HERWIG_FFSDecayer_H
 //
 // This is the declaration of the FFSDecayer class.
 //
 
 #include "GeneralTwoBodyDecayer.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Helicity/Vertex/Scalar/FFSVertex.h"
 #include "ThePEG/Helicity/Vertex/Scalar/VSSVertex.h"
 #include "ThePEG/Helicity/Vertex/Vector/FFVVertex.h"
 
 
 namespace Herwig {
 using namespace ThePEG;
 using Helicity::FFSVertexPtr;
 
   /** \ingroup Decay
    * The FFSDecayer class implements the decay of a fermion
    * to a fermion and a vector in a general model. It holds an FFVVertex
    * pointer that must be typecast from the VertexBase pointer held in
    * GeneralTwoBodyDecayer. It implents the virtual functions me2() and
    * partialWidth().
    *
    * @see GeneralTwoBodyDecayer
    */
 class FFSDecayer: public GeneralTwoBodyDecayer {
 
 public:
   
   /**
    * The default constructor.
    */
   FFSDecayer() {}
 
   /** @name Virtual functions required by the Decayer class. */
   //@{
   /**
    * Return the matrix element squared for a given mode and phase-space channel.
    * @param ichan The channel we are calculating the matrix element for.
    * @param part The decaying Particle.
    * @param decay The particles produced in the decay.
    * @param meopt Option for the calculation of the matrix element
    * @return The matrix element squared for the phase-space configuration.
    */
   virtual double me2(const int ichan, const Particle & part,
                      const ParticleVector & decay, MEOption meopt) const;
 
   /**
    * Function to return partial Width
    * @param inpart The decaying particle.
    * @param outa One of the decay products.
    * @param outb The other decay product.
    */
   virtual Energy partialWidth(PMPair inpart, PMPair outa, 
 			      PMPair outb) const;
   /**
    *  Has a POWHEG style correction
    */
   virtual POWHEGType hasPOWHEGCorrection()  {
-    return (vertex_->orderInGem()+vertex_->orderInGs())==1 ? FSR : No;
+    POWHEGType output = FSR;
+    for(auto vertex : vertex_) {
+      if(vertex->orderInAllCouplings()!=1) {
+	output = No;
+	break;
+      }
+    }
+    return output;
   }
 
   /**
    *  Three-body matrix element including additional QCD radiation
    */
   virtual double threeBodyME(const int , const Particle & inpart,
 			     const ParticleVector & decay,
 			     ShowerInteraction inter, MEOption meopt);
 
   /**
    *  Set the information on the decay
    */
-  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
+  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing,
+			    vector<VertexBasePtr>,
 			    map<ShowerInteraction,VertexBasePtr> &,
 			    const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			    map<ShowerInteraction,VertexBasePtr>);
   //@}
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const;
 
   /** Make a clone of this object, possibly modifying the cloned object
    * to make it sane.
    * @return a pointer to the new object.
    */
   virtual IBPtr fullclone() const;
   //@}
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FFSDecayer & operator=(const FFSDecayer &);
 
 private:
 
   /**
    *  Abstract pointer to AbstractFFSVertex
    */
-  AbstractFFSVertexPtr vertex_;
+  vector<AbstractFFSVertexPtr> vertex_;
 
   /**
    * Pointer to the perturbative vertex
    */
-  FFSVertexPtr perturbativeVertex_;
+  vector<FFSVertexPtr> perturbativeVertex_;
 
   /**
    *  Abstract pointer to AbstractFFVVertex for QCD radiation from incoming (anti)fermion
    */
   map<ShowerInteraction,AbstractFFVVertexPtr> incomingVertex_;
 
   /**
    *  Abstract pointer to AbstractFFVVertex for QCD radiation from outgoing (anti)fermion
    */
   map<ShowerInteraction,AbstractFFVVertexPtr> outgoingVertexF_;
 
   /**
    *  Abstract pointer to AbstractVSSVertex for QCD radiation from outgoing scalar
    */
   map<ShowerInteraction,AbstractVSSVertexPtr> outgoingVertexS_;
 
   /**
    *  Spin density matrix
    */
   mutable RhoDMatrix rho_;
 
   /**
    *  Spinor wavefunctions
    */
   mutable vector<SpinorWaveFunction>    wave_   ;
 
   /**
    *  Barred spinor wavefunctions
    */
   mutable vector<SpinorBarWaveFunction> wavebar_;
 
  /**
    *  Spin density matrix for 3 body decay
    */
   mutable RhoDMatrix rho3_;
 
   /**
    *  Scalar wavefunction for 3 body decay
    */
   mutable ScalarWaveFunction swave3_;
 
   /**
    *  Spinor wavefunction for 3 body decay
    */
   mutable vector<SpinorWaveFunction> wave3_;
 
   /**
    *  Barred spinor wavefunction for 3 body decay
    */
   mutable vector<SpinorBarWaveFunction> wavebar3_;
 
     /**
    *  Vector wavefunction for 3 body decay
    */
   mutable vector<VectorWaveFunction> gluon_;
 
 };
 
 }
 
 #endif /* HERWIG_FFSDecayer_H */
diff --git a/Decay/General/FFVDecayer.cc b/Decay/General/FFVDecayer.cc
--- a/Decay/General/FFVDecayer.cc
+++ b/Decay/General/FFVDecayer.cc
@@ -1,433 +1,456 @@
 // -*- C++ -*-
 //
 // FFVDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FFVDecayer class.
 //
 
 #include "FFVDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr FFVDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FFVDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void FFVDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
-			      VertexBasePtr vertex,
+			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> ) {
   decayInfo(incoming,outgoing);
-  vertex_             = dynamic_ptr_cast<AbstractFFVVertexPtr>(vertex);
-  perturbativeVertex_ = dynamic_ptr_cast<FFVVertexPtr>        (vertex);
+  for(auto vert : vertex) {
+    vertex_             .push_back(dynamic_ptr_cast<AbstractFFVVertexPtr>(vert));
+    perturbativeVertex_ .push_back(dynamic_ptr_cast<FFVVertexPtr>        (vert));
+  }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(inV.at(inter));
     if(outV[0].at(inter)) {
       if (outV[0].at(inter)->getName()==VertexType::FFV)
 	outgoingVertexF_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(outV[0].at(inter));
       else
 	outgoingVertexV_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[0].at(inter));
     }
     if(outV[1].at(inter)) {
       if (outV[1].at(inter)->getName()==VertexType::FFV)
 	outgoingVertexF_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(outV[1].at(inter));
       else
 	outgoingVertexV_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[1].at(inter));
     }
   }
 }
 
 void FFVDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_           << perturbativeVertex_
      << incomingVertex_   << outgoingVertexF_
      << outgoingVertexV_;
 }
 
 void FFVDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_           >> perturbativeVertex_
      >> incomingVertex_   >> outgoingVertexF_
      >> outgoingVertexV_;
 }
 
 double FFVDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay, 
 		       MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1)));
   // type of process
   int itype[2];
   if(inpart.dataPtr()->CC())    itype[0] = inpart.id() > 0 ? 0 : 1;
   else                          itype[0] = 2;
   if(decay[0]->dataPtr()->CC()) itype[1] = decay[0]->id() > 0 ? 0 : 1;
   else                          itype[1] = 2;  
   //Need to use different barred or unbarred spinors depending on 
   //whether particle is cc or not.
   bool ferm(itype[0] == 0 || itype[1] == 0 || (itype[0] == 2 && itype[1] == 2));
   if(meopt==Initialize) {
     // spinors and rho
     if(ferm) {
       SpinorWaveFunction   ::calculateWaveFunctions(wave_,rho_,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
       if(wave_[0].wave().Type() != SpinorType::u)
 	for(unsigned int ix = 0; ix < 2; ++ix) wave_   [ix].conjugate();
     }
     else {
       SpinorBarWaveFunction::calculateWaveFunctions(wavebar_,rho_,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
       if(wavebar_[0].wave().Type() != SpinorType::v)
 	for(unsigned int ix = 0; ix < 2; ++ix) wavebar_[ix].conjugate();
     }
   }
   // setup spin info when needed
   if(meopt==Terminate) {
     // for the decaying particle
     if(ferm) {
       SpinorWaveFunction::
 	constructSpinInfo(wave_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorBarWaveFunction::constructSpinInfo(wavebar_,decay[0],outgoing,true);
     }
     else {
       SpinorBarWaveFunction::
 	constructSpinInfo(wavebar_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorWaveFunction::constructSpinInfo(wave_,decay[0],outgoing,true);
     }
     VectorWaveFunction::
       constructSpinInfo(vector_,decay[1],outgoing,true,false);
   }
   Energy2 scale(sqr(inpart.mass()));
   if(ferm)
     SpinorBarWaveFunction::
       calculateWaveFunctions(wavebar_,decay[0],outgoing);
   else
     SpinorWaveFunction::
       calculateWaveFunctions(wave_   ,decay[0],outgoing);
   bool massless = decay[1]->dataPtr()->mass()==ZERO;
   VectorWaveFunction::
     calculateWaveFunctions(vector_,decay[1],outgoing,massless);
   for(unsigned int if1 = 0; if1 < 2; ++if1) {
     for(unsigned int if2 = 0; if2 < 2; ++if2) {
       for(unsigned int vhel = 0; vhel < 3; ++vhel) {
 	if(massless && vhel == 1) ++vhel;
 	if(ferm)
-	  (*ME())(if1, if2,vhel) = 
-	    vertex_->evaluate(scale,wave_[if1],wavebar_[if2],vector_[vhel]);
+	  (*ME())(if1, if2,vhel) = 0.;
 	else
-	  (*ME())(if2, if1, vhel) = 
-	    vertex_->evaluate(scale,wave_[if1],wavebar_[if2],vector_[vhel]);
+	  (*ME())(if2, if1, vhel) = 0.;
+	for(auto vertex : vertex_) {
+	  if(ferm)
+	    (*ME())(if1, if2,vhel) += 
+	      vertex->evaluate(scale,wave_[if1],wavebar_[if2],vector_[vhel]);
+	  else
+	    (*ME())(if2, if1, vhel) += 
+	      vertex->evaluate(scale,wave_[if1],wavebar_[if2],vector_[vhel]);
+	}
       }
     }
   }
   double output=(ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy FFVDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
-  if(perturbativeVertex_) {
+  if(perturbativeVertex_.size()==1 &&
+     perturbativeVertex_[0]) {
     double mu1(outa.second/inpart.second),mu2(outb.second/inpart.second);
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     if( outa.first->iSpin() == PDT::Spin1Half)
-      perturbativeVertex_->setCoupling(sqr(inpart.second), in,
+      perturbativeVertex_[0]->setCoupling(sqr(inpart.second), in,
 				       outa.first, outb.first);
     else {
       swap(mu1,mu2);
-      perturbativeVertex_->setCoupling(sqr(inpart.second),in,
+      perturbativeVertex_[0]->setCoupling(sqr(inpart.second),in,
 				       outb.first,outa.first);
     }
-    Complex cl(perturbativeVertex_->left()),cr(perturbativeVertex_->right());
+    Complex cl(perturbativeVertex_[0]->left()),cr(perturbativeVertex_[0]->right());
     double me2(0.);
     if( mu2 > 0. ) {
       me2 = (norm(cl) + norm(cr))*(1. + sqr(mu1*mu2) + sqr(mu2) 
 				   - 2.*sqr(mu1) - 2.*sqr(mu2*mu2) 
 				   +  sqr(mu1*mu1))
 	- 6.*mu1*sqr(mu2)*(conj(cl)*cr + conj(cr)*cl).real();
       me2 /= sqr(mu2);
     }
     else
       me2 = 2.*( (norm(cl) + norm(cr))*(sqr(mu1) + 1.) 
 		 - 4.*mu1*(conj(cl)*cr + conj(cr)*cl).real() );
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second, outa.second,
 					outb.second);
-    Energy output = norm(perturbativeVertex_->norm())*me2*pcm/16./Constants::pi; 
+    Energy output = norm(perturbativeVertex_[0]->norm())*me2*pcm/16./Constants::pi; 
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer 
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<FFVDecayer,GeneralTwoBodyDecayer>
 describeHerwigFFVDecayer("Herwig::FFVDecayer", "Herwig.so");
 
 void FFVDecayer::Init() {
 
   static ClassDocumentation<FFVDecayer> documentation
     ("The FFVDecayer class implements the decay of a fermion to a fermion and a vector boson");
 
 }
 
 double  FFVDecayer::threeBodyME(const int , const Particle & inpart,
 				const ParticleVector & decay,
 				ShowerInteraction inter, MEOption meopt) {
 
   int iferm (0), ivect (1), iglu (2);
   // get location of outgoing lepton/vector
   if(decay[1]->dataPtr()->iSpin()==PDT::Spin1Half) swap(iferm,ivect);
   // work out whether inpart is a fermion or antifermion
   int itype[2];
   if(inpart.dataPtr()->CC())        itype[0] = inpart.id() > 0 ? 0 : 1;
   else                              itype[0] = 2;
   if(decay[iferm]->dataPtr()->CC()) itype[1] = decay[iferm]->id() > 0 ? 0 : 1;
   else                              itype[1] = 2;
 
   bool ferm(itype[0] == 0 || itype[1] == 0 || 
 	   (itype[0] == 2 && itype[1] == 2 && decay[ivect]->id() < 0));  
 
   // no emissions from massive vectors
   bool massless = decay[ivect]->dataPtr()->mass()==ZERO;
 
   if(meopt==Initialize) {
     // create spinor (bar) for decaying particle
     if(ferm) {
       SpinorWaveFunction::calculateWaveFunctions(wave3_, rho3_, const_ptr_cast<tPPtr>(&inpart), 
 						 incoming);
       if(wave3_[0].wave().Type() != SpinorType::u)
    	for(unsigned int ix = 0; ix < 2; ++ix) wave3_[ix].conjugate();
     }
     else {
       SpinorBarWaveFunction::calculateWaveFunctions(wavebar3_,rho3_, const_ptr_cast<tPPtr>(&inpart), 
 						    incoming);
       if(wavebar3_[0].wave().Type() != SpinorType::v)
    	for(unsigned int ix = 0; ix < 2; ++ix) wavebar3_[ix].conjugate();
     }
   }
   // setup spin information when needed 
   if(meopt==Terminate) {
     if(ferm) {
       SpinorWaveFunction::
 	constructSpinInfo(wave3_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorBarWaveFunction::constructSpinInfo(wavebar3_,decay[iferm],outgoing,true);
     }
     else {
       SpinorBarWaveFunction::
 	constructSpinInfo(wavebar3_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       SpinorWaveFunction::constructSpinInfo(wave3_,decay[iferm],outgoing,true);
     }
     VectorWaveFunction::constructSpinInfo(vector3_, decay[ivect],outgoing,true,massless);
     VectorWaveFunction::constructSpinInfo(gluon_,   decay[iglu ],outgoing,true,false);
     return 0.;
   }
 
   // calulate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
 
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half, PDT::Spin1Half,
 								       PDT::Spin1,     PDT::Spin1)));
 
   // create wavefunctions
   if (ferm)  SpinorBarWaveFunction::calculateWaveFunctions(wavebar3_, decay[iferm],outgoing);
   else       SpinorWaveFunction::   calculateWaveFunctions(wave3_   , decay[iferm],outgoing);
   
   VectorWaveFunction::calculateWaveFunctions(vector3_, decay[ivect],outgoing,massless);
   VectorWaveFunction::calculateWaveFunctions(gluon_,   decay[iglu ],outgoing,true );
 
   // gauge invariance test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[iglu ]->momentum(),
   					  decay[iglu ]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
 
   if (! ((incomingVertex_[inter]  && (outgoingVertexF_[inter]  || outgoingVertexV_[inter])) ||
 	 (outgoingVertexF_[inter] &&  outgoingVertexV_[inter])))
     throw Exception()
       << "Invalid vertices for QCD radiation in FFV decay in FFVDecayer::threeBodyME"
       << Exception::runerror;
 
 
   // sort out colour flows
   int F(1), V(2);
   if (decay[iferm]->dataPtr()->iColour()==PDT::Colour3bar && 
       decay[ivect]->dataPtr()->iColour()==PDT::Colour8)
     swap(F,V);
   else if (decay[ivect]->dataPtr()->iColour()==PDT::Colour3 && 
 	   decay[iferm]->dataPtr()->iColour()==PDT::Colour8)
     swap(F,V);
 
   Complex diag;
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
   for(unsigned int ifi = 0; ifi < 2; ++ifi) {
     for(unsigned int ifo = 0; ifo < 2; ++ifo) {
       for(unsigned int iv = 0; iv < 3; ++iv) {
 	for(unsigned int ig = 0; ig < 2; ++ig) {
 	  // radiation from the incoming fermion
 	  if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(incomingVertex_[inter]);
 	    if (ferm){
 	      SpinorWaveFunction spinorInter =
 		incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),wave3_[ifi],
 						  gluon_[2*ig],inpart.mass());
 	      
 	      assert(wave3_[ifi].particle()->id()==spinorInter.particle()->id());
-	      diag = vertex_->evaluate(scale,spinorInter,wavebar3_[ifo],vector3_[iv]);
+	      diag = 0.;
+	      for(auto vertex : vertex_)
+		diag += vertex->evaluate(scale,spinorInter,wavebar3_[ifo],vector3_[iv]);
 	    }
 	    else {
 	      SpinorBarWaveFunction spinorBarInter = 
 		incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),wavebar3_[ifi],
 						  gluon_[2*ig],inpart.mass());
 	      
 	      assert(wavebar3_[ifi].particle()->id()==spinorBarInter.particle()->id());
-	      diag = vertex_->evaluate(scale,wave3_[ifo], spinorBarInter,vector3_[iv]);
+	      diag = 0.;
+	      for(auto vertex : vertex_)
+		diag += vertex->evaluate(scale,wave3_[ifo], spinorBarInter,vector3_[iv]);
 	    }
 	    if(!couplingSet) {
 	      gs = abs(incomingVertex_[inter]->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	      (*ME[colourFlow[0][ix].first])(ifi, ifo, iv, ig) += 
 		colourFlow[0][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 	  // radiation from outgoing fermion
 	  if((decay[iferm]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (decay[iferm]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(outgoingVertexF_[inter]);
 	    // ensure you get correct outgoing particle from first vertex
 	    tcPDPtr off = decay[iferm]->dataPtr();
 	    if(off->CC()) off = off->CC(); 
 	    if (ferm) {	    
 	      SpinorBarWaveFunction spinorBarInter = 
 		outgoingVertexF_[inter]->evaluate(scale,3,off,wavebar3_[ifo],
 						  gluon_[2*ig],decay[iferm]->mass());
 	      
 	      assert(wavebar3_[ifo].particle()->id()==spinorBarInter.particle()->id());
-	      diag = vertex_->evaluate(scale,wave3_[ifi],spinorBarInter,vector3_[iv]);
+	      diag = 0.;
+	      for(auto vertex : vertex_)
+		diag += vertex->evaluate(scale,wave3_[ifi],spinorBarInter,vector3_[iv]);
 	    }
 	    else {
 	      SpinorWaveFunction spinorInter = 
 		outgoingVertexF_[inter]->evaluate(scale,3,off,wave3_[ifo],
 						  gluon_[2*ig],decay[iferm]->mass());
 		
 	      assert(wave3_[ifo].particle()->id()==spinorInter.particle()->id());
 	      
-	      diag = vertex_->evaluate(scale,spinorInter,wavebar3_[ifi],vector3_[iv]);
+	      diag = 0.;
+	      for(auto vertex : vertex_)
+		diag += vertex->evaluate(scale,spinorInter,wavebar3_[ifi],vector3_[iv]);
 	    }
 	    if(!couplingSet) {
 	      gs = abs(outgoingVertexF_[inter]->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[F].size();++ix) {
 	      (*ME[colourFlow[F][ix].first])(ifi, ifo, iv, ig) += 
 		 colourFlow[F][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 	  
 	  // radiation from outgoing vector
 	  if((decay[ivect]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (decay[ivect]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(outgoingVertexV_[inter]);
 	    // ensure you get correct ougoing particle from first vertex
 	    tcPDPtr off = decay[ivect]->dataPtr();
 	    if(off->CC()) off = off->CC();
 	    VectorWaveFunction  vectorInter = 
 	      outgoingVertexV_[inter]->evaluate(scale,3,off,gluon_[2*ig],
 						vector3_[iv],decay[ivect]->mass());
 	    
-	   assert(vector3_[iv].particle()->id()==vectorInter.particle()->id());
-	    if (ferm)
-	      diag = vertex_->evaluate(scale,wave3_[ifi],wavebar3_[ifo],vectorInter);
-	    else
-	      diag = vertex_->evaluate(scale,wave3_[ifo],wavebar3_[ifi],vectorInter);
+	    assert(vector3_[iv].particle()->id()==vectorInter.particle()->id());
+	    if (ferm) {
+	      diag = 0.;
+	      for(auto vertex : vertex_)
+		diag += vertex->evaluate(scale,wave3_[ifi],wavebar3_[ifo],vectorInter);
+	    }
+	    else {
+	      diag = 0.;
+	      for(auto vertex : vertex_)
+		diag += vertex->evaluate(scale,wave3_[ifo],wavebar3_[ifi],vectorInter);
+	    }
 	    if(!couplingSet) {
 	      gs = abs(outgoingVertexV_[inter]->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[V].size();++ix) {
 	      (*ME[colourFlow[V][ix].first])(ifi, ifo, iv, ig) += 
 		colourFlow[V][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 	}
 	if(massless) ++iv;
       }
     }
   }
 
   // contract matrices
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha(S,eM)
   output *= (4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
   // return the answer
   return output;
 }
diff --git a/Decay/General/FFVDecayer.h b/Decay/General/FFVDecayer.h
--- a/Decay/General/FFVDecayer.h
+++ b/Decay/General/FFVDecayer.h
@@ -1,216 +1,223 @@
 // -*- C++ -*-
 //
 // FFVDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_FFVDecayer_H
 #define HERWIG_FFVDecayer_H
 //
 // This is the declaration of the FFVDecayer class.
 //
 
 #include "GeneralTwoBodyDecayer.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Helicity/Vertex/Vector/FFVVertex.h"
 #include "ThePEG/Helicity/Vertex/Vector/VVVVertex.h"
 
 namespace Herwig {
 using namespace ThePEG;
 using Helicity::FFVVertexPtr;
 
   /** \ingroup Decay
    * The FFVDecayer class implements the decay of a fermion
    * to a fermion and a vector in a general model. It holds an FFVVertex 
    * pointer that must be typecast from the VertexBase pointer held in 
    * GeneralTwoBodyDecayer. It implents the virtual functions me2() and
    * partialWidth(). 
    *
    * @see GeneralTwoBodyDecayer
    */
 class FFVDecayer: public GeneralTwoBodyDecayer {
 
 public:
 
   /**
    * The default constructor.
    */
   FFVDecayer() {}
   
 public:
 
   /** @name Virtual functions required by the Decayer class. */
   //@{
    /**
    * Return the matrix element squared for a given mode and phase-space channel.  
    * @param ichan The channel we are calculating the matrix element for.
    * @param part The decaying Particle.
    * @param decay The particles produced in the decay.
    * @param meopt Option for the matrix element
    * @return The matrix element squared for the phase-space configuration.
    */
   virtual double me2(const int ichan, const Particle & part,
 		     const ParticleVector & decay, MEOption meopt) const;
   
   /**
    * Function to return partial Width
    * @param inpart The decaying particle.
    * @param outa One of the decay products.
    * @param outb The other decay product.
    */
   virtual Energy partialWidth(PMPair inpart, PMPair outa, 
 			      PMPair outb) const;
 
   /**
    *  Has a POWHEG style correction
    */
   virtual POWHEGType hasPOWHEGCorrection()  {
-    return (vertex_->orderInGem()+vertex_->orderInGs())==1 ? FSR : No;
+    POWHEGType output = FSR;
+    for(auto vertex : vertex_) {
+      if(vertex->orderInAllCouplings()!=1) {
+	output = No;
+	break;
+      }
+    }
+    return output;
   }
 
   /**
    *  Three-body matrix element including additional QCD radiation
    */
   virtual double threeBodyME(const int , const Particle & inpart,
 			     const ParticleVector & decay,
 			     ShowerInteraction inter, MEOption meopt);
 
   /**
    *  Set the information on the decay
    */
-  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
+  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, vector<VertexBasePtr>,
 			    map<ShowerInteraction,VertexBasePtr> &,
 			    const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			    map<ShowerInteraction,VertexBasePtr>);
   //@}
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const;
 
   /** Make a clone of this object, possibly modifying the cloned object
    * to make it sane.
    * @return a pointer to the new object.
    */
   virtual IBPtr fullclone() const;
   //@}
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FFVDecayer & operator=(const FFVDecayer &);
 
 private:
 
   /**
    *  Abstract pointer to AbstractFFVVertex
    */
-  AbstractFFVVertexPtr vertex_;
+  vector<AbstractFFVVertexPtr> vertex_;
 
   /**
    * Pointer to the perturbative vertex
    */
-  FFVVertexPtr perturbativeVertex_;
+  vector<FFVVertexPtr> perturbativeVertex_;
 
   /**
    *  Abstract pointer to AbstractFFVVertex for QCD radiation from incoming (anti)fermion
    */
   map<ShowerInteraction,AbstractFFVVertexPtr> incomingVertex_;
 
   /**
    *  Abstract pointer to AbstractFFVVertex for QCD radiation from outgoing (anti)fermion
    */
   map<ShowerInteraction,AbstractFFVVertexPtr> outgoingVertexF_;
 
   /**
    *  Abstract pointer to AbstractVVVVertex for QCD radiation from outgoing vector
    */
   map<ShowerInteraction,AbstractVVVVertexPtr> outgoingVertexV_;
 
   /**
    *  Spin density matrix
    */
   mutable RhoDMatrix rho_;
 
   /**
    *  Spinor wavefunction
    */
   mutable vector<SpinorWaveFunction>    wave_   ;
 
   /**
    *  Barred spinor wavefunction
    */
   mutable vector<SpinorBarWaveFunction> wavebar_;
 
   /**
    *  Polarization vectors
    */
   mutable vector<VectorWaveFunction> vector_;
 
  /**
    *  Spin density matrix for 3 body decay
    */
   mutable RhoDMatrix rho3_;
 
   /**
    *  vector wavefunction for 3 body decay
    */
   mutable vector<VectorWaveFunction> vector3_;
 
   /**
    *  Spinor wavefunction for 3 body decay
    */
   mutable vector<SpinorWaveFunction> wave3_;
 
   /**
    *  Barred spinor wavefunction for 3 body decay
    */
   mutable vector<SpinorBarWaveFunction> wavebar3_;
 
     /**
    *  Vector wavefunction for gluon in 3 body decay
    */
   mutable vector<VectorWaveFunction> gluon_;
 
 };
 
 }
 
 #endif /* HERWIG_FFVDecayer_H */
diff --git a/Decay/General/FRSDecayer.cc b/Decay/General/FRSDecayer.cc
--- a/Decay/General/FRSDecayer.cc
+++ b/Decay/General/FRSDecayer.cc
@@ -1,183 +1,189 @@
 // -*- C++ -*-
 //
 // FRSDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FRSDecayer class.
 //
 
 #include "FRSDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr FRSDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FRSDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void FRSDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
-			      VertexBasePtr vertex,
+			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> &,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			      map<ShowerInteraction,VertexBasePtr>) {
   decayInfo(incoming,outgoing);
-  vertex_             = dynamic_ptr_cast<AbstractRFSVertexPtr>(vertex);
-  perturbativeVertex_ = dynamic_ptr_cast<RFSVertexPtr>        (vertex);
+  for(auto vert : vertex) {
+    vertex_            .push_back(dynamic_ptr_cast<AbstractRFSVertexPtr>(vert));
+    perturbativeVertex_.push_back(dynamic_ptr_cast<RFSVertexPtr>        (vert));
+  }
 }
 
 void FRSDecayer::persistentOutput(PersistentOStream & os) const {
   os << perturbativeVertex_ << vertex_;
 }
 
 void FRSDecayer::persistentInput(PersistentIStream & is, int) {
   is >> perturbativeVertex_ >> vertex_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<FRSDecayer,GeneralTwoBodyDecayer>
 describeHerwigFRSDecayer("Herwig::FRSDecayer", "Herwig.so");
 
 void FRSDecayer::Init() {
 
   static ClassDocumentation<FRSDecayer> documentation
     ("The FRSDecayer class implements the decay of a fermion to "
      "a spin-3/2 fermion and a scalar.");
 
 }
 
 double FRSDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay,
 		       MEOption meopt) const {
   bool ferm = inpart.id() > 0;
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half,PDT::Spin3Half,PDT::Spin0)));
   if(meopt==Initialize) {
     // spinors and rho
     if(ferm) {
       SpinorWaveFunction   ::calculateWaveFunctions(wave_,rho_,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
       if(wave_[0].wave().Type() != SpinorType::u)
 	for(unsigned int ix = 0; ix < 2; ++ix) wave_   [ix].conjugate();
     }
     else {
       SpinorBarWaveFunction::calculateWaveFunctions(wavebar_,rho_,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
       if(wavebar_[0].wave().Type() != SpinorType::v)
 	for(unsigned int ix = 0; ix < 2; ++ix) wavebar_[ix].conjugate();
     }
   }
   // setup spin info when needed
   if(meopt==Terminate) {
     // for the decaying particle
     if(ferm) {
       SpinorWaveFunction::
 	constructSpinInfo(wave_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       RSSpinorBarWaveFunction::constructSpinInfo(RSwavebar_,decay[0],outgoing,true);
     }
     else {
       SpinorBarWaveFunction::
 	constructSpinInfo(wavebar_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       RSSpinorWaveFunction::constructSpinInfo(RSwave_,decay[0],outgoing,true);
     }
     ScalarWaveFunction::constructSpinInfo(decay[1],outgoing,true);
   }
   if(ferm)
     RSSpinorBarWaveFunction::
       calculateWaveFunctions(RSwavebar_,decay[0],outgoing);
   else
     RSSpinorWaveFunction::
       calculateWaveFunctions(RSwave_   ,decay[0],outgoing);
   ScalarWaveFunction scal(decay[1]->momentum(),decay[1]->dataPtr(),outgoing);
   Energy2 scale(sqr(inpart.mass()));
   for(unsigned int if1 = 0; if1 < 2; ++if1) {
     for(unsigned int if2 = 0; if2 < 4; ++if2) {
-      if(ferm) (*ME())(if1, if2, 0) = 
-		 vertex_->evaluate(scale,wave_[if1],RSwavebar_[if2],scal);
-      else     (*ME())(if1, if2, 0) = 
-		 vertex_->evaluate(scale,RSwave_[if2],wavebar_[if1],scal);
+      (*ME())(if1, if2, 0) = 0.;
+      for(auto vert : vertex_) {
+	if(ferm) (*ME())(if1, if2, 0) +=
+		   vert->evaluate(scale,wave_[if1],RSwavebar_[if2],scal);
+	else     (*ME())(if1, if2, 0) += 
+		   vert->evaluate(scale,RSwave_[if2],wavebar_[if1],scal);
+      }
     }
   }
   double output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // test code
 //   Energy q = inpart.mass();
 //   Energy m1 = decay[0]->mass();
 //   Energy m2 = decay[1]->mass();
 //   Energy2 q2(q*q),m12(m1*m1),m22(m2*m2);
 //   Energy2 pcm2(0.25*(q2*(q2-2.*m12-2.*m22)+(m12-m22)*(m12-m22))/q2);
 //   Energy pcm(sqrt(pcm2));
 //   Energy Qp(sqrt((q+m1)*(q+m1)-m22)),Qm(sqrt((q-m1)*(q-m1)-m22));
 //   double r23(sqrt(2./3.));
 //   // couplings
 //   Complex left  = perturbativeVertex_-> left()*perturbativeVertex_-> norm();
 //   Complex right = perturbativeVertex_->right()*perturbativeVertex_-> norm();
 //   complex<InvEnergy> A1 = 0.5*(left+right)*UnitRemoval::InvE;
 //   complex<InvEnergy> B1 = 0.5*(right-left)*UnitRemoval::InvE;
 //   complex<Energy> h1(-2.*r23*pcm*q/m1*Qm*B1);
 //   complex<Energy> h2( 2.*r23*pcm*q/m1*Qp*A1);
 //   cout << "testing 1/2->3/2 0 "
 //        << output*scale/GeV2 << "   " 
 //        << real(h1*conj(h1)+h2*conj(h2))/4./GeV2     << "   " 
 //        << real(h1*conj(h1)+h2*conj(h2))/4./(output*scale) << endl;
   // return the answer
   return output;
 }
 
 Energy FRSDecayer::partialWidth(PMPair inpart, PMPair outa,
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
-  if(perturbativeVertex_) {
+  if(perturbativeVertex_.size()==1 &&
+     perturbativeVertex_[0]) {
     Energy q = inpart.second;
     Energy m1 = outa.second;
     Energy m2 = outb.second;
     Energy2 q2(q*q),m12(m1*m1),m22(m2*m2);
     Energy2 pcm2(0.25*(q2*(q2-2.*m12-2.*m22)+(m12-m22)*(m12-m22))/q2);
     Energy pcm(sqrt(pcm2));
     Energy Qp(sqrt((q+m1)*(q+m1)-m22)),Qm(sqrt((q-m1)*(q-m1)-m22));
     double r23(sqrt(2./3.));
     // couplings
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
-    perturbativeVertex_->setCoupling(sqr(inpart.second), outa.first, 
+    perturbativeVertex_[0]->setCoupling(sqr(inpart.second), outa.first, 
 				     in,  outb.first);
-    Complex left  = perturbativeVertex_-> left()*perturbativeVertex_-> norm();
-    Complex right = perturbativeVertex_->right()*perturbativeVertex_-> norm();
+    Complex left  = perturbativeVertex_[0]-> left()*perturbativeVertex_[0]-> norm();
+    Complex right = perturbativeVertex_[0]->right()*perturbativeVertex_[0]-> norm();
     complex<InvEnergy> A1 = 0.5*(left+right)*UnitRemoval::InvE;
     complex<InvEnergy> B1 = 0.5*(right-left)*UnitRemoval::InvE;
     complex<Energy> h1(-2.*r23*pcm*q/m1*Qm*B1);
     complex<Energy> h2( 2.*r23*pcm*q/m1*Qp*A1);
     double me2 = real(h1*conj(h1)+h2*conj(h2))/4./sqr(inpart.second);
     Energy output = me2*pcm/8./Constants::pi;
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
diff --git a/Decay/General/FRSDecayer.h b/Decay/General/FRSDecayer.h
--- a/Decay/General/FRSDecayer.h
+++ b/Decay/General/FRSDecayer.h
@@ -1,163 +1,164 @@
 // -*- C++ -*-
 //
 // FRSDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_FRSDecayer_H
 #define HERWIG_FRSDecayer_H
 //
 // This is the declaration of the FRSDecayer class.
 //
 
 #include "GeneralTwoBodyDecayer.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Helicity/Vertex/Scalar/RFSVertex.h"
 
 namespace Herwig {
 using namespace ThePEG;
 using Helicity::RFSVertexPtr;
 
   /** \ingroup Decay
    * The FRSDecayer class implements the decay of a fermion
    * to a spin-3/2 fermion and a vector in a general model. It holds an RFVVertex
    * pointer that must be typecast from the VertexBase pointer held in
    * GeneralTwoBodyDecayer. It implents the virtual functions me2() and
    * partialWidth().
    *
    * @see GeneralTwoBodyDecayer
    */
 class FRSDecayer: public GeneralTwoBodyDecayer {
 
 public:
   
   /**
    * The default constructor.
    */
   FRSDecayer() {}
 
   /** @name Virtual functions required by the Decayer class. */
   //@{
   /**
    * Return the matrix element squared for a given mode and phase-space channel.
    * @param ichan The channel we are calculating the matrix element for.
    * @param part The decaying Particle.
    * @param decay The particles produced in the decay.
    * @param meopt Option for the calculation of the matrix element
    * @return The matrix element squared for the phase-space configuration.
    */
   virtual double me2(const int ichan, const Particle & part,
                      const ParticleVector & decay, MEOption meopt) const;
 
   /**
    * Function to return partial Width
    * @param inpart The decaying particle.
    * @param outa One of the decay products.
    * @param outb The other decay product.
    */
   virtual Energy partialWidth(PMPair inpart, PMPair outa, 
 			      PMPair outb) const;
 
   /**
    *  Set the information on the decay
    */
-  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
+  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing,
+			    vector<VertexBasePtr>,
 			    map<ShowerInteraction,VertexBasePtr> &,
 			    const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			    map<ShowerInteraction,VertexBasePtr>);
   //@}
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const;
 
   /** Make a clone of this object, possibly modifying the cloned object
    * to make it sane.
    * @return a pointer to the new object.
    */
   virtual IBPtr fullclone() const;
   //@}
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FRSDecayer & operator=(const FRSDecayer &);
 
 private:
 
   /**
    *  Abstract pointer to AbstractFRSVertex
    */
-  AbstractRFSVertexPtr vertex_;
+  vector<AbstractRFSVertexPtr> vertex_;
 
   /**
    * Pointer to the perturbative vertex
    */
-  RFSVertexPtr perturbativeVertex_;
+  vector<RFSVertexPtr> perturbativeVertex_;
 
   /**
    *  Spin density matrix
    */
   mutable RhoDMatrix rho_;
 
   /**
    *  Spinor wavefunctions
    */
   mutable vector<SpinorWaveFunction>    wave_   ;
 
   /**
    *  Barred spinor wavefunctions
    */
   mutable vector<SpinorBarWaveFunction> wavebar_;
 
   /**
    *  RS Spinor wavefunctions
    */
   mutable vector<RSSpinorWaveFunction>    RSwave_   ;
 
   /**
    *  Barred RS spinor wavefunctions
    */
   mutable vector<RSSpinorBarWaveFunction> RSwavebar_;
 };
 
 }
 
 #endif /* HERWIG_FRSDecayer_H */
diff --git a/Decay/General/FRVDecayer.cc b/Decay/General/FRVDecayer.cc
--- a/Decay/General/FRVDecayer.cc
+++ b/Decay/General/FRVDecayer.cc
@@ -1,213 +1,219 @@
 // -*- C++ -*-
 //
 // FRVDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FRVDecayer class.
 //
 
 #include "FRVDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr FRVDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FRVDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void FRVDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
-			      VertexBasePtr vertex,
+			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> &,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			      map<ShowerInteraction,VertexBasePtr>) {
   decayInfo(incoming,outgoing);
-  vertex_             = dynamic_ptr_cast<AbstractRFVVertexPtr>(vertex);
-  perturbativeVertex_ = dynamic_ptr_cast<RFVVertexPtr>        (vertex);
+  for(auto vert : vertex) {
+    vertex_            .push_back(dynamic_ptr_cast<AbstractRFVVertexPtr>(vert));
+    perturbativeVertex_.push_back(dynamic_ptr_cast<RFVVertexPtr>        (vert));
+  }
 }
 
 void FRVDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_ << perturbativeVertex_;
 }
 
 void FRVDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_ >> perturbativeVertex_;
 }
 
 double FRVDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay, 
 		       MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half,PDT::Spin3Half,PDT::Spin1)));
   // decaying fermion or antifermion
   bool ferm = inpart.id() > 0;
   // initialize
   if(meopt==Initialize) {
     // spinors and rho
     if(ferm) {
       SpinorWaveFunction   ::calculateWaveFunctions(wave_,rho_,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
       if(wave_[0].wave().Type() != SpinorType::u)
 	for(unsigned int ix = 0; ix < 2; ++ix) wave_   [ix].conjugate();
     }
     else {
       SpinorBarWaveFunction::calculateWaveFunctions(wavebar_,rho_,
 						    const_ptr_cast<tPPtr>(&inpart),
 						    incoming);
       if(wavebar_[0].wave().Type() != SpinorType::v)
 	for(unsigned int ix = 0; ix < 2; ++ix) wavebar_[ix].conjugate();
     }
   }
   // setup spin info when needed
   if(meopt==Terminate) {
     // for the decaying particle
     if(ferm) {
       SpinorWaveFunction::
 	constructSpinInfo(wave_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       RSSpinorBarWaveFunction::constructSpinInfo(RSwavebar_,decay[0],outgoing,true);
     }
     else {
       SpinorBarWaveFunction::
 	constructSpinInfo(wavebar_,const_ptr_cast<tPPtr>(&inpart),incoming,true);
       RSSpinorWaveFunction::constructSpinInfo(RSwave_,decay[0],outgoing,true);
     }
     VectorWaveFunction::
       constructSpinInfo(vector_,decay[1],outgoing,true,false);
   }
   Energy2 scale(sqr(inpart.mass()));
   if(ferm)
     RSSpinorBarWaveFunction::
       calculateWaveFunctions(RSwavebar_,decay[0],outgoing);
   else
     RSSpinorWaveFunction::
       calculateWaveFunctions(RSwave_   ,decay[0],outgoing);
   bool massless = decay[1]->dataPtr()->mass()==ZERO;
   VectorWaveFunction::
     calculateWaveFunctions(vector_,decay[1],outgoing,massless);
   // loop over helicities
   for(unsigned int if1 = 0; if1 < 2; ++if1) {
     for(unsigned int if2 = 0; if2 < 4; ++if2) {
       for(unsigned int vhel = 0; vhel < 3; ++vhel) {
 	if(massless && vhel == 1) ++vhel;
-	if(ferm)
-	  (*ME())(if1, if2,vhel) = 
-	    vertex_->evaluate(scale,wave_[if1],
-			      RSwavebar_[if2],vector_[vhel]);
-	else
-	  (*ME())(if1, if2, vhel) = 
-	    vertex_->evaluate(scale,RSwave_[if2],
-			      wavebar_[if1],vector_[vhel]);
+	(*ME())(if1, if2,vhel) = 0.;
+	for(auto vert : vertex_) {
+	  if(ferm)
+	    (*ME())(if1, if2,vhel) += 
+	      vert->evaluate(scale,wave_[if1],
+			     RSwavebar_[if2],vector_[vhel]);
+	  else
+	    (*ME())(if1, if2, vhel) += 
+	      vert->evaluate(scale,RSwave_[if2],
+			     wavebar_[if1],vector_[vhel]);
+	}
       }
     }
   }
   double output=(ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // test
 //   Energy m1(inpart.mass()),m2(decay[0]->mass()),m3(decay[1]->mass());
 //   Energy2 m12(m1*m1),m22(m2*m2),m32(m3*m3);
 //   Energy Qp(sqrt(sqr(m1+m2)-sqr(m3))),Qm(sqrt(sqr(m1-m2)-sqr(m3)));
 //   double r2(sqrt(2.)),r3(sqrt(3.));
 //   Energy pcm(Kinematics::pstarTwoBodyDecay(m1,m2,m3));
 //   vector<Complex> left  = perturbativeVertex_-> left();
 //   vector<Complex> right = perturbativeVertex_->right();
 //   Complex A1 = 0.5*(left [0]+right[0])*perturbativeVertex_-> norm();
 //   Complex B1 = 0.5*(right[0]- left[0])*perturbativeVertex_-> norm();
 //   complex<InvEnergy> A2 = 0.5*(left [1]+right[1])*perturbativeVertex_-> norm()*UnitRemoval::InvE;
 //   complex<InvEnergy> B2 = 0.5*(right[1]- left[1])*perturbativeVertex_-> norm()*UnitRemoval::InvE;
 //   complex<InvEnergy2> A3 = 0.5*(left [2]+right[2])*perturbativeVertex_-> norm()*UnitRemoval::InvE2;
 //   complex<InvEnergy2> B3 = 0.5*(right[2]- left[2])*perturbativeVertex_-> norm()*UnitRemoval::InvE2;
 //   complex<Energy> h1(-2.*Qp*A1),h2(2.*Qm*B1);
 //   complex<Energy> h3(-2./r3*Qp*(A1-Qm*Qm/m2*A2));
 //   complex<Energy> h4( 2./r3*Qm*(B1-Qp*Qp/m2*B2));
 //   complex<Energy> h5(ZERO),h6(ZERO);
 //   if(decay[1]->mass()>ZERO) {
 //     h5 = -2.*r2/r3/m2/m3*Qp*(0.5*(m12-m22-m32)*A1+0.5*Qm*Qm*(m1+m2)*A2
 //     			   +m12*pcm*pcm*A3);
 //     h6 =  2.*r2/r3/m2/m3*Qm*(0.5*(m12-m22-m32)*B1-0.5*Qp*Qp*(m1-m2)*B2
 // 					   +m12*pcm*pcm*B3);
 //   }
 //   cout << "testing 1/2->3/2 1 " << inpart.id() << " "
 //        << output << "   " 
 //        << 0.25*(h1*conj(h1)+h2*conj(h2)+h3*conj(h3)+
 // 		h4*conj(h4)+h5*conj(h5)+h6*conj(h6))/sqr(inpart.mass()) << "   " 
 //        << 0.25*(h1*conj(h1)+h2*conj(h2)+h3*conj(h3)+
 // 		h4*conj(h4)+h5*conj(h5)+h6*conj(h6))/sqr(inpart.mass())/output << endl;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy FRVDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
-  if(perturbativeVertex_) {
+  if(perturbativeVertex_.size()==1 &&
+     perturbativeVertex_[0]) {
     Energy m1(inpart.second),m2(outa.second),m3(outb.second);
     Energy2 m12(m1*m1),m22(m2*m2),m32(m3*m3);
     Energy Qp(sqrt(sqr(m1+m2)-sqr(m3))),Qm(sqrt(sqr(m1-m2)-sqr(m3)));
     double r2(sqrt(2.)),r3(sqrt(3.));
     Energy pcm(Kinematics::pstarTwoBodyDecay(m1,m2,m3));
     // couplings
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
-    perturbativeVertex_->setCoupling(sqr(inpart.second), outa.first, 
+    perturbativeVertex_[0]->setCoupling(sqr(inpart.second), outa.first, 
 				     in,  outb.first);
-    vector<Complex> left  = perturbativeVertex_-> left();
-    vector<Complex> right = perturbativeVertex_->right();
-    Complex A1 = 0.5*(left [0]+right[0])*perturbativeVertex_-> norm();
-    Complex B1 = 0.5*(right[0]- left[0])*perturbativeVertex_-> norm();
-    complex<InvEnergy> A2 = 0.5*(left [1]+right[1])*perturbativeVertex_-> norm()*UnitRemoval::InvE;
-    complex<InvEnergy> B2 = 0.5*(right[1]- left[1])*perturbativeVertex_-> norm()*UnitRemoval::InvE;
-    complex<InvEnergy2> A3 = 0.5*(left [2]+right[2])*perturbativeVertex_-> norm()*UnitRemoval::InvE2;
-    complex<InvEnergy2> B3 = 0.5*(right[2]- left[2])*perturbativeVertex_-> norm()*UnitRemoval::InvE2;
+    vector<Complex> left  = perturbativeVertex_[0]-> left();
+    vector<Complex> right = perturbativeVertex_[0]->right();
+    Complex A1 = 0.5*(left [0]+right[0])*perturbativeVertex_[0]-> norm();
+    Complex B1 = 0.5*(right[0]- left[0])*perturbativeVertex_[0]-> norm();
+    complex<InvEnergy> A2 = 0.5*(left [1]+right[1])*perturbativeVertex_[0]-> norm()*UnitRemoval::InvE;
+    complex<InvEnergy> B2 = 0.5*(right[1]- left[1])*perturbativeVertex_[0]-> norm()*UnitRemoval::InvE;
+    complex<InvEnergy2> A3 = 0.5*(left [2]+right[2])*perturbativeVertex_[0]-> norm()*UnitRemoval::InvE2;
+    complex<InvEnergy2> B3 = 0.5*(right[2]- left[2])*perturbativeVertex_[0]-> norm()*UnitRemoval::InvE2;
     complex<Energy> h1(-2.*Qp*A1),h2(2.*Qm*B1);
     complex<Energy> h3(-2./r3*Qp*(A1-Qm*Qm/m2*A2));
     complex<Energy> h4( 2./r3*Qm*(B1-Qp*Qp/m2*B2));
     complex<Energy> h5(ZERO),h6(ZERO);
     if(outb.second>ZERO) {
       h5 = -2.*r2/r3/m2/m3*Qp*(0.5*(m12-m22-m32)*A1+0.5*Qm*Qm*(m1+m2)*A2
 			       +m12*pcm*pcm*A3);
       h6 =  2.*r2/r3/m2/m3*Qm*(0.5*(m12-m22-m32)*B1-0.5*Qp*Qp*(m1-m2)*B2
 			       +m12*pcm*pcm*B3);
     }
     double me2 = 0.25*real(h1*conj(h1)+h2*conj(h2)+h3*conj(h3)+
 			   h4*conj(h4)+h5*conj(h5)+h6*conj(h6))/sqr(inpart.second);
     Energy output = me2*pcm/8./Constants::pi;
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<FRVDecayer,GeneralTwoBodyDecayer>
 describeHerwigFRVDecayer("Herwig::FRVDecayer", "Herwig.so");
 
 void FRVDecayer::Init() {
 
   static ClassDocumentation<FRVDecayer> documentation
     ("The FRVDecayer class handles the decay of a fermion to "
      "a spin-3/2 particle and a vector boson.");
 
 }
diff --git a/Decay/General/FRVDecayer.h b/Decay/General/FRVDecayer.h
--- a/Decay/General/FRVDecayer.h
+++ b/Decay/General/FRVDecayer.h
@@ -1,170 +1,171 @@
 // -*- C++ -*-
 //
 // FRVDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_FRVDecayer_H
 #define HERWIG_FRVDecayer_H
 //
 // This is the declaration of the FRVDecayer class.
 //
 
 #include "GeneralTwoBodyDecayer.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Helicity/Vertex/Vector/RFVVertex.h"
 
 namespace Herwig {
 using namespace ThePEG;
 using Helicity::RFVVertexPtr;
 
   /** \ingroup Decay
    * The FRVDecayer class implements the decay of a fermion
    * to a spin-3/2 fermion and a vector in a general model. It holds an RFVVertex 
    * pointer that must be typecast from the VertexBase pointer held in 
    * GeneralTwoBodyDecayer. It implents the virtual functions me2() and
    * partialWidth(). 
    *
    * @see GeneralTwoBodyDecayer
    */
 class FRVDecayer: public GeneralTwoBodyDecayer {
 
 public:
 
   /**
    * The default constructor.
    */
   FRVDecayer() {}
   
 public:
 
   /** @name Virtual functions required by the Decayer class. */
   //@{
    /**
    * Return the matrix element squared for a given mode and phase-space channel.  
    * @param ichan The channel we are calculating the matrix element for.
    * @param part The decaying Particle.
    * @param decay The particles produced in the decay.
    * @param meopt Option for the matrix element
    * @return The matrix element squared for the phase-space configuration.
    */
   virtual double me2(const int ichan, const Particle & part,
 		     const ParticleVector & decay, MEOption meopt) const;
   
   /**
    * Function to return partial Width
    * @param inpart The decaying particle.
    * @param outa One of the decay products.
    * @param outb The other decay product.
    */
   virtual Energy partialWidth(PMPair inpart, PMPair outa, 
 			      PMPair outb) const;
 
   /**
    *  Set the information on the decay
    */
-  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
+  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing,
+			    vector<VertexBasePtr>,
 			    map<ShowerInteraction,VertexBasePtr> &,
 			    const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			    map<ShowerInteraction,VertexBasePtr>);
   //@}
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const;
 
   /** Make a clone of this object, possibly modifying the cloned object
    * to make it sane.
    * @return a pointer to the new object.
    */
   virtual IBPtr fullclone() const;
   //@}
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FRVDecayer & operator=(const FRVDecayer &);
 
 private:
 
   /**
    *  Abstract pointer to AbstractFRVVertex
    */
-  AbstractRFVVertexPtr vertex_;
+  vector<AbstractRFVVertexPtr> vertex_;
 
   /**
    * Pointer to the perturbative vertex
    */
-  RFVVertexPtr perturbativeVertex_;
+  vector<RFVVertexPtr> perturbativeVertex_;
 
   /**
    *  Spin density matrix
    */
   mutable RhoDMatrix rho_;
 
   /**
    *  Spinor wavefunction
    */
   mutable vector<SpinorWaveFunction>    wave_   ;
 
   /**
    *  Barred spinor wavefunction
    */
   mutable vector<SpinorBarWaveFunction> wavebar_;
 
   /**
    *  RS Spinor wavefunction
    */
   mutable vector<RSSpinorWaveFunction>    RSwave_   ;
 
   /**
    *  Barred RS spinor wavefunction
    */
   mutable vector<RSSpinorBarWaveFunction> RSwavebar_;
 
   /**
    *  Polarization vectors
    */
   mutable vector<VectorWaveFunction> vector_;
 };
 
 }
 
 #endif /* HERWIG_FRVDecayer_H */
diff --git a/Decay/General/GeneralTwoBodyDecayer.h b/Decay/General/GeneralTwoBodyDecayer.h
--- a/Decay/General/GeneralTwoBodyDecayer.h
+++ b/Decay/General/GeneralTwoBodyDecayer.h
@@ -1,305 +1,306 @@
 // -*- C++ -*-
 //
 // GeneralTwoBodyDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_GeneralTwoBodyDecayer_H
 #define HERWIG_GeneralTwoBodyDecayer_H
 //
 // This is the declaration of the GeneralTwoBodyDecayer class.
 //
 
 #include "Herwig/Decay/PerturbativeDecayer.h"
 #include "Herwig/Decay/DecayPhaseSpaceMode.h"
 #include "ThePEG/Helicity/Vertex/VertexBase.h"
 #include "GeneralTwoBodyDecayer.fh"
 
 namespace Herwig {
 using namespace ThePEG;
 using Helicity::VertexBasePtr;
 
 /** \ingroup Decay
  * The GeneralTwoBodyDecayer class is designed to be the base class 
  * for 2 body decays for some general model. It inherits from 
  * PerturbativeDecayer and implements the modeNumber() virtual function
  * that is the  same for all of the decays. A decayer for
  * a specific spin configuration should inherit from this and implement
  * the me2() and partialWidth() member functions. The colourConnections()
  * member should be called from inside me2() in the inheriting decayer
  * to set up the colour lines.
  *
  * @see \ref GeneralTwoBodyDecayerInterfaces "The interfaces"
  * defined for GeneralTwoBodyDecayer.
  * @see PerturbativeDecayer
  */
 class GeneralTwoBodyDecayer: public PerturbativeDecayer {
 
 public:
   
   /** A ParticleData ptr and (possible) mass pair.*/
   typedef pair<tcPDPtr, Energy> PMPair;
 
 public:
 
   /**
    * The default constructor.
    */
   GeneralTwoBodyDecayer() : maxWeight_(1.), colour_(1,DVector(1,1.))
   {}
 
 
   /** @name Virtual functions required by the Decayer class. */
   //@{
   /**
    * For a given decay mode and a given particle instance, perform the
    * decay and return the decay products. As this is the base class this
    * is not implemented.
    * @return The vector of particles produced in the decay.
    */
   virtual ParticleVector decay(const Particle & parent,
 			       const tPDVector & children) const;
 
   /**
    * Which of the possible decays is required
    * @param cc Is this mode the charge conjugate
    * @param parent The decaying particle
    * @param children The decay products
    */
   virtual int modeNumber(bool & cc, tcPDPtr parent,const tPDVector & children) const;
 
   /**
    * Return the matrix element squared for a given mode and phase-space channel
    * @param ichan The channel we are calculating the matrix element for.
    * @param part The decaying Particle.
    * @param decay The particles produced in the decay.
    * @param meopt Option for the calculation of the matrix element
    * @return The matrix element squared for the phase-space configuration.
    */
   virtual double me2(const int , const Particle & part,
 		     const ParticleVector & decay, MEOption meopt) const = 0;
   
   /**
    * Function to return partial Width
    * @param inpart The decaying particle.
    * @param outa One of the decay products.
    * @param outb The other decay product.
    */
   virtual Energy partialWidth(PMPair inpart, PMPair outa, 
 			      PMPair outb) const;
 
   /**
    * Specify the \f$1\to2\f$ matrix element to be used in the running width 
    * calculation.
    * @param dm The DecayMode
    * @param mecode The code for the matrix element as described
    *               in the GenericWidthGenerator class.
    * @param coupling The coupling for the matrix element.
    * @return True if the the order of the particles in the 
    * decayer is the same as the DecayMode tag.
    */
   virtual bool twoBodyMEcode(const DecayMode & dm, int & mecode,
 			     double & coupling) const;
 
   /**
    * An overidden member to calculate a branching ratio for a certain
    * particle instance.
    * @param dm The DecayMode of the particle
    * @param p The particle object
    * @param oldbrat The branching fraction given in the DecayMode object
    */
   virtual double brat(const DecayMode & dm, const Particle & p,
 		      double oldbrat) const;
   //@}
 
   /**
    *  Set the information on the decay
    */
-  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
+  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing,
+			    vector<VertexBasePtr>,
 			    map<ShowerInteraction,VertexBasePtr> &,
 			    const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			    map<ShowerInteraction,VertexBasePtr>) =0;
 
 protected:
   
   /** @name Functions used by inheriting decayers. */
   //@{
   /**
    * Set integration weight
    * @param wgt Maximum integration weight 
    */
   void setWeight(double wgt) { maxWeight_ = wgt; }
 
   /**
    * Set colour connections
    * @param parent Parent particle
    * @param out Particle vector containing particles to 
    * connect colour lines
    */
   void colourConnections(const Particle & parent, 
 			 const ParticleVector & out) const;
 
   /**
    *  Compute the spin and colour factor
    */
   double colourFactor(tcPDPtr in, tcPDPtr out1, tcPDPtr out2) const;
 
   /**
    *  Calculate matrix element ratio R/B
    */
   double matrixElementRatio(const Particle & inpart, const ParticleVector & decay2,
 			    const ParticleVector & decay3, MEOption meopt,
 			    ShowerInteraction inter);
 
   /**
    *  Set the information on the decay
    */
   void decayInfo(PDPtr incoming, PDPair outgoing);
   //@}
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Standard Interfaced functions. */
   //@{
   /**
    * Initialize this object after the setup phase before saving an
    * EventGenerator to disk.
    * @throws InitException if object could not be initialized properly.
    */
   virtual void doinit();
 
   /**
    * Initialize this object. Called in the run phase just before
    * a run begins.
    */
   virtual void doinitrun();
   //@}
 
 protected:
 
   /**
    *  Member for the generation of additional hard radiation
    */
   //@{
   /**
    * Return the matrix of colour factors 
    */
   typedef vector<pair<int,double > > CFlowPairVec;
   typedef vector<CFlowPairVec> CFlow;
 
   const vector<DVector> & getColourFactors(const Particle & inpart, 
 					   const ParticleVector & decay, 
 					   unsigned int & nflow); 
  
   const CFlow & colourFlows(const Particle & inpart,
 			    const ParticleVector & decay);
 
   /**
    *  Three-body matrix element including additional QCD radiation
    */
   virtual double threeBodyME(const int , const Particle & inpart,
 			     const ParticleVector & decay,
 			     ShowerInteraction inter, MEOption meopt);
 
   //@}
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   GeneralTwoBodyDecayer & operator=(const GeneralTwoBodyDecayer &);
  
 private:
 
   /**
    *  Store the incoming particle
    */
   PDPtr incoming_;
 
   /**
    *  Outgoing particles
    */
   vector<PDPtr> outgoing_;
 
   /**
    * Maximum weight for integration
    */
   double maxWeight_;
 
   /**
    * Store colour factors for ME calc.
    */
   vector<DVector> colour_;
 
 };
 
 
 /**
  * Write a map with ShowerInteraction as the key
  */
 template<typename T, typename Cmp, typename A>
 inline PersistentOStream & operator<<(PersistentOStream & os,
 				      const map<ShowerInteraction,T,Cmp,A> & m) {
   os << m.size();
   if(m.find(ShowerInteraction::QCD)!=m.end()) {
     os << 0 << m.at(ShowerInteraction::QCD);
   }
   if(m.find(ShowerInteraction::QED)!=m.end()) {
     os << 1 << m.at(ShowerInteraction::QED);
   }
   return os;
 }
 
 /**
  * Read a map with ShowerInteraction as the key
  */
 template <typename T, typename Cmp, typename A>
 inline PersistentIStream & operator>>(PersistentIStream & is, map<ShowerInteraction,T,Cmp,A> & m) {
   m.clear();
   long size;
   int k;
   is >> size;
   while ( size-- && is ) {
     is >> k;
     if(k==0)
       is >> m[ShowerInteraction::QCD];
     else if(k==1)
       is >> m[ShowerInteraction::QED];
     else
       assert(false);
   }
   return is;
 }
 }
 
 #endif /* HERWIG_GeneralTwoBodyDecayer_H */
diff --git a/Decay/General/SFFDecayer.cc b/Decay/General/SFFDecayer.cc
--- a/Decay/General/SFFDecayer.cc
+++ b/Decay/General/SFFDecayer.cc
@@ -1,478 +1,491 @@
 // -*- C++ -*-
 //
 // SFFDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the SFFDecayer class.
 //
 
 #include "SFFDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr SFFDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr SFFDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void SFFDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
-			      VertexBasePtr vertex,
+			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> ) {
   decayInfo(incoming,outgoing);
-  vertex_             = dynamic_ptr_cast<AbstractFFSVertexPtr>(vertex);
-  perturbativeVertex_ = dynamic_ptr_cast<FFSVertexPtr>        (vertex);
+  for(auto vert : vertex) {
+    vertex_             .push_back(dynamic_ptr_cast<AbstractFFSVertexPtr>(vert));
+    perturbativeVertex_ .push_back(dynamic_ptr_cast<FFSVertexPtr>        (vert));
+  }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(inV.at(inter));
     outgoingVertex1_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(outV[0].at(inter));
     outgoingVertex2_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(outV[1].at(inter));
   }
 }
 
 void SFFDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_           << perturbativeVertex_ 
      << incomingVertex_   << outgoingVertex1_
      << outgoingVertex2_;
 }
 
 void SFFDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_           >> perturbativeVertex_ 
      >> incomingVertex_   >> outgoingVertex1_
      >> outgoingVertex2_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<SFFDecayer,GeneralTwoBodyDecayer>
 describeHerwigSFFDecayer("Herwig::SFFDecayer", "Herwig.so");
 
 void SFFDecayer::Init() {
 
   static ClassDocumentation<SFFDecayer> documentation
     ("This class implements to decay of a scalar to 2 fermions");
 
 }
 
 double SFFDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay,MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin1Half,PDT::Spin1Half)));
   // work out which is the fermion and antifermion
   int iferm(1),ianti(0);
   int itype[2];
   for(unsigned int ix=0;ix<2;++ix) {
     if(decay[ix]->dataPtr()->CC()) itype[ix] = decay[ix]->id()>0 ? 0:1;
     else                           itype[ix] = 2;
   }
   if(itype[0]==0||itype[1]==1||(itype[0]==2&&itype[1]==2)) swap(iferm,ianti);
 
   if(meopt==Initialize) {
     ScalarWaveFunction::
       calculateWaveFunctions(rho_,const_ptr_cast<tPPtr>(&inpart),incoming);
     swave_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
   }
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
     SpinorBarWaveFunction::
       constructSpinInfo(wavebar_,decay[iferm],outgoing,true);
     SpinorWaveFunction::
       constructSpinInfo(wave_   ,decay[ianti],outgoing,true);
     return 0.;
   }
   SpinorBarWaveFunction::
     calculateWaveFunctions(wavebar_,decay[iferm],outgoing);
   SpinorWaveFunction::
     calculateWaveFunctions(wave_   ,decay[ianti],outgoing);
   Energy2 scale(sqr(inpart.mass()));
   for(unsigned int ifm = 0; ifm < 2; ++ifm){
     for(unsigned int ia = 0; ia < 2; ++ia) {
-      if(iferm > ianti){
-	(*ME())(0, ia, ifm) = vertex_->evaluate(scale,wave_[ia],
-						     wavebar_[ifm],swave_);
-      }
-      else {
-	(*ME())(0, ifm, ia) = vertex_->evaluate(scale,wave_[ia],
-						     wavebar_[ifm],swave_);	
+      if(iferm > ianti) (*ME())(0, ia, ifm) = 0.;
+      else              (*ME())(0, ifm, ia) = 0.;
+      for(auto vert : vertex_) {
+	if(iferm > ianti){
+	  (*ME())(0, ia, ifm) += vert->evaluate(scale,wave_[ia],
+						wavebar_[ifm],swave_);
+	}
+	else {
+	  (*ME())(0, ifm, ia) += vert->evaluate(scale,wave_[ia],
+						wavebar_[ifm],swave_);
+	}
       }
     }
   }
 
   double output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy SFFDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
-  if(perturbativeVertex_) {
+  if(perturbativeVertex_.size()==1 &&
+     perturbativeVertex_[0]) {
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
-    perturbativeVertex_->setCoupling(sqr(inpart.second), outb.first, outa.first,
+    perturbativeVertex_[0]->setCoupling(sqr(inpart.second), outb.first, outa.first,
 				     in);
     double mu1(outa.second/inpart.second),mu2(outb.second/inpart.second);
-    double c2 = norm(perturbativeVertex_->norm());
-    Complex al(perturbativeVertex_->left()), ar(perturbativeVertex_->right());
+    double c2 = norm(perturbativeVertex_[0]->norm());
+    Complex al(perturbativeVertex_[0]->left()), ar(perturbativeVertex_[0]->right());
     double me2 = -c2*( (norm(al) + norm(ar))*( sqr(mu1) + sqr(mu2) - 1.)
 		       + 2.*(ar*conj(al) + al*conj(ar)).real()*mu1*mu2 );
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second, outa.second,
 					outb.second);
     Energy output = me2*pcm/(8*Constants::pi);
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 double SFFDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   // work out which is the fermion and antifermion
   int ianti(0), iferm(1), iglu(2);
   int itype[2];
   for(unsigned int ix=0;ix<2;++ix) {
     if(decay[ix]->dataPtr()->CC()) itype[ix] = decay[ix]->id()>0 ? 0:1;
     else                           itype[ix] = 2;
   }
   if(itype[0]==0 && itype[1]!=0) swap(iferm, ianti);
   if(itype[0]==2 && itype[1]==1) swap(iferm, ianti);
   if(itype[0]==0 && itype[1]==0 && decay[0]->dataPtr()->id()<decay[1]->dataPtr()->id()) 
     swap(iferm, ianti);
   if(itype[0]==1 && itype[1]==1 && decay[0]->dataPtr()->id()<decay[1]->dataPtr()->id()) 
     swap(iferm, ianti);
   
   if(meopt==Initialize) {
     // create scalar wavefunction for decaying particle
     ScalarWaveFunction::
       calculateWaveFunctions(rho3_,const_ptr_cast<tPPtr>(&inpart),incoming);
     swave3_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
   }
   // setup spin information when needed
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
     SpinorBarWaveFunction::
       constructSpinInfo(wavebar3_ ,decay[iferm],outgoing,true);
     SpinorWaveFunction::
       constructSpinInfo(wave3_    ,decay[ianti],outgoing,true);
     VectorWaveFunction::
       constructSpinInfo(gluon_    ,decay[iglu ],outgoing,true,false);
     return 0.;
   }
 
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
 
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin0,     PDT::Spin1Half,
 								       PDT::Spin1Half, PDT::Spin1)));
   // create wavefunctions
   SpinorBarWaveFunction::
     calculateWaveFunctions(wavebar3_, decay[iferm],outgoing);
   SpinorWaveFunction::
     calculateWaveFunctions(wave3_   , decay[ianti],outgoing);
   VectorWaveFunction::
     calculateWaveFunctions(gluon_   , decay[iglu ],outgoing,true);
 
   // gauge invariance test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[iglu ]->momentum(),
   				          decay[iglu ]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
 
   // identify fermion and/or anti-fermion vertex
   AbstractFFVVertexPtr outgoingVertexF;
   AbstractFFVVertexPtr outgoingVertexA;
   identifyVertices(iferm, ianti, inpart, decay, outgoingVertexF, outgoingVertexA,
 		   inter);
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
 
   Energy2 scale(sqr(inpart.mass()));
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
   for(unsigned int ifm = 0; ifm < 2; ++ifm) {
     for(unsigned int ia = 0; ia < 2; ++ia) {
       for(unsigned int ig = 0; ig < 2; ++ig) {
 	// radiation from the incoming scalar
 	if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	   (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	  assert(incomingVertex_[inter]);
 
 	  ScalarWaveFunction scalarInter = 
 	    incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),
 					      gluon_[2*ig],swave3_,inpart.mass());
 
 	  assert(swave3_.particle()->id()==scalarInter.particle()->id());
 
 	  if(!couplingSet) {
 	    gs = abs(incomingVertex_[inter]->norm());
 	    couplingSet = true;
 	  }
-	  Complex diag = vertex_->evaluate(scale,wave3_[ia],
-					   wavebar3_[ifm],scalarInter);
+	  Complex diag = 0.;
+	  for(auto vertex : vertex_)
+	    diag += vertex->evaluate(scale,wave3_[ia],
+				     wavebar3_[ifm],scalarInter);
 	  for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	    (*ME[colourFlow[0][ix].first])(0, ia, ifm, ig) += 
 	      colourFlow[0][ix].second*diag;
 	  }
 #ifdef GAUGE_CHECK
 	  total+=norm(diag);
 #endif
 	}
 	// radiation from outgoing fermion
 	if((decay[iferm]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	   (decay[iferm]->dataPtr()->charged()  && inter==ShowerInteraction::QED)) {
 	  assert(outgoingVertexF);
 	  // ensure you get correct outgoing particle from first vertex
 	  tcPDPtr off = decay[iferm]->dataPtr();
 	  if(off->CC()) off = off->CC();
 	  SpinorBarWaveFunction interS = 
 	    outgoingVertexF->evaluate(scale,3,off,wavebar3_[ifm],
 				      gluon_[2*ig],decay[iferm]->mass());
 	  
 	  assert(wavebar3_[ifm].particle()->id()==interS.particle()->id());
 	  
 	  if(!couplingSet) {
 	    gs = abs(outgoingVertexF->norm());
 	    couplingSet = true;
 	  }
-	  Complex diag = vertex_->evaluate(scale,wave3_[ia], interS,swave3_);
+	  Complex diag = 0.;
+	  for(auto vertex : vertex_)
+	    diag += vertex->evaluate(scale,wave3_[ia], interS,swave3_);
 	  for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
 	    (*ME[colourFlow[1][ix].first])(0, ia, ifm, ig) += 
 	      colourFlow[1][ix].second*diag;
 	  }
 #ifdef GAUGE_CHECK
 	  total+=norm(diag);
 #endif
 	}
 	
 	// radiation from outgoing antifermion
 	if((decay[ianti]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	   (decay[ianti]->dataPtr()->charged()  && inter==ShowerInteraction::QED)) {
 	  assert(outgoingVertexA);
 	  // ensure you get correct outgoing particle from first vertex
 	  tcPDPtr off = decay[ianti]->dataPtr();
 	  if(off->CC()) off = off->CC();
 	  SpinorWaveFunction  interS = 
 	    outgoingVertexA->evaluate(scale,3,off,wave3_[ia],
 				      gluon_[2*ig],decay[ianti]->mass());
 	  
 	  assert(wave3_[ia].particle()->id()==interS.particle()->id());
 
 	  if(!couplingSet) {
 	    gs = abs(outgoingVertexA->norm());
 	    couplingSet = true;
 	  }
-	  Complex diag = vertex_->evaluate(scale,interS,wavebar3_[ifm],swave3_);
+	  Complex diag = 0.;
+	  for(auto vertex : vertex_)
+	    diag += vertex->evaluate(scale,interS,wavebar3_[ifm],swave3_);
 	  for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	    (*ME[colourFlow[2][ix].first])(0, ia, ifm, ig) += 
 	      colourFlow[2][ix].second*diag;
 	  }
 #ifdef GAUGE_CHECK
 	  total+=norm(diag);
 #endif
 	}
       }
     }
   }
   
   // contract matrices 
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha(S,EM)
   output *= (4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
     // return the answer
   return output;
 }
 
 void SFFDecayer::identifyVertices(const int iferm, const int ianti,
 				  const Particle & inpart, const ParticleVector & decay, 
 				  AbstractFFVVertexPtr & outgoingVertexF, 
 				  AbstractFFVVertexPtr & outgoingVertexA,
 				  ShowerInteraction inter) {
   // QCD
   if(inter==ShowerInteraction::QCD) {
     // work out which fermion each outgoing vertex corresponds to 
     // two outgoing vertices
     if( inpart.dataPtr()       ->iColour()==PDT::Colour0     &&
 	((decay[iferm]->dataPtr()->iColour()==PDT::Colour3     &&
 	  decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar) ||
 	 (decay[iferm]->dataPtr()->iColour()==PDT::Colour8     &&
 	  decay[ianti]->dataPtr()->iColour()==PDT::Colour8))) {
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]) {
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))) {
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))) {
 	outgoingVertexF = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
     else if(inpart.dataPtr()       ->iColour()==PDT::Colour8 &&
 	    decay[iferm]->dataPtr()->iColour()==PDT::Colour3 &&
 	    decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar) {
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]) {
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))) {
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))) {
 	outgoingVertexF = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
     
     // one outgoing vertex
     else if(inpart.dataPtr()->iColour()==PDT::Colour3){
       if(decay[iferm]->dataPtr()->iColour()==PDT::Colour3 &&  
 	 decay[ianti]->dataPtr()->iColour()==PDT::Colour0){
       if     (outgoingVertex1_[inter]) outgoingVertexF = outgoingVertex1_[inter];
       else if(outgoingVertex2_[inter]) outgoingVertexF = outgoingVertex2_[inter];
       }
       else if (decay[iferm]->dataPtr()->iColour()==PDT::Colour3 &&
 	       decay[ianti]->dataPtr()->iColour()==PDT::Colour8) {
 	if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[ianti]->dataPtr()))) {
 	  outgoingVertexF = outgoingVertex2_[inter];
 	  outgoingVertexA = outgoingVertex1_[inter];
 	}
 	else {
 	  outgoingVertexF = outgoingVertex1_[inter];
 	  outgoingVertexA = outgoingVertex2_[inter];
 	}
       }
       else if(decay[iferm]->dataPtr()->iColour()==PDT::Colour3bar &&
 	      decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar) {
 	if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))) {
 	  outgoingVertexF = outgoingVertex1_[inter];
 	  outgoingVertexA = outgoingVertex2_[inter];
 	}
 	else {
 	  outgoingVertexF = outgoingVertex2_[inter];
 	  outgoingVertexA = outgoingVertex1_[inter];
 	}
       }
     }
     else if(inpart.dataPtr()->iColour()==PDT::Colour3bar){
       if(decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar &&  
 	 decay[iferm]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertexA = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (decay[iferm]->dataPtr()->iColour()==PDT::Colour8 &&
 	       decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar){
 	if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))) {
 	  outgoingVertexF = outgoingVertex1_[inter];
 	  outgoingVertexA = outgoingVertex2_[inter];
 	}
 	else {
 	  outgoingVertexF = outgoingVertex2_[inter];
 	  outgoingVertexA = outgoingVertex1_[inter];
 	}
       }
       else if(decay[iferm]->dataPtr()->iColour()==PDT::Colour3 &&
 	      decay[ianti]->dataPtr()->iColour()==PDT::Colour3) {
 	if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))) {
 	  outgoingVertexF = outgoingVertex1_[inter];
 	  outgoingVertexA = outgoingVertex2_[inter];
 	}
 	else {
 	  outgoingVertexF = outgoingVertex2_[inter];
 	  outgoingVertexA = outgoingVertex1_[inter];
 	}
       }
     }
     else if(inpart.dataPtr()->iColour()==PDT::Colour6 ||
 	    inpart.dataPtr()->iColour()==PDT::Colour6bar) {
       if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))) {
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else {
 	outgoingVertexF = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
   
     if (! ((incomingVertex_[inter]  && (outgoingVertexF  || outgoingVertexA)) ||
 	   ( outgoingVertexF &&  outgoingVertexA))) {
       throw Exception()
 	<< "Invalid vertices for QCD radiation in SFF decay in SFFDecayer::identifyVertices"
 	<< Exception::runerror;
     }
   }
   // QED
   else {
     if(decay[iferm]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr())))
 	outgoingVertexF = outgoingVertex1_[inter];
       else
 	outgoingVertexF = outgoingVertex2_[inter];
     }
     if(decay[ianti]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[ianti]->dataPtr())))
 	outgoingVertexA = outgoingVertex1_[inter];
       else
 	outgoingVertexA = outgoingVertex2_[inter];
     }
   }
 }
diff --git a/Decay/General/SFFDecayer.h b/Decay/General/SFFDecayer.h
--- a/Decay/General/SFFDecayer.h
+++ b/Decay/General/SFFDecayer.h
@@ -1,226 +1,234 @@
 // -*- C++ -*-
 //
 // SFFDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_SFFDecayer_H
 #define HERWIG_SFFDecayer_H
 //
 // This is the declaration of the SFFDecayer class.
 //
 
 #include "GeneralTwoBodyDecayer.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Helicity/Vertex/Scalar/FFSVertex.h"
 #include "ThePEG/Helicity/Vertex/Scalar/VSSVertex.h"
 #include "ThePEG/Helicity/Vertex/Vector/FFVVertex.h"
 
 namespace Herwig {
 using namespace ThePEG;
 using Helicity::FFSVertexPtr;
 
   /** \ingroup Decay
    * The SFFDecayer class implements the decay of a scalar to 2
    * fermions in a general model. It holds an FFSVertex pointer that 
    * must be typecast from the VertexBase pointer held in 
    * GeneralTwoBodyDecayer. It implents the virtual functions me2() and
    * partialWidth(). 
    *
    * @see GeneralTwoBodyDecayer
    */
 class SFFDecayer: public GeneralTwoBodyDecayer {
 
 public:
 
   /**
    * The default constructor.
    */
   SFFDecayer() {}
 
   /** @name Virtual functions required by the Decayer class. */
   //@{
  /**
    * Return the matrix element squared for a given mode and phase-space channel.
    * @param ichan The channel we are calculating the matrix element for.
    * @param part The decaying Particle.
    * @param decay The particles produced in the decay.
    * @param meopt Option for the calculation of the matrix element
    * @return The matrix element squared for the phase-space configuration.
    */
   virtual double me2(const int ichan, const Particle & part,
 		     const ParticleVector & decay, MEOption meopt) const;
   
   /**
    * Function to return partial Width
    * @param inpart The decaying particle.
    * @param outa One of the decay products.
    * @param outb The other decay product.
    */
   virtual Energy partialWidth(PMPair inpart, PMPair outa, 
 			      PMPair outb) const;
 
   /**
    *  Has a POWHEG style correction
    */
   virtual POWHEGType hasPOWHEGCorrection()  {
-    return (vertex_->orderInGem()+vertex_->orderInGs())==1 ? FSR : No;
+    POWHEGType output = FSR;
+    for(auto vertex : vertex_) {
+      if(vertex->orderInAllCouplings()!=1) {
+	output = No;
+	break;
+      }
+    }
+    return output;
   }
 
   /**
    *  Three-body matrix element including additional QCD radiation
    */
   virtual double threeBodyME(const int , const Particle & inpart,
 			     const ParticleVector & decay,
 			     ShowerInteraction inter,
 			     MEOption meopt);
 
   /**
    * Indentify outgoing vertices for the fermion and antifermion
    */
   void identifyVertices(const int iferm, const int ianti,
 			const Particle & inpart, const ParticleVector & decay,
 			AbstractFFVVertexPtr & outgoingVertexF, 
 			AbstractFFVVertexPtr & outgoingVertexA,
 			ShowerInteraction inter);
 
   /**
    *  Set the information on the decay
    */
-  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
+  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing,
+			    vector<VertexBasePtr>,
 			    map<ShowerInteraction,VertexBasePtr> &,
 			    const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			    map<ShowerInteraction,VertexBasePtr>);
   //@}
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const;
 
   /** Make a clone of this object, possibly modifying the cloned object
    * to make it sane.
    * @return a pointer to the new object.
    */
   virtual IBPtr fullclone() const;
   //@}
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   SFFDecayer & operator=(const SFFDecayer &);
 
 private:
 
   /**
    *  Abstract pointer to AbstractFFSVertex
    */
-  AbstractFFSVertexPtr vertex_;
+  vector<AbstractFFSVertexPtr> vertex_;
 
   /**
    * Pointer to the perturbative vertex
    */
-  FFSVertexPtr perturbativeVertex_;
+  vector<FFSVertexPtr> perturbativeVertex_;
 
   /**
    *  Abstract pointer to AbstractVSSVertex for QCD radiation from incoming scalar
    */
   map<ShowerInteraction,AbstractVSSVertexPtr> incomingVertex_;
 
   /**
    *  Abstract pointer to AbstractFFVVertex for QCD radiation from outgoing (anti)fermion
    */
   map<ShowerInteraction,AbstractFFVVertexPtr> outgoingVertex1_;
 
   /**
    *  Abstract pointer to AbstractFFVVertex for QCD radiation from outgoing (anti)fermion
    */
   map<ShowerInteraction,AbstractFFVVertexPtr> outgoingVertex2_;
 
   /**
    *  Spin density matrix
    */
   mutable RhoDMatrix rho_;
 
   /**
    *  Scalar wavefunction
    */
   mutable ScalarWaveFunction swave_;
 
   /**
    *  Spinor wavefunction
    */
   mutable vector<SpinorWaveFunction> wave_;
 
   /**
    *  Barred spinor wavefunction
    */
   mutable vector<SpinorBarWaveFunction> wavebar_;
 
  /**
    *  Spin density matrix for 3 body decay
    */
   mutable RhoDMatrix rho3_;
 
   /**
    *  Scalar wavefunction for 3 body decay
    */
   mutable ScalarWaveFunction swave3_;
 
   /**
    *  Spinor wavefunction for 3 body decay
    */
   mutable vector<SpinorWaveFunction> wave3_;
 
   /**
    *  Barred spinor wavefunction for 3 body decay
    */
   mutable vector<SpinorBarWaveFunction> wavebar3_;
 
     /**
    *  Vector wavefunction for 3 body decay
    */
   mutable vector<VectorWaveFunction> gluon_;
 
   
 };
 
 }
 
 #endif /* HERWIG_SFFDecayer_H */
diff --git a/Decay/General/SRFDecayer.cc b/Decay/General/SRFDecayer.cc
--- a/Decay/General/SRFDecayer.cc
+++ b/Decay/General/SRFDecayer.cc
@@ -1,181 +1,196 @@
 // -*- C++ -*-
 //
 // SRFDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the SRFDecayer class.
 //
 
 #include "SRFDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr SRFDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr SRFDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void SRFDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
-			      VertexBasePtr vertex,
+			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> &,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			      map<ShowerInteraction,VertexBasePtr>) {
   decayInfo(incoming,outgoing);
-  vertex_             = dynamic_ptr_cast<AbstractRFSVertexPtr>(vertex);
-  perturbativeVertex_ = dynamic_ptr_cast<RFSVertexPtr>        (vertex);
+  for(auto vert : vertex) {
+    vertex_             .push_back(dynamic_ptr_cast<AbstractRFSVertexPtr>(vert));
+    perturbativeVertex_ .push_back(dynamic_ptr_cast<RFSVertexPtr>        (vert));
+  }
 }
 
 void SRFDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_ << perturbativeVertex_;
 }
 
 void SRFDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_ >> perturbativeVertex_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<SRFDecayer,GeneralTwoBodyDecayer>
 describeHerwigSRFDecayer("Herwig::SRFDecayer", "Herwig.so");
 
 void SRFDecayer::Init() {
 
   static ClassDocumentation<SRFDecayer> documentation
     ("This class implements to decay of a scalar to a spin-3/2 and"
      " spin-1/2 fermion");
 
 }
 
 double SRFDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay,MEOption meopt) const {
   unsigned int irs=0,ifm=1;
   if(decay[0]->dataPtr()->iSpin()==PDT::Spin1Half) swap(irs,ifm);
   if(!ME()) {
     if(irs==0)
       ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin3Half,PDT::Spin1Half)));
     else
       ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin1Half,PDT::Spin3Half)));
   }
   bool ferm = decay[ifm]->id()<0;
   if(meopt==Initialize) {
     ScalarWaveFunction::
       calculateWaveFunctions(rho_,const_ptr_cast<tPPtr>(&inpart),incoming);
     swave_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
   }
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
     if(ferm) {
       RSSpinorBarWaveFunction::
 	constructSpinInfo(RSwavebar_,decay[irs],outgoing,true);
       SpinorWaveFunction::
 	constructSpinInfo(wave_     ,decay[ifm],outgoing,true);
     }
     else {
       RSSpinorWaveFunction::
 	constructSpinInfo(RSwave_ ,decay[irs],outgoing,true);
       SpinorBarWaveFunction::
 	constructSpinInfo(wavebar_,decay[ifm],outgoing,true);
     }
     return 0.;
   }
   if(ferm) {
     RSSpinorBarWaveFunction::
       calculateWaveFunctions(RSwavebar_,decay[irs],outgoing);
     SpinorWaveFunction::
       calculateWaveFunctions(wave_     ,decay[ifm],outgoing);
   }
   else {
     RSSpinorWaveFunction::
       calculateWaveFunctions(RSwave_ ,decay[irs],outgoing);
     SpinorBarWaveFunction::
       calculateWaveFunctions(wavebar_,decay[ifm],outgoing);
   }
   Energy2 scale(sqr(inpart.mass()));
   for(unsigned int ifm = 0; ifm < 4; ++ifm){
     for(unsigned int ia = 0; ia < 2; ++ia) {
       if(irs==0) {
-	if(ferm)
-	  (*ME())(0, ifm, ia) = vertex_->evaluate(scale,wave_[ia],
-						       RSwavebar_[ifm],swave_);
-	else
-	  (*ME())(0, ifm, ia) = vertex_->evaluate(scale,RSwave_[ifm],
-						       wavebar_[ia],swave_);
+	if(ferm) {
+	  (*ME())(0, ifm, ia) = 0.;
+	  for(auto vert : vertex_)
+	    (*ME())(0, ifm, ia) += vert->evaluate(scale,wave_[ia],
+						  RSwavebar_[ifm],swave_);
+	}
+	else {
+	  (*ME())(0, ifm, ia) = 0.;
+	  for(auto vert : vertex_)
+	    (*ME())(0, ifm, ia) += vert->evaluate(scale,RSwave_[ifm],
+						  wavebar_[ia],swave_);
+	}
       }
       else {
-	if(ferm)
-	  (*ME())(0, ia, ifm) = vertex_->evaluate(scale,wave_[ia],
-						       RSwavebar_[ifm],swave_);
-	else
-	  (*ME())(0, ia, ifm) = vertex_->evaluate(scale,RSwave_[ifm],
-						       wavebar_[ia],swave_);
+	if(ferm) {
+	  (*ME())(0, ia, ifm) = 0.;
+	  for(auto vert : vertex_)
+	    (*ME())(0, ia, ifm) += vert->evaluate(scale,wave_[ia],
+						  RSwavebar_[ifm],swave_);
+	}
+	else {
+	  (*ME())(0, ia, ifm) = 0.;
+	  for(auto vert : vertex_)
+	    (*ME())(0, ia, ifm) += vert->evaluate(scale,RSwave_[ifm],
+						  wavebar_[ia],swave_);
+	}
       }
     }
   }
   double output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[irs]->dataPtr(),
 			 decay[ifm]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy SRFDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
-  if(perturbativeVertex_) {
+  if(perturbativeVertex_.size()==1 &&
+     perturbativeVertex_[0]) {
     Energy q = inpart.second;
     Energy m1 = outa.second, m2 = outb.second;
     // couplings
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     if(outa.first->iSpin()==PDT::Spin1Half) {
       swap(m1,m2);
-      perturbativeVertex_->setCoupling(sqr(inpart.second),outb.first,
+      perturbativeVertex_[0]->setCoupling(sqr(inpart.second),outb.first,
 				       outa.first, in);
     }
     else {
-      perturbativeVertex_->setCoupling(sqr(inpart.second),outa.first,
+      perturbativeVertex_[0]->setCoupling(sqr(inpart.second),outa.first,
 				       outb.first, in);
     }
-    Complex left  = perturbativeVertex_-> left()*perturbativeVertex_-> norm();
-    Complex right = perturbativeVertex_->right()*perturbativeVertex_-> norm();
+    Complex left  = perturbativeVertex_[0]-> left()*perturbativeVertex_[0]-> norm();
+    Complex right = perturbativeVertex_[0]->right()*perturbativeVertex_[0]-> norm();
     complex<InvEnergy> A1 = 0.5*(left+right)*UnitRemoval::InvE;
     complex<InvEnergy> B1 = 0.5*(right-left)*UnitRemoval::InvE;
     Energy2 q2(q*q),m12(m1*m1),m22(m2*m2);
     Energy2 pcm2(0.25*(q2*(q2-2.*m12-2.*m22)+(m12-m22)*(m12-m22))/q2);
     Energy pcm(sqrt(pcm2));
     Energy Qp(sqrt(-sqr(m2+m1)+q2)),Qm(sqrt(-sqr(m2-m1)+q2));
     double r23(sqrt(2./3.));
     complex<Energy> h1(-2.*r23*pcm*q/m1*Qm*B1);
     complex<Energy> h2( 2.*r23*pcm*q/m1*Qp*A1);
     double me2 = real(h1*conj(h1)+h2*conj(h2))/2./sqr(inpart.second);
     Energy output = me2*pcm/8./Constants::pi;
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
diff --git a/Decay/General/SRFDecayer.h b/Decay/General/SRFDecayer.h
--- a/Decay/General/SRFDecayer.h
+++ b/Decay/General/SRFDecayer.h
@@ -1,170 +1,171 @@
 // -*- C++ -*-
 //
 // SRFDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_SRFDecayer_H
 #define HERWIG_SRFDecayer_H
 //
 // This is the declaration of the SRFDecayer class.
 //
 
 #include "GeneralTwoBodyDecayer.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Helicity/Vertex/Scalar/RFSVertex.h"
 
 namespace Herwig {
 using namespace ThePEG;
 using Helicity::RFSVertexPtr;
 
 /** \ingroup Decay
  * The SRFDecayer class implements the decay of a scalar to spin-3/2
  * and spin-1/2 fermion in a general model. It holds an RFSVertex pointer that 
  * must be typecast from the VertexBase pointer held in 
  * GeneralTwoBodyDecayer. It implents the virtual functions me2() and
  * partialWidth(). 
  *
  * @see GeneralTwoBodyDecayer
  */
 class SRFDecayer: public GeneralTwoBodyDecayer {
 
 public:
 
   /**
    * The default constructor.
    */
   SRFDecayer() {}
 
   /** @name Virtual functions required by the Decayer class. */
   //@{
  /**
    * Return the matrix element squared for a given mode and phase-space channel.
    * @param ichan The channel we are calculating the matrix element for.
    * @param part The decaying Particle.
    * @param decay The particles produced in the decay.
    * @param meopt Option for the calculation of the matrix element
    * @return The matrix element squared for the phase-space configuration.
    */
   virtual double me2(const int ichan, const Particle & part,
 		     const ParticleVector & decay, MEOption meopt) const;
   
   /**
    * Function to return partial Width
    * @param inpart The decaying particle.
    * @param outa One of the decay products.
    * @param outb The other decay product.
    */
   virtual Energy partialWidth(PMPair inpart, PMPair outa, 
 			      PMPair outb) const;
 
   /**
    *  Set the information on the decay
    */
-  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
+  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing,
+			    vector<VertexBasePtr>,
 			    map<ShowerInteraction,VertexBasePtr> &,
 			    const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			    map<ShowerInteraction,VertexBasePtr>);
   //@}
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const;
 
   /** Make a clone of this object, possibly modifying the cloned object
    * to make it sane.
    * @return a pointer to the new object.
    */
   virtual IBPtr fullclone() const;
   //@}
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   SRFDecayer & operator=(const SRFDecayer &);
 
 private:
 
   /**
    *  Abstract pointer to AbstractFFSVertex
    */
-  AbstractRFSVertexPtr vertex_;
+  vector<AbstractRFSVertexPtr> vertex_;
 
   /**
    * Pointer to the perturbative vertex
    */
-  RFSVertexPtr perturbativeVertex_;
+  vector<RFSVertexPtr> perturbativeVertex_;
 
   /**
    *  Spin density matrix
    */
   mutable RhoDMatrix rho_;
 
   /**
    *  Scalar wavefunction
    */
   mutable ScalarWaveFunction swave_;
 
   /**
    *  Spinor wavefunction
    */
   mutable vector<SpinorWaveFunction> wave_;
 
   /**
    *  Barred spinor wavefunction
    */
   mutable vector<SpinorBarWaveFunction> wavebar_;
 
   /**
    *  RS Spinor wavefunction
    */
   mutable vector<RSSpinorWaveFunction> RSwave_;
 
   /**
    *  Barred RS spinor wavefunction
    */
   mutable vector<RSSpinorBarWaveFunction> RSwavebar_;
 
   
 };
 
 }
 
 #endif /* HERWIG_SRFDecayer_H */
diff --git a/Decay/General/SSSDecayer.cc b/Decay/General/SSSDecayer.cc
--- a/Decay/General/SSSDecayer.cc
+++ b/Decay/General/SSSDecayer.cc
@@ -1,398 +1,410 @@
 // -*- C++ -*-
 //
 // SSSDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the SSSDecayer class.
 //
 
 #include "SSSDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr SSSDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr SSSDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void SSSDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
-			      VertexBasePtr vertex,
+			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> ) {
   decayInfo(incoming,outgoing);
-  vertex_             = dynamic_ptr_cast<AbstractSSSVertexPtr>(vertex);
-  perturbativeVertex_ = dynamic_ptr_cast<SSSVertexPtr>        (vertex);
+  for(auto vert : vertex) {
+    vertex_            .push_back(dynamic_ptr_cast<AbstractSSSVertexPtr>(vert));
+    perturbativeVertex_.push_back(dynamic_ptr_cast<SSSVertexPtr>        (vert));
+  }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(inV.at(inter));
     outgoingVertex1_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[0].at(inter));
     outgoingVertex2_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[1].at(inter));
   }
 }
 
 void SSSDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_           << perturbativeVertex_
      << incomingVertex_   << outgoingVertex1_
      << outgoingVertex2_;
 }
 
 void SSSDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_           >> perturbativeVertex_
      >> incomingVertex_   >> outgoingVertex1_
      >> outgoingVertex2_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<SSSDecayer,GeneralTwoBodyDecayer>
 describeHerwigSSSDecayer("Herwig::SSSDecayer", "Herwig.so");
 
 void SSSDecayer::Init() {
 
   static ClassDocumentation<SSSDecayer> documentation
     ("This class implements the decay of a scalar to 2 scalars.");
 
 }
 
 double SSSDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay,
 		       MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin0,PDT::Spin0)));
   if(meopt==Initialize) {
     ScalarWaveFunction::
       calculateWaveFunctions(rho_,const_ptr_cast<tPPtr>(&inpart),incoming);
     swave_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
   }
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
     for(unsigned int ix=0;ix<2;++ix)
       ScalarWaveFunction::
 	constructSpinInfo(decay[ix],outgoing,true);
   }
   ScalarWaveFunction s1(decay[0]->momentum(),decay[0]->dataPtr(),outgoing);
   ScalarWaveFunction s2(decay[1]->momentum(),decay[1]->dataPtr(),outgoing);
   Energy2 scale(sqr(inpart.mass()));
-  (*ME())(0,0,0) = vertex_->evaluate(scale,s1,s2,swave_);
+  (*ME())(0,0,0) = 0.;
+  for(auto vert : vertex_) {
+    (*ME())(0,0,0) += vert->evaluate(scale,s1,s2,swave_);
+  }
   double output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy SSSDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
-  if(perturbativeVertex_ && !perturbativeVertex_->kinematics()) {
+  if(perturbativeVertex_.size()==1 &&
+     perturbativeVertex_[0] && !perturbativeVertex_[0]->kinematics()) {
     Energy2 scale(sqr(inpart.second));
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
-    perturbativeVertex_->setCoupling(scale, in, outa.first, outb.first);
+    perturbativeVertex_[0]->setCoupling(scale, in, outa.first, outb.first);
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second, outa.second,
 					       outb.second);
-    double c2 = norm(perturbativeVertex_->norm());
+    double c2 = norm(perturbativeVertex_[0]->norm());
     Energy pWidth = c2*pcm/8./Constants::pi/scale*UnitRemoval::E2;
     // colour factor
     pWidth *= colourFactor(inpart.first,outa.first,outb.first);
     return pWidth;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 double SSSDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   // work out which is the scalar and anti scalar
   int ianti(0), iscal(1), iglu(2);
   int itype[2];
   for(unsigned int ix=0;ix<2;++ix) {
     if(decay[ix]->dataPtr()->CC()) itype[ix] = decay[ix]->id()>0 ? 0:1;
     else                           itype[ix] = 2;
   }
   if(itype[0]==0 && itype[1]!=0) swap(ianti, iscal);
   if(itype[0]==2 && itype[1]==1) swap(ianti, iscal);
   if(itype[0]==0 && itype[1]==0 && abs(decay[0]->dataPtr()->id())>abs(decay[1]->dataPtr()->id())) 
     swap(iscal, ianti);
   if(itype[0]==1 && itype[1]==1 && abs(decay[0]->dataPtr()->id())<abs(decay[1]->dataPtr()->id())) 
     swap(iscal, ianti);
 
   if(meopt==Initialize) {
     // create scalar wavefunction for decaying particle
     ScalarWaveFunction::calculateWaveFunctions(rho3_,const_ptr_cast<tPPtr>(&inpart),incoming);
     swave3_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
   }
   // setup spin information when needed
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
     ScalarWaveFunction::
       constructSpinInfo(decay[iscal],outgoing,true);
     ScalarWaveFunction::
       constructSpinInfo(decay[ianti],outgoing,true);
     VectorWaveFunction::
       constructSpinInfo(gluon_,decay[iglu ],outgoing,true,false);
     return 0.;
   }
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
 
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin0, PDT::Spin0,
 								       PDT::Spin0, PDT::Spin1)));
 
   // create wavefunctions
   ScalarWaveFunction scal(decay[iscal]->momentum(), decay[iscal]->dataPtr(),outgoing);
   ScalarWaveFunction anti(decay[ianti]->momentum(), decay[ianti]->dataPtr(),outgoing);
   VectorWaveFunction::calculateWaveFunctions(gluon_,decay[iglu ],outgoing,true);
 
   // gauge invariance test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[iglu ]->momentum(),
 					  decay[iglu ]->dataPtr(),10,
 					  outgoing));
     }
   }
 #endif
 
   AbstractVSSVertexPtr outgoingVertexS;
   AbstractVSSVertexPtr outgoingVertexA;
   identifyVertices(iscal, ianti, inpart, decay, outgoingVertexS, outgoingVertexA,inter);
 
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
   for(unsigned int ig = 0; ig < 2; ++ig) {
     // radiation from the incoming scalar
     if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
        (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
       assert(incomingVertex_[inter]);
       ScalarWaveFunction scalarInter = 
 	incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),
 					  gluon_[2*ig],swave3_,inpart.mass());
 
       assert(swave3_.particle()->id()==scalarInter.particle()->id());
 
-      Complex diag = vertex_->evaluate(scale,scal,anti,scalarInter);
+      Complex diag = 0.;
+      for(auto vertex : vertex_)
+	diag += vertex->evaluate(scale,scal,anti,scalarInter);
       if(!couplingSet) {
 	gs = abs(incomingVertex_[inter]->norm());
 	couplingSet = true;
       }
       for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	(*ME[colourFlow[0][ix].first])(0, 0, 0, ig) += 
 	   colourFlow[0][ix].second*diag; 
       }
 #ifdef GAUGE_CHECK
       total+=norm(diag);
 #endif
     }
     // radiation from the outgoing scalar
     if((decay[iscal]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
        (decay[iscal]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
       assert(outgoingVertexS);
       // ensure you get correct outgoing particle from first vertex
       tcPDPtr off = decay[iscal]->dataPtr();
       if(off->CC()) off = off->CC();
       ScalarWaveFunction scalarInter = 
 	outgoingVertexS->evaluate(scale,3,off,gluon_[2*ig],scal,decay[iscal]->mass());
 
       assert(scal.particle()->id()==scalarInter.particle()->id());
 
-      Complex diag = vertex_->evaluate(scale,swave3_,anti,scalarInter);
+      Complex diag = 0.;
+      for(auto vertex : vertex_)
+	diag += vertex->evaluate(scale,swave3_,anti,scalarInter);
       if(!couplingSet) {
 	gs = abs(outgoingVertexS->norm());
 	couplingSet = true;
       }
       for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
 	(*ME[colourFlow[1][ix].first])(0, 0, 0, ig) += 
 	   colourFlow[1][ix].second*diag;
       }
 #ifdef GAUGE_CHECK
       total+=norm(diag);
 #endif
     }
     // radiation from the outgoing anti scalar
     if((decay[ianti]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
        (decay[ianti]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
       assert(outgoingVertexA);
       // ensure you get correct outgoing particle from first vertex
       tcPDPtr off = decay[ianti]->dataPtr();
       if(off->CC()) off = off->CC();
       ScalarWaveFunction scalarInter = 
 	outgoingVertexA->evaluate(scale,3,off, gluon_[2*ig],anti,decay[ianti]->mass());
 
       assert(anti.particle()->id()==scalarInter.particle()->id());
 
-      Complex diag = vertex_->evaluate(scale,swave3_,scal,scalarInter);
+      Complex diag = 0.;
+      for(auto vertex : vertex_)
+	diag += vertex->evaluate(scale,swave3_,scal,scalarInter);
       if(!couplingSet) {
 	gs = abs(outgoingVertexA->norm());
 	couplingSet = true;
       }
       for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	(*ME[colourFlow[2][ix].first])(0, 0, 0, ig) += 
 	  colourFlow[2][ix].second*diag;
       }
 #ifdef GAUGE_CHECK
       total+=norm(diag);
 #endif
     }
   }
 
   // contract matrices 
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha_(S,EM)
   output*=(4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
   // return the answer
   return output;
 }
 
 
 void SSSDecayer::identifyVertices(const int iscal, const int ianti,
 				  const Particle & inpart, const ParticleVector & decay, 
 				  AbstractVSSVertexPtr & outgoingVertexS, 
 				  AbstractVSSVertexPtr & outgoingVertexA,
 				  ShowerInteraction inter){
   // QCD
   if(inter==ShowerInteraction::QCD) {
     // work out which scalar each outgoing vertex corresponds to 
     // two outgoing vertices
     if( inpart.dataPtr()       ->iColour()==PDT::Colour0     &&
 	((decay[iscal]->dataPtr()->iColour()==PDT::Colour3     &&
 	  decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar) ||
 	 (decay[iscal]->dataPtr()->iColour()==PDT::Colour8     &&
 	  decay[ianti]->dataPtr()->iColour()==PDT::Colour8))){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertexS = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[iscal]->id()))){
 	outgoingVertexS = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(getParticleData(decay[iscal]->id()))){
 	outgoingVertexS = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
     else if(inpart.dataPtr()       ->iColour()==PDT::Colour8 &&
 	    decay[iscal]->dataPtr()->iColour()==PDT::Colour3 &&
 	    decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertexS = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[iscal]->id()))){
 	outgoingVertexS = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(getParticleData(decay[iscal]->id()))){
 	outgoingVertexS = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
     // one outgoing vertex
     else if(inpart.dataPtr()    ->iColour()==PDT::Colour3){ 
       if(decay[iscal]->dataPtr()->iColour()==PDT::Colour3 &&  
 	 decay[ianti]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertexS = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertexS = outgoingVertex2_[inter]; 
       }
       else if (decay[iscal]->dataPtr()->iColour()==PDT::Colour3 &&  
 	       decay[ianti]->dataPtr()->iColour()==PDT::Colour8){
 	if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[ianti]->dataPtr()->id()))){
 	  outgoingVertexS = outgoingVertex2_[inter];
 	  outgoingVertexA = outgoingVertex1_[inter];
 	}
 	else {
 	  outgoingVertexS = outgoingVertex1_[inter];
 	  outgoingVertexA = outgoingVertex2_[inter];
 	}
       }
     }
     else if(inpart.dataPtr()    ->iColour()==PDT::Colour3bar){
       if(decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar &&  
 	 decay[iscal]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertexA = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar &&  
 	       decay[iscal]->dataPtr()->iColour()==PDT::Colour8){
 	if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[iscal]->dataPtr()->id()))){
 	  outgoingVertexS = outgoingVertex1_[inter];
 	  outgoingVertexA = outgoingVertex2_[inter];
 	}
 	else {
 	  outgoingVertexS = outgoingVertex2_[inter];
 	  outgoingVertexA = outgoingVertex1_[inter];
 	}
       }
     }
     
     if (! ((incomingVertex_[inter]  && (outgoingVertexS || outgoingVertexA)) ||
 	   ( outgoingVertexS &&  outgoingVertexA)))
       throw Exception()
 	<< "Invalid vertices for QCD radiation in SSS decay in SSSDecayer::identifyVertices"
 	<< Exception::runerror;
   }
   // QED
   else {
     if(decay[iscal]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iscal]->dataPtr())))
 	outgoingVertexS = outgoingVertex1_[inter];
       else
 	outgoingVertexS = outgoingVertex2_[inter];
     }
     if(decay[ianti]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[ianti]->dataPtr())))
 	outgoingVertexA = outgoingVertex1_[inter];
       else
 	outgoingVertexA = outgoingVertex2_[inter];
     }
   }
 }
diff --git a/Decay/General/SSSDecayer.h b/Decay/General/SSSDecayer.h
--- a/Decay/General/SSSDecayer.h
+++ b/Decay/General/SSSDecayer.h
@@ -1,203 +1,211 @@
 // -*- C++ -*-
 //
 // SSSDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_SSSDecayer_H
 #define HERWIG_SSSDecayer_H
 //
 // This is the declaration of the SSSDecayer class.
 //
 
 #include "GeneralTwoBodyDecayer.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Helicity/Vertex/Scalar/SSSVertex.h"
 #include "ThePEG/Helicity/Vertex/Scalar/VSSVertex.h"
 
 namespace Herwig {
 using namespace ThePEG;
 using Helicity::SSSVertexPtr;
   
 /** \ingroup Decay
  * The SSDecayer class implements the decay of a scalar
  * to 2 scalars in a general model. It holds a SSSVertex
  * pointer that must be typecast from the VertexBase pointer held in
  * GeneralTwoBodyDecayer. It implents the virtual functions me2() and
  * partialWidth().
  *
  * @see GeneralTwoBodyDecayer
  */
 class SSSDecayer: public GeneralTwoBodyDecayer {
 
 public:
 
   /**
    * The default constructor.
    */
   SSSDecayer() {}
 
   /** @name Virtual functions required by the Decayer class. */
   //@{
   /**
    * Return the matrix element squared for a given mode and phase-space channel.
    * @param ichan The channel we are calculating the matrix element for.
    * @param part The decaying Particle.
    * @param decay The particles produced in the decay.
    * @param meopt Option for the calculation of the matrix element
    * @return The matrix element squared for the phase-space configuration.
    */
   virtual double me2(const int ichan, const Particle & part,
                      const ParticleVector & decay, MEOption meopt) const;
 
   /**
    * Function to return partial Width
    * @param inpart The decaying particle.
    * @param outa One of the decay products.
    * @param outb The other decay product.
    */
   virtual Energy partialWidth(PMPair inpart, PMPair outa, 
 			      PMPair outb) const;
 
   /**
    *  Has a POWHEG style correction
    */
   virtual POWHEGType hasPOWHEGCorrection()  {
-    return (vertex_->orderInGem()+vertex_->orderInGs())==1 ? FSR : No;
+    POWHEGType output = FSR;
+    for(auto vertex : vertex_) {
+      if(vertex->orderInAllCouplings()!=1) {
+	output = No;
+	break;
+      }
+    }
+    return output;
   }
 
   /**
    *  Three-body matrix element including additional QCD radiation
    */
   virtual double threeBodyME(const int , const Particle & inpart,
 			     const ParticleVector & decay,
 			     ShowerInteraction inter, MEOption meopt);
 
   /**
    * Indentify outgoing vertices for the scalar and anti scalar
    */
   void identifyVertices(const int iscal, const int ianti,
 			const Particle & inpart, const ParticleVector & decay,
 			AbstractVSSVertexPtr & abstractOutgoingVertexS, 
 			AbstractVSSVertexPtr & abstractOutgoingVertexA,
 			ShowerInteraction inter);
 
   /**
    *  Set the information on the decay
    */
-  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
+  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing,
+			    vector<VertexBasePtr>,
 			    map<ShowerInteraction,VertexBasePtr> &,
 			    const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			    map<ShowerInteraction,VertexBasePtr>);
   //@}
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const;
 
   /** Make a clone of this object, possibly modifying the cloned object
    * to make it sane.
    * @return a pointer to the new object.
    */
   virtual IBPtr fullclone() const;
   //@}
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   SSSDecayer & operator=(const SSSDecayer &);
 
 private:
 
   /**
    *  Abstract pointer to AbstractSSSVertex
    */
-  AbstractSSSVertexPtr vertex_;
+  vector<AbstractSSSVertexPtr> vertex_;
 
   /**
    * Pointer to the perturbative vertex
    */
-  SSSVertexPtr perturbativeVertex_;
+  vector<SSSVertexPtr> perturbativeVertex_;
 
   /**
    *  Abstract pointer to AbstractVSSVertex for QCD radiation from incoming scalar
    */
   map<ShowerInteraction,AbstractVSSVertexPtr> incomingVertex_;
 
   /**
    *  Abstract pointer to AbstractVSSVertex for QCD radiation from outgoing scalar
    */
   map<ShowerInteraction,AbstractVSSVertexPtr> outgoingVertex1_;
 
   /**
    *  Abstract pointer to AbstractVSSVertex for QCD radiation from outgoing scalar
    */
   map<ShowerInteraction,AbstractVSSVertexPtr> outgoingVertex2_;
 
   /**
    *  Spin density matrix
    */
   mutable RhoDMatrix rho_;
 
   /**
    *  Scalar wavefunctions
    */
   mutable Helicity::ScalarWaveFunction swave_;
 
  /**
    *  Spin density matrix for 3 body decay
    */
   mutable RhoDMatrix rho3_;
 
   /**
    *  Scalar wavefunction for 3 body decay
    */
   mutable Helicity::ScalarWaveFunction swave3_;
 
     /**
    *  Vector wavefunction for 3 body decay
    */
   mutable vector<Helicity::VectorWaveFunction> gluon_;
 
 };
 
 }
 
 #endif /* HERWIG_SSSDecayer_H */
diff --git a/Decay/General/SSVDecayer.cc b/Decay/General/SSVDecayer.cc
--- a/Decay/General/SSVDecayer.cc
+++ b/Decay/General/SSVDecayer.cc
@@ -1,351 +1,366 @@
 // -*- C++ -*-
 //
 // SSVDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the SSVDecayer class.
 //
 
 #include "SSVDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr SSVDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr SSVDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void SSVDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
-			      VertexBasePtr vertex,
+			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> fourV) {
   decayInfo(incoming,outgoing);
-  vertex_             = dynamic_ptr_cast<AbstractVSSVertexPtr>(vertex);
-  perturbativeVertex_ = dynamic_ptr_cast<VSSVertexPtr>        (vertex);
+  for(auto vert : vertex) {
+    vertex_            .push_back(dynamic_ptr_cast<AbstractVSSVertexPtr>(vert));
+    perturbativeVertex_.push_back(dynamic_ptr_cast<VSSVertexPtr>        (vert));
+  }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter]  = dynamic_ptr_cast<AbstractVSSVertexPtr>(inV.at(inter));
     fourPointVertex_[inter] = dynamic_ptr_cast<AbstractVVSSVertexPtr>(fourV.at(inter));
     outgoingVertexS_[inter] = AbstractVSSVertexPtr();
     outgoingVertexV_[inter] = AbstractVVVVertexPtr();  
     if(outV[0].at(inter)) {
       if (outV[0].at(inter)->getName()==VertexType::VSS)
 	outgoingVertexS_[inter]   = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[0].at(inter));
       else
 	outgoingVertexV_[inter]   = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[0].at(inter));
     }
     if(outV[1].at(inter)) {
       if (outV[1].at(inter)->getName()==VertexType::VSS)
 	outgoingVertexS_[inter]   = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[1].at(inter));
       else 
 	outgoingVertexV_[inter]   = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[1].at(inter));
     }
   }
 }
 
 void SSVDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_           << perturbativeVertex_
      << incomingVertex_   << outgoingVertexS_
      << outgoingVertexV_  << fourPointVertex_;
 }
 
 void SSVDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_           >> perturbativeVertex_
      >> incomingVertex_   >> outgoingVertexS_
      >> outgoingVertexV_  >> fourPointVertex_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<SSVDecayer,GeneralTwoBodyDecayer>
 describeHerwigSSVDecayer("Herwig::SSVDecayer", "Herwig.so");
 
 void SSVDecayer::Init() {
 
   static ClassDocumentation<SSVDecayer> documentation
     ("This implements the decay of a scalar to a vector and a scalar");
 
 }
 
 double SSVDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay,
 		       MEOption meopt) const {
   unsigned int isc(0),ivec(1);
   if(decay[0]->dataPtr()->iSpin() != PDT::Spin0) swap(isc,ivec);
   if(!ME()) {
     if(ivec==1)
       ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin0,PDT::Spin1)));
     else
       ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin1,PDT::Spin0)));
   }
   if(meopt==Initialize) {
     ScalarWaveFunction::
       calculateWaveFunctions(rho_,const_ptr_cast<tPPtr>(&inpart),incoming);
     swave_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
   }
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
     ScalarWaveFunction::
       constructSpinInfo(decay[isc],outgoing,true);
     VectorWaveFunction::
       constructSpinInfo(vector_,decay[ivec],outgoing,true,false);
   }
   VectorWaveFunction::
     calculateWaveFunctions(vector_,decay[ivec],outgoing,false);
   ScalarWaveFunction sca(decay[isc]->momentum(),decay[isc]->dataPtr(),outgoing);
   Energy2 scale(sqr(inpart.mass()));
   //make sure decay matrix element is in the correct order
   double output(0.);
   if(ivec == 0) {
-    for(unsigned int ix = 0; ix < 3; ++ix)
-      (*ME())(0, ix, 0) = vertex_->evaluate(scale,vector_[ix],sca, swave_);
+    for(unsigned int ix = 0; ix < 3; ++ix) {
+      (*ME())(0, ix, 0) = 0.;
+      for(auto vert : vertex_)
+	(*ME())(0, ix, 0) += vert->evaluate(scale,vector_[ix],sca, swave_);
+    }
   }
   else {
-    for(unsigned int ix = 0; ix < 3; ++ix)
-      (*ME())(0, 0, ix) = vertex_->evaluate(scale,vector_[ix],sca,swave_);
+    for(unsigned int ix = 0; ix < 3; ++ix) {
+      (*ME())(0, 0, ix) = 0.;
+      for(auto vert : vertex_)
+	(*ME())(0, 0, ix) += vert->evaluate(scale,vector_[ix],sca,swave_);
+    }
   }
   output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy SSVDecayer:: partialWidth(PMPair inpart, PMPair outa, 
 				 PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
-  if(perturbativeVertex_) {
+  if(perturbativeVertex_.size()==1 &&
+     perturbativeVertex_[0]) {
     double mu1sq(sqr(outa.second/inpart.second)),
       mu2sq(sqr(outb.second/inpart.second));
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     if(outa.first->iSpin() == PDT::Spin0) {
-      perturbativeVertex_->setCoupling(sqr(inpart.second), outb.first, outa.first,in);
+      perturbativeVertex_[0]->setCoupling(sqr(inpart.second), outb.first, outa.first,in);
     }
     else {
       swap(mu1sq,mu2sq);
-      perturbativeVertex_->setCoupling(sqr(inpart.second), outa.first, outb.first,in);
+      perturbativeVertex_[0]->setCoupling(sqr(inpart.second), outa.first, outb.first,in);
     }
     double me2(0.);
     if(mu2sq == 0.) 
       me2 = -2.*mu1sq - 2.;
     else
       me2 = ( sqr(mu2sq - mu1sq) - 2.*(mu2sq + mu1sq) + 1. )/mu2sq;
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second, outa.second,
 					       outb.second);
-    Energy output = pcm*me2*norm(perturbativeVertex_->norm())/8./Constants::pi;
+    Energy output = pcm*me2*norm(perturbativeVertex_[0]->norm())/8./Constants::pi;
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 
 double  SSVDecayer::threeBodyME(const int , const Particle & inpart,
 				const ParticleVector & decay,
 				ShowerInteraction inter, MEOption meopt) {
   int iscal (0), ivect (1), iglu (2);
   // get location of outgoing scalar/vector
   if(decay[1]->dataPtr()->iSpin()==PDT::Spin0) swap(iscal,ivect);
 
   if(meopt==Initialize) {
     // create scalar wavefunction for decaying particle
     ScalarWaveFunction::calculateWaveFunctions(rho3_,const_ptr_cast<tPPtr>(&inpart),incoming);
     swave3_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
   }
   // setup spin information when needed
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
     ScalarWaveFunction::
       constructSpinInfo(decay[iscal],outgoing,true);
      VectorWaveFunction::
       constructSpinInfo(vector3_,decay[ivect],outgoing,true,false);
     VectorWaveFunction::
       constructSpinInfo(gluon_,  decay[iglu ],outgoing,true,false);
     return 0.;
   }
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin0, PDT::Spin0,
 								       PDT::Spin1, PDT::Spin1)));
 
   // create wavefunctions
   ScalarWaveFunction scal(decay[iscal]->momentum(),  decay[iscal]->dataPtr(),outgoing);
   VectorWaveFunction::calculateWaveFunctions(vector3_,decay[ivect],outgoing,false);
   VectorWaveFunction::calculateWaveFunctions(gluon_,  decay[iglu ],outgoing,true );
 
   // gauge invariance test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[iglu ]->momentum(),
   					  decay[iglu ]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
 
   if (! ((incomingVertex_[inter]  && (outgoingVertexS_[inter] || outgoingVertexV_[inter])) ||
 	 (outgoingVertexS_[inter] &&  outgoingVertexV_[inter])))
     throw Exception()
       << "Invalid vertices for radiation in SSV decay in SSVDecayer::threeBodyME"
       << Exception::runerror;
 
 
   // sort out colour flows
   int S(1), V(2);
   if (decay[iscal]->dataPtr()->iColour()==PDT::Colour3bar && 
       decay[ivect]->dataPtr()->iColour()==PDT::Colour8)
     swap(S,V);
   else if (decay[ivect]->dataPtr()->iColour()==PDT::Colour3 && 
 	   decay[iscal]->dataPtr()->iColour()==PDT::Colour8)
     swap(S,V);
 
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
   for(unsigned int iv = 0; iv < 3; ++iv) {
     for(unsigned int ig = 0; ig < 2; ++ig) {
       // radiation from the incoming scalar
       if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	 (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	assert(incomingVertex_[inter]);
 	ScalarWaveFunction scalarInter = 
 	  incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),
 					   gluon_[2*ig],swave3_,inpart.mass());
 	
 	assert(swave3_.particle()->id()==scalarInter.particle()->id());
-	Complex diag = vertex_->evaluate(scale,vector3_[iv],scal,scalarInter);
+	Complex diag = 0.;
+	for(auto vertex : vertex_)
+	  diag += vertex->evaluate(scale,vector3_[iv],scal,scalarInter);
 	if(!couplingSet) {
 	  gs = abs(incomingVertex_[inter]->norm());
 	  couplingSet = true;
 	}
 	for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	  (*ME[colourFlow[0][ix].first])(0, 0, iv, ig) += 
 	    colourFlow[0][ix].second*diag; 
 	}
 #ifdef GAUGE_CHECK
 	total+=norm(diag);
 #endif
       }
       // radiation from the outgoing scalar
       if((decay[iscal]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	 (decay[iscal]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	assert(outgoingVertexS_[inter]);
 	// ensure you get correct outgoing particle from first vertex
 	tcPDPtr off = decay[iscal]->dataPtr();
 	if(off->CC()) off = off->CC();
 	ScalarWaveFunction scalarInter = 
 	  outgoingVertexS_[inter]->evaluate(scale,3,off,gluon_[2*ig],scal,decay[iscal]->mass());
 	
 	assert(scal.particle()->id()==scalarInter.particle()->id());
 
 	if(!couplingSet) {
 	  gs = abs(outgoingVertexS_[inter]->norm());
 	  couplingSet = true;
 	}
-	Complex diag = vertex_->evaluate(scale,vector3_[iv],scalarInter,swave3_);
+	Complex diag = 0.;
+	for(auto vertex : vertex_)
+	  diag += vertex->evaluate(scale,vector3_[iv],scalarInter,swave3_);
 	for(unsigned int ix=0;ix<colourFlow[S].size();++ix) {
 	  (*ME[colourFlow[S][ix].first])(0, 0, iv, ig) += 
 	    colourFlow[S][ix].second*diag;
 	}
 #ifdef GAUGE_CHECK
 	total+=norm(diag);
 #endif
       }
 
       // radiation from outgoing vector
       if((decay[ivect]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	 (decay[ivect]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	assert(outgoingVertexV_[inter]);
 	// ensure you get correct outgoing particle from first vertex
 	tcPDPtr off = decay[ivect]->dataPtr();
 	if(off->CC()) off = off->CC();
 	VectorWaveFunction  vectorInter = 
 	  outgoingVertexV_[inter]->evaluate(scale,3,off,gluon_[2*ig],
 					    vector3_[iv],decay[ivect]->mass());
 	
 	assert(vector3_[iv].particle()->id()==vectorInter.particle()->id());
 	
 	if(!couplingSet) {
 	  gs = abs(outgoingVertexV_[inter]->norm());
 	  couplingSet = true;
 	}	
-	Complex diag = vertex_->evaluate(scale,vectorInter,scal,swave3_);
+	Complex diag = 0.;
+	for(auto vertex : vertex_)
+	  diag += vertex->evaluate(scale,vectorInter,scal,swave3_);
 	for(unsigned int ix=0;ix<colourFlow[V].size();++ix) {
 	  (*ME[colourFlow[V][ix].first])(0, 0, iv, ig) += 
 	    colourFlow[V][ix].second*diag;
 	}
 #ifdef GAUGE_CHECK
 	total+=norm(diag);
 #endif
       }
       // radiation from 4 point vertex
       if (fourPointVertex_[inter]) {
 	Complex diag =  fourPointVertex_[inter]->evaluate(scale, gluon_[2*ig], vector3_[iv],
 							  scal, swave3_);
 	for(unsigned int ix=0;ix<colourFlow[3].size();++ix) {
 	  (*ME[colourFlow[3][ix].first])(0, 0, iv, ig) += 
 	     colourFlow[3][ix].second*diag;
 	}
 #ifdef GAUGE_CHECK
 	total+=norm(diag);
 #endif
       }
     }
   }
   
   // contract matrices
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha_(S,EM)
   output*=(4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
   // return the answer
   return output;
 }
diff --git a/Decay/General/SSVDecayer.h b/Decay/General/SSVDecayer.h
--- a/Decay/General/SSVDecayer.h
+++ b/Decay/General/SSVDecayer.h
@@ -1,216 +1,224 @@
 // -*- C++ -*-
 //
 // SSVDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_SSVDecayer_H
 #define HERWIG_SSVDecayer_H
 //
 // This is the declaration of the SSVDecayer class.
 //
 
 #include "GeneralTwoBodyDecayer.h"
 #include "ThePEG/Helicity/Vertex/Scalar/VSSVertex.h"
 #include "ThePEG/Helicity/Vertex/Vector/VVVVertex.h"
 #include "ThePEG/Helicity/Vertex/Scalar/VVSSVertex.h"
 #include "ThePEG/Repository/EventGenerator.h"
 
 namespace Herwig {
 using namespace ThePEG;
 using Helicity::VSSVertexPtr;
 
 /** \ingroup Decay
  * The SSVDecayer class implements the decay of a scalar to a vector 
  * and a scalar in a general model. It holds an VSSVertex pointer
  * that must be typecast from the VertexBase pointer held in 
  * GeneralTwoBodyDecayer. It implents the virtual functions me2() and
  * partialWidth(). 
  *
  * @see GeneralTwoBodyDecayer
  */
 class SSVDecayer: public GeneralTwoBodyDecayer {
 
 public:
 
   /**
    * The default constructor.
    */
   SSVDecayer() {}
 
   /** @name Virtual functions required by the Decayer class. */
   //@{
   /**
    * Return the matrix element squared for a given mode and phase-space channel
    * @param ichan The channel we are calculating the matrix element for.
    * @param part The decaying Particle.
    * @param decay The particles produced in the decay.
    * @param meopt Option for the calculation of the matrix element
    * @return The matrix element squared for the phase-space configuration.
    */
   virtual double me2(const int ichan, const Particle & part,
 		     const ParticleVector & decay, MEOption meopt) const;
   
   /**
    * Function to return partial Width
    * @param inpart The decaying particle.
    * @param outa One of the decay products.
    * @param outb The other decay product.
    */
   virtual Energy partialWidth(PMPair inpart, PMPair outa, 
 			      PMPair outb) const;
 
   /**
    *  Has a POWHEG style correction
    */
   virtual POWHEGType hasPOWHEGCorrection()  {
-    return (vertex_->orderInGem()+vertex_->orderInGs())==1 ? FSR : No;
+    POWHEGType output = FSR;
+    for(auto vertex : vertex_) {
+      if(vertex->orderInAllCouplings()!=1) {
+	output = No;
+	break;
+      }
+    }
+    return output;
   }
 
   /**
    *  Three-body matrix element including additional QCD radiation
    */
   virtual double threeBodyME(const int , const Particle & inpart,
 			     const ParticleVector & decay,
 			     ShowerInteraction inter,
 			     MEOption meopt);
 
   /**
    *  Set the information on the decay
    */
-  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
+  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing,
+			    vector<VertexBasePtr>,
 			    map<ShowerInteraction,VertexBasePtr> &,
 			    const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			    map<ShowerInteraction,VertexBasePtr>);
   //@}
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const;
 
   /** Make a clone of this object, possibly modifying the cloned object
    * to make it sane.
    * @return a pointer to the new object.
    */
   virtual IBPtr fullclone() const;
   //@}
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   SSVDecayer & operator=(const SSVDecayer &);
 
 private:
 
   /**
    *  Abstract pointer to AbstractFFVVertex
    */
-  AbstractVSSVertexPtr vertex_;
+  vector<AbstractVSSVertexPtr> vertex_;
   
   /**
    * Pointer to the perturbative vertex
    */
-  VSSVertexPtr perturbativeVertex_;
+  vector<VSSVertexPtr> perturbativeVertex_;
 
   /**
    *  Abstract pointer to AbstractVSSVertex for QCD radiation from incoming scalar
    */
   map<ShowerInteraction,AbstractVSSVertexPtr> incomingVertex_;
 
   /**
    *  Abstract pointer to AbstractVSSVertex for QCD radiation from outgoing scalar
    */
   map<ShowerInteraction,AbstractVSSVertexPtr> outgoingVertexS_;
 
   /**
    *  Abstract pointer to AbstractVVVVertex for QCD radiation from outgoing vector
    */
   map<ShowerInteraction,AbstractVVVVertexPtr> outgoingVertexV_;
 
   /**
    *  Abstract pointer to AbstractVVSSVertex for QCD radiation from 4 point vertex
    */
   map<ShowerInteraction,AbstractVVSSVertexPtr> fourPointVertex_;
 
   /**
    *  Spinor density matrix
    */
   mutable RhoDMatrix rho_;
 
   /**
    *  Scalar wavefunction
    */
   mutable Helicity::ScalarWaveFunction swave_;
 
   /**
    *  Vector wavefunction
    */
   mutable vector<Helicity::VectorWaveFunction> vector_;
 
  /**
    *  Spin density matrix for 3 body decay
    */
   mutable RhoDMatrix rho3_;
 
   /**
    *  Scalar wavefunction for 3 body decay
    */
   mutable Helicity::ScalarWaveFunction swave3_;
 
   /**
    *  Scalar wavefunction for 3 body decay
    */
   mutable Helicity::ScalarWaveFunction scal_;
 
     /**
    *  Vector wavefunction for 3 body decay
    */
   mutable vector<Helicity::VectorWaveFunction> vector3_;
 
     /**
    *  Vector wavefunction for 3 body decay
    */
   mutable vector<Helicity::VectorWaveFunction> gluon_;
 
 };
 
 }
 
 #endif /* HERWIG_SSVDecayer_H */
diff --git a/Decay/General/SVVDecayer.cc b/Decay/General/SVVDecayer.cc
--- a/Decay/General/SVVDecayer.cc
+++ b/Decay/General/SVVDecayer.cc
@@ -1,421 +1,432 @@
 // -*- C++ -*-
 //
 // SVVDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the SVVDecayer class.
 //
 
 #include "SVVDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/Vertex/Scalar/VVSVertex.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr SVVDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr SVVDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void SVVDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
-			      VertexBasePtr vertex,
+			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> ) {
   decayInfo(incoming,outgoing);
-  vertex_             = dynamic_ptr_cast<AbstractVVSVertexPtr>(vertex);
-  perturbativeVertex_ = dynamic_ptr_cast<VVSVertexPtr>        (vertex);
+  for(auto vert : vertex) {
+    vertex_            .push_back(dynamic_ptr_cast<AbstractVVSVertexPtr>(vert));
+    perturbativeVertex_.push_back(dynamic_ptr_cast<VVSVertexPtr>        (vert));
+  }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(inV.at(inter));
     outgoingVertex1_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[0].at(inter));
     outgoingVertex2_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[1].at(inter));
   }
 }
 
 void SVVDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_ << perturbativeVertex_
      << incomingVertex_   << outgoingVertex1_
      << outgoingVertex2_;
 }
 
 void SVVDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_ >> perturbativeVertex_
      >> incomingVertex_   >> outgoingVertex1_
      >> outgoingVertex2_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<SVVDecayer,GeneralTwoBodyDecayer>
 describeHerwigSVVDecayer("Herwig::SVVDecayer", "Herwig.so");
 
 void SVVDecayer::Init() {
 
   static ClassDocumentation<SVVDecayer> documentation
     ("This implements the decay of a scalar to 2 vector bosons.");
 
 }
 
 double SVVDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector& decay, 
 		       MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin1,PDT::Spin1)));
   bool photon[2];
   for(unsigned int ix=0;ix<2;++ix)
     photon[ix] = decay[ix]->mass()==ZERO;
   if(meopt==Initialize) {
     ScalarWaveFunction::
       calculateWaveFunctions(rho_,const_ptr_cast<tPPtr>(&inpart),incoming);
     swave_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
   }
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
     for(unsigned int ix=0;ix<2;++ix)
       VectorWaveFunction::
 	constructSpinInfo(vectors_[ix],decay[ix],outgoing,true,photon[ix]);
   }
   for(unsigned int ix=0;ix<2;++ix)
     VectorWaveFunction::
       calculateWaveFunctions(vectors_[ix],decay[ix],outgoing,photon[ix]);
   
   
   Energy2 scale(sqr(inpart.mass()));
   unsigned int iv1,iv2;
   for(iv2 = 0; iv2 < 3; ++iv2) {
     if( photon[1] && iv2 == 1 ) ++iv2;
     for(iv1=0;iv1<3;++iv1) {
       if( photon[0] && iv1 == 1) ++iv1;
-      (*ME())(0, iv1, iv2) = vertex_->evaluate(scale,vectors_[0][iv1],
+      (*ME())(0, iv1, iv2) = 0.;
+      for(auto vert : vertex_)
+	(*ME())(0, iv1, iv2) += vert->evaluate(scale,vectors_[0][iv1],
 					       vectors_[1][iv2],swave_);
     }
   }
   double output = ME()->contract(rho_).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy SVVDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
-  if(perturbativeVertex_) {
+  if(perturbativeVertex_.size()==1 &&
+     perturbativeVertex_[0]) {
     Energy2 scale(sqr(inpart.second));
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
-    perturbativeVertex_->setCoupling(scale, outa.first , 
+    perturbativeVertex_[0]->setCoupling(scale, outa.first , 
 				    outb.first, in);
     double mu1sq = sqr(outa.second/inpart.second);
     double mu2sq = sqr(outb.second/inpart.second);
     double m1pm2 = mu1sq + mu2sq;
     double me2(0.); 
     if( mu1sq > 0. && mu2sq > 0.)
       me2 = ( m1pm2*(m1pm2 - 2.) + 8.*mu1sq*mu2sq + 1.)/4./mu1sq/mu2sq;
     else if( mu1sq == 0. || mu2sq == 0. )
       me2 = 3.;
     else 
       me2 = 4.;
     
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second,outa.second,
 					outb.second);
-    Energy output = norm(perturbativeVertex_->norm())*
+    Energy output = norm(perturbativeVertex_[0]->norm())*
       me2*pcm/(8*Constants::pi)/scale*UnitRemoval::E2;
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 double SVVDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   if(meopt==Initialize) {
     // create scalar wavefunction for decaying particle
     ScalarWaveFunction::
       calculateWaveFunctions(rho3_,const_ptr_cast<tPPtr>(&inpart),incoming);
     swave3_ = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
   }
   if(meopt==Terminate) {
     ScalarWaveFunction::
       constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
     VectorWaveFunction::
       constructSpinInfo(vectors3_[0],decay[0],outgoing,true,false);
     VectorWaveFunction::
       constructSpinInfo(vectors3_[1],decay[1],outgoing,true,false);
     VectorWaveFunction::
       constructSpinInfo(gluon_      ,decay[2],outgoing,true,false);
     return 0.;
   }
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin0, PDT::Spin1,
 								       PDT::Spin1, PDT::Spin1)));
   bool massless[2];
   for(unsigned int ix=0;ix<2;++ix)
     massless[ix] = decay[ix]->mass()!=ZERO;
   // create wavefunctions
   VectorWaveFunction::calculateWaveFunctions(vectors3_[0],decay[0],outgoing,massless[0]);
   VectorWaveFunction::calculateWaveFunctions(vectors3_[1],decay[1],outgoing,massless[1]);
   VectorWaveFunction::calculateWaveFunctions(gluon_      ,decay[2],outgoing,true);
 
   // gauge test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[2]->momentum(),
   					  decay[2]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
 
   // get the outgoing vertices
   AbstractVVVVertexPtr outgoingVertex1;
   AbstractVVVVertexPtr outgoingVertex2;
   identifyVertices(inpart,decay, outgoingVertex1, outgoingVertex2,inter);
 
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
 
    for(unsigned int iv1 = 0; iv1 < 3; ++iv1) {
      if(massless[0] && iv1==1) continue;
      for(unsigned int iv2 = 0; iv2 < 3; ++iv2) {
        if(massless[1] && iv2==1) continue;
        for(unsigned int ig = 0; ig < 2; ++ig) {
 	 // radiation from the incoming vector
 	 if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	    (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	   assert(incomingVertex_[inter]);	
 	   ScalarWaveFunction scalarInter = 
 	     incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),gluon_[2*ig],
 					      swave3_,inpart.mass());
 	
 	   assert(swave3_.particle()->id()==scalarInter.particle()->id());
 	
-	   Complex diag = vertex_->evaluate(scale,vectors3_[0][iv1],
-					    vectors3_[1][iv2],scalarInter);
+	   Complex diag = 0.;
+	   for(auto vertex : vertex_)
+	     diag += vertex->evaluate(scale,vectors3_[0][iv1],
+				      vectors3_[1][iv2],scalarInter);
 	   if(!couplingSet) {
 	     gs = abs(incomingVertex_[inter]->norm());
 	     couplingSet = true;
 	   }
 	   for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	     (*ME[colourFlow[0][ix].first])(0, iv1, iv2, ig) += 
 	       colourFlow[0][ix].second*diag;
 	   }
 #ifdef GAUGE_CHECK
 	   total+=norm(diag);
 #endif
 	 }
 	 // radiation from the 1st outgoing vector
 	 if((decay[0]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	    (decay[0]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	   assert(outgoingVertex1);
 	// ensure you get correct outgoing particle from first vertex
 	   tcPDPtr off = decay[0]->dataPtr();
 	   if(off->CC()) off = off->CC();
 	   VectorWaveFunction vectorInter = 
 	     outgoingVertex1->evaluate(scale,3,off,gluon_[2*ig],vectors3_[0][iv1],decay[0]->mass());
 	   
 	   assert(vectors3_[0][iv1].particle()->id()==vectorInter.particle()->id());
 	 
-	   Complex diag =vertex_->evaluate(scale,vectorInter,vectors3_[1][iv2],swave3_);
+	   Complex diag =0.;
+	   for(auto vertex : vertex_)
+	     diag += vertex->evaluate(scale,vectorInter,vectors3_[1][iv2],swave3_);
 	   if(!couplingSet) {
 	     gs = abs(outgoingVertex1->norm());
 	     couplingSet = true;
 	   }
 	   for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
 	     (*ME[colourFlow[1][ix].first])(0, iv1, iv2, ig) += 
 	       colourFlow[1][ix].second*diag;
 	   }
 #ifdef GAUGE_CHECK
 	   total+=norm(diag);
 #endif
 	 }
 	 
 	 if((decay[1]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	    (decay[1]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	   assert(outgoingVertex2);
 	   // ensure you get correct outgoing particle from first vertex
 	   tcPDPtr off = decay[1]->dataPtr();
 	   if(off->CC()) off = off->CC();
 	   VectorWaveFunction vectorInter = 
 	     outgoingVertex2->evaluate(scale,3,off, gluon_[2*ig],vectors3_[1][iv2],decay[1]->mass());
 	
 	   assert(vectors3_[1][iv2].particle()->id()==vectorInter.particle()->id());
 	
-	   Complex diag = vertex_->evaluate(scale,vectors3_[0][iv1],vectorInter,swave3_);
+	   Complex diag = 0.;
+	   for(auto vertex : vertex_)
+	     diag += vertex->evaluate(scale,vectors3_[0][iv1],vectorInter,swave3_);
 	   if(!couplingSet) {
 	     gs = abs(outgoingVertex2->norm());
 	     couplingSet = true;
 	   }
 	   for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	     (*ME[colourFlow[2][ix].first])(0, iv1, iv2, ig) += 
 	       colourFlow[2][ix].second*diag;
 	   }
 #ifdef GAUGE_CHECK
 	   total+=norm(diag);
 #endif
 	 }
        }
      }
    }
 
   // contract matrices 
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha_(S,EM)
   output*=(4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
   // return the answer
   return output;
 }
 
 void SVVDecayer::identifyVertices(const Particle & inpart, const ParticleVector & decay, 
 				  AbstractVVVVertexPtr & outgoingVertex1, 
 				  AbstractVVVVertexPtr & outgoingVertex2,
 				  ShowerInteraction inter) {
   if(inter==ShowerInteraction::QCD) {
     // work out which scalar each outgoing vertex corresponds to 
     // two outgoing vertices
     if( inpart.dataPtr()       ->iColour()==PDT::Colour0     &&
 	((decay[0]->dataPtr()->iColour()==PDT::Colour3     &&
 	  decay[1]->dataPtr()->iColour()==PDT::Colour3bar) ||
 	 (decay[0]->dataPtr()->iColour()==PDT::Colour8     &&
 	  decay[1]->dataPtr()->iColour()==PDT::Colour8))){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertex1 = outgoingVertex1_[inter];
 	outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[0]->id()))){
 	outgoingVertex1 = outgoingVertex1_[inter];
 	outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(getParticleData(decay[0]->id()))){
 	outgoingVertex1 = outgoingVertex2_[inter];
 	outgoingVertex2 = outgoingVertex1_[inter];
       }
     }
     else if(inpart.dataPtr()       ->iColour()==PDT::Colour8 &&
 	    decay[0]->dataPtr()->iColour()==PDT::Colour3 &&
 	    decay[1]->dataPtr()->iColour()==PDT::Colour3bar){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertex1 = outgoingVertex1_[inter];
 	outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[0]->id()))){
 	outgoingVertex1 = outgoingVertex1_[inter];
 	outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(getParticleData(decay[0]->id()))){
 	outgoingVertex1 = outgoingVertex2_[inter];
 	outgoingVertex2 = outgoingVertex1_[inter];
       }
     }
     
     // one outgoing vertex
     else if(inpart.dataPtr()->iColour()==PDT::Colour3){
       if(decay[0]->dataPtr()->iColour()==PDT::Colour3 &&  
 	 decay[1]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertex1 = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertex1 = outgoingVertex2_[inter];
       }
       else if (decay[0]->dataPtr()->iColour()==PDT::Colour3 &&
 	       decay[1]->dataPtr()->iColour()==PDT::Colour8){
 	if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[1]->dataPtr()->id()))){
 	  outgoingVertex1 = outgoingVertex2_[inter];
 	  outgoingVertex2 = outgoingVertex1_[inter];
 	}
 	else {
 	  outgoingVertex1 = outgoingVertex1_[inter];
 	  outgoingVertex2 = outgoingVertex2_[inter];
 	}
       }
     }
     else if(inpart.dataPtr()->iColour()==PDT::Colour3bar){
       if(decay[1]->dataPtr()->iColour()==PDT::Colour3bar &&  
 	 decay[0]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertex2 = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (decay[0]->dataPtr()->iColour()==PDT::Colour8 &&
 	       decay[1]->dataPtr()->iColour()==PDT::Colour3bar){
 	if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[0]->dataPtr()->id()))){
 	  outgoingVertex1 = outgoingVertex1_[inter];
 	  outgoingVertex2 = outgoingVertex2_[inter];
 	}
 	else {
 	  outgoingVertex1 = outgoingVertex2_[inter];
 	  outgoingVertex2 = outgoingVertex1_[inter];
 	}
       }
     }
     
     if (! ((incomingVertex_[inter]  && (outgoingVertex1  || outgoingVertex2)) ||
 	   ( outgoingVertex1 &&  outgoingVertex2)))
       throw Exception()
 	<< "Invalid vertices for QCD radiation in SVV decay in SVVDecayer::identifyVertices"
 	<< Exception::runerror;
   }
   else {
     if(decay[0]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[0]->dataPtr())))
 	outgoingVertex1 = outgoingVertex1_[inter];
       else
 	outgoingVertex1 = outgoingVertex2_[inter];
     }
     if(decay[1]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[1]->dataPtr())))
 	outgoingVertex2 = outgoingVertex1_[inter];
       else
 	outgoingVertex2 = outgoingVertex2_[inter];
     }
   }
 }
diff --git a/Decay/General/SVVDecayer.h b/Decay/General/SVVDecayer.h
--- a/Decay/General/SVVDecayer.h
+++ b/Decay/General/SVVDecayer.h
@@ -1,222 +1,230 @@
 // -*- C++ -*-
 //
 // SVVDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_SVVDecayer_H
 #define HERWIG_SVVDecayer_H
 //
 // This is the declaration of the SVVDecayer class.
 //
 
 #include "GeneralTwoBodyDecayer.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Helicity/Vertex/Scalar/VVSVertex.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 
 namespace Herwig {
 using namespace ThePEG;
 using Helicity::VVSVertexPtr; 
 
 /** \ingroup Decay
  * This SVVDecayer class implements the decay of a scalar to 
  * 2 vector bosons using either the tree level VVSVertex or the loop vertex.
  * It inherits from 
  * GeneralTwoBodyDecayer and implements the virtual member functions me2() 
  * and partialWidth(). It also stores a pointer to the VVSVertex.
  *
  * @see GeneralTwoBodyDecayer 
  * 
  */
 class SVVDecayer: public GeneralTwoBodyDecayer {
 
 public:
 
   /**
    * The default constructor.
    */
   SVVDecayer() {}
 
   /** @name Virtual functions required by the Decayer class. */
   //@{
   /**
    * Return the matrix element squared for a given mode and phase-space channel.
    * @param ichan The channel we are calculating the matrix element for.
    * @param part The decaying Particle.
    * @param decay The particles produced in the decay.
    * @param meopt Option for the calculation of the matrix element
    * @return The matrix element squared for the phase-space configuration.
    */
   virtual double me2(const int ichan, const Particle & part,
                       const ParticleVector & decay, MEOption meopt) const;
   
   /**
    * Function to return partial Width
    * @param inpart The decaying particle.
    * @param outa One of the decay products.
    * @param outb The other decay product.
    */
   virtual Energy partialWidth(PMPair inpart, PMPair outa, 
 			      PMPair outb) const;
 
   /**
    *  Set the information on the decay
    */
-  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
+  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing,
+			    vector<VertexBasePtr>,
 			    map<ShowerInteraction,VertexBasePtr> &,
 			    const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			    map<ShowerInteraction,VertexBasePtr>);
   
   /**
    *  Has a POWHEG style correction
    */
   virtual POWHEGType hasPOWHEGCorrection()  {
-    return (vertex_->orderInGem()+vertex_->orderInGs())==1 ? FSR : No;
+    POWHEGType output = FSR;
+    for(auto vertex : vertex_) {
+      if(vertex->orderInAllCouplings()!=1) {
+	output = No;
+	break;
+      }
+    }
+    return output;
   }
 
   /**
    *  Three-body matrix element including additional QCD radiation
    */
   virtual double threeBodyME(const int , const Particle & inpart,
 			     const ParticleVector & decay,
 			     ShowerInteraction inter, MEOption meopt);
   //@}
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const;
 
   /** Make a clone of this object, possibly modifying the cloned object
    * to make it sane.
    * @return a pointer to the new object.
    */
   virtual IBPtr fullclone() const;
   //@}
   
 protected:
 
   /**
    *  Find the vertices for the decay
    */
   void identifyVertices(const Particle & inpart, const ParticleVector & decay, 
 			AbstractVVVVertexPtr & outgoingVertex1, 
 			AbstractVVVVertexPtr & outgoingVertex2,
 			ShowerInteraction inter);
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   SVVDecayer & operator=(const SVVDecayer &);
 
 private:
   
   /**
    *  Abstract pointer to general VVS vertex
    */
-  AbstractVVSVertexPtr vertex_;
+  vector<AbstractVVSVertexPtr> vertex_;
 
   /**
    * Pointer to the perturbative form
    */
-  VVSVertexPtr perturbativeVertex_;
+  vector<VVSVertexPtr> perturbativeVertex_;
 
   /**
    *  Abstract pointer to AbstractVSSVertex for QCD radiation from incoming scalar
    */
   map<ShowerInteraction,AbstractVSSVertexPtr> incomingVertex_;
 
   /**
    *  Abstract pointer to AbstractFFVVertex for QCD radiation from the 1st outgoing vector
    */
   map<ShowerInteraction,AbstractVVVVertexPtr> outgoingVertex1_;
 
   /**
    *  Abstract pointer to AbstractFFVVertex for QCD radiation from the 2nd outgoing vector
    */
   map<ShowerInteraction,AbstractVVVVertexPtr> outgoingVertex2_;
 
   /**
    *  Spin density matrix
    */
   mutable RhoDMatrix rho_;
 
   /**
    *  Scalar wavefunction
    */
   mutable Helicity::ScalarWaveFunction swave_;
 
   /**
    *  Vector wavefunctions
    */
   mutable vector<Helicity::VectorWaveFunction> vectors_[2];
 
 private:
 
   /**
    *  Member for the POWHEG correction
    */
   //@{
   /**
    *  Spin density matrix for 3 body decay
    */
   mutable RhoDMatrix rho3_;
   
   /**
    *  Scalar wavefunction for 3 body decay
    */
   mutable ScalarWaveFunction swave3_;
 
   /**
    *  Vector wavefunctions
    */
   mutable vector<Helicity::VectorWaveFunction> vectors3_[2];
 
     /**
    *  Vector wavefunction for 3 body decay
    */
   mutable vector<Helicity::VectorWaveFunction> gluon_;
   //@}
 };
 
 }
 
 #endif /* HERWIG_SVVDecayer_H */
diff --git a/Decay/General/TFFDecayer.cc b/Decay/General/TFFDecayer.cc
--- a/Decay/General/TFFDecayer.cc
+++ b/Decay/General/TFFDecayer.cc
@@ -1,340 +1,351 @@
 // -*- C++ -*-
 //
 // TFFDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the TFFDecayer class.
 //
 
 #include "TFFDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/TensorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 IBPtr TFFDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr TFFDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void TFFDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
-			      VertexBasePtr vertex,
+			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> &,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> fourV) {
   decayInfo(incoming,outgoing);
-  vertex_             = dynamic_ptr_cast<AbstractFFTVertexPtr>(vertex);
-  perturbativeVertex_ = dynamic_ptr_cast<FFTVertexPtr>        (vertex);
+  for(auto vert : vertex) {
+    vertex_            .push_back(dynamic_ptr_cast<AbstractFFTVertexPtr>(vert));
+    perturbativeVertex_.push_back(dynamic_ptr_cast<FFTVertexPtr>        (vert));
+  }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     fourPointVertex_[inter] = dynamic_ptr_cast<AbstractFFVTVertexPtr>(fourV.at(inter));
     outgoingVertex1_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr> (outV[0].at(inter));
     outgoingVertex2_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr> (outV[1].at(inter));
   }
 }
 
 void TFFDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_          << perturbativeVertex_
      << outgoingVertex1_ << outgoingVertex2_
      << fourPointVertex_;
 }
 
 void TFFDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_          >> perturbativeVertex_
      >> outgoingVertex1_ >> outgoingVertex2_
      >> fourPointVertex_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<TFFDecayer,GeneralTwoBodyDecayer>
 describeHerwigTFFDecayer("Herwig::TFFDecayer", "Herwig.so");
 
 void TFFDecayer::Init() {
 
   static ClassDocumentation<TFFDecayer> documentation
     ("The TFFDecayer class implements the decay of a tensor particle "
      "to 2 fermions ");
   
 }
 
 double TFFDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay,
 		       MEOption meopt) const {
   unsigned int iferm(0),ianti(1);
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin2,PDT::Spin1Half,PDT::Spin1Half)));
   if(decay[0]->id()>=0) swap(iferm,ianti);
   if(meopt==Initialize) {
     TensorWaveFunction::
       calculateWaveFunctions(tensors_,rho_,const_ptr_cast<tPPtr>(&inpart),
 			     incoming,false);
   }
   if(meopt==Terminate) {
     TensorWaveFunction::
       constructSpinInfo(tensors_,const_ptr_cast<tPPtr>(&inpart),
 			incoming,true,false);
     SpinorBarWaveFunction::
       constructSpinInfo(wavebar_,decay[iferm],outgoing,true);
     SpinorWaveFunction::
       constructSpinInfo(wave_   ,decay[ianti],outgoing,true);
     return 0.;
   }
   SpinorBarWaveFunction::
     calculateWaveFunctions(wavebar_,decay[iferm],outgoing);
   SpinorWaveFunction::
     calculateWaveFunctions(wave_   ,decay[ianti],outgoing);
   Energy2 scale(sqr(inpart.mass()));
   unsigned int thel,fhel,ahel;
   for(thel=0;thel<5;++thel) {
     for(fhel=0;fhel<2;++fhel) {
       for(ahel=0;ahel<2;++ahel) {
 	if(iferm > ianti) {
-	  (*ME())(thel,fhel,ahel) = 
-	    vertex_->evaluate(scale,wave_[ahel],
-				      wavebar_[fhel],tensors_[thel]);
+	  (*ME())(thel,fhel,ahel) = 0.;
+	  for(auto vert : vertex_)
+	    (*ME())(thel,fhel,ahel) += 
+	      vert->evaluate(scale,wave_[ahel],
+			     wavebar_[fhel],tensors_[thel]);
 	}
 	else {
-	  (*ME())(thel,ahel,fhel) = 
-	    vertex_->evaluate(scale,wave_[ahel],
-				      wavebar_[fhel],tensors_[thel]);
+	  (*ME())(thel,ahel,fhel) = 0.;
+	  for(auto vert : vertex_)
+	    (*ME())(thel,ahel,fhel) += 
+	      vert->evaluate(scale,wave_[ahel],
+			     wavebar_[fhel],tensors_[thel]);
 	}
       }
     }
   }
   double output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy TFFDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
-  if(perturbativeVertex_) {
+  if(perturbativeVertex_.size()==1 &&
+     perturbativeVertex_[0]) {
     Energy2 scale = sqr(inpart.second);
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
-    perturbativeVertex_->setCoupling(scale, in, outa.first, outb.first);
+    perturbativeVertex_[0]->setCoupling(scale, in, outa.first, outb.first);
     double musq = sqr(outa.second/inpart.second);
     double b = sqrt(1- 4.*musq);
     double me2 = b*b*(5-2*b*b)*scale/120.*UnitRemoval::InvE2;
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second,outa.second,
 					outb.second);
-    Energy output = norm(perturbativeVertex_->norm())*me2*pcm/(8.*Constants::pi);
+    Energy output = norm(perturbativeVertex_[0]->norm())*me2*pcm/(8.*Constants::pi);
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 
 double TFFDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   // work out which is the fermion and antifermion
   int ianti(0), iferm(1), iglu(2);
   int itype[2];
   for(unsigned int ix=0;ix<2;++ix) {
     if(decay[ix]->dataPtr()->CC()) itype[ix] = decay[ix]->id()>0 ? 0:1;
     else                           itype[ix] = 2;
   }
   if(itype[0]==0 && itype[1]!=0) swap(iferm, ianti);
   if(itype[0]==2 && itype[1]==1) swap(iferm, ianti);
   if(itype[0]==0 && itype[1]==0 && decay[0]->dataPtr()->id()<decay[1]->dataPtr()->id()) 
     swap(iferm, ianti);
   if(itype[0]==1 && itype[1]==1 && decay[0]->dataPtr()->id()<decay[1]->dataPtr()->id()) 
     swap(iferm, ianti);
 
   if(meopt==Initialize) {
     // create tensor wavefunction for decaying particle
     TensorWaveFunction::
       calculateWaveFunctions(tensors3_, rho3_, const_ptr_cast<tPPtr>(&inpart), incoming, false);
   }
   // setup spin information when needed
   if(meopt==Terminate) {
     TensorWaveFunction::
       constructSpinInfo(tensors3_, const_ptr_cast<tPPtr>(&inpart),incoming,true, false);
     SpinorBarWaveFunction::
       constructSpinInfo(wavebar3_ ,decay[iferm],outgoing,true);
     SpinorWaveFunction::
       constructSpinInfo(wave3_    ,decay[ianti],outgoing,true);
     VectorWaveFunction::
       constructSpinInfo(gluon_    ,decay[iglu ],outgoing,true,false);
     return 0.;
   }
 
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
 
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin2,     PDT::Spin1Half,
 								       PDT::Spin1Half, PDT::Spin1)));
   // create wavefunctions
   SpinorBarWaveFunction::
     calculateWaveFunctions(wavebar3_, decay[iferm],outgoing);
   SpinorWaveFunction::
     calculateWaveFunctions(wave3_   , decay[ianti],outgoing);
   VectorWaveFunction::
     calculateWaveFunctions(gluon_   , decay[iglu ],outgoing,true);
 
   // gauge invariance test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[iglu ]->momentum(),
   				          decay[iglu ]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
   
   if (! (outgoingVertex1_[inter] && outgoingVertex2_[inter]))
     throw Exception()
       << "Invalid vertices for QCD radiation in TFF decay in TFFDecayer::threeBodyME"
       << Exception::runerror;
 
   // identify fermion and/or anti-fermion vertex
   AbstractFFVVertexPtr outgoingVertexF = outgoingVertex1_[inter];
   AbstractFFVVertexPtr outgoingVertexA = outgoingVertex2_[inter];
 
   if(outgoingVertex1_[inter]!=outgoingVertex2_[inter] &&
      outgoingVertex1_[inter]->isIncoming(getParticleData(decay[ianti]->id())))
     swap (outgoingVertexF, outgoingVertexA);  
   
   if(! (inpart.dataPtr()->iColour()==PDT::Colour0)){
     throw Exception()
       << "Invalid vertices for QCD radiation in TFF decay in TFFDecayer::threeBodyME"
       << Exception::runerror;
   }
 
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
   for(unsigned int it = 0; it < 5; ++it) {  
     for(unsigned int ifm = 0; ifm < 2; ++ifm) {
       for(unsigned int ia = 0; ia < 2; ++ia) {
 	for(unsigned int ig = 0; ig < 2; ++ig) {
 
 	  // radiation from outgoing fermion
 	  if((decay[iferm]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (decay[iferm]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(outgoingVertexF);
 	    // ensure you get correct outgoing particle from first vertex
 	    tcPDPtr off = decay[iferm]->dataPtr();
 	    if(off->CC()) off = off->CC();
 	    SpinorBarWaveFunction interS = 
 	      outgoingVertexF->evaluate(scale,3,off,wavebar3_[ifm],
 					gluon_[2*ig],decay[iferm]->mass());
 	  
 	    assert(wavebar3_[ifm].particle()->id()==interS.particle()->id());
 
-	    Complex diag = vertex_->evaluate(scale,wave3_[ia], interS,tensors3_[it]);
+	    Complex diag = 0.;
+	    for(auto vertex : vertex_)
+	      diag += vertex->evaluate(scale,wave3_[ia], interS,tensors3_[it]);
 	    if(!couplingSet) {
 	      gs = abs(outgoingVertexF->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
 	      (*ME[colourFlow[1][ix].first])(it, ifm, ia, ig) += 
 		colourFlow[1][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 
 	  // radiation from outgoing antifermion
 	  if((decay[ianti]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (decay[ianti]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(outgoingVertexA);
 	    // ensure you get correct outgoing particle from first vertex
 	    tcPDPtr off = decay[ianti]->dataPtr();
 	    if(off->CC()) off = off->CC();
 	    SpinorWaveFunction  interS = 
 	      outgoingVertexA->evaluate(scale,3,off,wave3_[ia],
 					gluon_[2*ig],decay[ianti]->mass());
 	    
 	    assert(wave3_[ia].particle()->id()==interS.particle()->id());
 
-	    Complex diag = vertex_->evaluate(scale,interS,wavebar3_[ifm],tensors3_[it]);
+	    Complex diag = 0.;
+	    for(auto vertex : vertex_)
+	      diag += vertex->evaluate(scale,interS,wavebar3_[ifm],tensors3_[it]);
 	    if(!couplingSet) {
 	      gs = abs(outgoingVertexA->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	      (*ME[colourFlow[2][ix].first])(it, ifm, ia, ig) += 
 		colourFlow[2][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 
 	  // radiation from 4 point vertex
 	  if (fourPointVertex_[inter]) {
 	    Complex diag = fourPointVertex_[inter]->evaluate(scale, wave3_[ia], wavebar3_[ifm],
 							     gluon_[2*ig], tensors3_[it]);
 	    for(unsigned int ix=0;ix<colourFlow[3].size();++ix) {
 	      (*ME[colourFlow[3][ix].first])(it, ifm, ia, ig) += 
 		colourFlow[3][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 	}
       }
     }
   }
 
   // contract matrices 
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha_(s,em)
   output *= (4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
   // return the answer
   return output;
 }
 
diff --git a/Decay/General/TFFDecayer.h b/Decay/General/TFFDecayer.h
--- a/Decay/General/TFFDecayer.h
+++ b/Decay/General/TFFDecayer.h
@@ -1,215 +1,223 @@
 // -*- C++ -*-
 //
 // TFFDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_TFFDecayer_H
 #define HERWIG_TFFDecayer_H
 //
 // This is the declaration of the TFFDecayer class.
 //
 
 #include "GeneralTwoBodyDecayer.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Helicity/Vertex/Tensor/FFTVertex.h"
 #include "ThePEG/Helicity/Vertex/Vector/FFVVertex.h"
 #include "ThePEG/Helicity/Vertex/Tensor/FFVTVertex.h"
 
 namespace Herwig {
 using namespace ThePEG;
 using Helicity::FFTVertexPtr;
 
 /** \ingroup Decay
  * The TFFDecayer class implements the decay of a tensor
  * to 2 fermions in a general model. It holds an FFTVertex pointer
  * that must be typecast from the VertexBase pointer held in 
  * GeneralTwoBodyDecayer. It implents the virtual functions me2() and
  * partialWidth(). 
  *
  * @see GeneralTwoBodyDecayer
  */
 class TFFDecayer: public GeneralTwoBodyDecayer {
 
 public:
 
   /**
    * The default constructor.
    */
   TFFDecayer() {}
 
   /** @name Virtual functions required by the Decayer class. */
   //@{
   /**
    * Return the matrix element squared for a given mode and phase-space channel.
    * @param ichan The channel we are calculating the matrix element for.
    * @param part The decaying Particle.
    * @param decay The particles produced in the decay.
    * @param meopt Option for the matrix element
    * @return The matrix element squared for the phase-space configuration.
    */
   virtual double me2(const int ichan, const Particle & part,
 		     const ParticleVector & decay, MEOption meopt) const;
   
   /**
    * Function to return partial Width
    * @param inpart The decaying particle.
    * @param outa One of the decay products.
    * @param outb The other decay product.
    */
   virtual Energy partialWidth(PMPair inpart, PMPair outa, 
 			      PMPair outb) const;
 
   /**
    *  Has a POWHEG style correction
    */
   virtual POWHEGType hasPOWHEGCorrection()  {
-    return (vertex_->orderInGem()+vertex_->orderInGs())==1 ? FSR : No;
+    POWHEGType output = FSR;
+    for(auto vertex : vertex_) {
+      if(vertex->orderInAllCouplings()!=1) {
+	output = No;
+	break;
+      }
+    }
+    return output;
   }
 
   /**
    *  Three-body matrix element including additional QCD radiation
    */
   virtual double threeBodyME(const int , const Particle & inpart,
 			     const ParticleVector & decay,
 			     ShowerInteraction inter, MEOption meopt);
 
   /**
    *  Set the information on the decay
    */
-  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
+  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing,
+			    vector<VertexBasePtr>,
 			    map<ShowerInteraction,VertexBasePtr> &,
 			    const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			    map<ShowerInteraction,VertexBasePtr>);
   //@}
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const;
 
   /** Make a clone of this object, possibly modifying the cloned object
    * to make it sane.
    * @return a pointer to the new object.
    */
   virtual IBPtr fullclone() const;
   //@}
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   TFFDecayer & operator=(const TFFDecayer &);
 
 private:
 
   /**
    *  Abstract pointer to AbstractFFTVertex
    */
-  AbstractFFTVertexPtr vertex_;
+  vector<AbstractFFTVertexPtr> vertex_;
 
   /**
    * Pointer to the perturbative vertex
    */
-  FFTVertexPtr perturbativeVertex_;
+  vector<FFTVertexPtr> perturbativeVertex_;
 
   /**
    *  Abstract pointer to AbstractFFVVertex for QCD radiation from outgoing (anti)fermion
    */
   map<ShowerInteraction,AbstractFFVVertexPtr> outgoingVertex1_;
 
   /**
    *  Abstract pointer to AbstractFFVVertex for QCD radiation from outgoing (anti)fermion
    */
   map<ShowerInteraction,AbstractFFVVertexPtr> outgoingVertex2_;
 
   /**
    *  Abstract pointer to AbstractFFVTVertex for QCD radiation from 4 point vertex
    */
   map<ShowerInteraction,AbstractFFVTVertexPtr> fourPointVertex_;
 
   /**
    *  Spin density matrix
    */
   mutable RhoDMatrix rho_;
 
   /**
    *  Polarization tensors for the decaying particle
    */
   mutable vector<TensorWaveFunction> tensors_;
 
   /**
    *  Spinors for the decay products
    */
   mutable vector<SpinorWaveFunction> wave_;
 
   /**
    *  Barred spinors for the decay products
    */
   mutable vector<SpinorBarWaveFunction> wavebar_;
 
   /**
    *  Spin density matrix for 3 body decay
    */
   mutable RhoDMatrix rho3_;
 
   /**
    *  Tensor wavefunction for 3 body decay
    */
   mutable vector<TensorWaveFunction> tensors3_;
 
   /**
    *  Spinor wavefunction for 3 body decay
    */
   mutable vector<SpinorWaveFunction> wave3_;
 
   /**
    *  Barred spinor wavefunction for 3 body decay
    */
   mutable vector<SpinorBarWaveFunction> wavebar3_;
 
     /**
    *  Vector wavefunction for 3 body decay
    */
   mutable vector<VectorWaveFunction> gluon_;
 
 };
 
 }
 
 #endif /* HERWIG_TFFDecayer_H */
diff --git a/Decay/General/TSSDecayer.cc b/Decay/General/TSSDecayer.cc
--- a/Decay/General/TSSDecayer.cc
+++ b/Decay/General/TSSDecayer.cc
@@ -1,125 +1,130 @@
 // -*- C++ -*-
 //
 // TSSDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the TSSDecayer class.
 //
 
 #include "TSSDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/TensorWaveFunction.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr TSSDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr TSSDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 
 void TSSDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
-			      VertexBasePtr vertex,
+			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & ,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & ,
 			      map<ShowerInteraction,VertexBasePtr> ) {
   decayInfo(incoming,outgoing);
-  vertex_             = dynamic_ptr_cast<AbstractSSTVertexPtr>(vertex);
-  perturbativeVertex_ = dynamic_ptr_cast<SSTVertexPtr>        (vertex);
+  for(auto vert : vertex) {
+    vertex_            .push_back(dynamic_ptr_cast<AbstractSSTVertexPtr>(vert));
+    perturbativeVertex_.push_back(dynamic_ptr_cast<SSTVertexPtr>        (vert));
+  }
 }
 
 
 void TSSDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_ << perturbativeVertex_;
 }
 
 void TSSDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_ >> perturbativeVertex_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<TSSDecayer,GeneralTwoBodyDecayer>
 describeHerwigTSSDecayer("Herwig::TSSDecayer", "Herwig.so");
 
 void TSSDecayer::Init() {
 
   static ClassDocumentation<TSSDecayer> documentation
     ("This class implements the decay of a tensor particle into "
      "2 scalars.");
 
 }
 
 double TSSDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay,
 		       MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin2,PDT::Spin0,PDT::Spin0)));
   if(meopt==Initialize) {
     TensorWaveFunction::
       calculateWaveFunctions(tensors_,rho_,const_ptr_cast<tPPtr>(&inpart),
 			     incoming,false);
   }
   if(meopt==Terminate) {
     TensorWaveFunction::
       constructSpinInfo(tensors_,const_ptr_cast<tPPtr>(&inpart),
 			incoming,true,false);
     for(unsigned int ix=0;ix<2;++ix)
       ScalarWaveFunction::
 	constructSpinInfo(decay[ix],outgoing,true);
     return 0.;
   }
   ScalarWaveFunction sca1(decay[0]->momentum(),decay[0]->dataPtr(),outgoing);
   ScalarWaveFunction sca2(decay[1]->momentum(),decay[1]->dataPtr(),outgoing);
   Energy2 scale(sqr(inpart.mass()));
   for(unsigned int thel=0;thel<5;++thel) {
-    (*ME())(thel,0,0) = vertex_->evaluate(scale,sca1,sca2,tensors_[thel]); 
+    (*ME())(thel,0,0) =0.;
+    for(auto vert : vertex_)
+      (*ME())(thel,0,0) += vert->evaluate(scale,sca1,sca2,tensors_[thel]); 
   }
   double output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 
 Energy TSSDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
-  if(perturbativeVertex_) {
+  if(perturbativeVertex_.size()==1 &&
+     perturbativeVertex_[0]) {
     Energy2 scale(sqr(inpart.second));
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
-    perturbativeVertex_->setCoupling(scale, outa.first, outb.first, in);
+    perturbativeVertex_[0]->setCoupling(scale, outa.first, outb.first, in);
     double musq = sqr(outa.second/inpart.second);
     double b = sqrt(1. - 4.*musq);
     double me2 = scale*pow(b,4)/120*UnitRemoval::InvE2;
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second,outa.second,
 					outb.second);
-    Energy output = norm(perturbativeVertex_->norm())*me2*pcm/(8.*Constants::pi);
+    Energy output = norm(perturbativeVertex_[0]->norm())*me2*pcm/(8.*Constants::pi);
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
diff --git a/Decay/General/TSSDecayer.h b/Decay/General/TSSDecayer.h
--- a/Decay/General/TSSDecayer.h
+++ b/Decay/General/TSSDecayer.h
@@ -1,150 +1,151 @@
 // -*- C++ -*-
 //
 // TSSDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_TSSDecayer_H
 #define HERWIG_TSSDecayer_H
 //
 // This is the declaration of the TSSDecayer class.
 //
 
 #include "GeneralTwoBodyDecayer.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Helicity/Vertex/Tensor/SSTVertex.h"
 
 namespace Herwig {
 using namespace ThePEG;
 using Helicity::SSTVertexPtr;
 
 /** \ingroup Decay
  * The TSSDecayer class implements the decay of a tensor
  * to 2 scalars in a general model. It holds an SSTVertex pointer
  * that must be typecast from the VertexBase pointer held in 
  * GeneralTwoBodyDecayer. It implents the virtual functions me2() and
  * partialWidth(). 
  *
  * @see GeneralTwoBodyDecayer
  */
 class TSSDecayer: public GeneralTwoBodyDecayer {
 
 public:
 
   /**
    * The default constructor.
    */
   TSSDecayer() {}
 
 public:
 
   /** @name Virtual functions required by the Decayer class. */
   //@{
   /**
    * Return the matrix element squared for a given mode and phase-space channel.
    * @param ichan The channel we are calculating the matrix element for.
    * @param part The decaying Particle.
    * @param decay The particles produced in the decay.
    * @param meopt Option for the matrix element
    * @return The matrix element squared for the phase-space configuration.
    */
   virtual double me2(const int ichan, const Particle & part,
 		     const ParticleVector & decay, MEOption meopt) const;
   
   /**
    * Function to return partial Width
    * @param inpart The decaying particle.
    * @param outa One of the decay products.
    * @param outb The other decay product.
    */
   virtual Energy partialWidth(PMPair inpart, PMPair outa, 
 			      PMPair outb) const;
 
   /**
    *  Set the information on the decay
    */
-  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
+  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing,
+			    vector<VertexBasePtr>,
 			    map<ShowerInteraction,VertexBasePtr> &,
 			    const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			    map<ShowerInteraction,VertexBasePtr>);
   //@}
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const;
 
   /** Make a clone of this object, possibly modifying the cloned object
    * to make it sane.
    * @return a pointer to the new object.
    */
   virtual IBPtr fullclone() const;
   //@}
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   TSSDecayer & operator=(const TSSDecayer &);
 
 private:
 
   /**
    *  Abstract pointer to AbstractSSTVertex
    */
-  AbstractSSTVertexPtr vertex_;
+  vector<AbstractSSTVertexPtr> vertex_;
 
   /**
    * Pointer to the perturbative vertex
    */
-  SSTVertexPtr perturbativeVertex_;
+  vector<SSTVertexPtr> perturbativeVertex_;
 
   /**
    *  Spin density matrix
    */
   mutable RhoDMatrix rho_;
 
   /**
    *  Polarization tensors of the decaying particle
    */
   mutable vector<Helicity::TensorWaveFunction> tensors_;
 };
 
 }
 
 #endif /* HERWIG_TSSDecayer_H */
diff --git a/Decay/General/TVVDecayer.cc b/Decay/General/TVVDecayer.cc
--- a/Decay/General/TVVDecayer.cc
+++ b/Decay/General/TVVDecayer.cc
@@ -1,329 +1,338 @@
 // -*- C++ -*-
 //
 // TVVDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the TVVDecayer class.
 //
 
 #include "TVVDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/TensorWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "ThePEG/Helicity/LorentzTensor.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr TVVDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr TVVDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void TVVDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
-			      VertexBasePtr vertex,
+			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> &,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> fourV) {
   decayInfo(incoming,outgoing);
-  vertex_             = dynamic_ptr_cast<AbstractVVTVertexPtr>(vertex);
-  perturbativeVertex_ = dynamic_ptr_cast<VVTVertexPtr>        (vertex);
+  for(auto vert : vertex) {
+    vertex_            .push_back(dynamic_ptr_cast<AbstractVVTVertexPtr>(vert));
+    perturbativeVertex_.push_back(dynamic_ptr_cast<VVTVertexPtr>        (vert));
+  }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     fourPointVertex_[inter] = dynamic_ptr_cast<AbstractVVVTVertexPtr>(fourV.at(inter));
     outgoingVertex1_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr> (outV[0].at(inter));
     outgoingVertex2_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr> (outV[1].at(inter));
   }
 }
 
 void TVVDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_          << perturbativeVertex_
      << outgoingVertex1_ << outgoingVertex2_
      << fourPointVertex_;
 }
 
 void TVVDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_          >> perturbativeVertex_
      >> outgoingVertex1_ >> outgoingVertex2_
      >> fourPointVertex_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<TVVDecayer,GeneralTwoBodyDecayer>
 describeHerwigTVVDecayer("Herwig::TVVDecayer", "Herwig.so");
 
 void TVVDecayer::Init() {
 
   static ClassDocumentation<TVVDecayer> documentation
     ("This class implements the decay of a tensor to 2 vector bosons");
 
 }
 
 double TVVDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay,
 		       MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin2,PDT::Spin1,PDT::Spin1)));
   bool photon[2];
   for(unsigned int ix=0;ix<2;++ix)
     photon[ix] = decay[ix]->mass()==ZERO;
   if(meopt==Initialize) {
     TensorWaveFunction::
       calculateWaveFunctions(tensors_,rho_,const_ptr_cast<tPPtr>(&inpart),
 			     incoming,false);
   }
   if(meopt==Terminate) {
     TensorWaveFunction::
       constructSpinInfo(tensors_,const_ptr_cast<tPPtr>(&inpart),
 			incoming,true,false);
     for(unsigned int ix=0;ix<2;++ix)
       VectorWaveFunction::
 	constructSpinInfo(vectors_[ix],decay[ix],outgoing,true,photon[ix]);
     return 0.;
   }
   for(unsigned int ix=0;ix<2;++ix)
     VectorWaveFunction::
       calculateWaveFunctions(vectors_[ix],decay[ix],outgoing,photon[ix]);
   Energy2 scale(sqr(inpart.mass()));
   unsigned int thel,v1hel,v2hel;
   for(thel=0;thel<5;++thel) {
     for(v1hel=0;v1hel<3;++v1hel) {
       for(v2hel=0;v2hel<3;++v2hel) {
-	(*ME())(thel,v1hel,v2hel) = vertex_->evaluate(scale,
-							   vectors_[0][v1hel],
-							   vectors_[1][v2hel],
-							   tensors_[thel]);
+	(*ME())(thel,v1hel,v2hel) = 0.;
+	  for(auto vert : vertex_)
+	    (*ME())(thel,v1hel,v2hel) += vert->evaluate(scale,
+							vectors_[0][v1hel],
+							vectors_[1][v2hel],
+							tensors_[thel]);
 	if(photon[1]) ++v2hel;
       }
       if(photon[0]) ++v1hel;
     }
   }
   double output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
   
 Energy TVVDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
-  if(perturbativeVertex_) {
+  if(perturbativeVertex_.size()==1 &&
+     perturbativeVertex_[0]) {
     Energy2 scale(sqr(inpart.second));
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
-    perturbativeVertex_->setCoupling(scale, outa.first, outb.first, in);
+    perturbativeVertex_[0]->setCoupling(scale, outa.first, outb.first, in);
     double mu2 = sqr(outa.second/inpart.second);
     double b = sqrt(1 - 4.*mu2);
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second,outa.second,
 					outb.second);
     Energy2 me2;
     if(outa.second > ZERO && outb.second > ZERO)
       me2 = scale*(30 - 20.*b*b + 3.*pow(b,4))/120.; 
     else 
       me2 = scale/10.;
     
-    Energy output = norm(perturbativeVertex_->norm())*me2*pcm
+    Energy output = norm(perturbativeVertex_[0]->norm())*me2*pcm
       /(8.*Constants::pi)*UnitRemoval::InvE2;
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 double TVVDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   bool massless[2];
   for(unsigned int ix=0;ix<2;++ix)
     massless[ix] = decay[ix]->mass()==ZERO;
   int iglu(2);  
   if(meopt==Initialize) {
     // create tensor wavefunction for decaying particle
     TensorWaveFunction::
       calculateWaveFunctions(tensors3_, rho3_, const_ptr_cast<tPPtr>(&inpart), incoming, false);
   }
   // setup spin information when needed
   if(meopt==Terminate) {
     TensorWaveFunction::
       constructSpinInfo(tensors3_, const_ptr_cast<tPPtr>(&inpart),incoming,true, false);
     for(unsigned int ix=0;ix<2;++ix)
       VectorWaveFunction::
 	constructSpinInfo(vectors3_[ix],decay[ix   ],outgoing,true, massless[ix]);
     VectorWaveFunction::
         constructSpinInfo(gluon_       ,decay[iglu ],outgoing,true,false);
     return 0.;
   }
 
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
 
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin2, PDT::Spin1,
 								       PDT::Spin1, PDT::Spin1)));
   // create wavefunctions
   for(unsigned int ix=0;ix<2;++ix)
     VectorWaveFunction::
       calculateWaveFunctions(vectors3_[ix],decay[ix   ],outgoing,massless[ix]);
   VectorWaveFunction::
       calculateWaveFunctions(gluon_       ,decay[iglu ],outgoing,true);
 
   // gauge test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[iglu ]->momentum(),
   				          decay[iglu ]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
   
   // work out which vector each outgoing vertex corresponds to 
   if(outgoingVertex1_[inter]!=outgoingVertex2_[inter] &&
      outgoingVertex1_[inter]->isIncoming(getParticleData(decay[1]->id())))
     swap(outgoingVertex1_[inter], outgoingVertex2_[inter]);
   
   if (! (outgoingVertex1_[inter] && outgoingVertex2_[inter]))
     throw Exception()
       << "Invalid vertices for radiation in TVV decay in TVVDecayer::threeBodyME"
       << Exception::runerror;
 
   if( !(!inpart.dataPtr()->coloured() && inter ==ShowerInteraction::QCD) &&
       !(!inpart.dataPtr()->charged()  && inter ==ShowerInteraction::QED))
     throw Exception()
       << "Invalid vertices for radiation in TVV decay in TVVDecayer::threeBodyME"
       << Exception::runerror;
 
 
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
   for(unsigned int it = 0; it < 5; ++it) {  
     for(unsigned int iv0 = 0; iv0 < 3; ++iv0) {
       for(unsigned int iv1 = 0; iv1 < 3; ++iv1) {
 	for(unsigned int ig = 0; ig < 2; ++ig) {
 
 	  // radiation from first outgoing vector
 	  if((decay[0]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (decay[0]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(outgoingVertex1_[inter]);
 	    // ensure you get correct outgoing particle from first vertex
 	    tcPDPtr off = decay[0]->dataPtr();
 	    if(off->CC()) off = off->CC();
 	    VectorWaveFunction vectInter = 
 	      outgoingVertex1_[inter]->evaluate(scale,3,off,gluon_[2*ig],
 						 vectors3_[0][iv0],decay[0]->mass());
 	  
 	    assert(vectors3_[0][iv0].particle()->PDGName()==vectInter.particle()->PDGName());
 
-	    Complex diag = vertex_->evaluate(scale,vectors3_[1][iv1], 
-					     vectInter,tensors3_[it]);
+	    Complex diag = 0.;
+	    for(auto vertex : vertex_)
+	      diag += vertex->evaluate(scale,vectors3_[1][iv1], 
+				       vectInter,tensors3_[it]);
 	    if(!couplingSet) {
 	      gs = abs(outgoingVertex1_[inter]->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
 	      (*ME[colourFlow[1][ix].first])(it, iv0, iv1, ig) += 
 		colourFlow[1][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 
 	  // radiation from second outgoing vector
 	  if((decay[1]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (decay[1]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(outgoingVertex2_[inter]);
 	    // ensure you get correct outgoing particle from first vertex
 	    tcPDPtr off = decay[1]->dataPtr();
 	    if(off->CC()) off = off->CC();
 	    VectorWaveFunction  vectInter = 
 	      outgoingVertex2_[inter]->evaluate(scale,3,off,vectors3_[1][iv1],
 						gluon_[2*ig],decay[1]->mass());
 	    
 	    assert(vectors3_[1][iv1].particle()->PDGName()==vectInter.particle()->PDGName());
 	    
-	    Complex diag = vertex_->evaluate(scale,vectInter,vectors3_[0][iv0],
-					     tensors3_[it]);
+	    Complex diag = 0.;
+	    for(auto vertex : vertex_)
+	      diag += vertex->evaluate(scale,vectInter,vectors3_[0][iv0],
+					tensors3_[it]);
 	    if(!couplingSet) {
 	      gs = abs(outgoingVertex2_[inter]->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	      (*ME[colourFlow[2][ix].first])(it, iv0, iv1, ig) += 
 		colourFlow[2][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 
 	  // radiation from 4 point vertex
 	  if (fourPointVertex_[inter]) {
 	    Complex diag = fourPointVertex_[inter]->evaluate(scale, vectors3_[0][iv0],
 							     vectors3_[1][iv1],gluon_[2*ig], 
 							     tensors3_[it]);
 	    for(unsigned int ix=0;ix<colourFlow[3].size();++ix) {
 	      (*ME[colourFlow[3][ix].first])(it, iv0, iv1, ig) += 
 		colourFlow[3][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 	}
 	if(massless[1]) ++iv1;
       }
       if(massless[0]) ++iv0;
     }
   }
 
   // contract matrices 
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha_(s,em)
   output *= (4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
   // return the answer
   return output;
 }
diff --git a/Decay/General/TVVDecayer.h b/Decay/General/TVVDecayer.h
--- a/Decay/General/TVVDecayer.h
+++ b/Decay/General/TVVDecayer.h
@@ -1,205 +1,213 @@
 // -*- C++ -*-
 //
 // TVVDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_TVVDecayer_H
 #define HERWIG_TVVDecayer_H
 //
 // This is the declaration of the TVVDecayer class.
 //
 
 #include "GeneralTwoBodyDecayer.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Helicity/Vertex/Vector/VVVVertex.h"
 #include "ThePEG/Helicity/Vertex/Tensor/VVTVertex.h"
 #include "ThePEG/Helicity/Vertex/Tensor/VVVTVertex.h"
 
 namespace Herwig {
 using namespace ThePEG;
 using Helicity::VVTVertexPtr;
 
 /** \ingroup Decay
  * The TVVDecayer class implements the decay of a tensor
  * to 2 vector bosons in a general model. It holds a VVTVertex pointer
  * that must be typecast from the VertexBase pointer held in 
  * GeneralTwoBodyDecayer. It implents the virtual functions me2() and
  * partialWidth(). 
  *
  * @see GeneralTwoBodyDecayer
  */
 class TVVDecayer: public GeneralTwoBodyDecayer {
 
 public:
 
   /**
    * The default constructor.
    */
   TVVDecayer() {}
 
   /** @name Virtual functions required by the Decayer class. */
   //@{
   /**
    * Return the matrix element squared for a given mode and phase-space channel.
    * @param ichan The channel we are calculating the matrix element for.
    * @param part The decaying Particle.
    * @param decay The particles produced in the decay.
    * @param meopt Option for the matrix element
    * @return The matrix element squared for the phase-space configuration.
    */
   virtual double me2(const int ichan, const Particle & part,
                       const ParticleVector & decay, MEOption meopt) const;
   
   /**
    * Function to return partial Width
    * @param inpart The decaying particle.
    * @param outa One of the decay products.
    * @param outb The other decay product.
    */
   virtual Energy partialWidth(PMPair inpart, PMPair outa, 
 			      PMPair outb) const;
   /**
    *  Has a POWHEG style correction
    */
   virtual POWHEGType hasPOWHEGCorrection()  {
-    return (vertex_->orderInGem()+vertex_->orderInGs())==1 ? FSR : No;
+    POWHEGType output = FSR;
+    for(auto vertex : vertex_) {
+      if(vertex->orderInAllCouplings()!=1) {
+	output = No;
+	break;
+      }
+    }
+    return output;
   }
 
   /**
    *  Three-body matrix element including additional QCD radiation
    */
   virtual double threeBodyME(const int , const Particle & inpart,
 			     const ParticleVector & decay,
 			     ShowerInteraction inter, MEOption meopt);
 
   /**
    *  Set the information on the decay
    */
-  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
+  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing,
+			    vector<VertexBasePtr>,
 			    map<ShowerInteraction,VertexBasePtr> &,
 			    const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			    map<ShowerInteraction,VertexBasePtr>);
 
   //@}
   
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const;
 
   /** Make a clone of this object, possibly modifying the cloned object
    * to make it sane.
    * @return a pointer to the new object.
    */
   virtual IBPtr fullclone() const;
   //@}
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   TVVDecayer & operator=(const TVVDecayer &);
 
 private:
 
   /**
    *  Abstract pointer to AbstractVVTVertex
    */
-  AbstractVVTVertexPtr vertex_;
+  vector<AbstractVVTVertexPtr> vertex_;
 
   /**
    * Pointer to the perturbative vertex
    */
-  VVTVertexPtr perturbativeVertex_;
+  vector<VVTVertexPtr> perturbativeVertex_;
 
   /**
    *  Abstract pointer to AbstractVVVVertex for QCD radiation from outgoing vector
    */
   map<ShowerInteraction,AbstractVVVVertexPtr> outgoingVertex1_;
 
   /**
    *  Abstract pointer to AbstractVVVVertex for QCD radiation from outgoing vector
    */
   map<ShowerInteraction,AbstractVVVVertexPtr> outgoingVertex2_;
 
   /**
    *  Abstract pointer to AbstractVVVTVertex for QCD radiation from 4 point vertex
    */
   map<ShowerInteraction,AbstractVVVTVertexPtr> fourPointVertex_;
 
   /**
    *  Spin density matrix
    */
   mutable RhoDMatrix rho_;
 
   /**
    *  Polarization tensors of decaying particle
    */
   mutable vector<Helicity::TensorWaveFunction> tensors_;
 
   /**
    *  Polarization vectors of outgoing vector bosons
    */
   mutable vector<Helicity::VectorWaveFunction> vectors_[2];
 
   /**
    *  Spin density matrix for 3 body decay
    */
   mutable RhoDMatrix rho3_;
 
   /**
    *  Tensor wavefunction for 3 body decay
    */
   mutable vector<Helicity::TensorWaveFunction> tensors3_;
 
   /**
    *  Polarization vectors of outgoing vector bosons
    */
   mutable vector<Helicity::VectorWaveFunction> vectors3_[2];
 
     /**
    *  Vector wavefunction for 3 body decay
    */
   mutable vector<Helicity::VectorWaveFunction> gluon_;
 
 };
 
 }
 
 #endif /* HERWIG_TVVDecayer_H */
diff --git a/Decay/General/VFFDecayer.cc b/Decay/General/VFFDecayer.cc
--- a/Decay/General/VFFDecayer.cc
+++ b/Decay/General/VFFDecayer.cc
@@ -1,456 +1,470 @@
 // -*- C++ -*-
 //
 // VFFDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the VFFDecayer class.
 //
 
 #include "VFFDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "ThePEG/Helicity/Vertex/Vector/FFVVertex.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 IBPtr VFFDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr VFFDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void VFFDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
-			      VertexBasePtr vertex,
+			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> ) {
   decayInfo(incoming,outgoing);
-  vertex_             = dynamic_ptr_cast<AbstractFFVVertexPtr>(vertex);
-  perturbativeVertex_ = dynamic_ptr_cast<FFVVertexPtr>        (vertex);
+  for(auto vert : vertex) {
+    vertex_            .push_back(dynamic_ptr_cast<AbstractFFVVertexPtr>(vert));
+    perturbativeVertex_.push_back(dynamic_ptr_cast<FFVVertexPtr>        (vert));
+  }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(inV.at(inter));
     outgoingVertex1_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(outV[0].at(inter));
     outgoingVertex2_[inter] = dynamic_ptr_cast<AbstractFFVVertexPtr>(outV[1].at(inter));
   }
 }
 
 void VFFDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_           << perturbativeVertex_
      << incomingVertex_   << outgoingVertex1_
      << outgoingVertex2_;
 }
 
 void VFFDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_           >> perturbativeVertex_
      >> incomingVertex_   >> outgoingVertex1_
      >> outgoingVertex2_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<VFFDecayer,GeneralTwoBodyDecayer>
 describeHerwigVFFDecayer("Herwig::VFFDecayer", "Herwig.so");
 
 void VFFDecayer::Init() {
 
   static ClassDocumentation<VFFDecayer> documentation
     ("The VFFDecayer implements the matrix element for the"
      " decay of a vector to fermion-antifermion pair");
 
 }
 
 double VFFDecayer::me2(const int , const Particle & inpart,
 		       const ParticleVector & decay, 
 		       MEOption meopt) const {
   int iferm(1),ianti(0);
   if(decay[0]->id()>0) swap(iferm,ianti);
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1Half)));
   if(meopt==Initialize) {
     VectorWaveFunction::calculateWaveFunctions(vectors_,rho_,
 					       const_ptr_cast<tPPtr>(&inpart),
 					       incoming,false);
   }
   if(meopt==Terminate) {
     VectorWaveFunction::constructSpinInfo(vectors_,const_ptr_cast<tPPtr>(&inpart),
 					  incoming,true,false);
     SpinorBarWaveFunction::
       constructSpinInfo(wavebar_,decay[iferm],outgoing,true);
     SpinorWaveFunction::
       constructSpinInfo(wave_   ,decay[ianti],outgoing,true);
     return 0.;
   }
   SpinorBarWaveFunction::
     calculateWaveFunctions(wavebar_,decay[iferm],outgoing);
   SpinorWaveFunction::
     calculateWaveFunctions(wave_   ,decay[ianti],outgoing);
   // compute the matrix element
   Energy2 scale(inpart.mass()*inpart.mass());
   for(unsigned int ifm = 0; ifm < 2; ++ifm) { //loop over fermion helicities
     for(unsigned int ia = 0; ia < 2; ++ia) {// loop over antifermion helicities
       for(unsigned int vhel = 0; vhel < 3; ++vhel) {//loop over vector helicities
 	if(iferm > ianti) {
-	  (*ME())(vhel, ia, ifm) = 
-	    vertex_->evaluate(scale,wave_[ia],
-				      wavebar_[ifm],vectors_[vhel]);
+	  (*ME())(vhel, ia, ifm) = 0.;
+	  for(auto vert : vertex_)
+	    (*ME())(vhel, ia, ifm) += 
+	      vert->evaluate(scale,wave_[ia],
+			     wavebar_[ifm],vectors_[vhel]);
 	}
-	else
-	  (*ME())(vhel,ifm,ia)=
-	    vertex_->evaluate(scale,wave_[ia],
-				      wavebar_[ifm],vectors_[vhel]);
+	else {
+	  (*ME())(vhel,ifm,ia)= 0.;
+	  for(auto vert : vertex_)
+	    (*ME())(vhel,ifm,ia) +=
+	      vert->evaluate(scale,wave_[ia],
+			     wavebar_[ifm],vectors_[vhel]);
+	}
       }
     }
   }
   double output=(ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy VFFDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
-  if(perturbativeVertex_) {
+  if(perturbativeVertex_.size()==1 &&
+     perturbativeVertex_[0]) {
     double mu1(outa.second/inpart.second), mu2(outb.second/inpart.second);
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
-    perturbativeVertex_->setCoupling(sqr(inpart.second), outa.first, outb.first,in);
-    Complex cl(perturbativeVertex_->left()), cr(perturbativeVertex_->right());
+    perturbativeVertex_[0]->setCoupling(sqr(inpart.second), outa.first, outb.first,in);
+    Complex cl(perturbativeVertex_[0]->left()), cr(perturbativeVertex_[0]->right());
     double me2 = (norm(cl) + norm(cr))*( sqr(sqr(mu1) - sqr(mu2)) 
 					 + sqr(mu1) + sqr(mu2) - 2.)
       - 6.*(cl*conj(cr) + cr*conj(cl)).real()*mu1*mu2;
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second,outa.second,
 					outb.second);
-    Energy output = -norm(perturbativeVertex_->norm())*me2*pcm / 
+    Energy output = -norm(perturbativeVertex_[0]->norm())*me2*pcm / 
       (24.*Constants::pi);
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 
 double VFFDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   // work out which is the fermion and antifermion
   int ianti(0), iferm(1), iglu(2);
   int itype[2];
   for(unsigned int ix=0;ix<2;++ix) {
     if(decay[ix]->dataPtr()->CC()) itype[ix] = decay[ix]->id()>0 ? 0:1;
     else                           itype[ix] = 2;
   }
   if(itype[0]==0 && itype[1]!=0) swap(iferm, ianti);
   if(itype[0]==2 && itype[1]==1) swap(iferm, ianti);
   if(itype[0]==0 && itype[1]==0 && decay[0]->dataPtr()->id()<decay[1]->dataPtr()->id()) 
     swap(iferm, ianti);
   if(itype[0]==1 && itype[1]==1 && decay[0]->dataPtr()->id()<decay[1]->dataPtr()->id()) 
     swap(iferm, ianti);
 
   if(meopt==Initialize) {
     // create vector wavefunction for decaying particle
     VectorWaveFunction::calculateWaveFunctions(vector3_, rho3_, const_ptr_cast<tPPtr>(&inpart), 
 					       incoming, false);
   }
   // setup spin information when needed
   if(meopt==Terminate) {
     VectorWaveFunction::
       constructSpinInfo(vector3_ ,const_ptr_cast<tPPtr>(&inpart),outgoing,true,false);
     SpinorBarWaveFunction::
       constructSpinInfo(wavebar3_,decay[iferm],outgoing,true);
     SpinorWaveFunction::
       constructSpinInfo(wave3_   ,decay[ianti],outgoing,true);
     VectorWaveFunction::
       constructSpinInfo(gluon_   ,decay[iglu ],outgoing,true,false);
     return 0.;
   }
 
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
 
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin1,     PDT::Spin1Half,
 								       PDT::Spin1Half, PDT::Spin1)));
   // create wavefunctions
   SpinorBarWaveFunction::
     calculateWaveFunctions(wavebar3_, decay[iferm],outgoing);
   SpinorWaveFunction::
     calculateWaveFunctions(wave3_   , decay[ianti],outgoing);
   VectorWaveFunction::
     calculateWaveFunctions(gluon_   , decay[iglu ],outgoing,true);
 
   // gauge invariance test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[iglu ]->momentum(),
   				          decay[iglu ]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
 
   // identify fermion and/or anti-fermion vertex
   AbstractFFVVertexPtr outgoingVertexF;
   AbstractFFVVertexPtr outgoingVertexA;
   identifyVertices(iferm, ianti, inpart, decay, outgoingVertexF, outgoingVertexA,inter);
 
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
   for(unsigned int iv = 0; iv < 3; ++iv) {
     for(unsigned int ifm = 0; ifm < 2; ++ifm) {
       for(unsigned int ia = 0; ia < 2; ++ia) {
 	for(unsigned int ig = 0; ig < 2; ++ig) {
 	  // radiation from the incoming vector
 	  if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(incomingVertex_[inter]);
 	    
 	    VectorWaveFunction vectorInter = 
 	      incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),vector3_[iv],
 						gluon_[2*ig],inpart.mass());
 	    
 	    assert(vector3_[iv].particle()->id()==vectorInter.particle()->id());
 
-	    Complex diag = vertex_->evaluate(scale,wave3_[ia],wavebar3_[ifm],vectorInter);
+	    Complex diag = 0.;
+	    for(auto vertex : vertex_)
+	      diag += vertex->evaluate(scale,wave3_[ia],wavebar3_[ifm],vectorInter);
 	    if(!couplingSet) {
               gs = abs(incomingVertex_[inter]->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	      (*ME[colourFlow[0][ix].first])(iv, ia, ifm, ig) += 
 		 colourFlow[0][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
   
 	  // radiation from outgoing fermion
 	  if((decay[iferm]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (decay[iferm]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(outgoingVertexF);
 	    // ensure you get correct outgoing particle from first vertex
 	    tcPDPtr off = decay[iferm]->dataPtr();
 	    if(off->CC()) off = off->CC();
 	    SpinorBarWaveFunction interS = 
 	      outgoingVertexF->evaluate(scale,3,off,wavebar3_[ifm],
 						gluon_[2*ig],decay[iferm]->mass());
 	    
 	    assert(wavebar3_[ifm].particle()->id()==interS.particle()->id());
 	    
-	    Complex diag = vertex_->evaluate(scale,wave3_[ia], interS,vector3_[iv]);
+	    Complex diag = 0.;
+	    for(auto vertex : vertex_)
+	      diag += vertex->evaluate(scale,wave3_[ia], interS,vector3_[iv]);
 	    if(!couplingSet) {
 	      gs = abs(outgoingVertexF->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
 	      (*ME[colourFlow[1][ix].first])(iv, ia, ifm, ig) += 
 		colourFlow[1][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 
 	  // radiation from outgoing antifermion
 	  if((decay[ianti]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	     (decay[ianti]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	    assert(outgoingVertexA);
 	    // ensure you get correct outgoing particle from first vertex
 	    tcPDPtr off = decay[ianti]->dataPtr();
 	    if(off->CC()) off = off->CC();
 	    SpinorWaveFunction  interS = 
 	      outgoingVertexA->evaluate(scale,3,off,wave3_[ia],
 						gluon_[2*ig],decay[ianti]->mass());
 
 	    assert(wave3_[ia].particle()->id()==interS.particle()->id());
 
-	    Complex diag = vertex_->evaluate(scale,interS,wavebar3_[ifm],vector3_[iv]);
+	    Complex diag = 0.;
+	    for(auto vertex : vertex_)
+	      diag += vertex->evaluate(scale,interS,wavebar3_[ifm],vector3_[iv]);
 	    if(!couplingSet) {
 	      gs = abs(outgoingVertexA->norm());
 	      couplingSet = true;
 	    }
 	    for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	      (*ME[colourFlow[2][ix].first])(iv, ia, ifm, ig) += 
 		colourFlow[2][ix].second*diag;
 	    }
 #ifdef GAUGE_CHECK
 	    total+=norm(diag);
 #endif
 	  }
 	}
       }
     }
   }
 
   // contract matrices 
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha_(S,EM)
   output*=(4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
   //return output
   return output;
 }
 
 
 void VFFDecayer::identifyVertices(const int iferm, const int ianti,
 				  const Particle & inpart, const ParticleVector & decay, 
 				  AbstractFFVVertexPtr & outgoingVertexF, 
 				  AbstractFFVVertexPtr & outgoingVertexA,
 				  ShowerInteraction inter){
   // QCD vertices
   if(inter==ShowerInteraction::QCD) {
     // work out which fermion each outgoing vertex corresponds to 
     // two outgoing vertices
     if( inpart.dataPtr()       ->iColour()==PDT::Colour0     &&
 	((decay[iferm]->dataPtr()->iColour()==PDT::Colour3     &&
 	  decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar) ||
 	 (decay[iferm]->dataPtr()->iColour()==PDT::Colour8     &&
 	  decay[ianti]->dataPtr()->iColour()==PDT::Colour8))){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))){
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))){
 	outgoingVertexF = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
     else if(inpart.dataPtr()       ->iColour()==PDT::Colour8 &&
 	    decay[iferm]->dataPtr()->iColour()==PDT::Colour3 &&
 	    decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))){
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))){
 	outgoingVertexF = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
     
     // one outgoing vertex
     else if(inpart.dataPtr()->iColour()==PDT::Colour3){
       if(decay[iferm]->dataPtr()->iColour()==PDT::Colour3 &&  
 	 decay[ianti]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertexF = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertexF = outgoingVertex2_[inter];
       }
       else if (decay[iferm]->dataPtr()->iColour()==PDT::Colour3 &&
 	       decay[ianti]->dataPtr()->iColour()==PDT::Colour8){
 	if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[ianti]->dataPtr()))){
 	  outgoingVertexF = outgoingVertex2_[inter];
 	  outgoingVertexA = outgoingVertex1_[inter];
 	}
 	else {
 	  outgoingVertexF = outgoingVertex1_[inter];
 	  outgoingVertexA = outgoingVertex2_[inter];
 	}
       }
     }
     else if(inpart.dataPtr()->iColour()==PDT::Colour3bar){
       if(decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar &&  
 	 decay[iferm]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertexA = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (decay[iferm]->dataPtr()->iColour()==PDT::Colour8 &&
 	       decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar){
 	if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))){
 	  outgoingVertexF = outgoingVertex1_[inter];
 	  outgoingVertexA = outgoingVertex2_[inter];
 	}
 	else {
 	  outgoingVertexF = outgoingVertex2_[inter];
 	  outgoingVertexA = outgoingVertex1_[inter];
 	}
       }
     }
     else if(inpart.dataPtr()->iColour()==PDT::Colour6 ||
 	    inpart.dataPtr()->iColour()==PDT::Colour6bar) {
       if (outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr()))) {
 	outgoingVertexF = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else {
 	outgoingVertexF = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
     
     if (! ((incomingVertex_[inter]  && (outgoingVertexF  || outgoingVertexA)) ||
 	   ( outgoingVertexF &&  outgoingVertexA)))
       throw Exception()
 	<< "Invalid vertices for QCD radiation in VFF decay in VFFDecayer::identifyVertices"
 	<< Exception::runerror;
   }
   // QED
   else {
     if(decay[iferm]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iferm]->dataPtr())))
 	outgoingVertexF = outgoingVertex1_[inter];
       else
 	outgoingVertexF = outgoingVertex2_[inter];
     }
     if(decay[ianti]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[ianti]->dataPtr())))
 	outgoingVertexA = outgoingVertex1_[inter];
       else
 	outgoingVertexA = outgoingVertex2_[inter];
     }
   }
 }
 
diff --git a/Decay/General/VFFDecayer.h b/Decay/General/VFFDecayer.h
--- a/Decay/General/VFFDecayer.h
+++ b/Decay/General/VFFDecayer.h
@@ -1,224 +1,232 @@
 // -*- C++ -*-
 //
 // VFFDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_VFFDecayer_H
 #define HERWIG_VFFDecayer_H
 //
 // This is the declaration of the VFFDecayer class.
 //
 
 #include "GeneralTwoBodyDecayer.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Helicity/Vertex/Vector/FFVVertex.h"
 #include "ThePEG/Helicity/Vertex/Vector/VVVVertex.h"
 
 namespace Herwig {
 using namespace ThePEG;
 using Helicity::FFVVertexPtr;
 
 /** \ingroup Decay
  * The VFFDecayer class implements the decay of a vector
  * to 2 fermions in a general model. It holds an FFVVertex pointer
  * that must be typecast from the VertexBase pointer held in 
  * GeneralTwoBodyDecayer. It implents the virtual functions me2() and
  * partialWidth(). 
  *
  * @see GeneralTwoBodyDecayer
  */
 class VFFDecayer: public GeneralTwoBodyDecayer {
 
 public:
   
   /**
    * The default constructor.
    */
   VFFDecayer() {}
 
 public:
 
   /** @name Virtual functions required by the Decayer class. */
   //@{
   /**
    * Return the matrix element squared for a given mode and phase-space channel.  
    * @param ichan The channel we are calculating the matrix element for.
    * @param part The decaying Particle.
    * @param decay The particles produced in the decay.
    * @param meopt Option for the matrix element
    * @return The matrix element squared for the phase-space configuration.
    */
   virtual double me2(const int ichan, const Particle & part,
 		     const ParticleVector & decay, MEOption meopt) const;
   
   /**
    * Function to return partial Width
    * @param inpart The decaying particle.
    * @param outa One of the decay products.
    * @param outb The other decay product.
    */
   virtual Energy partialWidth(PMPair inpart, PMPair outa, 
 			      PMPair outb) const;
 
   /**
    *  Has a POWHEG style correction
    */
   virtual POWHEGType hasPOWHEGCorrection()  {
-    return (vertex_->orderInGem()+vertex_->orderInGs())==1 ? FSR : No;
+    POWHEGType output = FSR;
+    for(auto vertex : vertex_) {
+      if(vertex->orderInAllCouplings()!=1) {
+	output = No;
+	break;
+      }
+    }
+    return output;
   }
 
   /**
    *  Three-body matrix element including additional QCD radiation
    */
   virtual double threeBodyME(const int , const Particle & inpart,
 			     const ParticleVector & decay,
 			     ShowerInteraction inter, MEOption meopt);
 
   /**
    * Indentify outgoing vertices for the fermion and antifermion
    */
   void identifyVertices(const int iferm, const int ianti,
 			const Particle & inpart, const ParticleVector & decay,
 			AbstractFFVVertexPtr & abstractOutgoingVertexF, 
 			AbstractFFVVertexPtr & abstractOutgoingVertexA,
 			ShowerInteraction inter);
 
   /**
    *  Set the information on the decay
    */
-  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
+  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing,
+			    vector<VertexBasePtr>,
 			    map<ShowerInteraction,VertexBasePtr> &,
 			    const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			    map<ShowerInteraction,VertexBasePtr>);
   //@}
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const;
 
   /** Make a clone of this object, possibly modifying the cloned object
    * to make it sane.
    * @return a pointer to the new object.
    */
   virtual IBPtr fullclone() const;
   //@}
 
 private:
   
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   VFFDecayer & operator=(const VFFDecayer &);
 
 private:
 
   /**
    *  Abstract pointer to AbstractFFVVertex
    */
-  AbstractFFVVertexPtr vertex_;
+  vector<AbstractFFVVertexPtr> vertex_;
 
   /**
    * Pointer to the perturbative vertex
    */
-  FFVVertexPtr perturbativeVertex_;
+  vector<FFVVertexPtr> perturbativeVertex_;
 
   /**
    *  Abstract pointer to AbstractVVVVertex for QCD radiation from incoming vector
    */
   map<ShowerInteraction,AbstractVVVVertexPtr> incomingVertex_;
 
   /**
    *  Abstract pointer to AbstractFFVVertex for QCD radiation from outgoing (anti)fermion
    */
   map<ShowerInteraction,AbstractFFVVertexPtr> outgoingVertex1_;
 
   /**
    *  Abstract pointer to AbstractFFVVertex for QCD radiation from outgoing (anti)fermion
    */
   map<ShowerInteraction,AbstractFFVVertexPtr> outgoingVertex2_;
 
   /**
    *  Spin density matrix 
    */
   mutable RhoDMatrix rho_;
 
   /**
    *  Polarization vectors for the decaying particle
    */
   mutable vector<VectorWaveFunction> vectors_;
 
   /**
    *  Spinors for the decay products 
    */
   mutable vector<SpinorWaveFunction> wave_;
 
   /**
    *  Barred spinors for the decay products
    */
   mutable vector<SpinorBarWaveFunction> wavebar_;
  /**
    *  Spin density matrix for 3 body decay
    */
   mutable RhoDMatrix rho3_;
 
   /**
    *  Scalar wavefunction for 3 body decay
    */
   mutable vector<VectorWaveFunction> vector3_;
 
   /**
    *  Spinor wavefunction for 3 body decay
    */
   mutable vector<SpinorWaveFunction> wave3_;
 
   /**
    *  Barred spinor wavefunction for 3 body decay
    */
   mutable vector<SpinorBarWaveFunction> wavebar3_;
 
     /**
    *  Vector wavefunction for 3 body decay
    */
   mutable vector<VectorWaveFunction> gluon_;
 
 };
 
 }
 
 #endif /* HERWIG_VFFDecayer_H */
diff --git a/Decay/General/VSSDecayer.cc b/Decay/General/VSSDecayer.cc
--- a/Decay/General/VSSDecayer.cc
+++ b/Decay/General/VSSDecayer.cc
@@ -1,405 +1,416 @@
 // -*- C++ -*-
 //
 // VSSDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the VSSDecayer class.
 //
 
 #include "VSSDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr VSSDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr VSSDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void VSSDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
-			      VertexBasePtr vertex,
+			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> ) {
   decayInfo(incoming,outgoing);
-  vertex_             = dynamic_ptr_cast<AbstractVSSVertexPtr>(vertex);
-  perturbativeVertex_ = dynamic_ptr_cast<VSSVertexPtr>        (vertex);
+  for(auto vert : vertex) {
+    vertex_            .push_back(dynamic_ptr_cast<AbstractVSSVertexPtr>(vert));
+    perturbativeVertex_.push_back(dynamic_ptr_cast<VSSVertexPtr>        (vert));
+  }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(inV.at(inter));
     outgoingVertex1_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[0].at(inter));
     outgoingVertex2_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[1].at(inter));
   }
 }
 
 void VSSDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_           << perturbativeVertex_
      << incomingVertex_   << outgoingVertex1_
      << outgoingVertex2_;
 }
 
 void VSSDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_           >> perturbativeVertex_
      >> incomingVertex_   >> outgoingVertex1_
      >> outgoingVertex2_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<VSSDecayer,GeneralTwoBodyDecayer>
 describeHerwigVSSDecayer("Herwig::VSSDecayer", "Herwig.so");
 
 void VSSDecayer::Init() {
 
   static ClassDocumentation<VSSDecayer> documentation
     ("This implements the decay of a vector to 2 scalars");
 
 }
 
 double VSSDecayer::me2(const int , const Particle & inpart,
  		       const ParticleVector & decay, 
 		       MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1,PDT::Spin0,PDT::Spin0)));
   if(meopt==Initialize) {
     VectorWaveFunction::calculateWaveFunctions(vectors_,rho_,
 					       const_ptr_cast<tPPtr>(&inpart),
 					       incoming,false);
   }
   if(meopt==Terminate) {
     VectorWaveFunction::constructSpinInfo(vectors_,const_ptr_cast<tPPtr>(&inpart),
 					  incoming,true,false);
     for(unsigned int ix=0;ix<2;++ix)
       ScalarWaveFunction::
 	constructSpinInfo(decay[ix],outgoing,true);
     return 0.;
   }
   ScalarWaveFunction sca1(decay[0]->momentum(),decay[0]->dataPtr(),outgoing);
   ScalarWaveFunction sca2(decay[1]->momentum(),decay[1]->dataPtr(),outgoing);
   Energy2 scale(sqr(inpart.mass()));
   for(unsigned int ix=0;ix<3;++ix) {
-    (*ME())(ix,0,0) = vertex_->evaluate(scale,vectors_[ix],sca1,sca2);
+    (*ME())(ix,0,0) = 0.;
+    for(auto vert : vertex_)
+      (*ME())(ix,0,0) += vert->evaluate(scale,vectors_[ix],sca1,sca2);
   }
   double output=(ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy VSSDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
-  if(perturbativeVertex_) {
+  if(perturbativeVertex_.size()==1 &&
+     perturbativeVertex_[0]) {
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
-    perturbativeVertex_->setCoupling(sqr(inpart.second), in, outa.first,
+    perturbativeVertex_[0]->setCoupling(sqr(inpart.second), in, outa.first,
 				     outb.first);
     double mu1sq = sqr(outa.second/inpart.second);
     double mu2sq = sqr(outb.second/inpart.second);
     double me2 = sqr(mu1sq - mu2sq) - 2.*(mu1sq + mu2sq);
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second,outa.second,
 					outb.second);
-    Energy output = -norm(perturbativeVertex_->norm())*me2*pcm /
+    Energy output = -norm(perturbativeVertex_[0]->norm())*me2*pcm /
       (24.*Constants::pi);
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 double VSSDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   // work out which is the scalar and anti-scalar
   int ianti(0), iscal(1), iglu(2);
   int itype[2];
   for(unsigned int ix=0;ix<2;++ix) {
     if(decay[ix]->dataPtr()->CC()) itype[ix] = decay[ix]->id()>0 ? 0:1;
     else                           itype[ix] = 2;
   }
   if(itype[0]==0 && itype[1]!=0) swap(ianti, iscal);
   if(itype[0]==2 && itype[1]==1) swap(ianti, iscal);
   if(itype[0]==0 && itype[1]==0 && abs(decay[0]->dataPtr()->id())>abs(decay[1]->dataPtr()->id())) 
     swap(iscal, ianti);
   if(itype[0]==1 && itype[1]==1 && abs(decay[0]->dataPtr()->id())<abs(decay[1]->dataPtr()->id())) 
     swap(iscal, ianti);
 
  if(meopt==Initialize) {
     // create vector wavefunction for decaying particle
     VectorWaveFunction::calculateWaveFunctions(vector3_, rho3_, const_ptr_cast<tPPtr>(&inpart), 
 					       incoming, false);
   }
   // setup spin information when needed
   if(meopt==Terminate) {
     VectorWaveFunction::
       constructSpinInfo(vector3_ ,const_ptr_cast<tPPtr>(&inpart),outgoing,true,false);
     ScalarWaveFunction::constructSpinInfo(       decay[iscal],outgoing,true);
     ScalarWaveFunction::constructSpinInfo(       decay[ianti],outgoing,true);
     VectorWaveFunction::constructSpinInfo(gluon_,decay[iglu ],outgoing,true,false);
     return 0.;
   }
 
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin1, PDT::Spin0,
 								       PDT::Spin0, PDT::Spin1)));
 
   // create wavefunctions
   ScalarWaveFunction scal(decay[iscal]->momentum(), decay[iscal]->dataPtr(),outgoing);
   ScalarWaveFunction anti(decay[ianti]->momentum(), decay[ianti]->dataPtr(),outgoing);
   VectorWaveFunction::calculateWaveFunctions(gluon_,decay[iglu ],outgoing,true);
 
   // gauge test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[iglu ]->momentum(),
   					  decay[iglu ]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
 
   // identify scalar and/or anti-scalar vertex
   AbstractVSSVertexPtr outgoingVertexS;
   AbstractVSSVertexPtr outgoingVertexA;
   identifyVertices(iscal, ianti, inpart, decay, outgoingVertexS, outgoingVertexA,inter);
 
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
   for(unsigned int iv = 0; iv < 3; ++iv) {
     for(unsigned int ig = 0; ig < 2; ++ig) {
       // radiation from the incoming vector
       if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	 (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	assert(incomingVertex_[inter]);	
 	VectorWaveFunction vectorInter = 
 	  incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),vector3_[iv],
 					    gluon_[2*ig],inpart.mass());
 	
 	assert(vector3_[iv].particle()->id()==vectorInter.particle()->id());
 	
-	Complex diag = vertex_->evaluate(scale,vectorInter,scal,anti);
+	Complex diag = 0.;
+	for(auto vertex : vertex_)
+	  diag += vertex->evaluate(scale,vectorInter,scal,anti);
 	if(!couplingSet) {
 	  gs = abs(incomingVertex_[inter]->norm());
 	  couplingSet = true;
 	}
 	for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	  (*ME[colourFlow[0][ix].first])(iv, 0, 0, ig) += 
 	    colourFlow[0][ix].second*diag;
 	}
 #ifdef GAUGE_CHECK
       total+=norm(diag);
 #endif
       }
       // radiation from the outgoing scalar
       if((decay[iscal]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	 (decay[iscal]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	assert(outgoingVertexS);
 	// ensure you get correct outgoing particle from first vertex
 	tcPDPtr off = decay[iscal]->dataPtr();
 	if(off->CC()) off = off->CC();
 	ScalarWaveFunction scalarInter = 
 	  outgoingVertexS->evaluate(scale,3,off,gluon_[2*ig],scal,decay[iscal]->mass());
 	
 	assert(scal.particle()->id()==scalarInter.particle()->id());
 	
-	Complex diag =vertex_->evaluate(scale,vector3_[iv],anti,scalarInter);
+	Complex diag = 0.;
+	for(auto vertex : vertex_)
+	  diag += vertex->evaluate(scale,vector3_[iv],anti,scalarInter);
 	if(!couplingSet) {
 	  gs = abs(outgoingVertexS->norm());
 	  couplingSet = true;
 	}
 	for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
 	  (*ME[colourFlow[1][ix].first])(iv, 0, 0, ig) += 
 	    colourFlow[1][ix].second*diag;
 	}
 #ifdef GAUGE_CHECK
       total+=norm(diag);
 #endif
       }
       
       if((decay[ianti]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	 (decay[ianti]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	assert(outgoingVertexA);
 	// ensure you get correct outgoing particle from first vertex
 	tcPDPtr off = decay[ianti]->dataPtr();
 	if(off->CC()) off = off->CC();
 	ScalarWaveFunction scalarInter = 
 	  outgoingVertexA->evaluate(scale,3,off, gluon_[2*ig],anti,decay[ianti]->mass());
 	
 	assert(anti.particle()->id()==scalarInter.particle()->id());
 	
-	Complex diag = vertex_->evaluate(scale,vector3_[iv],scal,scalarInter);
+	Complex diag = 0.;
+	for(auto vertex : vertex_)
+	  diag += vertex->evaluate(scale,vector3_[iv],scal,scalarInter);
 	if(!couplingSet) {
 	  gs = abs(outgoingVertexA->norm());
 	  couplingSet = true;
 	}
 	for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	  (*ME[colourFlow[2][ix].first])(iv, 0, 0, ig) += 
 	    colourFlow[2][ix].second*diag;
 	}
 #ifdef GAUGE_CHECK
       total+=norm(diag);
 #endif
       }
     }
   }
 
   // contract matrices 
   double output=0.;
   for(unsigned int ix=0; ix<nflow; ++ix){
     for(unsigned int iy=0; iy<nflow; ++iy){
       output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
     }
   }
   // divide by alpha_(S,EM)
   output*=(4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
   double ratio = output/total;
   if(abs(ratio)>1e-20) {
     generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
     for(unsigned int ix=0;ix<decay.size();++ix)
       generator()->log() << *decay[ix] << "\n";
     generator()->log() << "Test of gauge invariance " << ratio << "\n";
   }
 #endif
   // return the answer
   return output;
 }
 
 
 void VSSDecayer::identifyVertices(const int iscal, const int ianti,
 				  const Particle & inpart, const ParticleVector & decay, 
 				  AbstractVSSVertexPtr & outgoingVertexS, 
 				  AbstractVSSVertexPtr & outgoingVertexA,
 				  ShowerInteraction inter){
   if(inter==ShowerInteraction::QCD) {
     // work out which scalar each outgoing vertex corresponds to 
     // two outgoing vertices
     if( inpart.dataPtr()       ->iColour()==PDT::Colour0     &&
 	((decay[iscal]->dataPtr()->iColour()==PDT::Colour3     &&
 	  decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar) ||
 	 (decay[iscal]->dataPtr()->iColour()==PDT::Colour8     &&
 	  decay[ianti]->dataPtr()->iColour()==PDT::Colour8))){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertexS = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[iscal]->id()))){
 	outgoingVertexS = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(getParticleData(decay[iscal]->id()))){
 	outgoingVertexS = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
     else if(inpart.dataPtr()       ->iColour()==PDT::Colour8 &&
 	    decay[iscal]->dataPtr()->iColour()==PDT::Colour3 &&
 	    decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertexS = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[iscal]->id()))){
 	outgoingVertexS = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(getParticleData(decay[iscal]->id()))){
 	outgoingVertexS = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
     }
     
     // one outgoing vertex
     else if(inpart.dataPtr()->iColour()==PDT::Colour3){
       if(decay[iscal]->dataPtr()->iColour()==PDT::Colour3 &&  
 	 decay[ianti]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertexS = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertexS = outgoingVertex2_[inter];
       }
     else if (decay[iscal]->dataPtr()->iColour()==PDT::Colour3 &&
 	     decay[ianti]->dataPtr()->iColour()==PDT::Colour8){
       if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[ianti]->dataPtr()->id()))){
 	outgoingVertexS = outgoingVertex2_[inter];
 	outgoingVertexA = outgoingVertex1_[inter];
       }
       else {
 	outgoingVertexS = outgoingVertex1_[inter];
 	outgoingVertexA = outgoingVertex2_[inter];
       }
     }
     }
     else if(inpart.dataPtr()->iColour()==PDT::Colour3bar){
       if(decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar &&  
 	 decay[iscal]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertexA = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertexA = outgoingVertex2_[inter];
       }
       else if (decay[iscal]->dataPtr()->iColour()==PDT::Colour8 &&
 	       decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar){
 	if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[iscal]->dataPtr()->id()))){
 	  outgoingVertexS = outgoingVertex1_[inter];
 	  outgoingVertexA = outgoingVertex2_[inter];
 	}
 	else {
 	  outgoingVertexS = outgoingVertex2_[inter];
 	  outgoingVertexA = outgoingVertex1_[inter];
 	}
       }
     }
     
     if (! ((incomingVertex_[inter]  && (outgoingVertexS  || outgoingVertexA)) ||
 	   ( outgoingVertexS &&  outgoingVertexA)))
       throw Exception()
 	<< "Invalid vertices for QCD radiation in VSS decay in VSSDecayer::identifyVertices"
 	<< Exception::runerror;
   }
   else {
     if(decay[iscal]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[iscal]->dataPtr())))
 	outgoingVertexS = outgoingVertex1_[inter];
       else
 	outgoingVertexS = outgoingVertex2_[inter];
     }
     if(decay[ianti]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[ianti]->dataPtr())))
 	outgoingVertexA = outgoingVertex1_[inter];
       else
 	outgoingVertexA = outgoingVertex2_[inter];
     }
   }
 }
diff --git a/Decay/General/VSSDecayer.h b/Decay/General/VSSDecayer.h
--- a/Decay/General/VSSDecayer.h
+++ b/Decay/General/VSSDecayer.h
@@ -1,203 +1,211 @@
 // -*- C++ -*-
 //
 // VSSDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_VSSDecayer_H
 #define HERWIG_VSSDecayer_H
 //
 // This is the declaration of the VSSDecayer class.
 //
 
 #include "GeneralTwoBodyDecayer.h"
 #include "ThePEG/Helicity/Vertex/Scalar/VSSVertex.h"
 #include "ThePEG/Helicity/Vertex/Vector/VVVVertex.h"
 #include "ThePEG/Repository/EventGenerator.h"
 
 namespace Herwig {
 using namespace ThePEG;
 using Helicity::VSSVertexPtr;
 
 /** \ingroup Decay
  * The VSSDecayer class implements the decay of a vector
  * to 2 scalars in a general model. It holds an VSSVertex pointer
  * that must be typecast from the VertexBase pointer held in 
  * GeneralTwoBodyDecayer. It implents the virtual functions me2() and
  * partialWidth(). 
  *
  * @see GeneralTwoBodyDecayer
  */
 
 class VSSDecayer: public GeneralTwoBodyDecayer {
 
 public:
 
   /**
    * The default constructor.
    */
   VSSDecayer() {}
 
   /** @name Virtual functions required by the Decayer class. */
   //@{
   /**
    * Return the matrix element squared for a given mode and phase-space channel
    * @param ichan The channel we are calculating the matrix element for.
    * @param part The decaying Particle.
    * @param decay The particles produced in the decay.
    * @param meopt Option for the matrix element
    * @return The matrix element squared for the phase-space configuration.
    */
   virtual double me2(const int ichan, const Particle & part,
 		     const ParticleVector & decay, MEOption meopt) const;
 
   /**
    * Function to return partial Width
    * @param inpart The decaying particle.
    * @param outa One of the decay products.
    * @param outb The other decay product.
    */
   virtual Energy partialWidth(PMPair inpart, PMPair outa, 
 			      PMPair outb) const;
   /**
    *  Has a POWHEG style correction
    */
   virtual POWHEGType hasPOWHEGCorrection()  {
-    return (vertex_->orderInGem()+vertex_->orderInGs())==1 ? FSR : No;
+    POWHEGType output = FSR;
+    for(auto vertex : vertex_) {
+      if(vertex->orderInAllCouplings()!=1) {
+	output = No;
+	break;
+      }
+    }
+    return output;
   }
 
   /**
    *  Three-body matrix element including additional QCD radiation
    */
   virtual double threeBodyME(const int , const Particle & inpart,
 			     const ParticleVector & decay,
 			     ShowerInteraction inter, MEOption meopt);
 
   /**
    * Indentify outgoing vertices for the scalar and antiscalar
    */
   void identifyVertices(const int iscal, const int ianti,
 			const Particle & inpart, const ParticleVector & decay,
 			AbstractVSSVertexPtr & abstractOutgoingVertexS, 
 			AbstractVSSVertexPtr & abstractOutgoingVertexA,
 			ShowerInteraction inter);
 
   /**
    *  Set the information on the decay
    */
-  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
+  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing,
+			    vector<VertexBasePtr>,
 			    map<ShowerInteraction,VertexBasePtr> &,
 			    const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			    map<ShowerInteraction,VertexBasePtr>);
   //@}
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const;
 
   /** Make a clone of this object, possibly modifying the cloned object
    * to make it sane.
    * @return a pointer to the new object.
    */
   virtual IBPtr fullclone() const;
   //@}
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   VSSDecayer & operator=(const VSSDecayer &);
 
 private:
 
   /**
    *  Abstract pointer to AbstractVSSVertex
    */
-  AbstractVSSVertexPtr vertex_;
+  vector<AbstractVSSVertexPtr> vertex_;
 
   /**
    * Pointer to the perturbative vertex
    */
-  VSSVertexPtr perturbativeVertex_;
+  vector<VSSVertexPtr> perturbativeVertex_;
 
   /**
    *  Abstract pointer to AbstractVVVVertex for QCD radiation from incoming vector
    */
   map<ShowerInteraction,AbstractVVVVertexPtr> incomingVertex_;
 
   /**
    *  Abstract pointer to AbstractFFVVertex for QCD radiation from outgoing scalar
    */
   map<ShowerInteraction,AbstractVSSVertexPtr> outgoingVertex1_;
 
   /**
    *  Abstract pointer to AbstractFFVVertex for QCD radiation from outgoing scalar
    */
   map<ShowerInteraction,AbstractVSSVertexPtr> outgoingVertex2_;
 
   /**
    *  Spin density matrix
    */
   mutable RhoDMatrix rho_;
 
   /**
    *  Polarization vectors for the decaying particle
    */
   mutable vector<Helicity::VectorWaveFunction> vectors_;
 
  /**
    *  Spin density matrix for 3 body decay
    */
   mutable RhoDMatrix rho3_;
 
   /**
    *  Vector wavefunction for 3 body decay
    */
   mutable vector<Helicity::VectorWaveFunction> vector3_;
 
     /**
    *  Vector wavefunction for 3 body decay
    */
   mutable vector<Helicity::VectorWaveFunction> gluon_;
 
 };
 
 }
 
 #endif /* HERWIG_VSSDecayer_H */
diff --git a/Decay/General/VVSDecayer.cc b/Decay/General/VVSDecayer.cc
--- a/Decay/General/VVSDecayer.cc
+++ b/Decay/General/VVSDecayer.cc
@@ -1,302 +1,313 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the VVSDecayer class.
 //
 
 #include "VVSDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 IBPtr VVSDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr VVSDecayer::fullclone() const {
   return new_ptr(*this);
 }
 void VVSDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
-			      VertexBasePtr vertex,
+			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr>) {
   decayInfo(incoming,outgoing);
-  vertex_             = dynamic_ptr_cast<AbstractVVSVertexPtr>(vertex);
-  perturbativeVertex_ = dynamic_ptr_cast<VVSVertexPtr>        (vertex);
+  for(auto vert : vertex) {
+    vertex_            .push_back(dynamic_ptr_cast<AbstractVVSVertexPtr>(vert));
+    perturbativeVertex_.push_back(dynamic_ptr_cast<VVSVertexPtr>        (vert));
+  }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter]  = dynamic_ptr_cast<AbstractVVVVertexPtr>(inV.at(inter));
     outgoingVertexS_[inter] = AbstractVSSVertexPtr();
     outgoingVertexV_[inter] = AbstractVVVVertexPtr();  
     if(outV[0].at(inter)) {
       if (outV[0].at(inter)->getName()==VertexType::VSS)
 	outgoingVertexS_[inter]   = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[0].at(inter));
       else
 	outgoingVertexV_[inter]   = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[0].at(inter));
     }
     if(outV[1].at(inter)) {
       if (outV[1].at(inter)->getName()==VertexType::VSS)
 	outgoingVertexS_[inter]   = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[1].at(inter));
       else 
 	outgoingVertexV_[inter]   = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[1].at(inter));
     }
   }
 }
 
 void VVSDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_ << perturbativeVertex_
      << incomingVertex_ << outgoingVertexS_ << outgoingVertexV_;
 }
 
 void VVSDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_ >> perturbativeVertex_
      >> incomingVertex_ >> outgoingVertexS_ >> outgoingVertexV_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<VVSDecayer,GeneralTwoBodyDecayer>
 describeHerwigVVSDecayer("Herwig::VVSDecayer", "Herwig.so");
 
 void VVSDecayer::Init() {
 
   static ClassDocumentation<VVSDecayer> documentation
     ("The VVSDecayer class implements the decay of a vector"
      " to a vector and a scalar");
 
 }
 
 double VVSDecayer::me2(const int , const Particle & inpart,
  		       const ParticleVector & decay,
 		       MEOption meopt) const {
   bool massless = ( decay[0]->id()==ParticleID::gamma || 
 		    decay[0]->id()==ParticleID::g );
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1,PDT::Spin1,PDT::Spin0)));
   if(meopt==Initialize) {
     VectorWaveFunction::calculateWaveFunctions(vectors_[0],rho_,
 					       const_ptr_cast<tPPtr>(&inpart),
 					       incoming,false);
   }
   if(meopt==Terminate) {
     VectorWaveFunction::constructSpinInfo(vectors_[0],const_ptr_cast<tPPtr>(&inpart),
 					  incoming,true,false);
     VectorWaveFunction::
       constructSpinInfo(vectors_[1],decay[0],outgoing,true,massless);
     ScalarWaveFunction::
       constructSpinInfo(decay[1],outgoing,true);
     return 0.;
   }
   VectorWaveFunction::
     calculateWaveFunctions(vectors_[1],decay[0],outgoing,massless);
   ScalarWaveFunction sca(decay[1]->momentum(),decay[1]->dataPtr(),outgoing);
   Energy2 scale(sqr(inpart.mass()));
   for(unsigned int in=0;in<3;++in) {
     for(unsigned int out=0;out<3;++out) {
       if(massless&&out==1) ++out;
-      (*ME())(in,out,0) = 
-	vertex_->evaluate(scale,vectors_[0][in],vectors_[1][out],sca);
+      (*ME())(in,out,0) = 0.;
+      for(auto vert : vertex_)
+	(*ME())(in,out,0) += 
+	  vert->evaluate(scale,vectors_[0][in],vectors_[1][out],sca);
     }
   }
   double output=(ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy VVSDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
-  if(perturbativeVertex_) {
+  if(perturbativeVertex_.size()==1 &&
+     perturbativeVertex_[0]) {
     Energy2 scale(sqr(inpart.second));
     double mu1sq = sqr(outa.second/inpart.second);
     double mu2sq = sqr(outb.second/inpart.second);
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
     if( outb.first->iSpin() == PDT::Spin0 )
-      perturbativeVertex_->setCoupling(sqr(inpart.second), in, 
+      perturbativeVertex_[0]->setCoupling(sqr(inpart.second), in, 
 				       outa.first, outb.first);
     else {
-      perturbativeVertex_->setCoupling(sqr(inpart.second), in, 
+      perturbativeVertex_[0]->setCoupling(sqr(inpart.second), in, 
 				       outb.first, outa.first);
       swap(mu1sq, mu2sq);
     }
-    double vn = norm(perturbativeVertex_->norm());
+    double vn = norm(perturbativeVertex_[0]->norm());
     if(vn == ZERO || mu1sq == ZERO) return ZERO;
     double me2 = 2. + 0.25*sqr(1. + mu1sq - mu2sq)/mu1sq;
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second,outa.second,
 					outb.second);
     Energy output = vn*me2*pcm/(24.*Constants::pi)/scale*UnitRemoval::E2;
     // colour factor
     output *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return output;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 double VVSDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   unsigned int ivec(0),isca(1);
   if(decay[ivec]->dataPtr()->iSpin()!=PDT::Spin1) swap(ivec,isca);
   if(meopt==Initialize) {
     // create vector wavefunction for decaying particle
     VectorWaveFunction::calculateWaveFunctions(vectors3_[0], rho3_,
 					       const_ptr_cast<tPPtr>(&inpart), 
 					       incoming, false);
   }
   if(meopt==Terminate) {
     VectorWaveFunction::
       constructSpinInfo(vectors3_[0] ,const_ptr_cast<tPPtr>(&inpart),outgoing,true,false);
     VectorWaveFunction::
       constructSpinInfo(vectors3_[1],decay[ivec],outgoing,true,false); 
     ScalarWaveFunction::
       constructSpinInfo(decay[isca],outgoing,true);
     VectorWaveFunction::
       constructSpinInfo(gluon_      ,decay[2],outgoing,true,false);
     return 0.;
   }
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin1, PDT::Spin1,
 								       PDT::Spin0, PDT::Spin1)));
   bool massless= decay[ivec]->mass()!=ZERO;
   // create wavefunctions
   VectorWaveFunction::calculateWaveFunctions(vectors3_[1],decay[0],outgoing,massless);
   ScalarWaveFunction scal(decay[isca]->momentum(),  decay[isca]->dataPtr(),outgoing);
   VectorWaveFunction::calculateWaveFunctions(gluon_      ,decay[2],outgoing,true);
 
   // gauge test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[2]->momentum(),
   					  decay[2]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
 
   Energy2 scale(sqr(inpart.mass()));
   
   const GeneralTwoBodyDecayer::CFlow & colourFlow
     = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
 
    for(unsigned int iv0 = 0; iv0 < 3; ++iv0) {
      for(unsigned int iv1 = 0; iv1 < 3; ++iv1) {
        if(massless && iv1==1) continue;
        for(unsigned int ig = 0; ig < 2; ++ig) {
 	 // radiation from the incoming vector
 	 if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	    (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	   assert(incomingVertex_[inter]);
 	   VectorWaveFunction vectorInter = 
 	     incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),vectors3_[0][iv0],
 					      gluon_[2*ig],inpart.mass());
 	   
 	   assert(vectors3_[0][iv0].particle()->id()==vectorInter.particle()->id());
-	   Complex diag = vertex_->evaluate(scale,vectorInter,vectors3_[1][iv1],scal);
+	   Complex diag = 0.;
+	   for(auto vertex : vertex_)
+	     diag += vertex->evaluate(scale,vectorInter,vectors3_[1][iv1],scal);
 	   if(!couplingSet) {
 	     gs = abs(incomingVertex_[inter]->norm());
 	     couplingSet = true;
 	   }
 	   for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	     (*ME[colourFlow[0][ix].first])(iv0, iv1, 0, ig) += 
 	       colourFlow[0][ix].second*diag;
 	   }
 #ifdef GAUGE_CHECK
 	   total+=norm(diag);
 #endif
 	 }
 	 // radiation from the outgoing vector
 	 if((decay[ivec]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	    (decay[ivec]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	   assert(outgoingVertexV_[inter]);
 	   // ensure you get correct outgoing particle from first vertex
 	   tcPDPtr off = decay[ivec]->dataPtr();
 	   if(off->CC()) off = off->CC();
 	   VectorWaveFunction vectorInter = 
 	     outgoingVertexV_[inter]->evaluate(scale,3,off,gluon_[2*ig],vectors3_[1][iv1],decay[ivec]->mass());
 	   
 	   assert(vectors3_[1][iv1].particle()->id()==vectorInter.particle()->id());
 	   
-	   Complex diag =vertex_->evaluate(scale,vectors3_[0][iv0],vectorInter,scal);
+	   Complex diag = 0.;
+	   for(auto vertex : vertex_)
+	     diag += vertex->evaluate(scale,vectors3_[0][iv0],vectorInter,scal);
 	   if(!couplingSet) {
 	     gs = abs(outgoingVertexV_[inter]->norm());
 	     couplingSet = true;
 	   }
 	   for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
 	     (*ME[colourFlow[1][ix].first])(iv0, iv1, 0, ig) += 
 	       colourFlow[1][ix].second*diag;
 	   }
 #ifdef GAUGE_CHECK
 	   total+=norm(diag);
 #endif
 	 }
 	 // radiation from the outgoing scalar
 	 if((decay[isca]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	    (decay[isca]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	   assert(outgoingVertexS_[inter]);
 	   // ensure you get correct outgoing particle from first vertex
 	   tcPDPtr off = decay[isca]->dataPtr();
 	   if(off->CC()) off = off->CC();
 	   ScalarWaveFunction scalarInter = 
 	     outgoingVertexS_[inter]->evaluate(scale,3,off,gluon_[2*ig],scal,decay[isca]->mass());
 	
 	   assert(scal.particle()->id()==scalarInter.particle()->id());
 	 
-	   Complex diag = vertex_->evaluate(scale,vectors3_[0][iv0],vectors3_[1][iv1],scalarInter);
+	   Complex diag = 0.;
+	   for(auto vertex : vertex_)
+	     diag += vertex->evaluate(scale,vectors3_[0][iv0],vectors3_[1][iv1],scalarInter);
 	   if(!couplingSet) {
 	     gs = abs(outgoingVertexS_[inter]->norm());
 	     couplingSet = true;
 	   }
 	   for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	     (*ME[colourFlow[2][ix].first])(iv0, iv1, 0, ig) += 
 	       colourFlow[2][ix].second*diag;
 	   }
 #ifdef GAUGE_CHECK
 	   total+=norm(diag);
 #endif
 	 }
        }
      }
    }
    
    // contract matrices 
    double output=0.;
    for(unsigned int ix=0; ix<nflow; ++ix){
      for(unsigned int iy=0; iy<nflow; ++iy){
        output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
      }
    }
    // divide by alpha_(S,EM)
    output*=(4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
    double ratio = output/total;
    if(abs(ratio)>1e-20) {
      generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
      for(unsigned int ix=0;ix<decay.size();++ix)
        generator()->log() << *decay[ix] << "\n";
      generator()->log() << "Test of gauge invariance " << ratio << "\n";
    }
 #endif
    // return the answer
    return output;
 }
diff --git a/Decay/General/VVSDecayer.h b/Decay/General/VVSDecayer.h
--- a/Decay/General/VVSDecayer.h
+++ b/Decay/General/VVSDecayer.h
@@ -1,193 +1,201 @@
 // -*- C++ -*-
 #ifndef THEPEG_VVSDecayer_H
 #define THEPEG_VVSDecayer_H
 //
 // This is the declaration of the VVSDecayer class.
 //
 
 #include "GeneralTwoBodyDecayer.h"
 #include "ThePEG/Helicity/Vertex/Scalar/VVSVertex.h"
 #include "ThePEG/Repository/EventGenerator.h"
 
 namespace Herwig {
 using namespace ThePEG;
 using Helicity::VVSVertexPtr;
 
 /** \ingroup Decay
  * The VVSDecayer class implements the decay of a vector to a
  * vector and a scalar in a general model. It holds an VVSVertex pointer
  * that must be typecast from the  VertexBase pointer helid in the
  * GeneralTwoBodyDecayer. It implents the virtual functions me2() and
  * partialWidth(). 
  *
  * @see \ref VVSDecayerInterfaces "The interfaces"
  * defined for VVSDecayer.
  */
 class VVSDecayer: public GeneralTwoBodyDecayer {
 
 public:
 
   /**
    * The default constructor.
    */
   VVSDecayer() {}
 
   /** @name Virtual functions required by the Decayer class. */
   //@{
   /**
    * Return the matrix element squared for a given mode and phase-space channel
    * @param ichan The channel we are calculating the matrix element for.
    * @param part The decaying Particle.
    * @param decay The particles produced in the decay.
    * @param meopt Option for the calculation of the matrix element
    * @return The matrix element squared for the phase-space configuration.
    */
   virtual double me2(const int ichan, const Particle & part,
 		     const ParticleVector & decay, MEOption meopt) const;
 
   /**
    * Function to return partial Width
    * @param inpart The decaying particle.
    * @param outa One of the decay products.
    * @param outb The other decay product.
    */
   virtual Energy partialWidth(PMPair inpart, PMPair outa, 
 			      PMPair outb) const;
 
   /**
    *  Set the information on the decay
    */
-  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
+  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing,
+			    vector<VertexBasePtr>,
 			    map<ShowerInteraction,VertexBasePtr> &,
 			    const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			    map<ShowerInteraction,VertexBasePtr>);
   
   /**
    *  Has a POWHEG style correction
    */
   virtual POWHEGType hasPOWHEGCorrection()  {
-    return (vertex_->orderInGem()+vertex_->orderInGs())==1 ? FSR : No;
+    POWHEGType output = FSR;
+    for(auto vertex : vertex_) {
+      if(vertex->orderInAllCouplings()!=1) {
+	output = No;
+	break;
+      }
+    }
+    return output;
   }
 
   /**
    *  Three-body matrix element including additional QCD radiation
    */
   virtual double threeBodyME(const int , const Particle & inpart,
 			     const ParticleVector & decay,
 			     ShowerInteraction inter, MEOption meopt);
   //@}
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const;
 
   /** Make a clone of this object, possibly modifying the cloned object
    * to make it sane.
    * @return a pointer to the new object.
    */
   virtual IBPtr fullclone() const;
   //@}
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   VVSDecayer & operator=(const VVSDecayer &);
 
 private:
 
   /**
    *  Abstract pointer to AbstractVVSVertex
    */
-  AbstractVVSVertexPtr vertex_;
+  vector<AbstractVVSVertexPtr> vertex_;
 
   /**
    * Pointer to the perturbative vertex
    */
-  VVSVertexPtr perturbativeVertex_;
+  vector<VVSVertexPtr> perturbativeVertex_;
 
   /**
    *  Abstract pointer to AbstractVVVVertex for QCD radiation from incoming vector
    */
   map<ShowerInteraction,AbstractVVVVertexPtr> incomingVertex_;
 
   /**
    *  Abstract pointer to AbstractVVVVertex for QCD radiation from the first outgoing vector
    */
   map<ShowerInteraction,AbstractVVVVertexPtr> outgoingVertexV_;
 
   /**
    *  Abstract pointer to AbstractVVVVertex for QCD radiation from the second outgoing vector
    */
   map<ShowerInteraction,AbstractVSSVertexPtr> outgoingVertexS_;
 
   /**
    *  Spin density matrix
    */
   mutable RhoDMatrix rho_;
 
   /**
    *  Vector wavefunctions
    */
   mutable vector<Helicity::VectorWaveFunction> vectors_[2];
   
 private:
 
   /**
    *  Members for the POWHEG correction
    */
   //@{
   /**
    *  Spin density matrix for 3 body decay
    */
   mutable RhoDMatrix rho3_;
 
   /**
    *  Vector wavefunctions
    */
   mutable vector<Helicity::VectorWaveFunction> vectors3_[2];
 
     /**
    *  Vector wavefunction for 3 body decay
    */
   mutable vector<Helicity::VectorWaveFunction> gluon_;
   //@}
 };
 
 }
 
 #endif /* THEPEG_VVSDecayer_H */
diff --git a/Decay/General/VVVDecayer.cc b/Decay/General/VVVDecayer.cc
--- a/Decay/General/VVVDecayer.cc
+++ b/Decay/General/VVVDecayer.cc
@@ -1,429 +1,441 @@
 // -*- C++ -*-
 //
 // VVVDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the VVVDecayer class.
 //
 
 #include "VVVDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "Herwig/Utilities/Kinematics.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 IBPtr VVVDecayer::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr VVVDecayer::fullclone() const {
   return new_ptr(*this);
 }
 
 void VVVDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
-			      VertexBasePtr vertex,
+			      vector<VertexBasePtr> vertex,
 			      map<ShowerInteraction,VertexBasePtr> & inV,
 			      const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
 			      map<ShowerInteraction,VertexBasePtr> fourV) {
   decayInfo(incoming,outgoing);
-  vertex_             = dynamic_ptr_cast<AbstractVVVVertexPtr>(vertex);
-  perturbativeVertex_ = dynamic_ptr_cast<VVVVertexPtr>        (vertex);
+  for(auto vert : vertex) {
+    vertex_             .push_back(dynamic_ptr_cast<AbstractVVVVertexPtr>(vert));
+    perturbativeVertex_ .push_back(dynamic_ptr_cast<VVVVertexPtr>        (vert));
+  }
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     incomingVertex_[inter]  = dynamic_ptr_cast<AbstractVVVVertexPtr>(inV.at(inter));
     outgoingVertex1_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[0].at(inter));
     outgoingVertex2_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[1].at(inter));
     fourPointVertex_[inter] = dynamic_ptr_cast<AbstractVVVVVertexPtr>(fourV.at(inter));
   }
 }
 
 void VVVDecayer::persistentOutput(PersistentOStream & os) const {
   os << vertex_ << perturbativeVertex_
      << incomingVertex_  << outgoingVertex1_
      << outgoingVertex2_ << fourPointVertex_;
 }
 
 void VVVDecayer::persistentInput(PersistentIStream & is, int) {
   is >> vertex_ >> perturbativeVertex_
      >> incomingVertex_   >> outgoingVertex1_
      >> outgoingVertex2_ >> fourPointVertex_;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<VVVDecayer,GeneralTwoBodyDecayer>
 describeHerwigVVVDecayer("Herwig::VVVDecayer", "Herwig.so");
 
 void VVVDecayer::Init() {
 
   static ClassDocumentation<VVVDecayer> documentation
     ("The VVVDecayer class implements the decay of a vector boson "
      "into 2 vector bosons");
 
 }
 
 double VVVDecayer::me2(const int , const Particle & inpart,
                        const ParticleVector & decay,
 		       MEOption meopt) const {
   if(!ME())
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1,PDT::Spin1,PDT::Spin1)));
   bool massless[2];
   for(unsigned int ix=0;ix<2;++ix) 
     massless[ix] = (decay[ix]->id()==ParticleID::gamma ||
 		    decay[ix]->id()==ParticleID::g);
   if(meopt==Initialize) {
     VectorWaveFunction::calculateWaveFunctions(vectors_[0],rho_,
 					       const_ptr_cast<tPPtr>(&inpart),
 					       incoming,false);
   }
   if(meopt==Terminate) {
     VectorWaveFunction::constructSpinInfo(vectors_[0],const_ptr_cast<tPPtr>(&inpart),
 					  incoming,true,false);
     for(unsigned int ix=0;ix<2;++ix)
       VectorWaveFunction::
 	constructSpinInfo(vectors_[ix+1],decay[ix],outgoing,true,massless[ix]);
     return 0.;
   }
   for(unsigned int ix=0;ix<2;++ix)
     VectorWaveFunction::
       calculateWaveFunctions(vectors_[ix+1],decay[ix],outgoing,massless[ix]);
   Energy2 scale(sqr(inpart.mass()));
   for(unsigned int iv3=0;iv3<3;++iv3) {
     for(unsigned int iv2=0;iv2<3;++iv2) {
       for(unsigned int iv1=0;iv1<3;++iv1) {
-	(*ME())(iv1,iv2,iv3) = vertex_->
-	  evaluate(scale,vectors_[1][iv2],vectors_[2][iv3],vectors_[0][iv1]);
+	(*ME())(iv1,iv2,iv3) = 0.;
+	for(auto vert : vertex_) {
+	  (*ME())(iv1,iv2,iv3) += vert->
+	    evaluate(scale,vectors_[1][iv2],vectors_[2][iv3],vectors_[0][iv1]);
+	}
       }
     }
   }
   double output = (ME()->contract(rho_)).real()/scale*UnitRemoval::E2;
   // colour and identical particle factors
   output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
 			 decay[1]->dataPtr());
   // return the answer
   return output;
 }
 
 Energy VVVDecayer::partialWidth(PMPair inpart, PMPair outa, 
 				PMPair outb) const {
   if( inpart.second < outa.second + outb.second  ) return ZERO;
-  if(perturbativeVertex_) {
+  if(perturbativeVertex_.size()==1 &&
+     perturbativeVertex_[0]) {
     tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
-    perturbativeVertex_->setCoupling(sqr(inpart.second), in,
-				     outa.first, outb.first);
+    perturbativeVertex_[0]->setCoupling(sqr(inpart.second), in,
+					outa.first, outb.first);
     double mu1(outa.second/inpart.second), mu1sq(sqr(mu1)),
       mu2(outb.second/inpart.second), mu2sq(sqr(mu2));
-    double vn = norm(perturbativeVertex_->norm());
+    double vn = norm(perturbativeVertex_[0]->norm());
     if(vn == ZERO || mu1sq == ZERO || mu2sq == ZERO) return ZERO;
     double me2 = 
       (mu1 - mu2 - 1.)*(mu1 - mu2 + 1.)*(mu1 + mu2 - 1.)*(mu1 + mu2 + 1.)
       * (sqr(mu1sq) + sqr(mu2sq) + 10.*(mu1sq*mu2sq + mu1sq + mu2sq) + 1.)
       /4./mu1sq/mu2sq;
     Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second,outa.second,
 					outb.second);
     Energy pWidth = vn*me2*pcm/24./Constants::pi;
     // colour factor
     pWidth *= colourFactor(inpart.first,outa.first,outb.first);
     // return the answer
     return pWidth;
   }
   else {
     return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
   }
 }
 
 double VVVDecayer::threeBodyME(const int , const Particle & inpart,
 			       const ParticleVector & decay,
 			       ShowerInteraction inter, MEOption meopt) {
   if(meopt==Initialize) {
     // create vector wavefunction for decaying particle
     VectorWaveFunction::calculateWaveFunctions(vector3_, rho3_, const_ptr_cast<tPPtr>(&inpart), 
 					       incoming, false);
   }
   if(meopt==Terminate) {
     VectorWaveFunction::
       constructSpinInfo(vector3_ ,const_ptr_cast<tPPtr>(&inpart),outgoing,true,false);
     VectorWaveFunction::
       constructSpinInfo(vectors3_[0],decay[0],outgoing,true,false);
     VectorWaveFunction::
       constructSpinInfo(vectors3_[1],decay[1],outgoing,true,false);
     VectorWaveFunction::
       constructSpinInfo(gluon_      ,decay[2],outgoing,true,false);
     return 0.;
   }
   // calculate colour factors and number of colour flows
   unsigned int nflow;
   vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
   vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin1, PDT::Spin1,
 								       PDT::Spin1, PDT::Spin1)));
   bool massless[2];
   for(unsigned int ix=0;ix<2;++ix)
     massless[ix] = decay[ix]->mass()!=ZERO;
   // create wavefunctions
   VectorWaveFunction::calculateWaveFunctions(vectors3_[0],decay[0],outgoing,massless[0]);
   VectorWaveFunction::calculateWaveFunctions(vectors3_[1],decay[1],outgoing,massless[1]);
   VectorWaveFunction::calculateWaveFunctions(gluon_      ,decay[2],outgoing,true);
 
   // gauge test
 #ifdef GAUGE_CHECK
   gluon_.clear();
   for(unsigned int ix=0;ix<3;++ix) {
     if(ix==1) gluon_.push_back(VectorWaveFunction());
     else {
       gluon_.push_back(VectorWaveFunction(decay[2]->momentum(),
   					  decay[2]->dataPtr(),10,
   					  outgoing));
     }
   }
 #endif
 
   // get the outgoing vertices
   AbstractVVVVertexPtr outgoingVertex1;
   AbstractVVVVertexPtr outgoingVertex2;
   identifyVertices(inpart,decay, outgoingVertex1, outgoingVertex2,inter);
 
   Energy2 scale(sqr(inpart.mass()));
 
   const GeneralTwoBodyDecayer::CFlow & colourFlow
         = colourFlows(inpart, decay);
   double gs(0.);
   bool couplingSet(false);
 #ifdef GAUGE_CHECK
   double total=0.;
 #endif
 
    for(unsigned int iv0 = 0; iv0 < 3; ++iv0) {
      for(unsigned int iv1 = 0; iv1 < 3; ++iv1) {
        if(massless[0] && iv1==1) continue;
        for(unsigned int iv2 = 0; iv2 < 3; ++iv2) {
 	 if(massless[1] && iv2==1) continue;
 	 for(unsigned int ig = 0; ig < 2; ++ig) {
 	   // radiation from the incoming vector
 	   if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	      (inpart.dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	     assert(incomingVertex_[inter]);
 	     VectorWaveFunction vectorInter = 
 	       incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),vector3_[iv0],
 						gluon_[2*ig],inpart.mass());
 	     
 	     assert(vector3_[iv0].particle()->id()==vectorInter.particle()->id());
 	     
-	     Complex diag = vertex_->evaluate(scale,vectorInter,vectors3_[0][iv1],
-					      vectors3_[1][iv2]);
+	     Complex diag = 0.;
+	     for(auto vertex : vertex_)
+	       diag += vertex->evaluate(scale,vectorInter,vectors3_[0][iv1],
+					vectors3_[1][iv2]);
 	     if(!couplingSet) {
 	       gs = abs(incomingVertex_[inter]->norm());
 	       couplingSet = true;
 	     }
 	     for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
 	       (*ME[colourFlow[0][ix].first])(iv0, iv1, iv2, ig) += 
 		 colourFlow[0][ix].second*diag;
 	     }
 #ifdef GAUGE_CHECK
 	     total+=norm(diag);
 #endif
 	   }
 	   // radiation from the 1st outgoing vector
 	   if((decay[0]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	      (decay[0]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	     assert(outgoingVertex1);
 	     // ensure you get correct outgoing particle from first vertex
 	     tcPDPtr off = decay[0]->dataPtr();
 	     if(off->CC()) off = off->CC();
 	     VectorWaveFunction vectorInter = 
 	       outgoingVertex1->evaluate(scale,3,off,gluon_[2*ig],vectors3_[0][iv1],decay[0]->mass());
 	     
 	     assert(vectors3_[0][iv1].particle()->id()==vectorInter.particle()->id());
 	     
-	     Complex diag =vertex_->evaluate(scale,vector3_[iv0],vectorInter,vectors3_[1][iv2]);
+	     Complex diag = 0.;
+	     for(auto vertex : vertex_)
+	       diag += vertex->evaluate(scale,vector3_[iv0],vectorInter,vectors3_[1][iv2]);
 	     if(!couplingSet) {
 	       gs = abs(outgoingVertex1->norm());
 	       couplingSet = true;
 	     }
 	     for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
 	       (*ME[colourFlow[1][ix].first])(iv0, iv1, iv2, ig) += 
 		 colourFlow[1][ix].second*diag;
 	     }
 #ifdef GAUGE_CHECK
 	     total+=norm(diag);
 #endif
 	   }
 	   // radiation from the second outgoing vector
 	   if((decay[1]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
 	      (decay[1]->dataPtr()->charged()  && inter==ShowerInteraction::QED) ) {
 	     assert(outgoingVertex2);
 	     // ensure you get correct outgoing particle from first vertex
 	     tcPDPtr off = decay[1]->dataPtr();
 	     if(off->CC()) off = off->CC();
 	     VectorWaveFunction vectorInter = 
 	       outgoingVertex2->evaluate(scale,3,off, gluon_[2*ig],vectors3_[1][iv2],decay[1]->mass());
 	     
 	     assert(vectors3_[1][iv2].particle()->id()==vectorInter.particle()->id());
 	     
-	     Complex diag = vertex_->evaluate(scale,vector3_[iv0],vectors3_[0][iv1],vectorInter);
+	     Complex diag = 0.;
+	     for(auto vertex : vertex_)
+	       diag += vertex->evaluate(scale,vector3_[iv0],vectors3_[0][iv1],vectorInter);
 	     if(!couplingSet) {
 	       gs = abs(outgoingVertex2->norm());
 	       couplingSet = true;
 	     }
 	     for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	       (*ME[colourFlow[2][ix].first])(iv0, iv1, iv2, ig) += 
 		 colourFlow[2][ix].second*diag;
 	     }
 #ifdef GAUGE_CHECK
 	     total+=norm(diag);
 #endif
 	   }
 	   // 4-point vertex
 	   if (fourPointVertex_[inter]) {
 	     Complex diag = fourPointVertex_[inter]->evaluate(scale,0, vector3_[iv0],
 							      vectors3_[0][iv1],
 							      vectors3_[1][iv2],gluon_[2*ig]);
 	     for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
 	       (*ME[colourFlow[3][ix].first])(iv0, iv1, iv2, ig) += 
 		 colourFlow[3][ix].second*diag;
 	     }
 #ifdef GAUGE_CHECK
 	     total+=norm(diag);
 #endif
 	   }
 	 }
        }
      }
    }
    
    // contract matrices 
    double output=0.;
    for(unsigned int ix=0; ix<nflow; ++ix){
      for(unsigned int iy=0; iy<nflow; ++iy){
        output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],rho3_)).real();
      }
    }
    // divide by alpha_(S,EM)
    output*=(4.*Constants::pi)/sqr(gs);
 #ifdef GAUGE_CHECK
    double ratio = output/total;
    if(abs(ratio)>1e-20) {
      generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
      for(unsigned int ix=0;ix<decay.size();++ix)
        generator()->log() << *decay[ix] << "\n";
      generator()->log() << "Test of gauge invariance " << ratio << "\n";
    }
 #endif
    // return the answer
    return output;
 }
 
 void VVVDecayer::identifyVertices(const Particle & inpart, const ParticleVector & decay, 
 				  AbstractVVVVertexPtr & outgoingVertex1, 
 				  AbstractVVVVertexPtr & outgoingVertex2,
 				  ShowerInteraction inter) {
   if(inter==ShowerInteraction::QCD) {
     // work out which scalar each outgoing vertex corresponds to 
     // two outgoing vertices
     if( inpart.dataPtr()       ->iColour()==PDT::Colour0     &&
 	((decay[0]->dataPtr()->iColour()==PDT::Colour3     &&
 	  decay[1]->dataPtr()->iColour()==PDT::Colour3bar) ||
 	 (decay[0]->dataPtr()->iColour()==PDT::Colour8     &&
 	  decay[1]->dataPtr()->iColour()==PDT::Colour8))){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertex1 = outgoingVertex1_[inter];
 	outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[0]->id()))){
 	outgoingVertex1 = outgoingVertex1_[inter];
 	outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(getParticleData(decay[0]->id()))){
 	outgoingVertex1 = outgoingVertex2_[inter];
 	outgoingVertex2 = outgoingVertex1_[inter];
       }
     }
     else if(inpart.dataPtr()       ->iColour()==PDT::Colour8 &&
 	    decay[0]->dataPtr()->iColour()==PDT::Colour3 &&
 	    decay[1]->dataPtr()->iColour()==PDT::Colour3bar){
       if(outgoingVertex1_[inter]==outgoingVertex2_[inter]){
 	outgoingVertex1 = outgoingVertex1_[inter];
 	outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[0]->id()))){
 	outgoingVertex1 = outgoingVertex1_[inter];
 	outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (outgoingVertex2_[inter]->isIncoming(getParticleData(decay[0]->id()))){
 	outgoingVertex1 = outgoingVertex2_[inter];
 	outgoingVertex2 = outgoingVertex1_[inter];
       }
     }
     
     // one outgoing vertex
     else if(inpart.dataPtr()->iColour()==PDT::Colour3){
       if(decay[0]->dataPtr()->iColour()==PDT::Colour3 &&  
 	 decay[1]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertex1 = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertex1 = outgoingVertex2_[inter];
       }
       else if (decay[0]->dataPtr()->iColour()==PDT::Colour3 &&
 	       decay[1]->dataPtr()->iColour()==PDT::Colour8){
 	if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[1]->dataPtr()->id()))){
 	  outgoingVertex1 = outgoingVertex2_[inter];
 	  outgoingVertex2 = outgoingVertex1_[inter];
 	}
 	else {
 	  outgoingVertex1 = outgoingVertex1_[inter];
 	  outgoingVertex2 = outgoingVertex2_[inter];
 	}
       }
     }
     else if(inpart.dataPtr()->iColour()==PDT::Colour3bar){
       if(decay[1]->dataPtr()->iColour()==PDT::Colour3bar &&  
 	 decay[0]->dataPtr()->iColour()==PDT::Colour0){
 	if     (outgoingVertex1_[inter]) outgoingVertex2 = outgoingVertex1_[inter];
 	else if(outgoingVertex2_[inter]) outgoingVertex2 = outgoingVertex2_[inter];
       }
       else if (decay[0]->dataPtr()->iColour()==PDT::Colour8 &&
 	       decay[1]->dataPtr()->iColour()==PDT::Colour3bar){
 	if (outgoingVertex1_[inter]->isIncoming(getParticleData(decay[0]->dataPtr()->id()))){
 	  outgoingVertex1 = outgoingVertex1_[inter];
 	  outgoingVertex2 = outgoingVertex2_[inter];
 	}
 	else {
 	  outgoingVertex1 = outgoingVertex2_[inter];
 	  outgoingVertex2 = outgoingVertex1_[inter];
 	}
       }
     }
     
     if (! ((incomingVertex_[inter]  && (outgoingVertex1  || outgoingVertex2)) ||
 	   ( outgoingVertex1 &&  outgoingVertex2)))
       throw Exception()
 	<< "Invalid vertices for QCD radiation in VVV decay in VVVDecayer::identifyVertices"
 	<< Exception::runerror;
   }
   else {
     if(decay[0]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[0]->dataPtr())))
 	outgoingVertex1 = outgoingVertex1_[inter];
       else
 	outgoingVertex1 = outgoingVertex2_[inter];
     }
     if(decay[1]->dataPtr()->charged()) {
       if (outgoingVertex1_[inter] &&
 	  outgoingVertex1_[inter]->isIncoming(const_ptr_cast<tPDPtr>(decay[1]->dataPtr())))
 	outgoingVertex2 = outgoingVertex1_[inter];
       else
 	outgoingVertex2 = outgoingVertex2_[inter];
     }
   }
 }
diff --git a/Decay/General/VVVDecayer.h b/Decay/General/VVVDecayer.h
--- a/Decay/General/VVVDecayer.h
+++ b/Decay/General/VVVDecayer.h
@@ -1,220 +1,228 @@
 // -*- C++ -*-
 //
 // VVVDecayer.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_VVVDecayer_H
 #define HERWIG_VVVDecayer_H
 //
 // This is the declaration of the VVVDecayer class.
 //
 
 #include "GeneralTwoBodyDecayer.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Helicity/Vertex/Vector/VVVVertex.h"
 #include "ThePEG/Helicity/Vertex/AbstractVVVVVertex.h"
 
 namespace Herwig {
 using namespace ThePEG;
 using Helicity::VVVVertexPtr;
 
   /** \ingroup Decay
    * The VVVDecayer class implements the decay of a vector
    * to 2 vectors in a general model. It holds an VVVVertex pointer
    * that must be typecast from the VertexBase pointer held in
    * GeneralTwoBodyDecayer. It implents the virtual functions me2() and
    * partialWidth().
    *
    * @see GeneralTwoBodyDecayer
    */
 class VVVDecayer: public GeneralTwoBodyDecayer {
 
 public:
 
   /**
    * The default constructor.
    */
   VVVDecayer() {}
 
   /** @name Virtual functions required by the Decayer class. */
   //@{
   /**
    * Return the matrix element squared for a given mode and phase-space channel.
    * @param ichan The channel we are calculating the matrix element for.
    * @param part The decaying Particle.
    * @param decay The particles produced in the decay.
    * @param meopt Option for the calculation of the matrix element
    * @return The matrix element squared for the phase-space configuration.
    */
   virtual double me2(const int ichan, const Particle & part,
                       const ParticleVector & decay, MEOption meopt) const;
 
   /**
    * Function to return partial Width
    * @param inpart The decaying particle.
    * @param outa One of the decay products.
    * @param outb The other decay product.
    */
   virtual Energy partialWidth(PMPair inpart, PMPair outa, 
 			      PMPair outb) const;
 
   /**
    *  Set the information on the decay
    */
-  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
+  virtual void setDecayInfo(PDPtr incoming, PDPair outgoing,
+			    vector<VertexBasePtr>,
 			    map<ShowerInteraction,VertexBasePtr> &,
 			    const vector<map<ShowerInteraction,VertexBasePtr> > &,
 			    map<ShowerInteraction,VertexBasePtr>);
   
   /**
    *  Has a POWHEG style correction
    */
   virtual POWHEGType hasPOWHEGCorrection()  {
-    return (vertex_->orderInGem()+vertex_->orderInGs())==1 ? FSR : No;
+    POWHEGType output = FSR;
+    for(auto vertex : vertex_) {
+      if(vertex->orderInAllCouplings()!=1) {
+	output = No;
+	break;
+      }
+    }
+    return output;
   }
 
   /**
    *  Three-body matrix element including additional QCD radiation
    */
   virtual double threeBodyME(const int , const Particle & inpart,
 			     const ParticleVector & decay,
 			     ShowerInteraction inter, MEOption meopt);
   //@}
 
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const;
 
   /** Make a clone of this object, possibly modifying the cloned object
    * to make it sane.
    * @return a pointer to the new object.
    */
   virtual IBPtr fullclone() const;
   //@}
   
 protected:
 
   /**
    *  Find the vertices for the decay
    */
   void identifyVertices(const Particle & inpart, const ParticleVector & decay, 
 			AbstractVVVVertexPtr & outgoingVertex1, 
 			AbstractVVVVertexPtr & outgoingVertex2,
 			ShowerInteraction inter);
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   VVVDecayer & operator=(const VVVDecayer &);
 
 private:
 
   /**
    *  Abstract pointer to AbstractVVVVertex
    */
-  AbstractVVVVertexPtr vertex_;
+  vector<AbstractVVVVertexPtr> vertex_;
 
   /**
    * Pointer to the perturbative vertex
    */
-  VVVVertexPtr perturbativeVertex_;
+  vector<VVVVertexPtr> perturbativeVertex_;
 
   /**
    *  Abstract pointer to AbstractVVVVertex for QCD radiation from incoming vector
    */
   map<ShowerInteraction,AbstractVVVVertexPtr> incomingVertex_;
 
   /**
    *  Abstract pointer to AbstractVVVVertex for QCD radiation from the first outgoing vector
    */
   map<ShowerInteraction,AbstractVVVVertexPtr> outgoingVertex1_;
 
   /**
    *  Abstract pointer to AbstractVVVVertex for QCD radiation from the second outgoing vector
    */
   map<ShowerInteraction,AbstractVVVVertexPtr> outgoingVertex2_;
 
   /**
    *  Abstract pointer to AbstractVVVVertex for QCD radiation from the 4-point vertex
    */
   map<ShowerInteraction,AbstractVVVVVertexPtr> fourPointVertex_;
 
   /**
    *  Spin density matrix
    */
   mutable RhoDMatrix rho_;
 
   /**
    * Vector wavefunctions
    */
   mutable vector<Helicity::VectorWaveFunction> vectors_[3];
 
 private:
 
   /**
    *  Members for the POWHEG correction
    */
   //@{
   /**
    *  Spin density matrix for 3 body decay
    */
   mutable RhoDMatrix rho3_;
 
   /**
    *  Vector wavefunction for 3 body decay
    */
   mutable vector<Helicity::VectorWaveFunction> vector3_;
 
   /**
    *  Vector wavefunctions
    */
   mutable vector<Helicity::VectorWaveFunction> vectors3_[2];
 
     /**
    *  Vector wavefunction for 3 body decay
    */
   mutable vector<Helicity::VectorWaveFunction> gluon_;
   //@}
 };
 
 }
 
 #endif /* HERWIG_VVVDecayer_H */
diff --git a/Models/General/TwoBodyDecayConstructor.cc b/Models/General/TwoBodyDecayConstructor.cc
--- a/Models/General/TwoBodyDecayConstructor.cc
+++ b/Models/General/TwoBodyDecayConstructor.cc
@@ -1,432 +1,432 @@
 // -*- C++ -*-
 //
 // TwoBodyDecayConstructor.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the TwoBodyDecayConstructor class.
 //
 
 #include "TwoBodyDecayConstructor.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Interface/Switch.h"
 #include "Herwig/Decay/General/GeneralTwoBodyDecayer.h"
 #include "Herwig/Models/StandardModel/StandardModel.h"
 #include "ThePEG/PDT/EnumParticles.h"
 #include "DecayConstructor.h"
 #include "ThePEG/Utilities/Throw.h"
 #include "ThePEG/Utilities/EnumIO.h"
 #include "ThePEG/Helicity/Vertex/AbstractFFVVertex.fh"
 #include "ThePEG/Helicity/Vertex/AbstractFFSVertex.fh"
 #include "ThePEG/Helicity/Vertex/AbstractVVSVertex.fh"
 #include "ThePEG/Helicity/Vertex/AbstractVSSVertex.fh"
 #include "ThePEG/Helicity/Vertex/AbstractVVTVertex.fh"
 #include "ThePEG/Helicity/Vertex/AbstractFFTVertex.fh"
 #include "ThePEG/Helicity/Vertex/AbstractSSTVertex.fh"
 #include "ThePEG/Helicity/Vertex/AbstractSSSVertex.fh"
 #include "ThePEG/Helicity/Vertex/AbstractVVVVertex.fh"
 #include "ThePEG/Helicity/Vertex/AbstractRFSVertex.fh"
 #include "ThePEG/Helicity/Vertex/AbstractRFVVertex.fh"
 
 using namespace Herwig;
 using ThePEG::Helicity::VertexBasePtr;
 
 IBPtr TwoBodyDecayConstructor::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr TwoBodyDecayConstructor::fullclone() const {
   return new_ptr(*this);
 }
 
 void TwoBodyDecayConstructor::persistentOutput(PersistentOStream & os) const {
   os << alphaQCD_ << alphaQED_ << oenum(inter_);
 }
 
 void TwoBodyDecayConstructor::persistentInput(PersistentIStream & is, int) {
   is  >> alphaQCD_ >> alphaQED_>> ienum(inter_);
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
 DescribeClass<TwoBodyDecayConstructor,NBodyDecayConstructorBase>
 describeHerwigTwoBodyDecayConstructor("Herwig::TwoBodyDecayConstructor", "Herwig.so");
 
 void TwoBodyDecayConstructor::Init() {
 
   static ClassDocumentation<TwoBodyDecayConstructor> documentation
     ("The TwoBodyDecayConstructor implements to creation of 2 body decaymodes "
      "and decayers that do not already exist for the given set of vertices.");
   
   static Reference<TwoBodyDecayConstructor,ShowerAlpha> interfaceShowerAlphaQCD
     ("AlphaQCD",
      "The coupling for QCD corrections",
      &TwoBodyDecayConstructor::alphaQCD_, false, false, true, false, false);
   
   static Reference<TwoBodyDecayConstructor,ShowerAlpha> interfaceShowerAlphaQED
     ("AlphaQED",
      "The coupling for QED corrections",
      &TwoBodyDecayConstructor::alphaQED_, false, false, true, false, false);
   
   static Switch<TwoBodyDecayConstructor,ShowerInteraction> interfaceInteractions
     ("Interactions",
      "which interactions to include for the hard corrections",
      &TwoBodyDecayConstructor::inter_, ShowerInteraction::QCD, false, false);
   static SwitchOption interfaceInteractionsQCD
     (interfaceInteractions,
      "QCD",
      "QCD Only",
      ShowerInteraction::QCD);
   static SwitchOption interfaceInteractionsQED
     (interfaceInteractions,
      "QED",
      "QED only",
      ShowerInteraction::QED);
   static SwitchOption interfaceInteractionsQCDandQED
     (interfaceInteractions,
      "QCDandQED",
      "Both QCD and QED",
      ShowerInteraction::Both);
 
 }
 
 void TwoBodyDecayConstructor::DecayList(const set<PDPtr> & particles) {
   if( particles.empty() ) return;
   tHwSMPtr model = dynamic_ptr_cast<tHwSMPtr>(generator()->standardModel());
   unsigned int nv(model->numberOfVertices());
   
   for(set<PDPtr>::const_iterator ip=particles.begin();
       ip!=particles.end();++ip) {
     tPDPtr parent = *ip;
     if ( Debug::level > 0 )
       Repository::cout() << "Constructing 2-body decays for " 
 			 << parent->PDGName() << '\n';
     multiset<TwoBodyDecay> decays;
     for(unsigned int iv = 0; iv < nv; ++iv) {
       if(excluded(model->vertex(iv)) || 
 	 model->vertex(iv)->getNpoint()>3) continue;
       for(unsigned int il = 0; il < 3; ++il) 
 	createModes(parent, model->vertex(iv), il,decays);
     }
     if( !decays.empty() ) createDecayMode(decays);
   }
 }
 
 void TwoBodyDecayConstructor::
 createModes(tPDPtr inpart, VertexBasePtr vertex,
 	    unsigned int list, multiset<TwoBodyDecay> & modes) {
   if( !vertex->isIncoming(inpart) || vertex->getNpoint() != 3 )
     return;
   Energy m1(inpart->mass());
   tPDPtr ccpart = inpart->CC() ? inpart->CC() : inpart;
   long id = ccpart->id();
   tPDVector decaylist = vertex->search(list, ccpart);
   tPDVector::size_type nd = decaylist.size();
   for( tPDVector::size_type i = 0; i < nd; i += 3 ) {
     tPDPtr pa(decaylist[i]), pb(decaylist[i + 1]), pc(decaylist[i + 2]);
     if( pb->id() == id ) swap(pa, pb);
     if( pc->id() == id ) swap(pa, pc);
     //allowed on-shell decay?
     if( m1 <= pb->mass() + pc->mass() ) continue;
     //vertices are defined with all particles incoming
     modes.insert( TwoBodyDecay(inpart,pb, pc, vertex) );
   }
 } 
 
 GeneralTwoBodyDecayerPtr
 TwoBodyDecayConstructor::createDecayer(TwoBodyDecay decay,
-				       vector<tVertexBasePtr> vertices) {
+				       vector<VertexBasePtr> vertices) {
   string name;
   using namespace Helicity::VertexType;
   PDT::Spin in   = decay.parent_->iSpin();
   // PDT::Spin out1 = decay.children_.first ->iSpin();
   PDT::Spin out2 = decay.children_.second->iSpin();
   switch(decay.vertex_->getName()) {
   case FFV :
     if(in == PDT::Spin1Half) {
       name = "FFVDecayer";
       if(out2==PDT::Spin1Half)
 	swap(decay.children_.first,decay.children_.second);
     }
     else {
       name = "VFFDecayer";
     }
     break;
   case FFS :
     if(in == PDT::Spin1Half) {
       name = "FFSDecayer";
       if(out2==PDT::Spin1Half)
 	swap(decay.children_.first,decay.children_.second);
     }
     else {
       name = "SFFDecayer";
     }
     break;
   case VVS :
     if(in == PDT::Spin1) {
       name = "VVSDecayer";
       if(out2==PDT::Spin1)
 	swap(decay.children_.first,decay.children_.second);
     }
     else {
       name = "SVVDecayer";
     }
     break;
   case VSS :
     if(in == PDT::Spin1) {
       name = "VSSDecayer";
     }
     else {
       name = "SSVDecayer";
       if(out2==PDT::Spin0)
 	swap(decay.children_.first,decay.children_.second);
     }
     break;
   case VVT :
     name = in==PDT::Spin2 ? "TVVDecayer" : "Unknown";
     break;
   case FFT :
     name = in==PDT::Spin2 ? "TFFDecayer" : "Unknown";
     break;
   case SST :
     name = in==PDT::Spin2 ? "TSSDecayer" : "Unknown";
     break;
   case SSS :
     name = "SSSDecayer";
     break;
   case VVV :
     name = "VVVDecayer";
     break;
   case RFS :
     if(in==PDT::Spin1Half) {
       name = "FRSDecayer";
       if(out2==PDT::Spin3Half)
 	swap(decay.children_.first,decay.children_.second);
     }
     else if(in==PDT::Spin0) {
       name = "SRFDecayer";
       if(out2==PDT::Spin3Half)
 	swap(decay.children_.first,decay.children_.second);
     }
     else {
       name = "Unknown";
     }
     break;
   case RFV :
     if(in==PDT::Spin1Half) {
       name = "FRVDecayer";
       if(out2==PDT::Spin3Half)
 	swap(decay.children_.first,decay.children_.second);
     }
     else
       name = "Unknown";
     break;
   default : Throw<NBodyDecayConstructorError>() 
       << "Error: Cannot assign " << decay.vertex_->fullName() << " to a decayer. " 
       <<  "Decay is " << decay.parent_->PDGName() << " -> "
       << decay.children_.first ->PDGName() << " " 
       << decay.children_.second->PDGName() << Exception::runerror;
   }
   if(name=="Unknown") 
     Throw<NBodyDecayConstructorError>() 
       << "Error: Cannot assign " << decay.vertex_->fullName() << " to a decayer. " 
       <<  "Decay is " << decay.parent_->PDGName() << " -> "
       << decay.children_.first ->PDGName() << " " 
       << decay.children_.second->PDGName() << Exception::runerror;
   ostringstream fullname;
   fullname << "/Herwig/Decays/" << name << "_" << decay.parent_->PDGName() 
 	   << "_" << decay.children_.first ->PDGName() 
 	   << "_" << decay.children_.second->PDGName();
   string classname = "Herwig::" + name;
   GeneralTwoBodyDecayerPtr decayer;
   decayer = dynamic_ptr_cast<GeneralTwoBodyDecayerPtr>
     (generator()->preinitCreate(classname,fullname.str()));
   if(!decayer) 
     Throw<NBodyDecayConstructorError>() 
       << "Error: Cannot assign " << decay.vertex_->fullName() << " to a decayer. " 
       << "Decay is " << decay.parent_->PDGName() << " -> "
       << decay.children_.first ->PDGName() << " " 
       << decay.children_.second->PDGName() << Exception::runerror;
   // set the strong coupling for radiation
   generator()->preinitInterface(decayer, "AlphaS" , "set", alphaQCD_->fullName());
   // set the EM     coupling for radiation
   generator()->preinitInterface(decayer, "AlphaEM", "set", alphaQED_->fullName());
   // set the type of interactions for the correction
   if(inter_==ShowerInteraction::QCD)
     generator()->preinitInterface(decayer, "Interactions", "set", "QCD");
   else if(inter_==ShowerInteraction::QED)
     generator()->preinitInterface(decayer, "Interactions", "set", "QED");
   else
     generator()->preinitInterface(decayer, "Interactions", "set", "QCDandQED");
   // get the vertices for radiation from the external legs
   map<ShowerInteraction,VertexBasePtr> inRad,fourRad;
   vector<map<ShowerInteraction,VertexBasePtr> > outRad(2);
   vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
   for(auto & inter : itemp) {
     inRad[inter] = radiationVertex(decay.parent_,inter);
     outRad[0][inter] = radiationVertex(decay.children_.first ,inter);
     outRad[1][inter] = radiationVertex(decay.children_.second,inter);
     // get any contributing 4 point vertices
     fourRad[inter]   = radiationVertex(decay.parent_,inter, decay.children_);
   }
 
   // set info on decay
-  decayer->setDecayInfo(decay.parent_,decay.children_,decay.vertex_,
+  decayer->setDecayInfo(decay.parent_,decay.children_,vertices,
   			inRad,outRad,fourRad);
   // initialised the decayer
   setDecayerInterfaces(fullname.str());
   decayer->init();
   return decayer;
 }
 
 void TwoBodyDecayConstructor::
 createDecayMode(multiset<TwoBodyDecay> & decays) {
   tPDPtr inpart = decays.begin()->parent_;
   for( multiset<TwoBodyDecay>::iterator dit = decays.begin();
        dit != decays.end(); ) {
     TwoBodyDecay mode = *dit;
     // get all the moees with the same in and outgoing particles
     pair<multiset<TwoBodyDecay>::iterator,
 	 multiset<TwoBodyDecay>::iterator> range = decays.equal_range(mode);
     // construct the decay mode
     tPDPtr pb((mode).children_.first), pc((mode).children_.second);
     string tag = inpart->name() + "->" + pb->name() + "," + 
       pc->name() + ";";
     // Does it exist already ?
     tDMPtr dm = generator()->findDecayMode(tag);
     // find the vertices
-    vector<tVertexBasePtr> vertices;
+    vector<VertexBasePtr> vertices;
     for ( multiset<TwoBodyDecay>::iterator dit2 = range.first;
 	  dit2 != range.second; ++dit2) {
       vertices.push_back(dit2->vertex_);
     }
     dit=range.second;
     // now create DecayMode objects that do not already exist      
     if( createDecayModes() && (!dm || inpart->id() == ParticleID::h0) ) {
       tDMPtr ndm = generator()->preinitCreateDecayMode(tag);
       if(ndm) {
 	inpart->stable(false);
 	GeneralTwoBodyDecayerPtr decayer=createDecayer(mode,vertices);
 	if(!decayer) continue;
 	generator()->preinitInterface(ndm, "Decayer", "set",
 				      decayer->fullName());
 	generator()->preinitInterface(ndm, "Active", "set", "Yes");
 	Energy width = 
 	  decayer->partialWidth(make_pair(inpart,inpart->mass()),
 				make_pair(pb,pb->mass()) , 
 				make_pair(pc,pc->mass()));
 	setBranchingRatio(ndm, width);
 	if(width==ZERO || ndm->brat()<decayConstructor()->minimumBR()) {
 	  generator()->preinitInterface(decayer->fullName(),
 					"Initialize", "set","0");
 	}
       }
       else
 	Throw<NBodyDecayConstructorError>() 
 	  << "TwoBodyDecayConstructor::createDecayMode - Needed to create "
 	  << "new decaymode but one could not be created for the tag " 
 	  << tag << Exception::warning;
     }
     else if( dm ) {
       if(dm->brat()<decayConstructor()->minimumBR()) {
 	continue;
       }
       if((dm->decayer()->fullName()).find("Mambo") != string::npos) {
 	inpart->stable(false);
 	GeneralTwoBodyDecayerPtr decayer=createDecayer(mode,vertices);
 	if(!decayer) continue;
 	generator()->preinitInterface(dm, "Decayer", "set", 
 				      decayer->fullName());
 	Energy width = 
 	  decayer->partialWidth(make_pair(inpart,inpart->mass()),
 				make_pair(pb,pb->mass()) , 
 				make_pair(pc,pc->mass()));
 	if(width/(dm->brat()*inpart->width())<1e-10) {
 	  string message = "Herwig calculation of the partial width for the decay mode "
 	    + inpart->PDGName() + " -> " + pb->PDGName() + " " + pc->PDGName()
 	    + " is zero.\n This will cause problems with the calculation of"
 	    + " spin correlations.\n It is probably due to inconsistent parameters"
 	    + " and decay modes being passed to Herwig via the SLHA file.\n"
 	    + " Zeroing the branching ratio for this mode.";
 	  setBranchingRatio(dm,ZERO);
 	  generator()->logWarning(NBodyDecayConstructorError(message,Exception::warning));
 	}
       }
     }
   }
   // update CC mode if it exists
   if( inpart->CC() ) inpart->CC()->synchronize();
 }
 
 VertexBasePtr TwoBodyDecayConstructor::radiationVertex(tPDPtr particle,
 						       ShowerInteraction inter,
 						       tPDPair children) {
   tHwSMPtr model = dynamic_ptr_cast<tHwSMPtr>(generator()->standardModel());
   map<tPDPtr,VertexBasePtr>::iterator rit = radiationVertices_[inter].find(particle);
   tPDPtr cc = particle->CC() ? particle->CC() : particle;
   if(children==tPDPair() && rit!=radiationVertices_[inter].end()) return rit->second;
   unsigned int nv(model->numberOfVertices());
   long bosonID = inter==ShowerInteraction::QCD ? ParticleID::g : ParticleID::gamma;
   tPDPtr gluon = getParticleData(bosonID);
   // look for radiation vertices for incoming and outgoing particles
   for(unsigned int iv=0;iv<nv;++iv) {
     VertexBasePtr vertex = model->vertex(iv);
     // look for 3 point vertices
     if (children==tPDPair()){
       if( !vertex->isIncoming(particle) ||  vertex->getNpoint() != 3 ||
 	  !vertex->isOutgoing(particle) || !vertex->isOutgoing(gluon)) continue;      
       for(unsigned int list=0;list<3;++list) {
 	tPDVector decaylist = vertex->search(list, particle);
 	for( tPDVector::size_type i = 0; i < decaylist.size(); i += 3 ) {
 	  tPDPtr pa(decaylist[i]), pb(decaylist[i + 1]), pc(decaylist[i + 2]);
 	  if( pb->id() == bosonID ) swap(pa, pb);
 	  if( pc->id() == bosonID ) swap(pa, pc);
 	  if( pb->id() != particle->id()) swap(pb, pc);
 	  if( pa->id() != bosonID) continue;
 	  if( pb       != particle)      continue;
 	  if( pc       != cc)            continue;
 	  radiationVertices_[inter][particle] = vertex; 
 	  return vertex;
 	}
       }
     }
     // look for 4 point vertex including a gluon
     else {           
       if( !vertex->isIncoming(particle)       ||  vertex->getNpoint()!=4              ||
       	  !vertex->isOutgoing(children.first) || !vertex->isOutgoing(children.second) || 
 	  !vertex->isOutgoing(gluon)) continue;
       
       for(unsigned int list=0;list<4;++list) {
 	tPDVector decaylist = vertex->search(list, particle);
 	for( tPDVector::size_type i = 0; i < decaylist.size(); i += 4 ) {
 	  tPDPtr pa(decaylist[i]), pb(decaylist[i+1]), pc(decaylist[i+2]), pd(decaylist[i+3]);
 	  // order so that a = g, b = parent
 	  if( pb->id() == bosonID ) swap(pa, pb);
 	  if( pc->id() == bosonID ) swap(pa, pc);
 	  if( pd->id() == bosonID ) swap(pa, pd);
 	  if( pc->id() == particle->id()) swap(pb, pc);
 	  if( pd->id() == particle->id()) swap(pb, pd);
 	  if( pa->id() != bosonID)  continue;
 	  if( pb->id() != particle->id()) continue;
 
 	  if( !((abs(pd->id()) == abs(children. first->id()) &&
 		 abs(pc->id()) == abs(children.second->id())) ||
 		(abs(pc->id()) == abs(children. first->id()) &&
 		 abs(pd->id()) == abs(children.second->id()))))
 	    continue;
 
 	  return vertex;
 	}
       }
     }
   }
   return VertexBasePtr();
 }
 
 
diff --git a/Models/General/TwoBodyDecayConstructor.h b/Models/General/TwoBodyDecayConstructor.h
--- a/Models/General/TwoBodyDecayConstructor.h
+++ b/Models/General/TwoBodyDecayConstructor.h
@@ -1,177 +1,177 @@
 // -*- C++ -*-
 //
 // TwoBodyDecayConstructor.h is a part of Herwig - A multi-purpose Monte Carlo event generator
 // Copyright (C) 2002-2017 The Herwig Collaboration
 //
 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef HERWIG_TwoBodyDecayConstructor_H
 #define HERWIG_TwoBodyDecayConstructor_H
 //
 // This is the declaration of the TwoBodyDecayConstructor class.
 //
 
 #include "NBodyDecayConstructorBase.h"
 #include "ThePEG/Helicity/Vertex/VertexBase.h"
 #include "Herwig/Decay/General/GeneralTwoBodyDecayer.fh"
 #include "Herwig/Shower/ShowerAlpha.h"
 #include "TwoBodyDecay.h"
 
 namespace Herwig {
 using namespace ThePEG;
 
 using Helicity::VertexBasePtr;
 using Helicity::tVertexBasePtr;
 
 /**
  * The TwoBodyDecayConstructor class inherits from the dummy base class
  * NBodyDecayConstructorBase and implements the necessary functions in
  * order to create the 2 body decay modes for a given set of vertices
  * stored in a Model class.
  *
  * @see \ref TwoBodyDecayConstructorInterfaces "The interfaces"
  * defined for TwoBodyDecayConstructor.
  * @see NBodyDecayConstructor
  **/
 class TwoBodyDecayConstructor: public NBodyDecayConstructorBase {
 
 public:
 
   /**
    * The default constructor.
    */
   TwoBodyDecayConstructor() : inter_(ShowerInteraction::Both) {
     radiationVertices_[ShowerInteraction::QCD] = map<tPDPtr,VertexBasePtr>();
     radiationVertices_[ShowerInteraction::QED] = map<tPDPtr,VertexBasePtr>();
   }
 
   /**
    * Function used to determine allowed decaymodes
    *@param part vector of ParticleData pointers containing particles in model
    */
   virtual void DecayList(const set<PDPtr> & part);
 
   /**
    * Number of outgoing lines. Required for correct ordering.
    */
   virtual unsigned int numBodies() const { return 2; }
 
   
 public:
 
   /** @name Functions used by the persistent I/O system. */
   //@{
   /**
    * Function used to write out object persistently.
    * @param os the persistent output stream written to.
    */
   void persistentOutput(PersistentOStream & os) const;
 
   /**
    * Function used to read in object persistently.
    * @param is the persistent input stream read from.
    * @param version the version number of the object when written.
    */
   void persistentInput(PersistentIStream & is, int version);
   //@}
 
   /**
    * The standard Init function used to initialize the interfaces.
    * Called exactly once for each class by the class description system
    * before the main function starts or
    * when this class is dynamically loaded.
    */
   static void Init();
 
 protected:
 
   /** @name Clone Methods. */
   //@{
   /**
    * Make a simple clone of this object.
    * @return a pointer to the new object.
    */
   virtual IBPtr clone() const;
 
   /** Make a clone of this object, possibly modifying the cloned object
    * to make it sane.
    * @return a pointer to the new object.
    */
   virtual IBPtr fullclone() const;
   //@}
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   TwoBodyDecayConstructor & operator=(const TwoBodyDecayConstructor &);
 
 private:
   
   /** @name Functions to create decayers and decaymodes. */
   //@{
   /**
    * Function to create decays
    * @param inpart Incoming particle 
    * @param vert The vertex to create decays for
    * @param ilist Which list to search
    * @param iv Row number in _theExistingDecayers member
    * @return A vector a decay modes
    */
   void createModes(tPDPtr inpart, VertexBasePtr vert,
 		   unsigned int ilist,
 		   multiset<TwoBodyDecay> & modes);
 
   /**
    * Function to create decayer for specific vertex
    * @param decay decay mode for this decay
    * member variable
    */
   GeneralTwoBodyDecayerPtr createDecayer(TwoBodyDecay decay,
-					 vector<tVertexBasePtr> );
+					 vector<VertexBasePtr> );
 
   /**
    * Create decay mode(s) from given part and decay modes
    * @param decays The vector of decay modes
    * @param decayer The decayer responsible for this decay
    */
   void createDecayMode(multiset<TwoBodyDecay> & decays);
   //@}
 
   /**
    * Get the vertex for QED/QCD radiation
    */
   VertexBasePtr radiationVertex(tPDPtr particle,ShowerInteraction inter,
 				tPDPair children = tPDPair ());
 
 private:
 
   /**
    *  Map of particles and the vertices which generate their QCD
    *  radiation
    */
   map<ShowerInteraction,map<tPDPtr,VertexBasePtr> > radiationVertices_;
 
   /**
    *  Default choice for the strong coupling object for hard QCD radiation
    */
   ShowerAlphaPtr  alphaQCD_;
 
   /**
    *  Default choice for the strong coupling object for hard QED radiation
    */
   ShowerAlphaPtr  alphaQED_;
 
   /**
    *  Which type of corrections to the decays to include
    */
   ShowerInteraction inter_; 
   
 };
   
 }
 
 #endif /* HERWIG_TwoBodyDecayConstructor_H */