diff --git a/Decay/ScalarMeson/ScalarMesonFactorizedDecayer.cc b/Decay/ScalarMeson/ScalarMesonFactorizedDecayer.cc
--- a/Decay/ScalarMeson/ScalarMesonFactorizedDecayer.cc
+++ b/Decay/ScalarMeson/ScalarMesonFactorizedDecayer.cc
@@ -1,753 +1,785 @@
 // -*- C++ -*-
 //
 // ScalarMesonFactorizedDecayer.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 ScalarMesonFactorizedDecayer class.
 //
 
 #include "ScalarMesonFactorizedDecayer.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/RefVector.h"
 #include "ThePEG/Interface/Parameter.h"
 #include "ThePEG/Interface/ParVector.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
 #include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
 #include "ThePEG/Helicity/epsilon.h"
 #include "ThePEG/Helicity/WaveFunction/TensorWaveFunction.h"
 #include "Herwig/Decay/GeneralDecayMatrixElement.h"
 
 using namespace Herwig;
 using namespace ThePEG::Helicity;
 
 
 ScalarMesonFactorizedDecayer::ScalarMesonFactorizedDecayer() 
 // default values of the couplings (taken from ZPC34, 103)
   : _a1b(1.10), _a2b(-0.24), _a1c(1.30), _a2c(-0.55) { 
   // intermediates
   generateIntermediates(true);
 }
 
 void ScalarMesonFactorizedDecayer::rebind(const TranslationMap & trans)
   {
   _ckm = trans.translate(_ckm);
-  DecayIntegrator::rebind(trans);
+  DecayIntegrator2::rebind(trans);
 }
 
 IVector ScalarMesonFactorizedDecayer::getReferences() {
-  IVector ret = DecayIntegrator::getReferences();
+  IVector ret = DecayIntegrator2::getReferences();
   ret.push_back(_ckm);
   return ret;
 }
 
 void ScalarMesonFactorizedDecayer::doinit() {
-  DecayIntegrator::doinit();
+  DecayIntegrator2::doinit();
   // get the ckm object
   _ckm=dynamic_ptr_cast<Ptr<StandardCKM>::pointer>(SM().CKM());
   if(!_ckm) throw InitException() << "ScalarMesonFactorizedDecayer::doinit() "
-				  << "the CKM object must be the Herwig one"
-				  << Exception::runerror;
-  unsigned int ix,iy,iz,icurr,iform;
+  				  << "the CKM object must be the Herwig one"
+  				  << Exception::runerror;
   // get the CKM matrix (unsquared for interference)
   Complex ckmmat[3][3];
   vector< vector<Complex > > CKM(_ckm->getUnsquaredMatrix(SM().families()));
-  for(ix=0;ix<3;++ix){for(iy=0;iy<3;++iy){ckmmat[ix][iy]=CKM[ix][iy];}}
-  int id0,id1,Wcharge,iq,ia,jspin,spect,inq,outq;
+  for(unsigned int ix=0;ix<3;++ix) {
+    for(unsigned int iy=0;iy<3;++iy){
+      ckmmat[ix][iy]=CKM[ix][iy];
+    }
+  }
   // make sure the currents and form factors got initialised
-  for(ix=0;ix<_current.size();++ix) _current[ix]->init();
-  for(ix=0;ix<_form.size();++ix)    _form[ix]->init();
+  for(unsigned int ix=0;ix<_current.size();++ix)
+    _current[ix]->init();
+  for(unsigned int ix=0;ix<_form.size();++ix)
+    _form[ix]->init();
   // find all the possible modes
   vector<unsigned int> tformmap[2],tcurrmap[2];
   vector<int> inquark,outquark,currq,curra;
-  vector<tPDVector> particles;
-  tPDVector extpart,ptemp;
-  Energy min,minb;
+  tPDVector incoming;
+  vector<tPDVector> outgoing;
   // loop over the modes in the form factors and currents
-  for(iform=0;iform<_form.size();++iform) {
-    for(ix=0;ix<_form[iform]->numberOfFactors();++ix) {
-      // particles from the form-factor
-      extpart.resize(2);
+  for(unsigned int iform=0;iform<_form.size();++iform) {
+    for(unsigned int ix=0;ix<_form[iform]->numberOfFactors();++ix) {
+      // information from the form-factor
+      int id0,id1,jspin,spect,inq,outq;
       _form[iform]->particleID(ix,id0,id1);
       _form[iform]->formFactorInfo(ix,jspin,spect,inq,outq);
       // particles from the form factor
-      extpart[0]=getParticleData(id0);
-      extpart[1]=getParticleData(id1);
+      tPDPtr in  = getParticleData(id0);
+      tPDPtr out = getParticleData(id1);
       // charge of the decay products
-      Wcharge =extpart[0]->iCharge()-extpart[1]->iCharge();
+      int Wcharge = in->iCharge()-out->iCharge();
       // max mass for the particles in the current
-      min = extpart[0]->massMax()-extpart[1]->massMin();
-      for(icurr=0;icurr<_current.size();++icurr) {
-	for(iy=0;iy<_current[icurr]->numberOfModes();++iy) {
-	  extpart.resize(2);
+      Energy min = in->massMax()-out->massMin();
+      for(unsigned int icurr=0;icurr<_current.size();++icurr) {
+  	for(unsigned int iy=0;iy<_current[icurr]->numberOfModes();++iy) {
 	  // get the particles from the current
+	  int iq,ia;
 	  _current[icurr]->decayModeInfo(iy,iq,ia);
-	  ptemp=_current[icurr]->particles(Wcharge,iy,iq,ia);
-	  minb=ZERO;
-	  for(iz=0;iz<ptemp.size();++iz) {
-	    extpart.push_back(ptemp[iz]);
-	    minb+=ptemp[iz]->massMin();
-	  }
-	  // add this mode to the list
-	  if(extpart.size()>2&&minb<min&&
-	     (Wcharge!=0||(Wcharge==0&&((inq>0&&inq%2!=iq%2)||
-					(inq<0&&abs(inq)%2!=abs(ia)%2))))) {
-	    tformmap[0].push_back(iform);tformmap[1].push_back(ix);
-	    tcurrmap[0].push_back(icurr);tcurrmap[1].push_back(iy);
-	    particles.push_back(extpart);
-	    inquark.push_back(inq);outquark.push_back(outq);
-	    currq.push_back(iq);curra.push_back(ia);
-	  }
-	  // if the meson in the current is neutral try the CC mode
-	  if(Wcharge==0&&iq!=-ia&&((inq>0&&inq%2!=iq%2)||
-				   (inq<0&&abs(inq)%2!=abs(ia)%2))) {
-	    extpart.resize(2);
-	    // get the particles from the current
-	    ptemp=_current[icurr]->particles(Wcharge,iy,-ia,-iq);
-	    minb=ZERO;
-	    for(iz=0;iz<ptemp.size();++iz) {
-	      extpart.push_back(ptemp[iz]);
+	  tPDVector ptemp=_current[icurr]->particles(Wcharge,iy,iq,ia);
+	  tPDVector outV = {out};
+	  outV.insert(std::end(outV), std::begin(ptemp), std::end(ptemp));
+	  // create the mode
+	  PhaseSpaceModePtr mode = new_ptr(PhaseSpaceMode(in,outV,1.));
+	  // create the first piece of the channel
+	  PhaseSpaceChannel channel((PhaseSpaceChannel(mode),0,1)); 	  
+   	  Energy minb=ZERO;
+   	  for(unsigned int iz=0;iz<ptemp.size();++iz)
+	    minb += ptemp[iz]->massMin();
+  	  // add this mode to the list
+   	  if(outV.size()>1&&minb<min&&
+  	     (Wcharge!=0||(Wcharge==0&&((inq>0&&inq%2!=iq%2)||
+   					(inq<0&&abs(inq)%2!=abs(ia)%2))))) {
+   	    tformmap[0].push_back(iform);tformmap[1].push_back(ix);
+   	    tcurrmap[0].push_back(icurr);tcurrmap[1].push_back(iy);
+ 	    incoming.push_back( in );
+ 	    outgoing.push_back(outV);
+ 	    inquark.push_back(inq);outquark.push_back(outq);
+ 	    currq.push_back(iq);curra.push_back(ia);
+ 	  }
+   	  // if the meson in the current is neutral try the CC mode
+   	  if(Wcharge==0&&iq!=-ia&&((inq>0&&inq%2!=iq%2)||
+   				   (inq<0&&abs(inq)%2!=abs(ia)%2))) {
+   	    // get the particles from the current
+   	    tPDVector ptemp=_current[icurr]->particles(Wcharge,iy,-ia,-iq);
+	    outV = {out};
+	    outV.insert(std::end(outV), std::begin(ptemp), std::end(ptemp));
+   	    minb=ZERO;
+   	    for(unsigned int iz=0;iz<ptemp.size();++iz)
 	      minb+=ptemp[iz]->massMin();
-	    }
-	    if(extpart.size()>2&&minb<min) {
-	      tformmap[0].push_back(iform);tformmap[1].push_back(ix);
-	      tcurrmap[0].push_back(icurr);tcurrmap[1].push_back(iy);
-	      particles.push_back(extpart);
-	      inquark.push_back(inq);outquark.push_back(outq);
-	      currq.push_back(-ia);curra.push_back(-iq);
-	    }
-	  }
-	}
+   	    if(outV.size()>1&&minb<min) {
+   	      tformmap[0].push_back(iform);tformmap[1].push_back(ix);
+   	      tcurrmap[0].push_back(icurr);tcurrmap[1].push_back(iy);
+	      incoming.push_back(in);
+   	      outgoing.push_back(outV);
+   	      inquark.push_back(inq);outquark.push_back(outq);
+   	      currq.push_back(-ia);curra.push_back(-iq);
+   	    }
+   	  }
+  	}
       }
     }
   }
   // loop over the modes and find the dupliciates
-  vector<bool> modecc; vector<unsigned int> modeloc,tformpart,ttform[2],ttcurr[2];
-  vector<Complex> tCKM; Complex ckm;
-  DecayPhaseSpaceModePtr mode;
-  DecayPhaseSpaceChannelPtr channel;
-  bool done;
-  int id,idbar;
-  double maxweight;
-  vector<double> channelwgts;
-  unsigned int isize;double ort(sqrt(0.5));
-  vector<double>::iterator start,end;
-  for(ix=0;ix<particles.size();++ix) {
+  static const double ort(sqrt(0.5));
+  for(unsigned int ix=0;ix<outgoing.size();++ix) {
     while (true) {
-      if(particles[ix].empty()) break;
-      findModes(ix,particles,modeloc,modecc);
-      // if more than three particles only allow one diagram
-      if ( particles[ix].size()>3 && !modeloc.empty() ) break;
+      if(outgoing[ix].empty()) break;
+      vector<bool> modecc;
+      vector<unsigned int> modeloc;
+      findModes(ix,incoming,outgoing,modeloc,modecc);
+      // if more than two outgoing only allow one diagram
+      if ( outgoing[ix].size()>2 && !modeloc.empty() ) break;
       // create the mode and set the particles as for the first instance
-      mode=new_ptr(DecayPhaseSpaceMode(particles[ix],this));
-      channel = new_ptr(DecayPhaseSpaceChannel(mode));
-      channel->addIntermediate(particles[ix][0],0,0.0,1,-1);
-      min = particles[ix][0]->massMax()-particles[ix][1]->massMin();
-      Wcharge = particles[ix][0]->iCharge()-particles[ix][1]->iCharge();
-      done=_current[tcurrmap[0][ix]]->createMode(Wcharge,tcurrmap[1][ix],
-						 mode,2,1,channel,min);
+      PhaseSpaceModePtr mode=new_ptr(PhaseSpaceMode(incoming[ix],outgoing[ix],1.));
+      PhaseSpaceChannel channel((PhaseSpaceChannel(mode),0,1));
+      Energy min = incoming[ix]->massMax()-outgoing[ix][0]->massMin();
+      int Wcharge = incoming[ix]->iCharge()-outgoing[ix][0]->iCharge();
+      bool done = _current[tcurrmap[0][ix]]->
+	createMode(Wcharge,tcPDPtr(),IsoSpin::IUnknown,IsoSpin::I3Unknown,
+		   tcurrmap[1][ix],mode,1,0,channel,min);
       if(!done) throw InitException() << "Failed to construct mode in "
-				      << "ScalarMesonFactorizedDecayer::doinit()." 
-				      << Exception::abortnow;
+   				      << "ScalarMesonFactorizedDecayer::doinit()." 
+   				      << Exception::abortnow;
       // set the parameters for the additional modes
-      ttform[0].clear();ttform[1].clear();
-      ttcurr[0].clear();ttcurr[1].clear();
+      vector<unsigned int> tformpart(1,0),ttform[2],ttcurr[2];
       ttform[0].push_back(tformmap[0][ix]);ttform[1].push_back(tformmap[1][ix]);
       ttcurr[0].push_back(tcurrmap[0][ix]);ttcurr[1].push_back(tcurrmap[1][ix]);
-      tformpart.clear();tformpart.push_back(0);
-      id=particles[ix][1]->id();
-      idbar = particles[ix][1]->CC() ? particles[ix][1]->CC()->id() : id;
-      for(iy=0;iy<modeloc.size();++iy) {
-	ttform[0].push_back(tformmap[0][modeloc[iy]]);
-	ttform[1].push_back(tformmap[1][modeloc[iy]]);
-	ttcurr[0].push_back(tcurrmap[0][modeloc[iy]]);
-	ttcurr[1].push_back(tcurrmap[1][modeloc[iy]]);
-	iz=1;
-	do {
-	  if(( modecc[iy]&&particles[modeloc[iy]][iz]->id()==idbar)||
-	     (!modecc[iy]&&particles[modeloc[iy]][iz]->id()==id))
-	    tformpart.push_back(iz-1);
-	  ++iz;
-	}
-	while(tformpart.size()!=iy+2&&iz<3);
+      int id    = outgoing[ix][0]->id();
+      int idbar = outgoing[ix][0]->CC() ? outgoing[ix][0]->CC()->id() : id;
+      for(unsigned int iy=0;iy<modeloc.size();++iy) {
+   	ttform[0].push_back(tformmap[0][modeloc[iy]]);
+   	ttform[1].push_back(tformmap[1][modeloc[iy]]);
+   	ttcurr[0].push_back(tcurrmap[0][modeloc[iy]]);
+   	ttcurr[1].push_back(tcurrmap[1][modeloc[iy]]);
+   	unsigned int iz=0;
+   	do {
+   	  if(( modecc[iy]&&outgoing[modeloc[iy]][iz]->id()==idbar)||
+   	     (!modecc[iy]&&outgoing[modeloc[iy]][iz]->id()==id))
+   	    tformpart.push_back(iz);
+   	  ++iz;
+   	}
+   	while(tformpart.size()!=iy+2&&iz<2);
       }
       // calculate ckm factors
-      tCKM.clear();
-      for(iy=0;iy<ttcurr[0].size();++iy) {
-	// get the quarks involved in the process
-	if(iy==0) {
-	  iq=currq[ix];ia=curra[ix];
-	  inq=inquark[ix];outq=outquark[ix];
+      vector<Complex> tCKM;
+      for(unsigned int iy=0;iy<ttcurr[0].size();++iy) {
+  	// get the quarks involved in the process
+	int iq,ia,inq,outq;
+  	if(iy==0) {
+   	  iq=currq[ix];ia=curra[ix];
+   	  inq=inquark[ix];outq=outquark[ix];
 	}
-	else {
-	  if(!modecc[iy-1]) {
-	    iq=currq[modeloc[iy-1]];ia=curra[modeloc[iy-1]];
-	    inq=inquark[modeloc[iy-1]];outq=outquark[modeloc[iy-1]];
-	  }
-	  else {
-	    ia=-currq[modeloc[iy-1]];iq=-curra[modeloc[iy-1]];
-	    inq=-inquark[modeloc[iy-1]];outq=-outquark[modeloc[iy-1]];
-	  }
-	}
+ 	else {
+ 	  if(!modecc[iy-1]) {
+ 	    iq=currq[modeloc[iy-1]];ia=curra[modeloc[iy-1]];
+ 	    inq=inquark[modeloc[iy-1]];outq=outquark[modeloc[iy-1]];
+ 	  }
+ 	  else {
+ 	    ia=-currq[modeloc[iy-1]];iq=-curra[modeloc[iy-1]];
+ 	    inq=-inquark[modeloc[iy-1]];outq=-outquark[modeloc[iy-1]];
+ 	  }
+ 	}
+	int id0,id1;
 	_form[ttform[0][iy]]->particleID(ttform[1][iy],id0,id1);
-	Wcharge = getParticleData(id0)->iCharge()-getParticleData(id1)->iCharge();
-	ckm=1.;
-	if(Wcharge!=0) {
-	  ckm=1.;
-	  if(abs(iq)%2==0)  ckm *= conj(ckmmat[abs(iq)/2-1][(abs(ia)-1)/2]);
-	  else              ckm *= conj(ckmmat[abs(ia)/2-1][(abs(iq)-1)/2]);
-	  if(abs(inq)%2==0) ckm *= ckmmat[abs(inq)/2-1][(abs(outq)-1)/2];
-	  else              ckm *= ckmmat[abs(outq)/2-1][(abs(inq)-1)/2];
-	  if(abs(inq)==5)   ckm*=_a1b;
-	  else              ckm*=_a1c;
-	}
-	else {
-	  ckm=1.;
-	  if(inq>0) {
-	    if(abs(inq)%2==0)  ckm *= ckmmat[abs(inq)/2-1][(abs(iq)-1)/2];
-	    else               ckm *= ckmmat[abs(iq)/2-1][(abs(inq)-1)/2];
-	    if(abs(outq)%2==0) ckm *= conj(ckmmat[abs(outq)/2-1][(abs(ia)-1)/2]);
-	    else               ckm *= conj(ckmmat[abs(ia)/2-1][(abs(outq)-1)/2]);
-	  }
-	  else {
-	    if(abs(inq)%2==0)  ckm *= ckmmat[abs(inq)/2-1][(abs(ia)-1)/2];
-	    else               ckm *= ckmmat[abs(ia)/2-1][(abs(inq)-1)/2];
-	    if(abs(outq)%2==0) ckm *= conj(ckmmat[abs(outq)/2-1][(abs(iq)-1)/2]);
-	    else               ckm *= conj(ckmmat[abs(iq)/2-1][(abs(outq)-1)/2]);
-	  }
-	  if(abs(inq)==5) ckm*=_a2b;
-	  else            ckm*=_a2c;
-	}
-	if((abs(inq)%2==0&&inq<0)||(abs(inq)%2!=0&&inq>0)){ckm=conj(ckm);}
-	tCKM.push_back(ckm);
+  	int Wcharge = getParticleData(id0)->iCharge()-getParticleData(id1)->iCharge();
+   	Complex ckm=1.;
+   	if(Wcharge!=0) {
+   	  if(abs(iq)%2==0)  ckm *= conj(ckmmat[abs(iq)/2-1][(abs(ia)-1)/2]);
+   	  else              ckm *= conj(ckmmat[abs(ia)/2-1][(abs(iq)-1)/2]);
+   	  if(abs(inq)%2==0) ckm *= ckmmat[abs(inq)/2-1][(abs(outq)-1)/2];
+   	  else              ckm *= ckmmat[abs(outq)/2-1][(abs(inq)-1)/2];
+   	  if(abs(inq)==5)   ckm*=_a1b;
+   	  else              ckm*=_a1c;
+   	}
+   	else {
+   	  if(inq>0) {
+   	    if(abs(inq)%2==0)  ckm *= ckmmat[abs(inq)/2-1][(abs(iq)-1)/2];
+   	    else               ckm *= ckmmat[abs(iq)/2-1][(abs(inq)-1)/2];
+   	    if(abs(outq)%2==0) ckm *= conj(ckmmat[abs(outq)/2-1][(abs(ia)-1)/2]);
+   	    else               ckm *= conj(ckmmat[abs(ia)/2-1][(abs(outq)-1)/2]);
+   	  }
+   	  else {
+   	    if(abs(inq)%2==0)  ckm *= ckmmat[abs(inq)/2-1][(abs(ia)-1)/2];
+   	    else               ckm *= ckmmat[abs(ia)/2-1][(abs(inq)-1)/2];
+   	    if(abs(outq)%2==0) ckm *= conj(ckmmat[abs(outq)/2-1][(abs(iq)-1)/2]);
+   	    else               ckm *= conj(ckmmat[abs(iq)/2-1][(abs(outq)-1)/2]);
+   	  }
+   	  if(abs(inq)==5) ckm*=_a2b;
+   	  else            ckm*=_a2c;
+   	}
+   	if((abs(inq)%2==0&&inq<0)||(abs(inq)%2!=0&&inq>0)){ckm=conj(ckm);}
+   	tCKM.push_back(ckm);
       }
       // special if the particles are idential add additional modes and 
       // identical particle factors
-      if(particles[ix][1]->id()==particles[ix][2]->id()&&particles[ix].size()==3) {
-	isize=ttcurr[0].size();
-	for(iy=0;iy<isize;++iy) {
-	  ttcurr[0].push_back(ttcurr[0][iy]);ttcurr[1].push_back(ttcurr[1][iy]);
-	  ttform[0].push_back(ttform[0][iy]);ttform[1].push_back(ttform[1][iy]);
-	  if(tformpart[iy]==0){tformpart.push_back(1);}
-	  else{tformpart.push_back(0);}
-	  tCKM[iy]*=ort;tCKM.push_back(tCKM[iy]);
-	}
+      if(outgoing[ix][0]->id()==outgoing[ix][1]->id()&&outgoing[ix].size()==2) {
+  	unsigned int isize=ttcurr[0].size();
+   	for(unsigned int iy=0;iy<isize;++iy) {
+  	  ttcurr[0].push_back(ttcurr[0][iy]);ttcurr[1].push_back(ttcurr[1][iy]);
+  	  ttform[0].push_back(ttform[0][iy]);ttform[1].push_back(ttform[1][iy]);
+  	  if(tformpart[iy]==0){tformpart.push_back(1);}
+  	  else{tformpart.push_back(0);}
+  	  tCKM[iy]*=ort;tCKM.push_back(tCKM[iy]);
+  	}
       }
       // add the parameters for the mode to the list
       _currentmapA.push_back(ttcurr[0]);_currentmapB.push_back(ttcurr[1]);
       _formmapA.push_back(ttform[0]);_formmapB.push_back(ttform[1]);
       _formpart.push_back(tformpart);
       _CKMfact.push_back(tCKM);
       // add the mode to the list
-      if(_wgtmax.size()>numberModes()){maxweight=_wgtmax[numberModes()];}
-      else{maxweight=0.;}
-      // the weights for the channel
-      if(_wgtloc.size()>numberModes()&&
-	 _wgtloc[numberModes()]+mode->numberChannels()<=_weights.size()) {
-	start=_weights.begin()+_wgtloc[numberModes()];
-	end  = start+mode->numberChannels();
-	channelwgts=vector<double>(start,end);
-      }
-      else {
-	channelwgts.resize(mode->numberChannels(),1./(mode->numberChannels()));
-      }
-      // don't need channels for two body decays
-      if(particles[ix].size()==3) {
-	channelwgts.clear();
-	mode=new_ptr(DecayPhaseSpaceMode(particles[ix],this));
-      }
-      addMode(mode,maxweight,channelwgts);
-      // resize the duplicate modes to remove them
-      for(iy=0;iy<modeloc.size();++iy) particles[modeloc[iy]] = tPDVector();
-      break;
+      double maxweight(0.);
+      if(_wgtmax.size()>numberModes()) maxweight=_wgtmax[numberModes()];
+      // the weights for the channels
+      vector<double> channelwgts;
+     if(_wgtloc.size()>numberModes()&&
+ 	 _wgtloc[numberModes()]+mode->channels().size()<=_weights.size()) {
+       vector<double>::iterator start=_weights.begin()+_wgtloc[numberModes()];
+       vector<double>::iterator end  = start+mode->channels().size();
+ 	channelwgts=vector<double>(start,end);
+     }
+     else {
+ 	channelwgts.resize(mode->channels().size(),1./(mode->channels().size()));
+     }
+     // don't need channels for two body decays
+     if(outgoing[ix].size()==2) {
+       channelwgts.clear();
+       mode = new_ptr(PhaseSpaceMode(incoming[ix],outgoing[ix],maxweight));
+     }
+     else {
+       mode->maxWeight(maxweight);
+       mode->setWeights(channelwgts);
+     }
+     addMode(mode);
+     // resize the duplicate modes to remove them
+     for(unsigned int iy=0;iy<modeloc.size();++iy) outgoing[modeloc[iy]] = tPDVector();
+     break;
     }
   }
 }
 
 void ScalarMesonFactorizedDecayer::doinitrun() {
   unsigned int ix,iy;
   for(ix=0;ix<_current.size();++ix) _current[ix]->initrun();
   for(ix=0;ix<_form.size();++ix)    _form[ix]->initrun();
-  DecayIntegrator::doinitrun();
+  DecayIntegrator2::doinitrun();
   if(initialize()) {
     _weights.clear();
     _wgtloc.clear();
     _wgtmax.clear();
     for(ix=0;ix<numberModes();++ix) {
       _wgtmax.push_back(mode(ix)->maxWeight());
       _wgtloc.push_back(_weights.size());
-      for(iy=0;iy<mode(ix)->numberChannels();++iy) {
-	_weights.push_back(mode(ix)->channelWeight(iy));
+      for(iy=0;iy<mode(ix)->channels().size();++iy) {
+	_weights.push_back(mode(ix)->channels()[iy].weight());
       }
     }
   }
 }
 
 bool ScalarMesonFactorizedDecayer::accept(tcPDPtr parent,
 					  const tPDVector & children) const {
   // N.B. this is a necessary but not sufficient test
   bool allowed(false),dummy;
   // find the ids of the particles
   tPDVector::const_iterator pit  = children.begin();
   tPDVector::const_iterator pend = children.end();
   vector<int> ids,idcurr;
   int id(parent->id());
   for( ; pit!=pend;++pit) ids.push_back((**pit).id());
   // loop over the possible particles in the formfactor
   unsigned int ipart(0),iform,icurr,ix;
   do {
     idcurr.clear();
     for(ix=0;ix<ids.size();++ix){if(ix!=ipart){idcurr.push_back(ids[ix]);}}
     iform=0;
     do {
       // check if possible from the form factor
       if(_form[iform]->formFactorNumber(id,ids[ipart],dummy)>=0) {
 	// check if possible from the current
 	icurr=0;
 	do {
 	  allowed=_current[icurr]->accept(idcurr);
 	  ++icurr;
 	}
 	while(!allowed&&icurr<_current.size());
       }
       ++iform;
     }
     while(!allowed&&iform<_form.size());
     ++ipart;
   }
   while(!allowed&&ipart<ids.size());
   return allowed;
 }
 
 int ScalarMesonFactorizedDecayer::modeNumber(bool & cc,tcPDPtr parent,
 					     const tPDVector & children) const {
   int imode(-1);
   // id's of the particles and CC
   // of the parent
   int id0(parent->id()),id0bar(id0);
-  if(parent->CC()){id0bar=parent->CC()->id();}
+  if(parent->CC())  id0bar = parent->CC()->id();
   // of the products
   vector<int> ids,idbars;
   tPDVector::const_iterator pit  = children.begin();
   tPDVector::const_iterator pend = children.end();
   for( ;pit!=pend;++pit) {
     ids.push_back((**pit).id());
     if((**pit).CC()) idbars.push_back((**pit).CC()->id());
     else             idbars.push_back(ids.back());
   }
   // loop over the modes
-  vector<bool> done(ids.size(),false);
-  unsigned int nfound,ix,iy,iz;
-  int idtemp;
-  bool found;
   cc=false;
-  ix=0;
+  unsigned int ix=0;
   do {
     // particle mode
-    if(id0==mode(ix)->externalParticles(0)->id()&&
-       ids.size()+1==mode(ix)->numberofParticles()) {
-      nfound=0;
-      for(iy=0;iy<ids.size();++iy){done[iy]=false;}
-      for(iy=0;iy<ids.size();++iy) {
-	idtemp=mode(ix)->externalParticles(iy+1)->id();
-	iz=0;found=false;
-	do{if(idtemp==ids[iz]&&!done[iz]){done[iz]=true;found=true;}++iz;}
+    if(id0==mode(ix)->incoming().first->id()&&
+       ids.size()==mode(ix)->outgoing().size()) {
+      unsigned int nfound=0;
+      vector<bool> done(ids.size(),false);
+      for(unsigned int iy=0;iy<ids.size();++iy) {
+   	int idtemp = mode(ix)->outgoing()[iy]->id();
+	unsigned int iz=0;
+	bool found=false;
+	do{
+	  if(idtemp==ids[iz]&&!done[iz]) {
+	    done[iz]=true;
+	    found=true;
+	  }
+	  ++iz;
+	}
 	while(iz<ids.size()&&!found);
-	if(found){++nfound;}
+	if(found) ++nfound;
       }
-      if(nfound==ids.size()){cc=false;imode=ix;}
+      if(nfound==ids.size()) {
+	cc=false;
+	imode=ix;
+      }
     }
     // CC mode
-    if(id0bar==mode(ix)->externalParticles(0)->id()&&
-       ids.size()+1==mode(ix)->numberofParticles()) {
-      nfound=0;
-      for(iy=0;iy<idbars.size();++iy) done[iy]=false;
-      for(iy=0;iy<idbars.size();++iy) {
-	idtemp=mode(ix)->externalParticles(iy+1)->id();
-	iz=0;found=false;
+    if(id0bar==mode(ix)->incoming().first->id()&&
+       ids.size()==mode(ix)->outgoing().size()) {
+      unsigned int nfound=0;
+      vector<bool> done(ids.size(),false);
+      for(unsigned int iy=0;iy<idbars.size();++iy) {
+  	int idtemp=mode(ix)->outgoing()[iy]->id();
+	unsigned int iz=0;
+	bool found=false;
 	do {
 	  if(idtemp==idbars[iz]&&!done[iz]) {
 	    done[iz]=true;
 	    found=true;
 	  }
 	  ++iz;
 	}
 	while(iz<idbars.size()&&!found);
 	if(found) ++nfound;
       }
       if(nfound==idbars.size()) {
 	cc=true;
 	imode=ix;
       }
     }
     ++ix;
   }
   while(imode<0&&ix<numberModes());
   if(imode<0) {
     string mode = parent->PDGName() + "->";
     for(unsigned int ix=0;ix<children.size();++ix) 
       mode += children[ix]->PDGName() +",";
-    throw DecayIntegratorError() << "Unable to find the mode " << mode << " in " 
-				 << name() 
-				 << " ScalarMesonFactorizedDecayer::decay()" 
-				 << Exception::abortnow;
+    throw DecayIntegrator2Error() << "Unable to find the mode " << mode << " in " 
+				  << name() 
+				  << " ScalarMesonFactorizedDecayer::decay()" 
+				  << Exception::abortnow;
   }
   return imode;
 }
 
 
 void ScalarMesonFactorizedDecayer::persistentOutput(PersistentOStream & os) const {
   os << _current << _form << _ckm 
      << _a1b << _a2b << _a1c << _a2c 
      << _currentmapA << _currentmapB 
      << _formmapA << _formmapB << _formpart << _wgtloc 
      << _wgtmax << _weights << _CKMfact ;
 }
 
 void ScalarMesonFactorizedDecayer::persistentInput(PersistentIStream & is, int) {
   is >> _current >> _form >> _ckm 
      >> _a1b >> _a2b >> _a1c >> _a2c 
      >> _currentmapA >> _currentmapB 
      >> _formmapA >> _formmapB >> _formpart >> _wgtloc
      >> _wgtmax >> _weights >> _CKMfact;
 }
 
 // The following static variable is needed for the type
 // description system in ThePEG.
-DescribeClass<ScalarMesonFactorizedDecayer,DecayIntegrator>
+DescribeClass<ScalarMesonFactorizedDecayer,DecayIntegrator2>
 describeHerwigScalarMesonFactorizedDecayer("Herwig::ScalarMesonFactorizedDecayer", "HwSMDecay.so");
 
 void ScalarMesonFactorizedDecayer::Init() {
 
   static ClassDocumentation<ScalarMesonFactorizedDecayer> documentation
     ("The ScalarMesonFactorizedDecayer class is designed for the weak decay of"
      " scalar mesons using the factorization approximation.");
 
-  static RefVector<ScalarMesonFactorizedDecayer,WeakDecayCurrent> interfaceCurrents
+  static RefVector<ScalarMesonFactorizedDecayer,WeakCurrent> interfaceCurrents
     ("Currents",
      "A vector of references to the currents",
      &ScalarMesonFactorizedDecayer::_current, -1, false, false, true, false, false);
 
   static RefVector<ScalarMesonFactorizedDecayer,ScalarFormFactor> interfaceFormFactors
     ("FormFactors",
      "A vector of references to the form-factors",
      &ScalarMesonFactorizedDecayer::_form, -1, false, false, true, false, false);
 
   static Parameter<ScalarMesonFactorizedDecayer,double> interfacea1Bottom
     ("a1Bottom",
      "The factorization paramter a_1 for decays of bottom baryons",
      &ScalarMesonFactorizedDecayer::_a1b, 1.1, -10.0, 10.0,
      false, false, true);
 
   static Parameter<ScalarMesonFactorizedDecayer,double> interfacea2Bottom
     ("a2Bottom",
      "The factorization paramter a_2 for decays of bottom baryons",
      &ScalarMesonFactorizedDecayer::_a2b, -0.24, -10.0, 10.0,
      false, false, true);
 
   static Parameter<ScalarMesonFactorizedDecayer,double> interfacea1Charm
     ("a1Charm",
      "The factorization paramter a_1 for decays of charm baryons",
      &ScalarMesonFactorizedDecayer::_a1c, 1.3, -10.0, 10.0,
      false, false, true);
 
   static Parameter<ScalarMesonFactorizedDecayer,double> interfacea2Charm
     ("a2Charm",
      "The factorization paramter a_2 for decays of charm baryons",
      &ScalarMesonFactorizedDecayer::_a2c, -0.55, -10.0, 10.0,
      false, false, true);
 
   static ParVector<ScalarMesonFactorizedDecayer,int> interfaceWeightLocation
     ("WeightLocation",
      "The locations of the weights for a given channel in the vector",
      &ScalarMesonFactorizedDecayer::_wgtloc,
      0, 0, 0, 0, 10000, false, false, true);
 
   static ParVector<ScalarMesonFactorizedDecayer,double> interfaceWeightMax
     ("MaximumWeight",
      "The maximum weight for a given channel.",
      &ScalarMesonFactorizedDecayer::_wgtmax,
      0, 0, 0, 0., 100., false, false, true);
 
   static ParVector<ScalarMesonFactorizedDecayer,double> interfaceWeights
     ("Weights",
      "The weights for the integration.",
      &ScalarMesonFactorizedDecayer::_weights,
      0, 0, 0, 0., 1., false, false, true);
 }
  
-double ScalarMesonFactorizedDecayer::me2(const int ichan,
-					 const Particle & part,
-					 const ParticleVector & decay,
+void ScalarMesonFactorizedDecayer::
+constructSpinInfo(const Particle & part, ParticleVector decay) const {
+  // set up the spin information for the decay products
+  ScalarWaveFunction::constructSpinInfo(const_ptr_cast<tPPtr>(&part),
+  					incoming,true);
+  // get the wavefunctions of the decay products
+  for(unsigned int ix=0;ix<decay.size();++ix) {
+    switch(decay[ix]->dataPtr()->iSpin()) {
+    case PDT::Spin0:
+      ScalarWaveFunction::constructSpinInfo(decay[ix],outgoing,true);
+      break;
+    case PDT::Spin1:
+      VectorWaveFunction::constructSpinInfo(_vectors[ix],decay[ix],outgoing,
+					    true,false);
+      break;
+    case PDT::Spin2:
+      TensorWaveFunction::constructSpinInfo(_tensors[ix],decay[ix],outgoing,
+					    true,false);
+      break;
+    default:
+      assert(false);
+    }
+  }
+}
+
+double ScalarMesonFactorizedDecayer::me2(const int ichan, const Particle & part,
+					 const tPDVector & outgoing,
+					 const vector<Lorentz5Momentum> & momenta,
 					 MEOption meopt) const {
   if(!ME()) {
     // create the matrix element
     vector<PDT::Spin> spin;
-    for(unsigned int ix=0;ix<decay.size();++ix)
-      spin.push_back(decay[ix]->dataPtr()->iSpin());
+    for(unsigned int ix=0;ix<outgoing.size();++ix)
+      spin.push_back(outgoing[ix]->iSpin());
     ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,spin)));
   }
   // initialisation
   if(meopt==Initialize) {
     ScalarWaveFunction::
       calculateWaveFunctions(_rho,const_ptr_cast<tPPtr>(&part),incoming);
-    _vectors.resize(decay.size());
-    _tensors.resize(decay.size());
-  }
-  if(meopt==Terminate) {
-    // set up the spin information for the decay products
-    ScalarWaveFunction::constructSpinInfo(const_ptr_cast<tPPtr>(&part),
-					  incoming,true);
-    // get the wavefunctions of the decay products
-    for(unsigned int ix=0;ix<decay.size();++ix) {
-      switch(decay[ix]->dataPtr()->iSpin()) {
-      case 1:
-	ScalarWaveFunction::constructSpinInfo(decay[ix],outgoing,true);
-	break;
-      case 3:
-	VectorWaveFunction::constructSpinInfo(_vectors[ix],decay[ix],outgoing,
-					      true,false);
-	break;
-      case 5:
-	TensorWaveFunction::constructSpinInfo(_tensors[ix],decay[ix],outgoing,
-					      true,false);
-	break;
-      default:
-	assert(false);
-      }
-    }
-    return 0.;
+    _vectors.resize(outgoing.size());
+    _tensors.resize(outgoing.size());
   }
   // get the wavefunctions of the decay products
-  for(unsigned int ix=0;ix<decay.size();++ix) {
-    switch(decay[ix]->dataPtr()->iSpin()) {
-    case 1:
+  for(unsigned int ix=0;ix<outgoing.size();++ix) {
+    switch(outgoing[ix]->iSpin()) {
+    case PDT::Spin0:
       break;
-    case 3:
-      VectorWaveFunction::
-	calculateWaveFunctions(_vectors[ix],decay[ix],outgoing,false);
+    case PDT::Spin1:
+      _vectors[ix].resize(3);
+      for(unsigned int ihel=0;ihel<3;++ihel)
+	_vectors[ix][ihel] = HelicityFunctions::polarizationVector(-momenta[ix],ihel,
+								   Helicity::outgoing);
       break;
-    case 5:
-      TensorWaveFunction::
-	calculateWaveFunctions(_tensors[ix],decay[ix],outgoing,false);
-      break;
+    case PDT::Spin2:
+      {
+	TensorWaveFunction twave(momenta[ix],outgoing[ix],Helicity::outgoing);
+	_tensors[ix].resize(5);
+	for(unsigned int ihel=0;ihel<5;++ihel) {
+	  twave.reset(ihel);
+	  _tensors[ix][ihel] = twave.wave();
+	}
+      }
+    break;
     default:
       assert(false);
     }
   }
   ME()->zero();
   // find the mode
-  unsigned int mode(imode()),chel,fhel;
-  int id0(part.id()),id1;
+  unsigned int mode(imode());
+  int id0(part.id());
   Complex ii(0.,1.);
-  vector<unsigned int> ihel(decay.size());
+  vector<unsigned int> ihel(outgoing.size());
   // loop over the different diagrams
-  vector<LorentzPolarizationVectorE> form;
-  Complex fp,f0,A0,A1,A2,A3,V,k;
-  complex<InvEnergy2> h,bp,bm;
-  // complex<Energy2> dot;
-  Lorentz5Momentum q,sum; 
-  Energy2 q2;
-  Energy MP(part.mass()),MV,msum,mdiff,scale;
-  LorentzPolarizationVectorE dotv;
+  Energy MP(part.mass()),scale;
   double pre;
-  ParticleVector cpart;
   for(unsigned int iy=0;iy<_CKMfact[mode].size();++iy) {
-    MV=decay[_formpart[mode][iy]]->mass();
-    id1=decay[_formpart[mode][iy]]->id();
+    Energy MV = momenta[_formpart[mode][iy]].mass();
+    int id1   = outgoing[_formpart[mode][iy]]->id();
     int id0t,id1t;
     _form[_formmapA[mode][iy]]->particleID(_formmapB[mode][iy],id0t,id1t);
     bool cc(id0t!=id0);
     // calculate the form-factor part
-    form.clear();
-    q   = part.momentum()-decay[_formpart[mode][iy]]->momentum();  q.rescaleMass();
-    sum = part.momentum()+decay[_formpart[mode][iy]]->momentum();sum.rescaleMass();
-    q2=q.mass2();
-    if(decay[_formpart[mode][iy]]->dataPtr()->iSpin()==1) {
+    vector<LorentzPolarizationVectorE> form;
+    Lorentz5Momentum q   = part.momentum()-momenta[_formpart[mode][iy]];
+    q.rescaleMass();
+    Lorentz5Momentum sum = part.momentum()+momenta[_formpart[mode][iy]];
+    sum.rescaleMass();
+    Energy2 q2=q.mass2();
+    if(outgoing[_formpart[mode][iy]]->iSpin()==1) {
+      Complex fp,f0;
       _form[_formmapA[mode][iy]]->ScalarScalarFormFactor(q2,_formmapB[mode][iy],
-							 id0,id1,MP,MV,f0,fp);
+   							 id0,id1,MP,MV,f0,fp);
       pre=(MP*MP-MV*MV)/q2;
       form.push_back(fp*sum+pre*(f0-fp)*q);
     }
-    else if(decay[_formpart[mode][iy]]->dataPtr()->iSpin()==3) {
-      msum=MP+MV;mdiff=MP-MV;
-      _form[_formmapA[mode][iy]]->ScalarVectorFormFactor(q2,_formmapB[mode][iy],id0,
-							 id1,MP,MV,A0,A1,A2,V);
-      if(cc){V=-V;}
-      A3 = 0.5/MV*(msum*A1-mdiff*A2);
-      // compute the hadron currents
-      for(unsigned int ix=0;ix<3;++ix) {
-	// dot product
-	complex<Energy> dot = _vectors[_formpart[mode][iy]][ix]*part.momentum();
-	// current
-	form.push_back(-ii*msum*A1*_vectors[_formpart[mode][iy]][ix]
-		       +ii*A2/msum*dot*sum
-		       +2.*ii*MV/q2*(A3-A0)*dot*q
-		       +2.*V/msum*epsilon(_vectors[_formpart[mode][iy]][ix],
-					  part.momentum(),
-					  decay[_formpart[mode][iy]]->momentum())); 
-      }
+    else if(outgoing[_formpart[mode][iy]]->iSpin()==3) {
+      Energy msum  = MP+MV;
+      Energy mdiff = MP-MV;
+      Complex A0,A1,A2,V;
+       _form[_formmapA[mode][iy]]->ScalarVectorFormFactor(q2,_formmapB[mode][iy],id0,
+							  id1,MP,MV,A0,A1,A2,V);
+       if(cc) V=-V;
+       Complex A3 = 0.5/MV*(msum*A1-mdiff*A2);
+       // compute the hadron currents
+       for(unsigned int ix=0;ix<3;++ix) {
+	 // dot product
+	 complex<Energy> dot = _vectors[_formpart[mode][iy]][ix]*part.momentum();
+	 // current
+	 form.push_back(-ii*msum*A1*_vectors[_formpart[mode][iy]][ix]
+			+ii*A2/msum*dot*sum
+			+2.*ii*MV/q2*(A3-A0)*dot*q
+			+2.*V/msum*epsilon(_vectors[_formpart[mode][iy]][ix],
+					   part.momentum(),
+					   momenta[_formpart[mode][iy]])); 
+       }
     }
-    else if(decay[_formpart[mode][iy]]->dataPtr()->iSpin()==5) {
+    else if(outgoing[_formpart[mode][iy]]->iSpin()==5) {
+      Complex k;
+      complex<InvEnergy2> h,bp,bm;
       _form[_formmapA[mode][iy]]->ScalarTensorFormFactor(q2,_formmapB[mode][iy],
-							 id0,id1,MP,MV,h,k,bp,bm);
-      if(cc){h=-h;}
+  							 id0,id1,MP,MV,h,k,bp,bm);
+      if(cc) h=-h;
       // compute the hadron currents
       for(unsigned int ix=0;ix<5;++ix) {
-	dotv = _tensors[_formpart[mode][iy]][ix]*part.momentum();
-	complex<Energy2> dot = dotv*part.momentum();
-	form.push_back(ii*h*epsilon(dotv,sum,q)-k*dotv
-		       -bp*dot*sum-bm*dot*q);
+	LorentzPolarizationVectorE dotv =
+	  _tensors[_formpart[mode][iy]][ix]*part.momentum();
+   	complex<Energy2> dot = dotv*part.momentum();
+   	form.push_back(ii*h*epsilon(dotv,sum,q)-k*dotv
+   		       -bp*dot*sum-bm*dot*q);
       }
     }
     // find the particles for the current
-    cpart.clear();
-    for(unsigned int ix=0;ix<decay.size();++ix)
-      {if(ix!=_formpart[mode][iy]){cpart.push_back(decay[ix]);}}
-    unsigned int ix=decay.size();
-    vector<unsigned int> constants(decay.size()+1),ihel(decay.size()+1);
+    tPDVector cpart;
+    vector<Lorentz5Momentum> cmom;
+    for(unsigned int ix=0;ix<outgoing.size();++ix) {
+      if(ix!=_formpart[mode][iy]) {
+	cpart.push_back(outgoing[ix]);
+	cmom .push_back(momenta[ix]);
+      }
+    }
+    unsigned int ix=outgoing.size();
+    vector<unsigned int> constants(outgoing.size()+1),ihel(outgoing.size()+1);
     int itemp(1);
     do {
       --ix;
       if(ix!=_formpart[mode][iy]) {
-	itemp*=decay[ix]->data().iSpin();
+	itemp*=outgoing[ix]->iSpin();
 	constants[ix]=itemp;
       }
     }
     while(ix!=0);
-    constants[decay.size()]=1;
-    if(_formpart[mode][iy]!=decay.size())
+    constants[outgoing.size()]=1;
+    if(_formpart[mode][iy]!=outgoing.size())
       constants[_formpart[mode][iy]]=constants[_formpart[mode][iy]+1];
     // calculate the current
     vector<LorentzPolarizationVectorE>
       curr=_current[_currentmapA[mode][iy]]->
-      current(_currentmapB[mode][iy],ichan,scale,cpart,meopt);
+      current(tcPDPtr(),IsoSpin::IUnknown,IsoSpin::I3Unknown,
+	      _currentmapB[mode][iy],ichan,scale,cpart,cmom,meopt);
     pre = (pow(part.mass()/scale,int(cpart.size()-2)));
     // loop over the helicities to calculate the matrix element
     ihel[0]=0;
-    for(chel=0;chel<curr.size();++chel) {
-      for(ix=decay.size();ix>0;--ix) {
+    for(unsigned int chel=0;chel<curr.size();++chel) {
+      for(ix=outgoing.size();ix>0;--ix) {
 	if(ix!=_formpart[mode][iy]+1)
 	  ihel[ix]=(chel%constants[ix-1])/constants[ix];
       }
-      for(fhel=0;fhel<form.size();++fhel) {
+      for(unsigned int fhel=0;fhel<form.size();++fhel) {
 	ihel[_formpart[mode][iy]+1]=fhel;
 	(*ME())(ihel) +=pre*_CKMfact[mode][iy]*
 	  form[fhel].dot(curr[chel])*SM().fermiConstant();
       }
     }
   }
   // perform the contraction
   return 0.5*(ME()->contract(_rho)).real();
 }
   
 void ScalarMesonFactorizedDecayer::findModes(unsigned int imode,
-					     vector<tPDVector> & particles,
+					     tPDVector & incoming,
+					     vector<tPDVector> & outgoing,
 					     vector<unsigned int> & loc,
 					     vector<bool> & cc) {
-  unsigned int ix,iy,nfound,iz;
-  // resize the vectors
-  loc.clear();cc.clear();
   // get the id's for the mode
-  vector<int> id,idbar;
-  int idtemp; bool found;
-  for(ix=0;ix<particles[imode].size();++ix) {
-    id.push_back(particles[imode][ix]->id());
-    if(particles[imode][ix]->CC()) idbar.push_back(particles[imode][ix]->CC()->id());
-    else                           idbar.push_back(id[ix]);
+  // incoming
+  int id_in    = incoming[imode]->id();
+  int idbar_in = incoming[imode]->CC() ?
+    incoming[imode]->CC()->id() : incoming[imode]->id();
+  // outgoing
+  vector<int> id_out,idbar_out;
+  for(unsigned int ix=0;ix<outgoing[imode].size();++ix) {
+    id_out.push_back(outgoing[imode][ix]->id());
+    if(outgoing[imode][ix]->CC())
+      idbar_out.push_back(outgoing[imode][ix]->CC()->id());
+    else
+      idbar_out.push_back(id_out[ix]);
   }
-  vector<bool> done(id.size(),false);
   // loop over the modes
-  for(ix=0;ix<particles.size();++ix) {
-    if(ix==imode||particles[ix].empty()) continue;
-    assert(!particles[ix].empty());
-    assert(particles[ix][0]);
+  for(unsigned int ix=0;ix<outgoing.size();++ix) {
+    if(ix==imode||outgoing[ix].empty()) continue;
+    assert(!outgoing[ix].empty());
+    assert(incoming[ix]);
     // the particle mode
-    if(particles[ix][0]->id()==id[0]&&particles[ix].size()==id.size()) {
-      nfound=1;
-      for(iy=0;iy<id.size();++iy){done[iy]=false;}
-      for(iy=1;iy<id.size();++iy) {
-	idtemp=particles[ix][iy]->id();
-	iz=1;
-	found=false;
-	do {
-	  if(idtemp==id[iz]&&!done[iz]) {
-	    done[iz]=true;
-	    found=true;
-	  }
-	  ++iz;
-	}
-	while(iz<id.size()&&!found);
-	if(found) ++nfound;
+    if(incoming[ix]->id()==id_in&&outgoing[ix].size()==id_out.size()) {
+      vector<bool> done(id_out.size(),false);
+      unsigned int nfound = 0;
+      for(unsigned int iy=0;iy<id_out.size();++iy) {
+	int idtemp=outgoing[ix][iy]->id();
+     	unsigned int iz(0);
+     	bool found=false;
+    	do {
+	  if(idtemp==id_out[iz]&&!done[iz]) {
+     	    done[iz]=true;
+     	    found=true;
+    	  }
+    	  ++iz;
+    	}
+     	while(iz<id_out.size()&&!found);
+     	if(found) ++nfound;
+	if(nfound==id_out.size()) {
+	  cc.push_back(false);
+	  loc.push_back(ix);
+        }
       }
-      if(nfound==id.size()) {
+    }
+    // the charge conjugate mode
+    if(incoming[ix]->id()==idbar_in&&outgoing[ix].size()==idbar_out.size()) {
+      vector<bool> done(id_out.size(),false);
+      unsigned int nfound = 0;
+      for(unsigned int iy=0;iy<idbar_out.size();++iy) {
+    	int idtemp=outgoing[ix][iy]->id();
+	unsigned int iz(0);
+   	bool found=false;
+   	do {
+     	  if(idtemp==idbar_out[iz]&&!done[iz]) {
+     	    done[iz]=true;
+     	    found=true;
+     	  }
+     	  ++iz;
+     	}
+     	while(iz<idbar_out.size()&&!found);
+    	if(found) ++nfound;
+      }
+      if(nfound==idbar_out.size()) {
 	cc.push_back(false);
 	loc.push_back(ix);
       }
     }
-    // the charge conjugate mode
-    if(particles[ix][0]->id()==idbar[0]&&particles[ix].size()==idbar.size()) {
-      nfound=1;
-      for(iy=0;iy<idbar.size();++iy) done[iy]=false;
-      for(iy=1;iy<idbar.size();++iy) {
-	idtemp=particles[ix][iy]->id();
-	iz=1;
-	found=false;
-	do {
-	  if(idtemp==idbar[iz]&&!done[iz]) {
-	    done[iz]=true;
-	    found=true;
-	  }
-	  ++iz;
-	}
-	while(iz<idbar.size()&&!found);
-	if(found){++nfound;}
-      }
-      if(nfound==idbar.size()){cc.push_back(false);loc.push_back(ix);}
-    }
   }
 }
 
 void ScalarMesonFactorizedDecayer::dataBaseOutput(ofstream & output,
 						  bool header) const {
   unsigned int ix;
   if(header) output << "update decayers set parameters=\"";
-  DecayIntegrator::dataBaseOutput(output,false);
+  DecayIntegrator2::dataBaseOutput(output,false);
   output << "newdef " << name() << ":a1Bottom "  << _a1b << "\n";
   output << "newdef " << name() << ":a2Bottom "  << _a2b << "\n";
   output << "newdef " << name() << ":a1Charm "   << _a1c << "\n";
   output << "newdef " << name() << ":a2Charm "   << _a2c << "\n";
   for(ix=0;ix<_current.size();++ix) {
     _current[ix]->dataBaseOutput(output,false,true);
     output << "insert " << name() << ":Currents " << ix << " " 
 	   << _current[ix]->name() << " \n";
   }
   for(ix=0;ix<_form.size();++ix) {
     _form[ix]->dataBaseOutput(output,false,true);
     output << "insert " << name() << ":FormFactors " << ix << " " 
 	   << _form[ix]->name() << " \n";
   }
   for(ix=0;ix<_wgtloc.size();++ix) {
     output << "insert " << name() << ":WeightLocation " << ix << " " 
 	   << _wgtloc[ix] << "\n";
   }
   for(ix=0;ix<_wgtmax.size();++ix) {
     output << "insert " << name() << ":MaximumWeight "  << ix << " " 
 	   << _wgtmax[ix] << "\n";
   }
   for(ix=0;ix<_weights.size();++ix) {
     output << "insert " << name() << ":Weights "        << ix << " " 
 	   << _weights[ix] << "\n";
   }
   if(header) output << "\n\" where BINARY ThePEGName=\"" 
 		    << fullName() << "\";" << endl;
 }
diff --git a/Decay/ScalarMeson/ScalarMesonFactorizedDecayer.h b/Decay/ScalarMeson/ScalarMesonFactorizedDecayer.h
--- a/Decay/ScalarMeson/ScalarMesonFactorizedDecayer.h
+++ b/Decay/ScalarMeson/ScalarMesonFactorizedDecayer.h
@@ -1,305 +1,314 @@
 // -*- C++ -*-
 //
 // ScalarMesonFactorizedDecayer.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_ScalarMesonFactorizedDecayer_H
 #define HERWIG_ScalarMesonFactorizedDecayer_H
 //
 // This is the declaration of the ScalarMesonFactorizedDecayer class.
 //
 
-#include "Herwig/Decay/DecayIntegrator.h"
-#include "Herwig/Decay/WeakCurrents/WeakDecayCurrent.h"
+#include "Herwig/Decay/DecayIntegrator2.h"
+#include "Herwig/Decay/WeakCurrents/WeakCurrent.h"
 #include "Herwig/Decay/FormFactors/ScalarFormFactor.h"
 #include "ThePEG/StandardModel/StandardModelBase.h"
 #include "ThePEG/Helicity/LorentzPolarizationVector.h"
 #include "Herwig/Decay/DecayPhaseSpaceMode.h"
 #include "Herwig/Models/StandardModel/StandardCKM.h"
 
 namespace Herwig {
 using namespace ThePEG;
 
 /** \ingroup Decay
  *
  * The <code>ScalarMesonFactorizedDecayer</code> class is a class which combines a 
- * WeakDecayCurrent and a ScalarFormFactor in the naive factorization approximation
+ * WeakCurrent and a ScalarFormFactor in the naive factorization approximation
  * to perform the non-leptonic weak decays of scalar mesons.
  *
- * @see DecayIntegrator
- * @see WeakDecayCurrent
+ * @see DecayIntegrator2
+ * @see WeakCurrent
  * @see ScalarFormFactor
  *
  */
 
-class ScalarMesonFactorizedDecayer: public DecayIntegrator {
+class ScalarMesonFactorizedDecayer: public DecayIntegrator2 {
 
 public:
 
   /**
    * The default constructor.
    */
   ScalarMesonFactorizedDecayer();
 
 public:
 
-  /** @name Virtual functions required by the Decayer and DecayIntegrator classes. */
+  /** @name Virtual functions required by the Decayer and DecayIntegrator2 classes. */
   //@{
   /**
    * 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;
   
   /**
    * Check if this decayer can perfom the decay for a particular mode.
    * Uses the modeNumber member but can be overridden
    * @param parent The decaying particle
    * @param children The decay products
    */
   virtual bool accept(tcPDPtr parent, const tPDVector & children) const;
 
   /**
    * Return the matrix element squared for a given mode and phase-space channel.
-   * This function combines the current and the form factor to give the matrix
-   * element.
    * @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 outgoing The particles produced in the decay
+   * @param momenta  The momenta of 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;
+  double me2(const int ichan,const Particle & part,
+	     const tPDVector & outgoing,
+	     const vector<Lorentz5Momentum> & momenta,
+	     MEOption meopt) const;
+
+  /**
+   *   Construct the SpinInfos for the particles produced in the decay
+   */
+  virtual void constructSpinInfo(const Particle & part,
+				 ParticleVector outgoing) const;
   //@}
 
   /**
    * Output the setup information for the particle database
    * @param os The stream to output the information to
    * @param header Whether or not to output the information for MySQL
    */
   virtual void dataBaseOutput(ofstream & os,bool header) const;
 
 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 {return new_ptr(*this);}
 
   /** 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 {return new_ptr(*this);}
   //@}
 
 protected:
 
   /** @name Standard Interfaced functions. */
   //@{
   /**
    * Initialize this object after the setup phase before saving and
    * 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();
 
   /**
    * Rebind pointer to other Interfaced objects. Called in the setup phase
    * after all objects used in an EventGenerator has been cloned so that
    * the pointers will refer to the cloned objects afterwards.
    * @param trans a TranslationMap relating the original objects to
    * their respective clones.
    * @throws RebindException if no cloned object was found for a given
    * pointer.
    */
   virtual void rebind(const TranslationMap & trans)
    ;
 
   /**
    * Return a vector of all pointers to Interfaced objects used in this
    * object.
    * @return a vector of pointers.
    */
   virtual IVector getReferences();
   //@}
 
 
 private:
 
   /**
    * Find duplicate modes in the list of particles
    * @param imode The mode we are studying
-   * @param particles The external particles for the different modes
+   * @param incoming The incoming particles for the different modes
+   * @param outgoing The outgoing particles for the different modes
    * @param loc The location of the duplicate mode
    * @param cc  If the duplicate is the charge conjugate
    */
-  void findModes(unsigned int imode,vector<tPDVector> & particles,
+  void findModes(unsigned int imode, tPDVector & incoming,
+		 vector<tPDVector> & outgoing,
 		 vector<unsigned int> & loc,vector<bool> & cc);
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   ScalarMesonFactorizedDecayer & operator=(const ScalarMesonFactorizedDecayer &);
 
 private:
 
   /**
    *  The weak decay current
    */
-  vector<WeakDecayCurrentPtr> _current;
+  vector<WeakCurrentPtr> _current;
 
   /**
    * The baryon form factor
    */
   vector<ScalarFormFactorPtr> _form;
 
   /**
    *  The perturbative coefficients
    */
   //@{
   /**
    *  The perturbative \f$a_1\f$ coefficient for b decays.
    */
   double _a1b;
 
   /**
    *  The perturbative \f$a_2\f$ coefficient for b decays.
    */
   double _a2b;
 
   /**
    *  The perturbative \f$a_1\f$ coefficient for c decays.
    */
   double _a1c;
 
   /**
    *  The perturbative \f$a_2\f$ coefficient for c decays.
    */
   double _a2c;
   //@}
 
   /**
    * Mapping of the modes to the currents
    */
   //@{
   /**
    *  First map
    */
   vector<vector<unsigned int> > _currentmapA;
 
   /**
    *  Second map
    */
   vector<vector<unsigned int> > _currentmapB;
   //@}
 
   /**
    * Mapping of the modes to the form factors
    */
   //@{
   /**
    *  First map
    */
   vector<vector<unsigned int> > _formmapA;
 
   /**
    *  Second map
    */
   vector<vector<unsigned int> > _formmapB;
   //@}
   /**
    *  Outgoing particle from the form factor
    */
   vector<vector<unsigned int> > _formpart;
 
   /**
    * The CKM factors
    */
   vector<vector<Complex> > _CKMfact;
 
   /**
    * location of the weights
    */
   vector<int> _wgtloc;
 
   /**
    * the maximum weights
    */
   vector<double> _wgtmax;
 
   /**
    *  Weights for the different channels
    */
   vector<double> _weights;
 
   /**
    * Pointer to the CKM object.
    */
   Ptr<StandardCKM>::pointer _ckm;
 
   /**
    *  Spin density matrix
    */
   mutable RhoDMatrix _rho;
 
   /**
    *  Polarization vectors for the decay products
    */
   mutable vector<vector<Helicity::LorentzPolarizationVector> > _vectors;
 
   /**
    *  Polarization tensors for the decay products
    */
   mutable vector<vector<Helicity::LorentzTensor<double>    > > _tensors;
 
 };
 
 }
 
 #endif /* HERWIG_ScalarMesonFactorizedDecayer_H */