diff --git a/MatrixElement/Matchbox/Base/MatchboxMEBase.cc b/MatrixElement/Matchbox/Base/MatchboxMEBase.cc
--- a/MatrixElement/Matchbox/Base/MatchboxMEBase.cc
+++ b/MatrixElement/Matchbox/Base/MatchboxMEBase.cc
@@ -1,1658 +1,1663 @@
 // -*- C++ -*-
 //
 // MatchboxMEBase.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 MatchboxMEBase class.
 //
 
 #include "MatchboxMEBase.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 #include "ThePEG/PDF/PDF.h"
 #include "ThePEG/PDT/PDT.h"
 #include "ThePEG/StandardModel/StandardModelBase.h"
 #include "ThePEG/Cuts/Cuts.h"
 #include "ThePEG/Handlers/StdXCombGroup.h"
 #include "ThePEG/EventRecord/SubProcess.h"
 #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
 #include "Herwig/MatrixElement/Matchbox/Utility/DiagramDrawer.h"
 #include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h"
 #include "Herwig/MatrixElement/Matchbox/Base/MergerBase.h"
 #include "Herwig/API/RunDirectories.h"
 #include "Herwig/MatrixElement/ProductionMatrixElement.h"
 #include "Herwig/MatrixElement/HardVertex.h"
 
 #include <cctype>
 
 #include <iterator>
 using std::ostream_iterator;
 
 using namespace Herwig;
 
 MatchboxMEBase::MatchboxMEBase() 
   : MEBase(), 
     theOneLoop(false),
     theOneLoopNoBorn(false),
     theOneLoopNoLoops(false),
     theNoCorrelations(false),
     theHavePDFs(false,false), checkedPDFs(false) {}
 
 MatchboxMEBase::~MatchboxMEBase() {}
 
 Ptr<MatchboxFactory>::tptr MatchboxMEBase::factory() const {
   return MatchboxFactory::currentFactory();
 }
 
 Ptr<Tree2toNGenerator>::tptr MatchboxMEBase::diagramGenerator() const { return factory()->diagramGenerator(); }
 
 Ptr<ProcessData>::tptr MatchboxMEBase::processData() const { return factory()->processData(); }
 
 unsigned int MatchboxMEBase::getNLight() const { return factory()->nLight(); }
 
 vector<long> MatchboxMEBase::getNLightJetVec() const { return factory()->nLightJetVec(); }
 
 vector<long> MatchboxMEBase::getNHeavyJetVec() const { return factory()->nHeavyJetVec(); }
 
 vector<long> MatchboxMEBase::getNLightProtonVec() const { return factory()->nLightProtonVec(); }
 
 double MatchboxMEBase::factorizationScaleFactor() const { return factory()->factorizationScaleFactor(); }
 
 double MatchboxMEBase::renormalizationScaleFactor() const { return factory()->renormalizationScaleFactor(); }
 
 bool MatchboxMEBase::fixedCouplings() const { return factory()->fixedCouplings(); }
 
 bool MatchboxMEBase::fixedQEDCouplings() const { return factory()->fixedQEDCouplings(); }
 
 bool MatchboxMEBase::checkPoles() const { return factory()->checkPoles(); }
 
 bool MatchboxMEBase::verbose() const { return factory()->verbose(); }
 
 bool MatchboxMEBase::initVerbose() const { return factory()->initVerbose(); }
 
 void MatchboxMEBase::getDiagrams() const {
 
   if ( diagramGenerator() && processData() ) {
 
     vector<Ptr<Tree2toNDiagram>::ptr> diags;
 
     vector<Ptr<Tree2toNDiagram>::ptr>& res =
       processData()->diagramMap()[subProcess().legs];
     if ( res.empty() ) {
       res = diagramGenerator()->generate(subProcess().legs,orderInAlphaS(),orderInAlphaEW());
     }
     copy(res.begin(),res.end(),back_inserter(diags));
     processData()->fillMassGenerators(subProcess().legs);
 
     if ( diags.empty() )
       return;
 
     for (auto const & d :  diags )
       add(d);
     
     return;
 
   }
 
   throw Exception()
     << "MatchboxMEBase::getDiagrams() expects a Tree2toNGenerator and ProcessData object.\n"
     << "Please check your setup." << Exception::runerror;
 
 }
 
 Selector<MEBase::DiagramIndex> 
 MatchboxMEBase::diagrams(const DiagramVector & diags) const {
 
   if ( phasespace() ) {
     return phasespace()->selectDiagrams(diags);
   }
 
   throw Exception()
     << "MatchboxMEBase::diagrams() expects a MatchboxPhasespace object.\n"
     << "Please check your setup." << Exception::runerror;
   return Selector<MEBase::DiagramIndex>();
 
 }
 
 Selector<const ColourLines *>
 MatchboxMEBase::colourGeometries(tcDiagPtr diag) const {
 
   if ( matchboxAmplitude() ) {
     if ( matchboxAmplitude()->haveColourFlows() ) {
       if ( matchboxAmplitude()->treeAmplitudes() )
 	matchboxAmplitude()->prepareAmplitudes(this);
       return matchboxAmplitude()->colourGeometries(diag);
     }
   }
 
   Ptr<Tree2toNDiagram>::tcptr tdiag =
     dynamic_ptr_cast<Ptr<Tree2toNDiagram>::tcptr>(diag);
   assert(diag && processData());
 
   vector<ColourLines*>& flows = processData()->colourFlowMap()[tdiag];
 
   if ( flows.empty() ) {
 
     list<list<list<pair<int,bool> > > > cflows =
       ColourBasis::colourFlows(tdiag);
 
     for ( auto const & fit : cflows)
       flows.push_back(new ColourLines(ColourBasis::cfstring(fit)));
 
   }
 
   Selector<const ColourLines *> res;
   for ( auto const & f : flows ) res.insert(1.0,f);
 
   return res;
 
 }
 
 void MatchboxMEBase::constructVertex(tSubProPtr sub, const ColourLines* cl) {
 
   if ( !canFillRhoMatrix() || !factory()->spinCorrelations() )
     return;
 
   assert(matchboxAmplitude());
   assert(matchboxAmplitude()->colourBasis());
 
   // get the colour structure for the selected colour flow
   size_t cStructure = 
     matchboxAmplitude()->colourBasis()->tensorIdFromFlow(lastXComb().lastDiagram(),cl);
 
   // hard process for processing the spin info
   tPVector hard;
   hard.push_back(sub->incoming().first);
   hard.push_back(sub->incoming().second);
   
   vector<PDT::Spin> out;
   for ( auto const & p  : sub->outgoing() ) {
     out.push_back(p->data().iSpin());
     hard.push_back(p);
   }
 
   // calculate dummy wave functions to fill the spin info
   static vector<VectorWaveFunction> dummyPolarizations;
   static vector<SpinorWaveFunction> dummySpinors;
   static vector<SpinorBarWaveFunction> dummyBarSpinors;
   for ( size_t k = 0; k < hard.size(); ++k ) {
     if ( hard[k]->data().iSpin() == PDT::Spin1Half ) {
       if ( hard[k]->id() > 0 && k > 1 ) {
 	SpinorBarWaveFunction(dummyBarSpinors,hard[k],
 			      outgoing, true);
       } else if ( hard[k]->id() < 0 && k > 1 ) {
 	SpinorWaveFunction(dummySpinors,hard[k],
 			   outgoing, true);
       } else if ( hard[k]->id() > 0 && k < 2 ) {
 	SpinorWaveFunction(dummySpinors,hard[k],
 			   incoming, false);
       } else if ( hard[k]->id() < 0 && k < 2 ) {
 	SpinorBarWaveFunction(dummyBarSpinors,hard[k],
 			      incoming, false);
       }
     } 
     else if ( hard[k]->data().iSpin() == PDT::Spin1 ) {
       VectorWaveFunction(dummyPolarizations,hard[k],
 			 k > 1 ? outgoing : incoming,
 			 k > 1 ? true : false,
 			 hard[k]->data().hardProcessMass() == ZERO);
     }
     else if (hard[k]->data().iSpin() == PDT::Spin0 ) {
       ScalarWaveFunction(hard[k],k > 1 ? outgoing : incoming,
 			 k > 1 ? true : false);
     }
     else
       assert(false);
   }
 
   // fill the production matrix element
   ProductionMatrixElement pMe(mePartonData()[0]->iSpin(),
 			      mePartonData()[1]->iSpin(),
 			      out);
   for ( map<vector<int>,CVector>::const_iterator lamp = lastLargeNAmplitudes().begin();
 	lamp != lastLargeNAmplitudes().end(); ++lamp ) {
     vector<unsigned int> pMeHelicities
       = matchboxAmplitude()->physicalHelicities(lamp->first);
     pMe(pMeHelicities) = lamp->second[cStructure];
   }
 
   // set the spin information
   HardVertexPtr hardvertex = new_ptr(HardVertex());
   hardvertex->ME(pMe);
   if ( sub->incoming().first->spinInfo() )
     sub->incoming().first->spinInfo()->productionVertex(hardvertex);
   if ( sub->incoming().second->spinInfo() )
     sub->incoming().second->spinInfo()->productionVertex(hardvertex);
   for ( auto const & p : sub->outgoing() )
     if ( p->spinInfo() )
       p->spinInfo()->productionVertex(hardvertex);
   
 
 }
 
 unsigned int MatchboxMEBase::orderInAlphaS() const {
   return subProcess().orderInAlphaS;
 }
 
 unsigned int MatchboxMEBase::orderInAlphaEW() const {
   return subProcess().orderInAlphaEW;
 }
 
 void MatchboxMEBase::setXComb(tStdXCombPtr xc) {
 
   MEBase::setXComb(xc);
   lastMatchboxXComb(xc);
   if ( phasespace() )
     phasespace()->setXComb(xc);
   if ( scaleChoice() )
     scaleChoice()->setXComb(xc);
   if ( matchboxAmplitude() )
     matchboxAmplitude()->setXComb(xc);
   if (theMerger){
     theMerger->setME(this);
     theMerger->setXComb( xc );
   }
 
 }
 
 double MatchboxMEBase::generateIncomingPartons(const double* r1, const double* r2) {
   
   // shamelessly stolen from PartonExtractor.cc
 
   Energy2 shmax = lastCuts().sHatMax();
   Energy2 shmin = lastCuts().sHatMin();
   Energy2 sh = shmin*pow(shmax/shmin, *r1);
   double ymax = lastCuts().yHatMax();
   double ymin = lastCuts().yHatMin();
   double km = log(shmax/shmin);
   ymax = min(ymax, log(lastCuts().x1Max()*sqrt(lastS()/sh)));
   ymin = max(ymin, -log(lastCuts().x2Max()*sqrt(lastS()/sh)));
 
   double y = ymin + (*r2)*(ymax - ymin);
   double x1 = exp(-0.5*log(lastS()/sh) + y);
   double x2 = exp(-0.5*log(lastS()/sh) - y);
 
   Lorentz5Momentum P1 = lastParticles().first->momentum();
   LorentzMomentum p1 = lightCone((P1.rho() + P1.e())*x1, Energy());
   p1.rotateY(P1.theta());
   p1.rotateZ(P1.phi());
   meMomenta()[0] = p1;
 
   Lorentz5Momentum P2 = lastParticles().second->momentum();
   LorentzMomentum p2 = lightCone((P2.rho() + P2.e())*x2, Energy());
   p2.rotateY(P2.theta());
   p2.rotateZ(P2.phi());
   meMomenta()[1] = p2;
 
   lastXCombPtr()->lastX1X2(make_pair(x1,x2));
   lastXCombPtr()->lastSHat((meMomenta()[0]+meMomenta()[1]).m2());
 
   return km*(ymax - ymin);
 
 }
 
 bool MatchboxMEBase::generateKinematics(const double * r) {
 
   if ( phasespace() ) {
 
     jacobian(phasespace()->generateKinematics(r,meMomenta()));
     if ( jacobian() == 0.0 )
       return false;
 
     setScale();
     if (theMerger&&!theMerger->generateKinematics(r)){
       return false;
     }
 
     logGenerateKinematics(r);
 
     assert(lastMatchboxXComb());
 
     if ( nDimAmplitude() > 0 ) {
       amplitudeRandomNumbers().resize(nDimAmplitude());
       copy(r + nDimPhasespace(), 
 	   r + nDimPhasespace() + nDimAmplitude(),
 	   amplitudeRandomNumbers().begin());
     }
 
     if ( nDimInsertions() > 0 ) {
       insertionRandomNumbers().resize(nDimInsertions());
       copy(r + nDimPhasespace() + nDimAmplitude(), 
 	   r + nDimPhasespace() + nDimAmplitude() + nDimInsertions(),
 	   insertionRandomNumbers().begin());
     }
 
     return true;
 
   }
 
   throw Exception()
     << "MatchboxMEBase::generateKinematics() expects a MatchboxPhasespace object.\n"
     << "Please check your setup." << Exception::runerror;
 
   return false;
 
 }
 
 int MatchboxMEBase::nDim() const { 
 
   if ( lastMatchboxXComb() )
     return nDimPhasespace() + nDimAmplitude() + nDimInsertions();
 
   int ampAdd = 0;
   if ( matchboxAmplitude() ) {
     ampAdd = matchboxAmplitude()->nDimAdditional();
   }
 
   int insertionAdd = 0;
   for ( auto const & v : virtuals() ) {
     insertionAdd = max(insertionAdd,v->nDimAdditional());
   }
 
   return nDimBorn() + ampAdd + insertionAdd;
 
 }
 
 int MatchboxMEBase::nDimBorn() const { 
 
   if ( lastMatchboxXComb() )
     return nDimPhasespace();
 
   if ( phasespace() )
     return phasespace()->nDim(diagrams().front()->partons());
 
   throw Exception()
     << "MatchboxMEBase::nDim() expects a MatchboxPhasespace object.\n"
     << "Please check your setup." << Exception::runerror;
 
   return 0;
 
 }
 
 void MatchboxMEBase::setScale(Energy2 ren, Energy2 fac) const {
   if ( haveX1X2() ) {
     lastXCombPtr()->lastSHat((meMomenta()[0]+meMomenta()[1]).m2());
   }
   Energy2 fcscale = (fac == ZERO) ? factorizationScale() : fac;
   Energy2 fscale = fcscale*sqr(factorizationScaleFactor());
   Energy2 rscale = (ren == ZERO ? renormalizationScale() : ren)*sqr(renormalizationScaleFactor());
   Energy2 ewrscale = renormalizationScaleQED();
   lastXCombPtr()->lastScale(fscale);
   lastXCombPtr()->lastCentralScale(fcscale);
   lastXCombPtr()->lastShowerScale(showerScale());
   lastMatchboxXComb()->lastRenormalizationScale(rscale);
   if ( !fixedCouplings() ) {
     if ( rscale > lastCuts().scaleMin() )
       lastXCombPtr()->lastAlphaS(SM().alphaS(rscale));
     else
       lastXCombPtr()->lastAlphaS(SM().alphaS(lastCuts().scaleMin()));
   } else {
     lastXCombPtr()->lastAlphaS(SM().alphaS());
   }
   if ( !fixedQEDCouplings() ) {
     lastXCombPtr()->lastAlphaEM(SM().alphaEMME(ewrscale));
   } else {
     lastXCombPtr()->lastAlphaEM(SM().alphaEMMZ());
   }
   logSetScale();
 }
 
 Energy2 MatchboxMEBase::factorizationScale() const {
   if ( scaleChoice() ) {
     return scaleChoice()->factorizationScale();
   }
 
   throw Exception()
     << "MatchboxMEBase::factorizationScale() expects a MatchboxScaleChoice object.\n"
     << "Please check your setup." << Exception::runerror;
 
   return ZERO;
 
 }
 
 Energy2 MatchboxMEBase::renormalizationScale() const {
   if ( scaleChoice() ) {
     return scaleChoice()->renormalizationScale();
   }
 
   throw Exception()
     << "MatchboxMEBase::renormalizationScale() expects a MatchboxScaleChoice object.\n"
     << "Please check your setup." << Exception::runerror;
 
   return ZERO;
 
 }
 
 Energy2 MatchboxMEBase::renormalizationScaleQED() const {
   if ( scaleChoice() ) {
     return scaleChoice()->renormalizationScaleQED();
   }
   return renormalizationScale();
 }
 
 Energy2 MatchboxMEBase::showerScale() const {
   if ( scaleChoice() ) {
     return scaleChoice()->showerScale();
   }
 
   throw Exception()
     << "MatchboxMEBase::showerScale() expects a MatchboxScaleChoice object.\n"
     << "Please check your setup." << Exception::runerror;
 
   return ZERO;
 
 }
 
 void MatchboxMEBase::setVetoScales(tSubProPtr) const {}
 
 bool MatchboxMEBase::havePDFWeight1() const {
   if ( checkedPDFs )
     return theHavePDFs.first;
   theHavePDFs.first = 
     factory()->isIncoming(mePartonData()[0]) && 
     lastXCombPtr()->partonBins().first->pdf();
   theHavePDFs.second = 
     factory()->isIncoming(mePartonData()[1]) &&
     lastXCombPtr()->partonBins().second->pdf();
   checkedPDFs = true;
   return theHavePDFs.first;
 }
 
 bool MatchboxMEBase::havePDFWeight2() const {
   if ( checkedPDFs )
     return theHavePDFs.second;
   theHavePDFs.first = 
     factory()->isIncoming(mePartonData()[0]) && 
     lastXCombPtr()->partonBins().first->pdf();
   theHavePDFs.second = 
     factory()->isIncoming(mePartonData()[1]) &&
     lastXCombPtr()->partonBins().second->pdf();
   checkedPDFs = true;
   return theHavePDFs.second;
 }
 
 void MatchboxMEBase::getPDFWeight(Energy2 factorizationScale) const {
 
   if ( !havePDFWeight1() && !havePDFWeight2() ) {
     lastMEPDFWeight(1.0);
     logPDFWeight();
     return;
   }
 
   double w = 1.;
 
   if ( havePDFWeight1() )
     w *= pdf1(factorizationScale);
 
   if ( havePDFWeight2() )
     w *= pdf2(factorizationScale);
 
   lastMEPDFWeight(w);
 
   logPDFWeight();
 
 }
 
 double MatchboxMEBase::pdf1(Energy2 fscale, double xEx, double xFactor) const {
 
   assert(lastXCombPtr()->partonBins().first->pdf());
 
   if ( xEx < 1. && lastX1()*xFactor >= xEx ) {
     return
       ( ( 1. - lastX1()*xFactor ) / ( 1. - xEx ) ) *
       lastXCombPtr()->partonBins().first->pdf()->xfx(lastParticles().first->dataPtr(),
 						     lastPartons().first->dataPtr(),
 						     fscale == ZERO ? lastScale() : fscale,
 						     xEx)/xEx;
   }
 
   return lastXCombPtr()->partonBins().first->pdf()->xfx(lastParticles().first->dataPtr(),
 							lastPartons().first->dataPtr(),
 							fscale == ZERO ? lastScale() : fscale,
 							lastX1()*xFactor)/lastX1()/xFactor;
 }
 
 double MatchboxMEBase::pdf2(Energy2 fscale, double xEx, double xFactor) const {
 
   assert(lastXCombPtr()->partonBins().second->pdf());
 
   if ( xEx < 1. && lastX2()*xFactor >= xEx ) {
     return
       ( ( 1. - lastX2()*xFactor ) / ( 1. - xEx ) ) *
       lastXCombPtr()->partonBins().second->pdf()->xfx(lastParticles().second->dataPtr(),
 						      lastPartons().second->dataPtr(),
 						      fscale == ZERO ? lastScale() : fscale,
 						      xEx)/xEx;
   }
 
   return lastXCombPtr()->partonBins().second->pdf()->xfx(lastParticles().second->dataPtr(),
 							 lastPartons().second->dataPtr(),
 							 fscale == ZERO ? lastScale() : fscale,
 							 lastX2()*xFactor)/lastX2()/xFactor;
 
 }
 
 double MatchboxMEBase::me2() const {
 
   if ( matchboxAmplitude() ) {
 
     if ( matchboxAmplitude()->treeAmplitudes() )
       matchboxAmplitude()->prepareAmplitudes(this);
 
     double res = 
       matchboxAmplitude()->me2()*
       me2Norm();
 
     return res;
 
   }
 
   throw Exception()
     << "MatchboxMEBase::me2() expects a MatchboxAmplitude object.\n"
     << "Please check your setup." << Exception::runerror;
   return 0.;
 
 }
 
 double MatchboxMEBase::largeNME2(Ptr<ColourBasis>::tptr largeNBasis) const {
 
   if ( matchboxAmplitude() ) {
 
     if ( matchboxAmplitude()->treeAmplitudes() ) {
       largeNBasis->prepare(mePartonData(),false);
       matchboxAmplitude()->prepareAmplitudes(this);
     }
 
     double res = 
       matchboxAmplitude()->largeNME2(largeNBasis)*
       me2Norm();
 
     return res;
 
   }
 
   throw Exception()
     << "MatchboxMEBase::largeNME2() expects a MatchboxAmplitude object.\n"
     << "Please check your setup." << Exception::runerror;
   return 0.;
 
 }
 
 double MatchboxMEBase::finalStateSymmetry() const {
 
   if ( symmetryFactor() > 0.0 )
     return symmetryFactor();
 
   double sFactor = 1.;
 
   map<long,int> counts;
 
   cPDVector checkData;
   copy(mePartonData().begin()+2,mePartonData().end(),back_inserter(checkData));
 
   cPDVector::iterator p = checkData.begin();
   while ( !checkData.empty() ) {
     if ( counts.find((**p).id()) != counts.end() ) {
       counts[(**p).id()] += 1;
     } else {
       counts[(**p).id()] = 1;
     }
     checkData.erase(p);
     p = checkData.begin();
     continue;
   }
 
   for ( auto const & c : counts) {
     if ( c.second == 1 )
       continue;
     if ( c.second == 2 )
       sFactor /= 2.;
     else if ( c.second == 3 )
       sFactor /= 6.;
     else if ( c.second == 4 )
       sFactor /= 24.;
   }
 
   symmetryFactor(sFactor);
 
   return symmetryFactor();
 
 }
 
 double MatchboxMEBase::me2Norm(unsigned int addAlphaS) const {
 
   // assume that we always have incoming
   // spin-1/2 or massless spin-1 particles
   double fac = 1./4.;
 
   if ( hasInitialAverage() )
     fac = 1.;
 
   double couplings = 1.0;
   if ( (orderInAlphaS() > 0 || addAlphaS != 0) && !hasRunningAlphaS() ) {
     fac *= pow(lastAlphaS()/SM().alphaS(),double(orderInAlphaS()+addAlphaS));
     couplings *= pow(lastAlphaS(),double(orderInAlphaS()+addAlphaS));
   }
   if ( orderInAlphaEW() > 0 && !hasRunningAlphaEW() ) {
     fac *= pow(lastAlphaEM()/SM().alphaEMMZ(),double(orderInAlphaEW()));
     couplings *= pow(lastAlphaEM(),double(orderInAlphaEW()));
   }
   lastMECouplings(couplings);
 
   if ( !hasInitialAverage() ) {
     if ( mePartonData()[0]->iColour() == PDT::Colour3 || 
 	 mePartonData()[0]->iColour() == PDT::Colour3bar )
       fac /= SM().Nc();
     else if ( mePartonData()[0]->iColour() == PDT::Colour8 )
       fac /= (SM().Nc()*SM().Nc()-1.);
 
     if ( mePartonData()[1]->iColour() == PDT::Colour3 || 
 	 mePartonData()[1]->iColour() == PDT::Colour3bar )
       fac /= SM().Nc();
     else if ( mePartonData()[1]->iColour() == PDT::Colour8 )
       fac /= (SM().Nc()*SM().Nc()-1.);
   }
 
   return !hasFinalStateSymmetry() ? finalStateSymmetry()*fac : fac;
 
 }
 
 
 CrossSection MatchboxMEBase::prefactor()const{
   return (sqr(hbarc)/(2.*lastSHat())) *jacobian()* lastMEPDFWeight();
 }
 
 CrossSection MatchboxMEBase::dSigHatDRB() const {
   getPDFWeight();
   lastME2(me2());
   return oneLoopNoBorn()?ZERO:prefactor() * lastME2();
 }
 
 CrossSection MatchboxMEBase::dSigHatDRV() const {
   getPDFWeight();
   lastME2(me2());
   return ( oneLoop() && !oneLoopNoLoops() )?(prefactor() * oneLoopInterference()):ZERO;
 }
 
 CrossSection MatchboxMEBase::dSigHatDRI() const {
   getPDFWeight();
   lastME2(me2());
   CrossSection res=ZERO;
   if  (oneLoop() &&!onlyOneLoop())  {
     for ( auto const & v : virtuals()) {
       v->setXComb(lastXCombPtr());
       res += v->dSigHatDR();
     }
     if ( checkPoles() && oneLoop() )
       logPoles();
   }
   return res;
 }
 
 CrossSection MatchboxMEBase::dSigHatDRAlphaDiff(double alpha) const {
   getPDFWeight();
   lastME2(me2());
   CrossSection res=ZERO;
   for ( auto const & v: virtuals() ) {
     v->setXComb(lastXCombPtr());
     res+=v->dSigHatDRAlphaDiff( alpha);
   }
   return res;
 }
 
+
+
+
+
+
 CrossSection MatchboxMEBase::dSigHatDR() const {
   getPDFWeight();
   
   if (theMerger){
     lastMECrossSection(theMerger->MergingDSigDR());
     return lastMECrossSection();
   }
   else if (lastXCombPtr()->willPassCuts() ) {
 	lastME2(me2());
 	CrossSection _dSigHatDRB, _dSigHatDRV, _dSigHatDRI, res = ZERO;
 	// ----- dSigHatDRB -----
 	_dSigHatDRB = oneLoopNoBorn()?ZERO:prefactor() * lastME2();
 	// ----- dSigHatDRV -----
 	_dSigHatDRV = ( oneLoop() && !oneLoopNoLoops() )?(prefactor() * oneLoopInterference()):ZERO;
 	// ----- dSigHatDRI -----
     if  (oneLoop() &&!onlyOneLoop())  {
     for ( auto const & v : virtuals()) {
       v->setXComb(lastXCombPtr());
       res += v->dSigHatDR();
     }
     if ( checkPoles() && oneLoop() )
       logPoles();
   }
 	_dSigHatDRI = res;
 	// ----- finalizing -----
     lastMECrossSection(_dSigHatDRB + _dSigHatDRV + _dSigHatDRI);
     return lastMECrossSection();
   }
   else
   {
   lastME2(ZERO);
   lastMECrossSection(ZERO);
   return lastMECrossSection();
   }
 }
 
 double MatchboxMEBase::oneLoopInterference() const {
 
   if ( matchboxAmplitude() ) {
 
     if ( matchboxAmplitude()->oneLoopAmplitudes() )
       matchboxAmplitude()->prepareOneLoopAmplitudes(this);
 
     double res = 
       matchboxAmplitude()->oneLoopInterference()*
       me2Norm(1);
 
     return res;
 
   }
 
   throw Exception()
     << "MatchboxMEBase::oneLoopInterference() expects a MatchboxAmplitude object.\n"
     << "Please check your setup." << Exception::runerror;
   return 0.;
 
 }
 
 MatchboxMEBase::AccuracyHistogram::AccuracyHistogram(double low,
 						     double up,
 						     unsigned int nbins) 
   : lower(low), upper(up), 
     sameSign(0), oppositeSign(0), nans(0),
     overflow(0), underflow(0) {
 
   double step = (up-low)/nbins;
 
   for ( unsigned int k = 1; k <= nbins; ++k )
     bins[lower + k*step] = 0.0;
 
 }
 
 void MatchboxMEBase::AccuracyHistogram::book(double a, double b) {
   if ( ! (isfinite(a) && isfinite(b)) ) {
     ++nans;
     return;
   }
   if ( a*b >= 0. )
     ++sameSign;
   if ( a*b < 0. )
     ++oppositeSign;
   double r = 1.;
   if ( abs(a) != 0.0 )
     r = abs(1.-abs(b/a));
   else if ( abs(b) != 0.0 )
     r = abs(b);
   if ( log10(r) < lower || r == 0.0 ) {
     ++underflow;
     return;
   }
   if ( log10(r) > upper ) {
     ++overflow;
     return;
   }
   map<double,double>::iterator bin =
     bins.upper_bound(log10(r));
   if ( bin == bins.end() )
     return;
   bin->second += 1.;
 }
 
 void MatchboxMEBase::AccuracyHistogram::dump(const std::string& folder, const std::string& prefix,
 					     const cPDVector& proc) const {
   ostringstream fname("");
   for ( cPDVector::const_iterator p = proc.begin();
 	p != proc.end(); ++p )
     fname << (**p).PDGName();
   ofstream out((folder+"/"+prefix+fname.str()+".dat").c_str());
   out << "# same sign : " << sameSign << " opposite sign : "
       << oppositeSign << " nans : " << nans 
       << " overflow : " << overflow
       << " underflow : " << underflow << "\n";
   for ( map<double,double>::const_iterator b = bins.begin();
 	b != bins.end(); ++b ) {
     map<double,double>::const_iterator bp = b; --bp;
     if ( b->second != 0. ) {
       if ( b != bins.begin() )
 	out << bp->first;
       else
 	out << lower;
       out << " " << b->first
 	  << " " << b->second
 	  << "\n" << flush;
     }
   }
   ofstream gpout((folder+"/"+prefix+fname.str()+".gp").c_str());
   gpout << "set terminal png\n"
       << "set xlabel 'accuracy of pole cancellation [decimal places]'\n"
       << "set ylabel 'counts\n"
       << "set xrange [-20:0]\n"
       << "set output '" << prefix << fname.str() << ".png'\n"
       << "plot '" << prefix << fname.str() << ".dat' using (0.5*($1+$2)):3 with linespoints pt 7 ps 1 not";
 }
 
 void MatchboxMEBase::AccuracyHistogram::persistentOutput(PersistentOStream& os) const {
   os << lower << upper << bins
      << sameSign << oppositeSign << nans
      << overflow << underflow;
 }
 
 void MatchboxMEBase::AccuracyHistogram::persistentInput(PersistentIStream& is) {
   is >> lower >> upper >> bins
      >> sameSign >> oppositeSign >> nans
      >> overflow >> underflow;
 }
 
 void MatchboxMEBase::logPoles() const {
   double res2me = oneLoopDoublePole();
   double res1me = oneLoopSinglePole();
   double res2i = 0.;
   double res1i = 0.;
   for ( auto const & v : virtuals()) {
     res2i += v->oneLoopDoublePole();
     res1i += v->oneLoopSinglePole();
   }
   if (res2me != 0.0 || res2i != 0.0) epsilonSquarePoleHistograms[mePartonData()].book(res2me,res2i);
   if (res1me != 0.0 || res1i != 0.0) epsilonPoleHistograms[mePartonData()].book(res1me,res1i);
 }
 
 bool MatchboxMEBase::haveOneLoop() const {
   if ( matchboxAmplitude() )
     return matchboxAmplitude()->haveOneLoop();
   return false;
 }
 
 bool MatchboxMEBase::onlyOneLoop() const {
   if ( matchboxAmplitude() )
     return matchboxAmplitude()->onlyOneLoop();
   return false;
 }
 
 bool MatchboxMEBase::isDRbar() const {
   if ( matchboxAmplitude() )
     return matchboxAmplitude()->isDRbar();
   return false;
 }
 
 bool MatchboxMEBase::isDR() const {
   if ( matchboxAmplitude() )
     return matchboxAmplitude()->isDR();
   return false;
 }
 
 bool MatchboxMEBase::isCS() const {
   if ( matchboxAmplitude() )
     return matchboxAmplitude()->isCS();
   return false;
 }
 
 bool MatchboxMEBase::isBDK() const {
   if ( matchboxAmplitude() )
     return matchboxAmplitude()->isBDK();
   return false;
 }
 
 bool MatchboxMEBase::isExpanded() const {
   if ( matchboxAmplitude() )
     return matchboxAmplitude()->isExpanded();
   return false;
 }
 
 Energy2 MatchboxMEBase::mu2() const {
   if ( matchboxAmplitude() )
     return matchboxAmplitude()->mu2();
   return 0*GeV2;
 }
 
 double MatchboxMEBase::oneLoopDoublePole() const {
 
   if ( matchboxAmplitude() ) {
 
     return
       matchboxAmplitude()->oneLoopDoublePole()*
       me2Norm(1);
 
   }
 
   return 0.;
 
 }
 
 double MatchboxMEBase::oneLoopSinglePole() const {
 
   if ( matchboxAmplitude() ) {
 
     return 
       matchboxAmplitude()->oneLoopSinglePole()*
       me2Norm(1);
 
   }
 
   return 0.;
 
 }
 
 vector<SubtractionDipolePtr> 
 MatchboxMEBase::getDipoles(const vector<SubtractionDipolePtr>& dipoles,
 			   const vector<MatchboxMEBasePtr> & borns,bool slim) const {
 
   vector<SubtractionDipolePtr> res;
 
   // keep track of the dipoles we already did set up
   set<pair<pair<pair<int,int>,int>,pair<Ptr<MatchboxMEBase>::tptr,Ptr<SubtractionDipole>::tptr> > > done;
 
   cPDVector rep = diagrams().front()->partons();
   int nreal = rep.size();
 
   // now loop over configs
   for ( int emitter = 0; emitter < nreal; ++emitter ) {
 
     list<SubtractionDipolePtr> matchDipoles;
     for ( auto const & d : dipoles ) {
       if ( ! d->canHandleEmitter(rep,emitter) )
 	continue;
       matchDipoles.push_back(d);
     }
     if ( matchDipoles.empty() )
       continue;
 
     for ( int emission = 2; emission < nreal; ++emission ) {
       if ( emission == emitter )
 	continue;
 
       list<SubtractionDipolePtr> matchDipoles2;
       for ( auto const & d : matchDipoles ) {
 	if ( !d->canHandleSplitting(rep,emitter,emission) )
 	  continue;
 	matchDipoles2.push_back(d);
       }
       if ( matchDipoles2.empty() )
 	continue;
 
       map<Ptr<DiagramBase>::ptr,SubtractionDipole::MergeInfo> mergeInfo;
 
       for ( auto const & d : diagrams() ) {
 
 	Ptr<Tree2toNDiagram>::ptr check =
         new_ptr(Tree2toNDiagram(*dynamic_ptr_cast<Ptr<Tree2toNDiagram>::ptr>(d)));
 
 	map<int,int> theMergeLegs;
 
 	for ( unsigned int i = 0; i < check->external().size(); ++i )
 	  theMergeLegs[i] = -1;
 	int theEmitter = check->mergeEmission(emitter,emission,theMergeLegs);
 
 	// no underlying Born
 	if ( theEmitter == -1 )
 	  continue;
 
 	SubtractionDipole::MergeInfo info;
 	info.diagram = check;
 	info.emitter = theEmitter;
 	info.mergeLegs = theMergeLegs;
 	mergeInfo[d] = info;
 
       }
 
       if ( mergeInfo.empty() )
 	continue;
 
       for ( int spectator = 0; spectator < nreal; ++spectator ) {
 	if ( spectator == emitter || spectator == emission )
 	  continue;
 
 	list<SubtractionDipolePtr> matchDipoles3;
     for ( auto const & d : matchDipoles2 ) {
 	  if ( ! d->canHandleSpectator(rep,spectator) )
 	    continue;
 	  matchDipoles3.push_back(d);
 	}
 	if ( matchDipoles3.empty() )
 	  continue;
 
 	if ( noDipole(emitter,emission,spectator) )
 	  continue;
 
         for ( auto const & d : matchDipoles3 ) {
 
 	  if ( !d->canHandle(rep,emitter,emission,spectator) )
 	    continue;
 
           for ( auto const & b : borns ) {
 	    if ( b->onlyOneLoop() )
 	      continue;
 	    if ( done.find(make_pair(make_pair(make_pair(emitter,emission),spectator),make_pair(b,d)))
 		 != done.end() )
 	      continue;
 	    // now get to work
 	    d->clearBookkeeping();
 	    d->realEmitter(emitter);
 	    d->realEmission(emission);
 	    d->realSpectator(spectator);
 	    d->realEmissionME(const_cast<MatchboxMEBase*>(this));
 	    d->underlyingBornME(b);
 	    d->setupBookkeeping(mergeInfo,slim);
 	    if ( ! d->empty() )  {
 	      res.push_back( d->cloneMe() );
 	      Ptr<SubtractionDipole>::tptr nDipole = res.back();
 	      done.insert(make_pair(make_pair(make_pair(emitter,emission),spectator),make_pair(b,d)));
 	      if ( nDipole->isSymmetric() )
 		done.insert(make_pair(make_pair(make_pair(emission,emitter),spectator),make_pair(b,d)));
 	      ostringstream dname;
               if ( theMerger) {
                 dname << fullName();
                 if (theOneLoopNoBorn)  dname <<  ".virtual" << "." ;
                 dname   << b->name() << "."
                         << d->name() << ".[("
                         << emitter << "," << emission << ")," << spectator << "]";
               } else {
                 dname << fullName() << "." << b->name() << "."
 		    << d->name() << ".[("
 		    << emitter << "," << emission << ")," << spectator << "]";
               }
 	      if ( ! (generator()->preinitRegister(nDipole,dname.str()) ) )
 		throw Exception() << "MatchboxMEBase::getDipoles(): Dipole " << dname.str() << " already existing." << Exception::runerror;
 	      if ( !factory()->reweighters().empty() ) {
             for ( auto const & rw : factory()->reweighters())
 		  nDipole->addReweighter(rw);
 	      }
 	      if ( !factory()->preweighters().empty() ) {
             for ( auto const & rw : factory()->preweighters() )
 		  nDipole->addPreweighter(rw);
 	      }
 	      nDipole->cloneDependencies(dname.str(),slim);
 	    }
 	  }
 	}
       }
     }
   }
 
   vector<Ptr<SubtractionDipole>::tptr> partners;
   copy(res.begin(),res.end(),back_inserter(partners));
   for ( auto const & d : res )
     d->partnerDipoles(partners);
 
   return res;
 
 }
 
 double MatchboxMEBase::colourCorrelatedME2(pair<int,int> ij) const {
 
   if ( matchboxAmplitude() ) {
 
     if ( matchboxAmplitude()->treeAmplitudes() )
       matchboxAmplitude()->prepareAmplitudes(this);
 
     double res = 
       matchboxAmplitude()->colourCorrelatedME2(ij)*
       me2Norm();
 
     return res;
 
   }
 
   throw Exception()
     << "MatchboxMEBase::colourCorrelatedME2() expects a MatchboxAmplitude object.\n"
     << "Please check your setup." << Exception::runerror;
   return 0.;
 
 }
 
 double MatchboxMEBase::largeNColourCorrelatedME2(pair<int,int> ij,
 						 Ptr<ColourBasis>::tptr largeNBasis) const {
 
   if ( matchboxAmplitude() ) {
 
     if ( matchboxAmplitude()->treeAmplitudes() ) {
       largeNBasis->prepare(mePartonData(),false);
       matchboxAmplitude()->prepareAmplitudes(this);
     }
 
     double res = 
       matchboxAmplitude()->largeNColourCorrelatedME2(ij,largeNBasis)*
       me2Norm();
 
     return res;
 
   }
 
   throw Exception()
     << "MatchboxMEBase::largeNColourCorrelatedME2() expects a MatchboxAmplitude object.\n"
     << "Please check your setup." << Exception::runerror;
   return 0.;
 
 }
 
 double MatchboxMEBase::spinColourCorrelatedME2(pair<int,int> ij,
 					       const SpinCorrelationTensor& c) const {
 
   if ( matchboxAmplitude() ) {
 
     if ( matchboxAmplitude()->treeAmplitudes() )
       matchboxAmplitude()->prepareAmplitudes(this);
 
     double res = 
       matchboxAmplitude()->spinColourCorrelatedME2(ij,c)*
       me2Norm();
 
     return res;
 
   }
 
   throw Exception()
     << "MatchboxMEBase::spinColourCorrelatedME2() expects a MatchboxAmplitude object.\n"
     << "Please check your setup." << Exception::runerror;
   return 0.;
 
 }
 
 double MatchboxMEBase::spinCorrelatedME2(pair<int,int> ij,
 					 const SpinCorrelationTensor& c) const {
 
   if ( matchboxAmplitude() ) {
 
     if ( matchboxAmplitude()->treeAmplitudes() )
       matchboxAmplitude()->prepareAmplitudes(this);
 
     double res = 
       matchboxAmplitude()->spinCorrelatedME2(ij,c)*
       me2Norm();
 
     return res;
 
   }
 
   throw Exception()
     << "MatchboxMEBase::spinCorrelatedME2() expects a MatchboxAmplitude object.\n"
     << "Please check your setup." << Exception::runerror;
   return 0.;
 
 }
 
 
 void MatchboxMEBase::flushCaches() {
   if ( theMerger )theMerger->flushCaches(); 
   MEBase::flushCaches();
   if ( matchboxAmplitude() )
     matchboxAmplitude()->flushCaches();
   for ( auto const & r : reweights() ) 
     r->flushCaches();
   for ( auto const &  v : virtuals()) 
     v->flushCaches();
 }
 
 
 void MatchboxMEBase::setKinematics() {
   MEBase::setKinematics();
   if ( theMerger ) 
     theMerger->setKinematics();
 }
 
 void MatchboxMEBase::clearKinematics() {
   MEBase::clearKinematics();
   if ( theMerger )
     theMerger->clearKinematics();
 }
 
 const MergerBasePtr MatchboxMEBase::merger() const {
   return theMerger;
 }
 
 MergerBasePtr MatchboxMEBase::merger() {
   return theMerger;
 }
 
 void MatchboxMEBase::merger(MergerBasePtr v) {
   theMerger = v;
 }
 
 
 
 
 void MatchboxMEBase::print(ostream& os) const {
 
   os << "--- MatchboxMEBase setup -------------------------------------------------------\n";
 
   os << " '" << name() << "' for subprocess:\n";
 
   os << "  ";
   for ( PDVector::const_iterator pp = subProcess().legs.begin();
 	pp != subProcess().legs.end(); ++pp ) {
     os << (**pp).PDGName() << " ";
     if ( pp == subProcess().legs.begin() + 1 )
       os << "-> ";
   }
   os << "\n";
 
   os << " including " << (oneLoop() ? "" : "no ") << "virtual corrections";
   if ( oneLoopNoBorn() )
     os << " without Born contributions";
   if ( oneLoopNoLoops() )
     os << " without loop contributions";
   os << "\n";
 
   if ( oneLoop() && !onlyOneLoop() ) {
     os << " using insertion operators\n";
     for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
 	    virtuals().begin(); v != virtuals().end(); ++v ) {
       os << " '" << (**v).name() << "' with " 
 	 << ((**v).isDR() ? "" : "C") << "DR/";
       if ( (**v).isCS() )
 	os << "CS";
       if ( (**v).isBDK() )
 	os << "BDK";
       if ( (**v).isExpanded() )
 	os << "expanded";
       os << " conventions\n";
     }
   }
 
   os << "--------------------------------------------------------------------------------\n";
 
   os << flush;
 
 }
 
 void MatchboxMEBase::printLastEvent(ostream& os) const {
 
   os << "--- MatchboxMEBase last event information --------------------------------------\n";
 
   os << " for matrix element '" << name() << "'\n";
 
   os << " process considered:\n ";
 
   int in = 0;
   for ( cPDVector::const_iterator p = mePartonData().begin();
 	p != mePartonData().end(); ++p ) {
     os << (**p).PDGName() << " ";
     if ( ++in == 2 )
       os << " -> ";
   }
 
   os << " kinematic environment as set by the XComb " << lastXCombPtr() << ":\n"
      << " sqrt(shat)/GeV = " << sqrt(lastSHat()/GeV2)
      << " x1 = " << lastX1() << " x2 = " << lastX2() 
      << " alphaS = " << lastAlphaS() << "\n";
 
   os << " momenta/GeV generated from random numbers\n ";
   copy(lastXComb().lastRandomNumbers().begin(),
        lastXComb().lastRandomNumbers().end(),ostream_iterator<double>(os," "));
   os << ":\n ";
 
   for ( vector<Lorentz5Momentum>::const_iterator p = meMomenta().begin();
 	p != meMomenta().end(); ++p ) {
     os << (*p/GeV) << "\n ";
   }
 
   os << "last cross section/nb calculated was:\n "
      << (lastMECrossSection()/nanobarn) << " (pdf weight " << lastMEPDFWeight() << ")\n";
 
   os << "--------------------------------------------------------------------------------\n";
 
   os << flush;
 
 }
 
 void MatchboxMEBase::logGenerateKinematics(const double * r) const {
 
   if ( !verbose() )
     return;
 
   generator()->log() << "'" << name() << "' generated kinematics\nfrom "
 		     << nDim() << " random numbers:\n";
   copy(r,r+nDim(),ostream_iterator<double>(generator()->log()," "));
   generator()->log() << "\n";
 
   generator()->log() << "storing phase space information in XComb "
 		     << lastXCombPtr() << "\n";
 
   generator()->log() << "generated phase space point (in GeV):\n";
 
   vector<Lorentz5Momentum>::const_iterator pit = meMomenta().begin();
   cPDVector::const_iterator dit = mePartonData().begin();
 
   for ( ; pit != meMomenta().end() ; ++pit, ++dit )
     generator()->log() << (**dit).PDGName() << " : "
 		       << (*pit/GeV) << "\n";
 
   generator()->log() << "with x1 = " << lastX1() << " x2 = " << lastX2() << "\n"
 		     << "and Jacobian = " << jacobian() << " sHat/GeV2 = "
 		     << (lastSHat()/GeV2) << "\n" << flush;
 
 }
 
 void MatchboxMEBase::logSetScale() const {
 
   if ( !verbose() )
     return;
 
   generator()->log() << "'" << name() << "' set scales using XComb " << lastXCombPtr() << ":\n"
 		     << "scale/GeV2 = " << (scale()/GeV2) << " xi_R = "
 		     << renormalizationScaleFactor() << " xi_F = "
 		     << factorizationScaleFactor() << "\n"
 		     << "alpha_s = " << lastAlphaS() << "\n" << flush;
 
 }
 
 void MatchboxMEBase::logPDFWeight() const {
 
   if ( !verbose() )
     return;
 
   generator()->log() << "'" << name() << "' calculated pdf weight = "
 		     << lastMEPDFWeight() << " from XComb "
 		     << lastXCombPtr() << "\n"
 		     << "x1 = " << lastX1() << " (" << (mePartonData()[0]->coloured() ? "" : "not ") << "used) "
 		     << "x2 = " << lastX2() << " (" << (mePartonData()[1]->coloured() ? "" : "not ") << "used)\n"
 		     << flush;
 
 }
 
 void MatchboxMEBase::logME2() const {
 
   if ( !verbose() )
     return;
 
   generator()->log() << "'" << name() << "' evaluated me2 using XComb "
 		     << lastXCombPtr() << "\n"
 		     << "and phase space point (in GeV):\n";
 
   vector<Lorentz5Momentum>::const_iterator pit = meMomenta().begin();
   cPDVector::const_iterator dit = mePartonData().begin();
 
   for ( ; pit != meMomenta().end() ; ++pit, ++dit )
     generator()->log() << (**dit).PDGName() << " : "
 		       << (*pit/GeV) << "\n";
 
   generator()->log() << "with x1 = " << lastX1() << " x2 = " << lastX2() << "\n"
 		     << "sHat/GeV2 = " << (lastSHat()/GeV2) << "\n" << flush;
 
 }
 
 void MatchboxMEBase::logDSigHatDR() const {
 
   if ( !verbose() )
     return;
 
   generator()->log() << "'" << name() << "' evaluated cross section using XComb "
 		     << lastXCombPtr() << "\n"
 		     << "Jacobian = " << jacobian() << " sHat/GeV2 = "
 		     << (lastSHat()/GeV2) << " dsig/nb = "
 		     << (lastMECrossSection()/nanobarn) << "\n" << flush;
 
 }
 
 void MatchboxMEBase::cloneDependencies(const std::string& prefix,bool slim) {
 
   if ( phasespace() && !slim ) {
     Ptr<MatchboxPhasespace>::ptr myPhasespace = phasespace()->cloneMe();
     ostringstream pname;
     pname << (prefix == "" ? fullName() : prefix) << "/" << myPhasespace->name();
     if ( ! (generator()->preinitRegister(myPhasespace,pname.str()) ) )
       throw Exception() << "MatchboxMEBase::cloneDependencies(): Phasespace generator " << pname.str() << " already existing." << Exception::runerror;
     myPhasespace->cloneDependencies(pname.str());
     phasespace(myPhasespace);
   }
 
   theAmplitude = dynamic_ptr_cast<Ptr<MatchboxAmplitude>::ptr>(amplitude());
 
   if ( matchboxAmplitude() ) {
     Ptr<MatchboxAmplitude>::ptr myAmplitude = matchboxAmplitude()->cloneMe();
     ostringstream pname;
     pname << (prefix == "" ? fullName() : prefix) << "/" << myAmplitude->name();
     if ( ! (generator()->preinitRegister(myAmplitude,pname.str()) ) ){
       throw Exception() << "MatchboxMEBase::cloneDependencies(): Amplitude " << pname.str() << " already existing." << Exception::runerror;
     }
     myAmplitude->cloneDependencies(pname.str(),slim);
     matchboxAmplitude(myAmplitude);
     amplitude(myAmplitude);
     matchboxAmplitude()->orderInGs(orderInAlphaS());
     matchboxAmplitude()->orderInGem(orderInAlphaEW());
   }
 
   if ( scaleChoice() &&!slim ) {
     Ptr<MatchboxScaleChoice>::ptr myScaleChoice = scaleChoice()->cloneMe();
     ostringstream pname;
     pname << (prefix == "" ? fullName() : prefix) << "/" << myScaleChoice->name();
     if ( ! (generator()->preinitRegister(myScaleChoice,pname.str()) ) )
       throw Exception() << "MatchboxMEBase::cloneDependencies(): Scale choice " << pname.str() << " already existing." << Exception::runerror;
     scaleChoice(myScaleChoice);
   }
 
   for ( auto &  rw : theReweights ) {
     Ptr<MatchboxReweightBase>::ptr myReweight = rw->cloneMe();
     ostringstream pname;
     pname << (prefix == "" ? fullName() : prefix) << "/" << rw->name();
     if ( ! (generator()->preinitRegister(myReweight,pname.str()) ) )
       throw Exception() << "MatchboxMEBase::cloneDependencies(): Reweight " << pname.str() << " already existing." << Exception::runerror;
     myReweight->cloneDependencies(pname.str());
     rw = myReweight;
   }
 
   for ( auto & v : virtuals()) {
     Ptr<MatchboxInsertionOperator>::ptr myIOP = v->cloneMe();
     ostringstream pname;
     pname << (prefix == "" ? fullName() : prefix) << "/" << v->name();
     if ( ! (generator()->preinitRegister(myIOP,pname.str()) ) )
       throw Exception() << "MatchboxMEBase::cloneDependencies(): Insertion operator " << pname.str() << " already existing." << Exception::runerror;
     v = myIOP;
   }
 
 }
 
 void MatchboxMEBase::prepareXComb(MatchboxXCombData& xc) const {
 
   // fixme We need to pass on the partons from the xcmob here, not
   // assuming one subprocess per matrix element
 
   if ( phasespace() )
     xc.nDimPhasespace(phasespace()->nDim(diagrams().front()->partons()));
 
   if ( matchboxAmplitude() ) {
     xc.nDimAmplitude(matchboxAmplitude()->nDimAdditional());
     if ( matchboxAmplitude()->colourBasis() ) {
       size_t cdim = 
  	matchboxAmplitude()->colourBasis()->prepare(diagrams(),noCorrelations());
       xc.colourBasisDim(cdim);
     }
     if ( matchboxAmplitude()->isExternal() ) {
       xc.externalId(matchboxAmplitude()->externalId(diagrams().front()->partons()));
     }
   }
 
   int insertionAdd = 0;
   for ( auto const &  v : virtuals() )
     insertionAdd = max(insertionAdd,v->nDimAdditional());
   
   xc.nDimInsertions(insertionAdd);
 
   xc.nLight(getNLight());
   if(xc.nLightJetVec().empty())
   for (auto const & id : getNLightJetVec())
     xc.nLightJetVec( id );
   
   if(xc.nHeavyJetVec().empty())
   for (auto const & id :getNHeavyJetVec())
     xc.nHeavyJetVec(id);
 
   if(xc.nLightProtonVec().empty())
   for (auto const & id : getNLightProtonVec())
     xc.nLightProtonVec(id);
 
   xc.olpId(olpProcess());
 
   if ( initVerbose() ) {
     ostringstream fname_strm;
     // only allow alphanumeric, / and _ in filename
     for (const char c : name()) {
         switch (c) {
           case '+' : fname_strm << "+"; break;
           case '-' : fname_strm << "-"; break;
           case '~' : fname_strm << "_tilde"; break;
           case ']' : break;
           case ',' : fname_strm << "__"; break;
           default  : fname_strm << (isalnum(c) ? c : '_'); break;
         }
     }
     fname_strm << ".diagrams";
     const string fname = fname_strm.str();
     ifstream test(fname.c_str());
     if ( !test ) {
       test.close();
       ofstream out(fname.c_str());
       for ( vector<Ptr<DiagramBase>::ptr>::const_iterator d = diagrams().begin();
 	    d != diagrams().end(); ++d ) {
 	DiagramDrawer::drawDiag(out,dynamic_cast<const Tree2toNDiagram&>(**d));
 	out << "\n";
       }
     }
   }
 
 }
 
 StdXCombPtr MatchboxMEBase::makeXComb(Energy newMaxEnergy, const cPDPair & inc,
 				      tEHPtr newEventHandler,tSubHdlPtr newSubProcessHandler,
 				      tPExtrPtr newExtractor,	tCascHdlPtr newCKKW,
 				      const PBPair & newPartonBins, tCutsPtr newCuts,
 				      const DiagramVector & newDiagrams, bool mir,
 				      const PartonPairVec&,
 				      tStdXCombPtr newHead,
 				      tMEPtr newME) {
 
   if ( !newME )
     newME = this;
 
   Ptr<MatchboxXComb>::ptr xc =
     new_ptr(MatchboxXComb(newMaxEnergy, inc,
 			  newEventHandler, newSubProcessHandler,
 			  newExtractor, newCKKW,
 			  newPartonBins, newCuts, newME,
 			  newDiagrams, mir,
 			  newHead));
 
   prepareXComb(*xc);
 
   return xc;
 
 }
 
 StdXCombPtr MatchboxMEBase::makeXComb(tStdXCombPtr newHead,
 				      const PBPair & newPartonBins,
 				      const DiagramVector & newDiagrams,
 				      tMEPtr newME) {
   if ( !newME )
     newME = this;
 
   Ptr<MatchboxXComb>::ptr xc = 
     new_ptr(MatchboxXComb(newHead, newPartonBins, newME, newDiagrams));
 
   prepareXComb(*xc);
 
   return xc;
 }
 
 void MatchboxMEBase::persistentOutput(PersistentOStream & os) const {
   os << theLastXComb << thePhasespace 
      << theAmplitude << theScaleChoice << theVirtuals 
      << theReweights << theSubprocess << theOneLoop 
      << theOneLoopNoBorn << theOneLoopNoLoops
      << epsilonSquarePoleHistograms << epsilonPoleHistograms
      << theMerger
      << theOLPProcess << theNoCorrelations
      << theHavePDFs << checkedPDFs;
 }
 
 void MatchboxMEBase::persistentInput(PersistentIStream & is, int) {
   is >> theLastXComb >> thePhasespace 
      >> theAmplitude >> theScaleChoice >> theVirtuals 
      >> theReweights >> theSubprocess >> theOneLoop 
      >> theOneLoopNoBorn >> theOneLoopNoLoops
      >> epsilonSquarePoleHistograms >> epsilonPoleHistograms
      >> theMerger
      >> theOLPProcess >> theNoCorrelations
      >> theHavePDFs >> checkedPDFs;
   lastMatchboxXComb(theLastXComb);
 }
 
 void MatchboxMEBase::Init() {
 
   static ClassDocumentation<MatchboxMEBase> documentation
     ("MatchboxMEBase is the base class for matrix elements "
      "in the context of the matchbox NLO interface.");
 
 }
 
 IBPtr MatchboxMEBase::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr MatchboxMEBase::fullclone() const {
   return new_ptr(*this);
 }
 
 void MatchboxMEBase::doinit() {
   MEBase::doinit();
   if ( !theAmplitude )
     theAmplitude = dynamic_ptr_cast<Ptr<MatchboxAmplitude>::ptr>(amplitude());
   if ( matchboxAmplitude() )
     matchboxAmplitude()->init();
   if ( phasespace() ) {
     phasespace()->init();
     matchboxAmplitude()->checkReshuffling(phasespace());
   }
   if ( scaleChoice() ) {
     scaleChoice()->init();
   }
   for (auto const & rw : theReweights)
     rw->init();
   for (auto const & v :  virtuals() )
     v->init();
 }
 
 
 void MatchboxMEBase::doinitrun() {
   MEBase::doinitrun();
   if ( matchboxAmplitude() )
     matchboxAmplitude()->initrun();
   
   if ( phasespace() )
     phasespace()->initrun();
   
   if ( scaleChoice() )
     scaleChoice()->initrun();
   
   for (auto const & rw : theReweights)
     rw->initrun();
   for (auto const & v :  virtuals() )
     v->initrun();
 }
   
 void MatchboxMEBase::dofinish() {
   MEBase::dofinish();
   for (auto const & b : epsilonSquarePoleHistograms ) {
     b.second.dump(factory()->poleData(),"epsilonSquarePoles-",b.first);
   }
   for (auto const & b :  epsilonPoleHistograms ) {
     b.second.dump(factory()->poleData(),"epsilonPoles-",b.first);
   }
 }
 
 // *** Attention *** The following static variable is needed for the type
 // description system in ThePEG. Please check that the template arguments
 // are correct (the class and its base class), and that the constructor
 // arguments are correct (the class name and the name of the dynamically
 // loadable library where the class implementation can be found).
 DescribeClass<MatchboxMEBase,MEBase>
 describeHerwigMatchboxMEBase("Herwig::MatchboxMEBase", "Herwig.so");
 
diff --git a/MatrixElement/Matchbox/CVolver/ColourFlowBasis.cc b/MatrixElement/Matchbox/CVolver/ColourFlowBasis.cc
--- a/MatrixElement/Matchbox/CVolver/ColourFlowBasis.cc
+++ b/MatrixElement/Matchbox/CVolver/ColourFlowBasis.cc
@@ -1,248 +1,276 @@
 // -*- C++ -*-
 //
 // ColourFlowBasis.cc is a part of CVolver
 // Copyright (C) 2013-2017 Simon Platzer, The Herwig Collaboration
 //
 // CVolver 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 ColourFlowBasis class.
 //
 
 #include "ColourFlowBasis.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/EventRecord/Particle.h"
 #include "ThePEG/Repository/UseRandom.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace CVolver;
 
 ColourFlowBasis::ColourFlowBasis() {}
 
 ColourFlowBasis::~ColourFlowBasis() {}
 
 IBPtr ColourFlowBasis::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr ColourFlowBasis::fullclone() const {
   return new_ptr(*this);
 }
 
 void ColourFlowBasis::clear() {
   ColourBasis::clear();
 }
 
 map<size_t,vector<vector<size_t> > > 
 ColourFlowBasis::basisList(const vector<PDT::Colour>& basisId) const {
 
   assert(theCrossings.find(basisId) != theCrossings.end());
   const ColourFlowCrossing& crossing = theCrossings.find(basisId)->second;
 
   size_t n = crossing.nFlows();
   assert(theFlows.find(n) != theFlows.end());
 
   map<size_t,vector<vector<size_t> > > res;
 
   const vector<ColourFlow>& flows = theFlows.find(n)->second;
 
   for ( size_t n = 0; n < flows.size(); ++n ) {
     vector<size_t> fundamental;
     vector<size_t> antiFundamental;
     for ( size_t k = 0; k < flows[n].nLegs(); ++k ) {
       fundamental.push_back(crossing.colourLeg(k));
       size_t ac = flows[n].antiColour(k);
       antiFundamental.push_back(crossing.antiColourLeg(ac));
     }
     res[n].push_back(fundamental);
     res[n].push_back(antiFundamental);
   }
 
   return res;
 
 }
 
 size_t ColourFlowBasis::prepareBasis(const vector<PDT::Colour>& sub) {
 
   useMe();
 
   map<vector<PDT::Colour>,ColourFlowCrossing>::const_iterator cross =
     theCrossings.find(sub);
 
   if ( cross != theCrossings.end() )
     return cross->second.nFlows();
 
   ColourFlowCrossing newCrossing(sub,false);
   theCrossings[sub] = newCrossing;
 
   if ( theFlows.find(newCrossing.nFlows()) != theFlows.end() )
     return newCrossing.nFlows();
 
   set<ColourFlow> flows = ColourFlow::allFlows(newCrossing.nFlows());
 
   copy(flows.begin(),flows.end(),
        back_inserter(theFlows[newCrossing.nFlows()]));
 
   return newCrossing.nFlows();
 
 }
 
 void ColourFlowBasis::readBasisDetails(const vector<PDT::Colour>& sub) {
   prepareBasis(sub);
 }
 
 double ColourFlowBasis::scalarProduct(size_t i, size_t j,
 				      const vector<PDT::Colour>& abBasis) const {
 
   if ( largeN() && i != j )
     return 0.;
 
   assert(theCrossings.find(abBasis) != theCrossings.end());
 
   size_t n = theCrossings.find(abBasis)->second.nFlows();
 
   assert(theFlows.find(n) != theFlows.end());
 
   const ColourFlow& iflow = theFlows.find(n)->second[i];
   const ColourFlow& jflow = theFlows.find(n)->second[j];
 
   return pow(3.,(double)(iflow.scalarProduct(jflow)));
 
 }
 
 double ColourFlowBasis::tMatrixElement(size_t m, size_t a, size_t b,
 				       const vector<PDT::Colour>& aBasis,
-				       const vector<PDT::Colour>& bBasis) const {
+				       const vector<PDT::Colour>& bBasis,
+				       size_t k, size_t l,
+				       const map<size_t,size_t>& dict
+				       ) const {
+  // Check indices k and l
+  assert( k == m );
+  assert( l == bBasis.size() );
+  // Check that dict is the standardMap
+  assert( dict.size()+1 == bBasis.size() );
+  map<size_t,size_t>::const_iterator tmp;
+  for ( size_t ii = 0; ii < bBasis.size(); ii++ )
+    if ( ii != m ) {
+      tmp = dict.find(ii);
+      assert( tmp != dict.end() ); 
+      assert( tmp->second == ii );
+    }
 
   assert(theCrossings.find(bBasis) != theCrossings.end());
   const ColourFlowCrossing& bcrossing = theCrossings.find(bBasis)->second;
 
   assert(theFlows.find(bcrossing.nFlows()) != theFlows.end());
   const ColourFlow& bflow = theFlows.find(bcrossing.nFlows())->second[b];
 
   assert(theCrossings.find(aBasis) != theCrossings.end());
   const ColourFlowCrossing& acrossing = theCrossings.find(aBasis)->second;
 
   assert(theFlows.find(acrossing.nFlows()) != theFlows.end());
   const ColourFlow& aflow = theFlows.find(acrossing.nFlows())->second[a];
 
   size_t bEmitterLine = 
     bBasis[m] == PDT::Colour3 || bBasis[m] == PDT::Colour8 ? 
     bcrossing.colourLine(m) : bcrossing.antiColourLine(m);
   size_t bSpectatorLine = 
     bBasis[m] == PDT::Colour3 || bBasis[m] == PDT::Colour8 ? 
     bflow.antiColour(bEmitterLine) : bflow.colour(bEmitterLine);
 
   size_t aEmitterLine = 
     bBasis[m] == PDT::Colour3 || bBasis[m] == PDT::Colour8 ? 
     acrossing.colourLine(m) : acrossing.antiColourLine(m);
   size_t aSpectatorLine = 
     bBasis[m] == PDT::Colour3 || bBasis[m] == PDT::Colour8 ? 
     aflow.antiColour(aEmitterLine) : aflow.colour(aEmitterLine);
 
   assert(aEmitterLine == bEmitterLine);
 
   if ( bBasis[m] == PDT::Colour3 ) {
 
     if ( bSpectatorLine != aSpectatorLine ) {
       return 1./2.;
     } else {
       return -1./2./3.;
     }
 
   }
 
   if ( bBasis[m] == PDT::Colour3bar ) {
 
     if ( bSpectatorLine != aSpectatorLine ) {
       return -1./2.;
     } else {
       return 1./2./3.;
     }
 
   }
 
   if ( bBasis[m] == PDT::Colour8 ) {
 
     if ( bSpectatorLine != aSpectatorLine ) {
       return 1.;
     } else {
       return -1.;
     }
 
   }
 
   return 0.0;
 
 }
 
+double ColourFlowBasis::sMatrixElement(size_t, size_t, size_t,
+				       const vector<PDT::Colour>&,
+				       const vector<PDT::Colour>&,
+				       size_t, size_t,
+				       const map<size_t,size_t>&) const {
+
+  throw Exception() << "ATTENTION this is missing on the CVolver API"
+		    << Exception::runerror;
+
+  return 0.;
+
+}
+
 bool ColourFlowBasis::colourConnected(const cPDVector& sub,
 				      const vector<PDT::Colour>& basisId,
 				      const pair<int,bool>& first,
 				      const pair<int,bool>& second, 
 				      size_t tensor) const {
  
   assert(theCrossings.find(basisId) != theCrossings.end());
   const ColourFlowCrossing& crossing = theCrossings.find(basisId)->second;
 
   // translate process to basis ids
   map<cPDVector,map<size_t,size_t> >::const_iterator trans
     = indexMap().find(sub);
   assert(trans != indexMap().end());
 
   size_t idColoured = first.second ? second.first : first.first;
   idColoured = trans->second.find(idColoured)->second;
   size_t idAntiColoured = first.second ? first.first : second.first;
   idAntiColoured = trans->second.find(idAntiColoured)->second;
 
   size_t colourLine = crossing.colourLine(idColoured);
   size_t antiColourLine = crossing.antiColourLine(idAntiColoured);
 
   size_t n = crossing.nFlows();
   assert(theFlows.find(n) != theFlows.end());
 
   const ColourFlow& iflow = theFlows.find(n)->second[tensor];
 
   return antiColourLine == iflow.antiColour(colourLine);
 
 }
 
 // If needed, insert default implementations of virtual function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void ColourFlowBasis::persistentOutput(PersistentOStream &) const {}
 
 void ColourFlowBasis::persistentInput(PersistentIStream & , int) {}
 
 
 // *** Attention *** The following static variable is needed for the type
 // description system in ThePEG. Please check that the template arguments
 // are correct (the class and its base class), and that the constructor
 // arguments are correct (the class name and the name of the dynamically
 // loadable library where the class implementation can be found).
 DescribeClass<ColourFlowBasis,Herwig::ColourBasis>
   describeColourFlowBasis("CVolver::ColourFlowBasis", 
 			  "HwCVolver.so");
 
 void ColourFlowBasis::Init() {
 
   static ClassDocumentation<ColourFlowBasis> documentation
     ("ColourFlowBasis implements the colour flow basis.",
      "The colour algebra has been performed using CVolver \\cite{Platzer:2013fha}",
      "%\\cite{Platzer:2013fha}\n"
      "\\bibitem{Platzer:2013fha}\n"
      "S.~Platzer,\n"
      "``Summming Large-N Towers in Colour Flow Evolution,''\n"
      "arXiv:1312.2448 [hep-ph].\n"
      "%%CITATION = ARXIV:1312.2448;%%");
 
 }
 
diff --git a/MatrixElement/Matchbox/CVolver/ColourFlowBasis.h b/MatrixElement/Matchbox/CVolver/ColourFlowBasis.h
--- a/MatrixElement/Matchbox/CVolver/ColourFlowBasis.h
+++ b/MatrixElement/Matchbox/CVolver/ColourFlowBasis.h
@@ -1,211 +1,231 @@
 // -*- C++ -*-
 //
 // ColourFlowBasis.h is a part of CVolver
 // Copyright (C) 2013-2017 Simon Platzer, The Herwig Collaboration
 //
 // CVolver is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef CVOLVER_ColourFlowBasis_H
 #define CVOLVER_ColourFlowBasis_H
 //
 // This is the declaration of the ColourFlowBasis class.
 //
 
 #include "Herwig/MatrixElement/Matchbox/Utility/ColourBasis.h"
 #include "ColourFlows.h"
 
 namespace CVolver {
 
 using namespace ThePEG;
 using namespace Herwig;
 
 /**
  * Specify particle data traits for ThePEG
  */
 template<>
 struct ParticleDataTraits<ThePEG::PDT::Colour> {
 
   /**
    * Return true, if singlet
    */
   static bool isSinglet(const ThePEG::PDT::Colour& pd) { 
     return pd == PDT::Colour0;
   }
 
   /**
    * Return true, if anti-fundamental
    */
   static bool isAntiFundamental(const ThePEG::PDT::Colour& pd) {
     return pd == PDT::Colour3bar;
   }
 
   /**
    * Return true, if fundamental
    */
   static bool isFundamental(const ThePEG::PDT::Colour& pd) {
     return pd == PDT::Colour3;
   }
 
   /**
    * Return true, if adjoint
    */
   static bool isAdjoint(const ThePEG::PDT::Colour& pd) {
     return pd == PDT::Colour8;
   }
 
 };
 
 /**
  * ColourFlowBasis implements the colour flow basis.
  *
  * @see \ref ColourFlowBasisInterfaces "The interfaces"
  * defined for ColourFlowBasis.
  */
 class ColourFlowBasis: public Herwig::ColourBasis {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   ColourFlowBasis();
 
   /**
    * The destructor.
    */
   virtual ~ColourFlowBasis();
   //@}
 
 public:
 
   /**
    * Clear this colour basis
    */
   virtual void clear();
 
   /**
    * Return a map of basis tensor indices to vectors identifying a
    * certain ordering corresponding to the given colour structure. May
    * not be supported by all colour basis implementations.
    */
   virtual map<size_t,vector<vector<size_t> > > basisList(const vector<PDT::Colour>&) const;
 
   /**
    * Prepare the basis for the normal ordered legs and return the
    * dimensionality of the basis.
    */
   virtual size_t prepareBasis(const vector<PDT::Colour>&);
 
   /**
    * Gather any implementation dependend details when reading a basis
    */
   virtual void readBasisDetails(const vector<PDT::Colour>&);
 
   /**
    * Return the scalar product of basis tensors labelled a and b in
    * the basis used for the given normal ordered legs.
    */
   virtual double scalarProduct(size_t a, size_t b,
 			       const vector<PDT::Colour>& abBasis) const;
 
   /**
    * Return the matrix element of a colour charge
    * <c_{n+1,a}|T_i|c_{n,b}> between basis tensors a and b, with
    * respect to aBasis and bBasis
    */
   virtual double tMatrixElement(size_t i, size_t a, size_t b,
 				const vector<PDT::Colour>& aBasis,
-				const vector<PDT::Colour>& bBasis) const;
+				const vector<PDT::Colour>& bBasis,
+				size_t k, size_t l,
+				const map<size_t,size_t>& dict) const;
+
+  /**
+   * Return true, if this colour basis supports gluon splittings.
+   */
+  virtual bool canSplitGluons() const {
+    return false;
+  }
+
+  /**
+   * Return the matrix element of a quark splitting matrix
+   * <c_{n+1,a}|T_i|c_{n,b}> between basis tensors a and b, with
+   * respect to aBasis and bBasis
+   */
+  virtual double sMatrixElement(size_t i, size_t a, size_t b,
+				const vector<PDT::Colour>& aBasis,
+				const vector<PDT::Colour>& bBasis,
+				size_t k, size_t l,
+				const map<size_t,size_t>& dict) const;
 
   /**
    * Return true, if the colour basis is capable of assigning colour
    * flows.
    */
   virtual bool haveColourFlows() const { return true; }
 
   /**
    * Return true, if a large-N colour connection exists for the
    * given external legs and basis tensor.
    */
   virtual bool colourConnected(const cPDVector&,
 			       const vector<PDT::Colour>&,
 			       const pair<int,bool>&, 
 			       const pair<int,bool>&, 
 			       size_t) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 private:
 
   /**
    * Map colour signatures to colour crossings
    */
   map<vector<PDT::Colour>,ColourFlowCrossing> theCrossings;
 
   /**
    * Colour flows indexed by basis size; note this is a unique
    * assignment
    */
   map<size_t,vector<ColourFlow> > theFlows;
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   ColourFlowBasis & operator=(const ColourFlowBasis &) = delete;
 
 };
 
 }
 
 #endif /* CVOLVER_ColourFlowBasis_H */
diff --git a/MatrixElement/Matchbox/ColorFull/Col_amp.cc b/MatrixElement/Matchbox/ColorFull/Col_amp.cc
--- a/MatrixElement/Matchbox/ColorFull/Col_amp.cc
+++ b/MatrixElement/Matchbox/ColorFull/Col_amp.cc
@@ -1,1143 +1,1210 @@
 // -*- C++ -*-
 /*
  * Col_amp.cc
  *	Contains the definition of the class Col_amp and related operators
  *  Author: Malin Sjodahl
  */
 
 #include "Col_amp.h"
 #include <cassert>
 #include <fstream>
 #include <iostream>
 
 namespace ColorFull {
 
 std::ostream& operator<<(std::ostream& out, const col_amp & ca) {
 	int max = ca.size();
 	for (int i = 0; i < max; i++) {
 		if(i != 0) out <<" + ";
 		out << ca.at(i) ;
 	}
 	return out;
 }
 
 
 void Col_amp::normal_order_col_strs() {
 	for (uint m = 0; m < ca.size(); m++) {
 		ca.at(m).normal_order();
 	}
 }
 
 
 void Col_amp::normal_order() {
 
 	// First normal order the Col_strs
 	normal_order_col_strs();
 
 	// To contain the Col_strs in order
 	col_amp ca_ordered;
 
 	// Order the different Col_strs in the Col_amp
 	// Do this by moving the Cs one by one to ca_ordered
 	while ( ca.size() > 0 ) {
 		// Next Cs to put in place (the last Cs in ca)
 		Col_str Cs_next = ca.at( ca.size() - 1 );
 
 		// Then insert the Cs among the ordered Col_strs
 		// Count how many steps left Cs_next should be moved in ca_ordered
 		uint steps_left = 0;
 		while ( (steps_left < (ca_ordered.size())) && Cs_next.smallest( Cs_next, ca_ordered.at(ca_ordered.size()-1-steps_left )) ==1) {
 			steps_left++;
 		}
 
 		// Insert the Cs in the right place among the ordered Col_strs
 		col_amp::iterator it=ca_ordered.end()-steps_left;
 		ca_ordered.insert( it, Cs_next);
 
 		// Erase the Cs from ca
 		ca.erase(  ca.end()-1 ) ;
 
 	}
 	ca=ca_ordered;
 }
 
 
 void Col_amp::erase( int i ) {
 	ca.erase(ca.begin() + i);
 }
 
 
-void Col_amp::append(col_amp ca_in) {
+void Col_amp::append( col_amp ca_in ) {
 	for (uint m = 0; m < ca_in.size(); m++) {
 		ca.push_back(ca_in.at(m));
 	}
 }
 
 
 void Col_amp::read_in_Col_amp( std::string filename) {
 
 	// Read in file
 	std::ifstream fin( filename.c_str() );
 
 	// Check that file exists
 	if( !fin ){
 		std::cerr << "Col_amp::read_in_Col_amp: The file "
 				<< filename << " could not be opened." << std::endl;
 		assert( 0 );
 	}
 
 	// Erase current information
 	ca.clear();
 	Scalar.clear();
 
 	// Copy info from file to string
 	std::string str((std::istreambuf_iterator<char>(fin)), std::istreambuf_iterator<char>());
-	str.erase(str.size()-1);
+
+	// Skip lines starting with #
+	while( str.at(0)== '#' ){
+		while (str.at(0) != '\n'){
+			str.erase(str.begin());
+		}
+		// erase endl sign(s)
+		while(str.at(0)== '\n'){
+			str.erase(str.begin());
+		}
+	}
+
+	// Remove endl chars at the end of the file
+	while( str.at(str.size()-1) == '\n' ) str.erase(str.size()-1);
+
 	Col_amp_of_str( str );
 }
 
+
 void Col_amp::write_out_Col_amp( std::string filename ) const {
 
 	if ((ca.size() == 0)) {
 		std::cout
 		<< "Col_amp::write_out_Col_amp: The Col_amp is empty."
 		<< std::endl;
 		std::cout.flush();
 		return;
 	}
 
 	std::ofstream outfile(filename.c_str());
 
 
 	if ( !outfile )
 	std::cerr << "Col_amp::write_out_Col_amp: Cannot write out Col_amp as the file \""
 		<< filename.c_str() << "\" could not be opened. (Does the directory exist? Consider creating the directory.)" << std::endl;
 
 
 	outfile << *this;
 }
 
 
 void Col_amp::Col_amp_of_str( const std::string str ){
 
 	// First split the string into Col_str and Polynomial part
 	uint j=0;
 
 	// Check that left and right normal brackets match up
 	int left_brackets=0,right_brackets=0;
 	while (j < str.size()) {
 		if(str.at(j)=='(') left_brackets++;
 		if(str.at(j)==')') right_brackets++;
 		j++;
 	}
 	if(left_brackets != right_brackets){
 		std::cerr << "Col_amp::Col_amp_of_str: The normal brackets, (), in the Col_amp \"" << str <<"\" do not seem to match up. There were "
 				<< left_brackets <<" left bracket(s) and "<< right_brackets << " right bracket(s)." << std::endl;
 		assert( 0 );
 	}
 
 	// Check that left and right curly brackets match up
 	left_brackets=0,right_brackets=0;
 	j=0;
 	while (j < str.size()) {
 		if(str.at(j)=='{') left_brackets++;
 		if(str.at(j)=='}') right_brackets++;
 		j++;
 	}
 	if(left_brackets != right_brackets){
 		std::cerr << "Col_amp::Col_amp_of_str: The curly brackets in the Col_amp \"" << str <<"\" do not seem to match up. There were "
 				<< left_brackets <<" left bracket(s) and "<< right_brackets << " right bracket(s)." << std::endl;
 		assert( 0 );
 	}
 
 	// Check that left and right [] brackets match up
 	j=0;
 	left_brackets=0, right_brackets=0;
 	while (j < str.size()) {
 		if(str.at(j)=='[') left_brackets++;
 		if(str.at(j)==']') right_brackets++;
 		j++;
 	}
 	if(left_brackets != right_brackets){
 		std::cerr << "Col_amp::Col_amp_of_str: The square brackets, [], in the string \"" << str <<"\" do not seem to match up. There were "
 				<< left_brackets <<" left bracket(s) and "<< right_brackets << " right bracket(s)." << std::endl;
 		assert( 0 );
 	}
 
 	if(left_brackets < 1){
 		std::cerr << "Col_amp::Col_amp_of_str: The Col_amp string constructor requires at least one Col_str, i.e."
 				<< " at least one set of square brackets, []. The string \"" << str << "\" contains "
 				<< left_brackets  << std::endl;
 		assert( 0 );
 	}
 
 	// Find various Col_strs, read until final ]
 	j=0;
 	std::string Cs_string;
 	while (j< str.size() ){
 
 		// Skip some white spaces
 		while (j< str.size() and str.at(j)==' ') j++;
 
 		Cs_string.clear();
 		while (j< str.size() and str.at(j)!=']'){
 			Cs_string.push_back( str.at(j) );
 			j++;
 		}
 		// get fina l ]
 		if( j< str.size() and str.at(j)==']' ) Cs_string.push_back( str.at(j) );
 
 		std::cout.flush();
 		j++;
 		if( !Cs_string.empty() ) ca.push_back(  Col_str(Cs_string) );
 	}
 
 	Scalar=Scalar*0;
 }
 
 
 void Col_amp::remove_1_rings() {
 	// Loop Col_strs, if empty, remove
 	for (uint m = 0; m < ca.size(); m++) {
 		// Try removing 1-rings in Col_str
 		// If there was a 1-ring, the col_str will multiply 0 after Quark_line.remove_1_rings()
 		ca.at(m).remove_1_rings();
 		// If the result is multiplying only 0 (in the form of a monomial=0), remove the Col_str
 		if (ca.at(m).Poly.size() == 1 && ca.at(m).Poly.at(0).int_part == 0)
 			erase(m);
 	}
 }
 
 
 void Col_amp::remove_0_rings() {
 	// Loop Col_strs, and remove empty Quark_lines
 	for (uint m = 0; m < ca.size(); m++) {
 		// Try removing 0-rings in Col_str
 		ca.at(m).remove_0_rings();
 		// If the result is empty (no Quark_lines), keep the Polynomial (in scalar),
 		// but remove that Col_str
 		if (ca.at(m).cs.empty()) {
-			Scalar = Scalar + ca.at(m).Poly;
+			Scalar += ca.at(m).Poly;
 			erase(m);
 		}
 	}
 }
 
 
 void Col_amp::remove_empty_Col_strs() {
 	// Loop Col_strs
 	for (uint m = 0; m < ca.size(); m++) {
 		if ( ca.at(m).cs.empty() ){
-			Scalar=Scalar+ca.at(m).Poly;
+			Scalar+=ca.at(m).Poly;
 			erase(m);
 		}
 	}
 }
 
 
 bool Col_amp::gluons_only() const {
 	// Loop over Col_strs
 	for (uint m = 0; m < ca.size(); m++) {
 		if (!ca.at(m).gluons_only())
 			return false;
 	}
 	// If all Cs had gluons only
 	return true;
 }
 
 
 int Col_amp::n_gluon() const {
 	if	(ca.size()>0) return ca.at(0).n_gluon();
 	else{
 		std::cerr << "Col_amp::n_gluon(): ca has no Col_str " << std::endl;
 		return 0;
 	}
 }
 
 
 int Col_amp::n_quark() const {
 	if	(ca.size()>0) return ca.at(0).n_quark();
 	else{
 		std::cerr << "Col_amp::n_quark(): ca has no Col_str " << std::endl;
 		return 0;
 	}
 }
 
 
 int Col_amp::n_gluon_check() const {
 	int ng=n_gluon();
 	for(uint n=0; n< ca.size(); n++)
 		if( ca.at(n).n_gluon() != ng) {
 			std::cerr << "Col_amp::n_gluon_check: The Col_strs in " << ca << " have differently many gluons." << std::endl;
 
 		}
 	return ng;
 }
 
 
 int Col_amp::n_quark_check() const {
 	int nq=n_quark();
 	for(uint n=0; n< ca.size(); n++)
 		if( ca.at(n).n_quark() != nq) {
 			std::cerr << "Col_amp::n_quark_check: The Col_strs in " << ca << " have differently many quarks." << std::endl;
 		}
 	return nq;
 }
 
 
 int Col_amp::longest_quark_line() const{
 
 	int length=0;
 	for ( uint j = 0; j < ca.size(); j++ ) {
 		if( static_cast<int> ( at(j).longest_quark_line() )> length ) length=static_cast<int> ( at(j).longest_quark_line() );
 	}
 
 	return length;
 }
 
 void Col_amp::collect_col_strs() {
 
 	normal_order_col_strs();
 
 	// Special case of empty Col_amp, do nothing
 	if (ca.empty())
 		return;
 
 	// Resulting col_amp
 	col_amp ca_out;
 
 	// Move first Cs to ca_out
 	ca_out.push_back(ca.at(0));
 	ca.erase(ca.begin());
 
 	// Move elements (starting from the beginning) in ca to ca_out
 	// and sort as long as elements remain to sort
 	while (!ca.empty()) {
 
 		// Compare next =0th col_str to all terms in ca_out
 		bool was_found = false;
 		for (uint i = 0; (i < ca_out.size() && !was_found); i++) {
 
 			if (ca.at(0).cs == ca_out.at(i).cs) {
 				was_found = true;
 				// Add Polynomial multiplying the Monomial to Polynomial multiplying
 				// existing term
-				ca_out.at(i).Poly = ca_out.at(i).Poly + ca.at(0).Poly;
+				ca_out.at(i).Poly +=  ca.at(0).Poly;
 				// See if Polynomial can be simplified
 				//ca_out.at(i).Poly=simplify( ca_out.at(i).Poly );
 			}
 		}
 		// If the Col_str wasn't represented add info
 		if (!was_found)
 			ca_out.push_back(ca.at(0));
 
 		// Erase Cs after saving info
 		ca.erase(ca.begin());
 	}
 	ca = ca_out;
 }
 
 
 void Col_amp::simplify() {
 	remove_1_rings();
 	remove_0_rings();
 
 	// Simplify scalar factor
 	Scalar.simplify();
 	// Collect similar col_str's
 	collect_col_strs();
 
 	// Loop over Col_strs
 	for (uint m = 0; (m < ca.size() ); m++) {
 
 		// Simplify Col_strs
 		ca.at(m).simplify();
 
 		// If there's only one term in the Polynomial, and the term is 0
 		// remove Col_str
 		if (ca.at(m).Poly.size() == 1 && ca.at(m).Poly.at(0).int_part == 0){
 			erase(m);
 		}
 	}
 }
 
 
 void Col_amp::conjugate( ) {
 
 	Scalar.conjugate();
 
 	// Take conjugate by reversing order of all partons in each Quark_line
 	// Loop over Col_strs
 	for (uint i=0; i < ca.size(); i++ ){
 		ca.at(i).conjugate();
 	}
 }
 
 
 void Col_amp::contract_next_neighboring_gluons(  )  {
 	// Loop over Col_str's
 	for (uint m = 0; m < ca.size(); m++) {
 		ca.at(m).contract_next_neighboring_gluons( );
 	}
 	return;
 }
 
 void Col_amp::contract_2_rings( ){
 	// Loop over Col_str's
 	for (uint m = 0; m < size(); m++) {
 		at(m).contract_2_rings( );
 	}
 	return;
 }
 
 
 void Col_amp::contract_Quark_line_gluons( Quark_line & Ql )  {
 
 	// Check that all quark indices have been removed
 	if (Ql.open){
 		std::cerr
 		<< "Col_amp::contract_Quark_line_gluons(Ql): all quark indices were not contracted in " << Ql << std::endl;
 	}
 
 	if( !ca.empty() or (Scalar.size()==!1 or Scalar.at(0).int_part!=0 ) ){
 		std::cerr
 		<< "Col_amp::contract_Quark_line_gluons(Ql): This member function "
 		<< "stores the result from contracting the Quark_line in the Col_amp itself. "
 		<< "It therefore expects an empty initially Col_amp, but it was:" << *this << std::endl;
 	}
 
 	// If the Quark_line was empty, return a Col_amp with info in Col_str
 	if (Ql.empty()) {
 		Col_str Cs;
 		// Move Polynomial to Col_str
 		Cs.Poly = Ql.Poly;
 		Ql.Poly.clear();
 		Cs.cs.push_back(Ql);
 		ca.push_back(Cs);
 		return;
 	}
 
 	// To keep track if partner was found or not
 	bool found_pair = false;
 
 	// Take first term and look for partner
 	for (uint j1 = 0; j1 < Ql.ql.size() - 1; j1++) {
 		int the_g = Ql.ql.at(j1);
 		// Look for same g
 		for (uint j2 = j1 + 1; j2 < Ql.ql.size(); j2++) {
 			// if same g found
 			if (Ql.ql.at(j2) == the_g) {
 
 				// Special case that the gluons are neighbors
 				if (j2 == j1 + 1 or (!Ql.open && j1 == 0 && j2 == Ql.ql.size()
 						- 1)) {
 					Ql.contract_neighboring_gluons( j1 );
 					// Make a Col_str out of the Quark_line
 					Col_str Cs;
 					Cs.cs.push_back(Ql);
 					ca.push_back(Cs);
 					simplify();
 					return;
 				}
 				// Special case that the gluons are next to neighbors
 				else if (j2 == j1 + 2 //normal case
 						or (!Ql.open && j1 == 0 && j2 == Ql.ql.size()- 2) 	//first and second last
 				or (!Ql.open && j1 == 1 && j2 == Ql.ql.size()- 1) //second and last
 				) {
 					if (j2 == j1 + 2)
 						Ql.contract_next_neighboring_gluons( j1 );
 					if ((!Ql.open && j1 == 0 && j2 == Ql.ql.size() - 2))
 						Ql.contract_next_neighboring_gluons( Ql.ql.size() - 2);
 					if( (!Ql.open && j1 == 1 && j2 == Ql.ql.size()- 1) )
 						Ql.contract_next_neighboring_gluons( Ql.ql.size() - 1);
 
 					// Make a Col_str out of the Quark_line
 					Col_str Cs;
 					Cs.cs.push_back(Ql);
 					ca.push_back(Cs);
 					simplify();
 					return;
 				}
 				// normal case, not neighbors or next to neighbors
 				else{
 					// Make a Col_str out of the Quark_line
 					Col_str Cs;
 
 					// Move color factor to multiply Cs instead of Ql
 					Cs.Poly = Ql.Poly;
 					Ql.Poly.clear();
 					Cs.cs.push_back(Ql);
 
 					// Make two copies to store both terms
 					ca.push_back(Cs);
 					ca.push_back(Cs);
 
 					std::pair <Quark_line, Quark_line> Ql_parts=ca.at(0).cs.at(0).split_Quark_line( j1, j2 );
 					Col_str Cs_Ql_parts;
 					Cs_Ql_parts.cs.push_back(Ql_parts.first);
 					Cs_Ql_parts.cs.push_back(Ql_parts.second);
 
 					ca.at(0)=Cs_Ql_parts;
 
 					// This is multiplying a factor TR
 					Monomial Mon_tmp;
 					Mon_tmp.pow_TR = 1;
 
-					ca.at(0).Poly = ca.at(0).Poly * Mon_tmp;
+					ca.at(0).Poly *=  Mon_tmp;
 					// The split can generate new (next to) neighbors
 					ca.at(0).contract_next_neighboring_gluons( );
 
 					// The second Nc suppressed term, obtained by just removing gluon
 					// remove g
 					quark_line::iterator it1 = ca.at(1).cs.at(0).ql.begin() + j1;
 					quark_line::iterator it2 = ca.at(1).cs.at(0).ql.begin() + j2;
 					ca.at(1).cs.at(0).ql.erase(it2);
 					ca.at(1).cs.at(0).ql.erase(it1);
 					// Multiply with -TR/(Nc)
 					Mon_tmp.pow_TR = 1;
 					Mon_tmp.pow_Nc = -1;
 					Mon_tmp.int_part = -1;
 
-					ca.at(1).Poly = ca.at(1).Poly * Mon_tmp;
+					ca.at(1).Poly *= Mon_tmp;
 
 					// A pair was found, use for stopping
 					found_pair = true;
 				}
 			}
 			if (found_pair)
 				break; // Stop j2 loop
 		}
 		if (found_pair)
 			break; // Stop j1 loop
 	}
 
 	// If a pair was never found return the info of the original Ql
 	// but with the Polynomial moved to the Col_str
 	if(!found_pair){
 		Col_str Cs;
 		Cs.Poly=Ql.Poly;
 		Ql.Poly.clear();
 		Cs.cs.push_back(Ql);
 		ca.push_back(Cs);
 	}
 
 	// Remove possible 0 and 1-rings
 	remove_1_rings();
 	remove_0_rings();
 
 	return;
 }
 
 
 void Col_amp::contract_Quark_line_gluons( Col_str & Cs ) {
 
 	if( !ca.empty() or (Scalar.size()==!1 or Scalar.at(0).int_part!=0 ) ){
 		std::cerr
 		<< "Col_amp::contract_Quark_line_gluons(Cs): This member function "
 		<< "stores the result from contracting the Quark_line in the Col_amp itself. "
 		<< "It therefore expects an empty initially Col_amp, but it was:" << *this << std::endl;
 	}
 
 	Cs.remove_1_rings();
 	Cs.remove_0_rings();
 
 	// If the Cs is empty there is no color structure
 	if( Cs.empty() ) {
 		ca.push_back(Cs);
 		return;
 	}
 
 	// Make sure to get Poly, both from Cs and Ql.at(0)
 	// First the result of the contracted Quakr_line is stored in this Col_amp
 	contract_Quark_line_gluons( Cs.at(0) );
 	// if the Col_str had a Polynomial we multiply with it here
 	*this=*this*Cs.Poly;
 
 	// Loop over Quark_lines
 	for( uint i=1; i < Cs.size(); i++ ){
 
 		// If the Quark_line is short do nothing with it as no gluons
 		// can not be neighbors or next to neighbors
 		if ( Cs.at(i).size()< 6 ){
-			*this=*this*Col_str( Cs.at(i) );
+			//*this=*this*Col_str( Cs.at(i) );
+			*this=*this*Cs.at(i);
+
 		}
 		else{
 			Col_amp contracted_Ql;
 			contracted_Ql.contract_Quark_line_gluons( Cs.at(i) );
 			*this*=contracted_Ql;
 		}
 	}
 
 	simplify();
 
 	return;
 }
 
 void Col_amp::contract_Quark_line_gluons( ) {
 
 	// If all the Col_strs are short nothing can be gained
 	// compared to contract_next_neighboring gluons, do nothing
 	// If there is no remaining color structure, do nothing
 	if ( longest_quark_line() < 6 ) return;
 
 	// Make a copy of the old ca part (from this Ca)
 	Col_amp Ca_copy;
 	Ca_copy.ca=ca;
 
 	// Keep the scalar part, but replace the ca part
 	ca.clear();
 
 	for ( uint i = 0; i < Ca_copy.size(); i++ ) {
 		Col_amp Ca_from_Cs;
 		Ca_from_Cs.contract_Quark_line_gluons( Ca_copy.at(i) );
 		*this+=Ca_from_Cs;
 	}
 }
 
 void Col_amp::contract_quarks( const Col_amp & Ca1, const Col_amp & Ca2 ) {
 
 	if( !ca.empty() or (Scalar.size()==!1 or Scalar.at(0).int_part!=0 ) ){
 		std::cerr
 		<< "Col_amp::contract_quarks(Ca1, Ca2): This member function "
 		<< "stores the result from contracting quarks in the Col_amp itself. "
 		<< "It therefore expects an empty initially Col_amp, but it was:" << *this << std::endl;
 	}
 
 
 	if(Ca1.empty()){
 		std::cerr << "Col_amp::contract_quarks: Expects non-empty Col_amps, got first argument "
 				<< Ca1 << std::endl;
 		assert(0);
 	}
 	if(Ca2.empty()){
 		std::cerr << "Col_amp::contract_quarks: Expects non-empty Col_amps, got second argument "
 				<< Ca2 << std::endl;
 		assert(0);
 	}
 
 	//Col_amp Ca_res;
 	Col_amp Ca1_copy=Ca1;
 	Col_amp Ca2_copy=Ca2;
 
 	// Make sure the Col_strs are not empty "[]"=1, as all indices contracted
 	Ca1_copy.remove_empty_Col_strs();
 	Ca1_copy.remove_empty_Col_strs();
 
 	// Loop over Col_strs, and contract quarks between all possible combinations
 	// Loop over Col_strs in Ca1
 	for(uint m1=0; m1 < Ca1_copy.ca.size(); m1++ ){
 		// Loop over Col_strs in Ca2
 		for(uint m2=0; m2 < Ca2_copy.ca.size(); m2++ ){
 			Col_str Cs_tmp;
 			Cs_tmp.contract_quarks( Ca1_copy.ca.at(m1), Ca2_copy.ca.at(m2));
 			ca.push_back( Cs_tmp );
 		}
 	}
 
 	return;
 }
 
 void Col_amp::contract_a_gluon( Col_str & Cs )  {
 
 	if( Cs.n_quark()!=0 ){
 		std::cerr << "Col_amp::contract_a_gluon(Cs): Expects Col_str with gluons only, got Cs" <<
 				std::endl;
 	}
 
 
 	if( !ca.empty() or (Scalar.size()==!1 or Scalar.at(0).int_part!=0 ) ){
 		std::cerr
 		<< "Col_amp::contract_Quark_line_gluons(Cs): This member function "
 		<< "stores the result from contracting the Quark_line in the Col_amp itself. "
 		<< "It therefore expects an empty initially Col_amp, but it was:" << *this << std::endl;
 	}
 
 	//If the Col_str is empty, or the first ql is empty return it as Col_amp
 	if ( Cs.empty() or Cs.cs.at(0).empty() ) {
 		ca.push_back(Cs);
 		return;
 	}
 
 	// Pick first gluon
 	int the_g = Cs.at(0, 0);
 	std::vector<int> place;
 	place.push_back(0);
 	place.push_back(0);
 
 	// For storing place of second gluon
 	std::vector<int> place2;
 
 	// Locate the same gluon
 	for (uint i2 = 0; i2 < Cs.cs.size(); i2++) {
 		for (uint j2 = 0; j2 < Cs.cs.at(i2).ql.size(); j2++) {
 			// Make sure it is a different gluon
 			if ((i2 != 0 or j2 != 0) && Cs.at(i2, j2) == the_g) {
 				place2.push_back(i2);
 				place2.push_back(j2);
 			}
 		}
 	}
 
 	// If the gluon was not found, something went wrong
 	if (place2.empty()) {
 		std::cerr << "Col_functions::contract_a_gluon: The gluon " << the_g
 				<< " was only found once " << Cs;
 	    std::cerr.flush();
 		assert( 0 );
 	}
 
 	// If the gluon was found in same Ql, use contract_Ql_gluons
 	if (place.at(0) == place2.at(0)) {
 		contract_Quark_line_gluons( Cs );
 		return;
 	}
 	// If the removed gluon was part of a two-ring
 	else if( Cs.cs.at(place.at(0)).ql.size()==2 or Cs.cs.at(place2.at(0)).ql.size()==2){
 		Cs.contract_2_rings( );
 		ca.push_back(Cs);
 		return;
 	}
 	else
 	{
 	// The result is a sum of two terms, to contain these
 	Col_str Cs1 = Cs;
 	Col_str Cs2;
 
 	// The Nc suppressed term, obtained by just removing the g
 	// location of first and second g to remove
 	quark_line::iterator it1 = Cs1.cs.at(place.at(0)).ql.begin();
 	quark_line::iterator it2 = Cs1.cs.at(place2.at(0)).ql.begin() + place2.at(1);
 	// Remove the gluon in both places
 	Cs1.cs.at(place2.at(0)).ql.erase(it2);
 	Cs1.cs.at(place.at(0)).ql.erase(it1);
 
 
 	// The non-suppressed term, obtained by joining the ql's (where the g is removed)
 	Cs2 = Cs1;
 	// Construct the contracted ql by
 	// 1, taking the first part of the 2nd ql, by erasing everything after the erased gluon
 	Quark_line ql_first_part= Cs.cs.at(place2.at(0)).before( place2.at(1) );
 	// 2, the in between part=first ql, the contracted gluon is already erased
 	Quark_line middle_part=Cs2.cs.at(place.at(0));
 	// 3, Last part equal to second part of 2nd ql
 	Quark_line last_part= Cs.cs.at(place2.at(0)).after( place2.at(1) );
 	// The new combined Ql, to replace the 2nd involved Qualk_line
 	Quark_line new_Ql=ql_first_part;
 	new_Ql.append( middle_part.ql );
 	new_Ql.append( last_part.ql );
 	// Copy Polynomial info, both from first and 2nd involved Ql
 	new_Ql.Poly=Cs.cs.at(place2.at(0)).Poly*Cs.cs.at(place.at(0)).Poly;
 	// Replace the first involved Ql with the constructed Ql
 	Cs2.cs.at(0)=new_Ql;
 
 	// erase moved ql
 	col_str::iterator it = Cs2.cs.begin() + place2.at(0);
 	Cs2.cs.erase(it);
 
 	// Multiply with TR for non-suppressed term
 	Monomial Mon_tmp;
 	Mon_tmp.pow_TR = 1;
-	Cs2.Poly = Cs2.Poly * Mon_tmp;
+	Cs2.Poly *= Mon_tmp;
 
 	// Multiply with -TR/Nc for suppressed term
 	Mon_tmp.pow_Nc = -1;
 	Mon_tmp.int_part = -1;
-	Cs1.Poly = Cs1.Poly * Mon_tmp;
+	Cs1.Poly *= Mon_tmp;
 
 	// Look for simple simplifications in Cs1
 	// This has to be done after Cs1 is used to construct Cs2
 	// After the removal there may be new next to neighbors in the affected ql's
 	// First affected Ql
 	// look forward at nn
 	Cs1.cs.at(place.at(0)).contract_neighboring_gluons(place.at(0));
 	// look backward at nn
 	Cs1.cs.at(place.at(0)).contract_neighboring_gluons( place.at(0) - 1);
 	// look forward at next nei
 	Cs1.cs.at(place.at(0)).contract_next_neighboring_gluons( place.at(0) );
 	// look backward at next nei
 	Cs1.cs.at(place.at(0)).contract_next_neighboring_gluons( place.at(0) - 2);
 	// Second affected ql
 	// look forward at nn
 	Cs1.cs.at(place2.at(0)).contract_neighboring_gluons( place2.at(0));
 	// look backward at nn
 	Cs1.cs.at(place2.at(0)).contract_neighboring_gluons( place2.at(0) - 1);
 	// look forward at next nei
 	Cs1.cs.at(place2.at(0)).contract_next_neighboring_gluons( place2.at(0) );
 	// look backward at next nei
 	Cs1.cs.at(place2.at(0)).contract_next_neighboring_gluons( place2.at(0) - 2);
 
 	ca.push_back(Cs1);
 	ca.push_back(Cs2);
 
 	// remove rings with just one gluon (=0)
 	remove_1_rings();
 	// remove rings with no partons (=Nc, if closed)
 	remove_0_rings();
 	}
 	return;
 
 }
 
 
 void Col_amp::contract_a_gluon( ) {
 
   // If the Ca has only an empty Col_str or a Col_str with an empty Quark_line, do nothing
   if( size()==1 && ( at(0).empty() or at(0).cs.at(0).empty())) return ;
 
 
   // Copy ca to copy, not that the ca is in the copy and the Scalar is still in this Ca
   Col_amp Ca_copy;
   Ca_copy.ca=ca;
   ca.clear();
 
   // Make one contraction in each Col_str
 	for ( uint i=0; i< Ca_copy.ca.size(); i++ ) {
 
 			// Contract one gluon in Col_str
 			Col_amp Ca_part;
 			// The copy has no Scalar, so adding does not double count Scalar
 			Ca_part.contract_a_gluon( Ca_copy.ca.at(i) );
 			// ... and add resulting Col_amp to Ca_res
 			*this+=Ca_part;
 	}
 	return;
 }
 
 
 void Col_amp::contract_all_gluons( Col_str & Cs )  {
 
 	if( !ca.empty() or (Scalar.size()==!1 or Scalar.at(0).int_part!=0 ) ){
 		std::cerr
 		<< "Col_amp::contract_all_gluons(Cs): This member function "
 		<< "stores the result from contracting the Quark_line in the Col_amp itself"
 		<< "It therefore expects an empty initially Col_amp, but it was:" << *this << std::endl;
 	}
 
 	ca.push_back( Cs );
 	contract_all_gluons();
 
 	return ;
 }
 
 
 void Col_amp::contract_all_gluons( ) {
 	//std::cout << "Col_functions::contract_all_gluons: incoming " << Ca << std::endl;
 
 
 	// Make sure the Col_strs are not empty "[]"=1, as all indices contracted
 	remove_empty_Col_strs();
 	remove_empty_Col_strs();
 
 	// Check that all quark indices have been removed
 	if ( !gluons_only() ) {
 		std::cerr << "Col_amp::contract_all_gluons(Ca): Error, all quark indices were not contracted in " << *this << std::endl;
 		std::cerr.flush();
 		assert( 0 );
 	}
 
 	// First normal order and look for simple simplification
 	simplify();
 
 	Col_amp Ca_old; // For comparison
 	// Contract remaining gluons as long as result keep changing
 		// Start with contractions only giving one term
-		while (Ca_old != *this) {
+		while ( Ca_old != *this ) {
 
 			Ca_old = *this;
 
 			// Contract gluons from 2-ring as this gives only one term
 			// and may result in new neighbors or next to neighbors
 			contract_2_rings( );
-
 			//std::cout << "Col_functions::contract_all_gluons: after 2 rings " << Ca << std::endl;
 
 
 			// Remove neighboring and next to neighboring gluon indices
 			// in each quark_line as this gives only (at most) one term
 			contract_next_neighboring_gluons( );
-			//std::cout << "Col_functions::contract_all_gluons: after nn " << Ca << std::endl;
+			contract_2_rings( );
 
 
 			// Contract gluons within same quark_line
 			// This will give >1 term, but at least rings will be shorter and shorter
-			contract_Quark_line_gluons(  );
-			//std::cout << "Col_functions::contract_all_gluons: after Qlg " << Ca << std::endl;
-
-
+			contract_Quark_line_gluons( );
+			contract_2_rings( );
 			// To maximize number of CF's
 			contract_next_neighboring_gluons( );
-			//std::cout << "Col_functions::contract_all_gluons: after nn " << Ca << std::endl;
+			contract_2_rings( );
+
 
 			// Make "arbitrary" gluon contraction when no simple or Ql contraction remains
 			// In each Col_str, contract the first gluon in the first Ql
 			contract_a_gluon( );
 
+
 			// Look if same Col_str is represented more than once in the Col_amp and simplify
 			simplify();
 
 		} //end of while (Ca keeps changing)
 
 		return;
 }
 
 
 std::ostream& operator<<(std::ostream& out, const Col_amp & Ca) {
 	int max = Ca.ca.size();
 
 	// Write out Scalar part if it is not obviously 0
 	Polynomial Poly0; // For comparison, the default Polynomial=1
 	Poly0=Poly0*0;
 	if( ! (Ca.Scalar==Poly0) ) {
 		out << Ca.Scalar << " + ";
 	}
 
 	// Print color structure
 	if (max == 0)
 		out << "{[]}";
 	else {
 		for (int i = 0; i < max - 1; i++) {
 			out << Ca.ca.at(i) << " + ";
 		}
 		out << Ca.ca.at(max - 1);
 	}
 	return out;
 }
 
 
 bool operator==( const Col_amp & Ca1, const Col_amp & Ca2 ) {
 
 	// The Ca's should have equal length
 	if (Ca1.ca.size() != Ca2.ca.size())
 		return false;
 
 	// All Col_strs should be the same
 	for (uint i = 0; i < Ca1.ca.size(); i++) {
 		if (Ca1.ca.at(i) != Ca2.ca.at(i))
 			return false;
 	}
 	// The scalar part should be the same
 	if (Ca1.Scalar!=Ca2.Scalar) return false;
 	return true;
 }
 
 
 bool operator!=( const Col_amp & Ca1,const Col_amp & Ca2 ) {
 	if (Ca1 == Ca2)
 		return false;
 	else
 		return true;
 }
 
 
 Col_amp operator+( const Col_amp & Ca, const Col_str & Cs ){
 
 	Col_amp Ca_out(Ca);
 
 	// Add Col_str Cs to Ca
 	Ca_out.ca.push_back(Cs);
 
 	return Ca_out;
 }
 
 
 Col_amp operator+( const Col_str & Cs, const Col_amp & Ca ){
 
 	return Ca+Cs;
 }
 
 
 Col_amp operator+( const Col_amp & Ca1, const Col_amp & Ca2 ){
 
 	// To contin the result
 	Col_amp Ca_out;
 
 	// Add Scalars
 	Ca_out.Scalar = Ca1.Scalar +Ca2.Scalar;
 
 	// Add col_strs of Ca1 and Ca2 to Ca_out
 	Ca_out.append(Ca1.ca);
 	Ca_out.append(Ca2.ca);
 
 	return Ca_out;
 }
 
 
 Col_amp operator+=( Col_amp & Ca1, const Col_amp & Ca2 ){
 
 	// Add Scalars
 	Ca1.Scalar+=Ca2.Scalar;
 
 	// Add col_strs of Ca1 and Ca2 to Ca_out
 	Ca1.append(Ca2.ca);
 
 	return Ca1;
 }
 
+Col_amp operator+=( Col_amp & Ca, const Col_str & Cs ){
+
+	// Add Col_str Cs to Ca
+	Ca.ca.push_back(Cs);
+
+	return Ca;
+}
+
 Col_amp operator-( const Col_amp & Ca1, const Col_amp & Ca2 ) {
 
 	Col_amp Ca2_out(Ca2);
 
-	// 	Change sign of Ca2 in Polynomial
+	// 	Change sign of Ca2 in Scalar
 	Ca2_out.Scalar=Ca2_out.Scalar*(-1);
 
 	// Loop over Col_strs to change sign for each term
 	for( uint m=0; m < Ca2_out.ca.size(); m++ ) {
 		Ca2_out.ca.at(m).Poly=Ca2_out.ca.at(m).Poly*(-1);
 	}
 
 	// Now the subtraction is equal to an addition
 	return Ca1+Ca2_out;
 }
 
 
+Col_amp operator-( const Col_amp & Ca, const Col_str & Cs ) {
+
+	Col_amp Ca_out(Ca);
+
+	Col_str Cs_tmp=Cs*(-1);
+
+	return Ca_out+Cs_tmp;
+}
+
+Col_amp operator-( const Col_str & Cs, const Col_amp & Ca ) {
+
+	return Ca-Cs;
+}
+
 Col_amp operator*( const Col_amp & Ca, const int i ){
 
 	Col_amp Ca_res(Ca);
 	// Multiply scalar factor (Polynomial)
 	Ca_res.Scalar=Ca_res.Scalar*i;
 
 	// Loop over Col_strs and multiply Polynomials
 	for(uint m=0; m< Ca_res.ca.size(); m++){
 		// Multiply Polynomial of Col_str with the int
 		Ca_res.ca.at(m).Poly=Ca_res.ca.at(m).Poly*i;
 	}
 	return Ca_res;
 }
 Col_amp operator*( const int i, const Col_amp & Ca ) {
 
 	return Ca*i;
 }
 
 
 Col_amp operator*(const Col_amp & Ca, const cnum c){
 	Col_amp Ca_res = Ca;
 	// Multiply scalar factor (Polynomial)
-	Ca_res.Scalar = Ca_res.Scalar * c;
+	Ca_res.Scalar *= c;
 
 	// Loop over Col_strs and multiply Polynomials
 	for (uint m = 0; m < Ca_res.ca.size(); m++) {
 		// Multiply Polynomial of Col_str with the complex number
-		Ca_res.ca.at(m).Poly = Ca_res.ca.at(m).Poly * c;
+		Ca_res.ca.at(m).Poly *= c;
 	}
 	return Ca_res;
 }
 Col_amp operator*( const cnum c, const Col_amp & Ca ){
 
 	return Ca*c;
 }
 
 
 Col_amp operator*( const Col_amp & Ca, const double d ){
 	Col_amp Ca_res = Ca;
 	// Multiply scalar factor (Polynomial)
-	Ca_res.Scalar = Ca_res.Scalar * d;
+	Ca_res.Scalar *=  d;
 	// Loop over Col_strs and multiply Polynomials
 	for (uint m = 0; m < Ca_res.ca.size(); m++) {
 		// Multiply Polynomial of Col_str with the complex number
-		Ca_res.ca.at(m).Poly = Ca_res.ca.at(m).Poly * d;
+		Ca_res.ca.at(m).Poly *= d;
 	}
 	return Ca_res;
 }
 Col_amp operator*( const double d, const Col_amp & Ca ) {
 
 	return Ca*d;
 }
 
 
 Col_amp operator*( const Col_amp & Ca, const Monomial & Mon ){
 
 	// To contain result
 	Col_amp Ca_out(Ca);
 
 	// Multiply scalar factor (Polynomial)
-	Ca_out.Scalar=Ca_out.Scalar*Mon;
+	Ca_out.Scalar *= Mon;
 
 	// Loop over Col_strs and multiply Polynomials
 	for(uint m=0; m< Ca_out.ca.size(); m++){
 		// Multiply Polynomial of Col_str with the complex number
-		Ca_out.ca.at(m).Poly=Ca_out.ca.at(m).Poly*Mon;
+		Ca_out.ca.at(m).Poly *= Mon;
 	}
 	return Ca_out;
 }
 Col_amp operator*(const Monomial & Mon, const Col_amp & Ca){
 	return Ca*Mon;
 }
 
 
 Col_amp operator*(const Col_amp & Ca, const Polynomial & Poly){
 
 	Col_amp Ca_out(Ca);
 
 	// Multiply scalar factor (Polynomial)
 	Ca_out.Scalar=Ca_out.Scalar*Poly;
 	// Loop over Col_strs and multiply Polynomials
 	for(uint m=0; m< Ca_out.ca.size(); m++){
 
 		// Multiply Polynomial of Col_str with the Polynomial
 		Ca_out.ca.at(m).Poly=Ca_out.ca.at(m).Poly*Poly;
 	}
 	return Ca_out;
 }
 Col_amp operator*( const Polynomial & Poly, const Col_amp & Ca ){
 	return Ca*Poly;
 }
 
 
 Col_amp operator*( const Col_amp & Ca, const Col_str & Cs ){
 
 	Col_amp Ca_res;
 
 	// The Scalar part of Ca gives rise to a Col_str=Cs*Scalar when multiplied with Cs
 	// but this should only be kept if the scalar Polynomial is non-zero
 	if(! (Ca.Scalar.size()==1 and Ca.Scalar.at(0).int_part==0) ) {
 		Col_str Cs_tmp=	Ca.Scalar*Cs;
 		Ca_res=Ca_res+Cs_tmp;
 	}
 
 	// Multiply each Col_str in Col_amp with Cs
 	for(uint m=0; m< Ca.ca.size(); m++){
 		// Multiply Col_str in Col_amp with the Col_str
 		Col_str Cs_tmp=	Ca.ca.at(m)*Cs;
-		Ca_res=Ca_res+Cs_tmp;
+		//Ca_res=Ca_res+Cs_tmp;
+		Ca_res+=Cs_tmp;
+
 	}
 
 	return Ca_res;
 }
 Col_amp operator*( const Col_str & Cs, const Col_amp & Ca ){
 
 	return Ca*Cs;
 }
 
 
+Col_amp operator*( const Col_amp & Ca, const Quark_line & Ql ){
+
+	Col_amp Ca_res;
+
+	// The Scalar part of Ca gives rise to a Col_str=Cs*Scalar when multiplied with Cs
+	// but this should only be kept if the scalar Polynomial is non-zero
+	if(! (Ca.Scalar.size()==1 and Ca.Scalar.at(0).int_part==0) ) {
+		Col_str Cs_tmp=	Ca.Scalar*Col_str(Ql);
+		Ca_res+=Cs_tmp;
+	}
+
+	// Multiply each Col_str in Col_amp with Cs
+	for(uint m=0; m< Ca.ca.size(); m++){
+		// Multiply Col_str in Col_amp with the Col_str
+		Col_str Cs_tmp=	Ca.ca.at(m)*Ql;
+		//Ca_res=Ca_res+Cs_tmp;
+		Ca_res+=Cs_tmp;
+	}
+
+	return Ca_res;
+}
+Col_amp operator*( const Quark_line & Ql, const Col_amp & Ca ){
+
+	return Ca*Ql;
+}
+
+
 Col_amp operator*(const Col_amp & Ca1, const Col_amp & Ca2){
 
 	Col_amp Ca_res;
 
 	Ca_res=Ca2*Ca1.Scalar;
 
 	// Multiply each Col_str in Col_amp Ca1 with Ca2 and add to result
 	for( uint m=0; m< Ca1.ca.size(); m++){
 		// Multiply Col_str in Col_amp with the Col_str
 		Ca_res+=Ca1.ca.at(m)*Ca2;
 	}
 
 	return Ca_res;
 }
 
 Col_amp operator*=( Col_amp & Ca1, const Col_amp & Ca2){
 
 	Col_amp Ca_res;
 	Col_amp Ca1_old=Ca1;
 
 	Ca1=Ca2*Ca1_old.Scalar;
 
 	// Multiply each Col_str in Col_amp Ca1 with Ca2 and add to result
 	for( uint m=0; m< Ca1_old.ca.size(); m++){
 		// Multiply Col_str in Col_amp with the Col_str
 		Ca1+=Ca1_old.ca.at(m)*Ca2;
 	}
 
 	return Ca1;
 }
 
 }// end namespace ColorFull
diff --git a/MatrixElement/Matchbox/ColorFull/Col_amp.h b/MatrixElement/Matchbox/ColorFull/Col_amp.h
--- a/MatrixElement/Matchbox/ColorFull/Col_amp.h
+++ b/MatrixElement/Matchbox/ColorFull/Col_amp.h
@@ -1,292 +1,310 @@
 // -*- C++ -*-
 
 /*
  * Col_amp.h
  *	Contains the declarations of the class Col_amp, related types and operators
  *  Created on: Jul 7, 2010
  *  Author: Malin Sjodahl
  */
 
 #ifndef COLORFULL_Col_amp_h
 #define COLORFULL_Col_amp_h
 
 #include "Col_str.h"
 
 namespace ColorFull {
 
 /// Define a type to contain a linear combination of color structures,
 /// a col_amp contains the actual color amplitude in a Col_amp.
 typedef std::vector<Col_str> col_amp;
 
 
 /// The full color amplitude is Scalar + Cs1+Cs2+Cs3...
 /// Col_amp is a class to contain info on several Col_strs, a color amplitude.
 class Col_amp {
 
 public:
 
-	/// Default constructor
+	/// Default constructor, sets Scalar=0, and leaves ca empty.
 	Col_amp() {Scalar = Scalar * 0;}
 
 	/// Constructor taking a string as argument.
 	/// The string should be of form
 	/// Polynomial1* col_str1 + Polynomial2*col_str2,
 	/// for example:
 	/// Col_amp Ca("13*Nc*[(1, 3, 4, 2)] +2 TR 5 Nc^(-3) [(1, 4) (3,  2)]").
 	/// (The Polynomials should multiply the whole col_strs in square brackets,
-	/// rather than a quark_line inside the [] brackets.)
+	/// rather than a quark_line inside the []-brackets.)
 	Col_amp( const std::string str ){Col_amp_of_str( str );}
 
 	/// Constructor converting a Col_str to a Col_amp.
 	Col_amp( Col_str Cs ) {
 		Scalar = Scalar * 0;
 		ca.push_back(Cs);
 	}
 
-	/// To actually contain the info of the Col_strs, ca=Cs1+Cs2+Cs3+... .
+	/// To actually contain the information about the Col_strs, ca=Cs1+Cs2+Cs3+... .
 	/// Technically the ca is a vector of Col_strs, a col_amp.
 	col_amp ca;
 
-	/// Scalar is Polynomial for collecting color factors when the color structure
-	/// has been fully contracted.
-	/// The full color amplitude is Scalar + Cs1+Cs2+Cs3..., the Polynomial should thus be non-zero
-	/// only if all indices can be contracted.
+	/// Scalar is Polynomial for collecting color factors appearing when
+	/// the color structure has been fully contracted.
+	/// The full color amplitude is Scalar + Cs1+Cs2+Cs3....
+	/// Scalar should thus be non-zero only if all indices can be contracted.
 	Polynomial Scalar;
 
 	/// Reads in the Col_amp to the member ca from the file filename.
 	/// (This is for reading in an actual color amplitude,
 	/// nothing is read in the the Polynomial member scalar.)
 	void read_in_Col_amp( std::string filename );
 
 	/// Function for writing out the Col_amp to a file
 	/// with name filename.
 	void write_out_Col_amp( std::string filename ) const;
 
 	/// Returns the Col_str at place i.
 	const Col_str & at( int i ) const{ return ca.at(i); }
 
 	/// Returns the Col_str at place i.
 	Col_str & at( int i ) {return ca.at(i);}
 
 	/// The size of the col_amp ca.
 	uint size() const {return ca.size();}
 
 	/// Is the col_amp empty?
 	bool empty() const { return ca.empty(); }
 
-	/// Erase information in col_amp.
+	/// Erases the information in the col_amp.
 	void clear() { ca.clear(); }
 
 	/// Erases the Col_str at place i.
 	void erase( int i );
 
+	/// Appends a Col_str to the data member ca.
+	void append( Col_str Cs ) {ca.push_back( Cs );}
+
 	/// Appends the Col_strs in ca_in to the col_amp member ca.
 	void append( col_amp ca_in );
 
+
 	// Functions for probing the Col_amp
 
 	/// Checks if the Col_amp only contains gluons, i.e., if all Quark_lines are closed.
 	bool gluons_only() const;
 
 	/// Returns the number of gluons in the Col_amp as the number of gluons in the first Col_str.
 	/// Note that the other Col_strs could have a different number of (contracted) gluons.
 	/// (Intended for tree-level Col_ams with only one Col_str.)
 	int n_gluon() const;
 
 	/// Returns the number of quarks  in the Col_amp as the number of quarks in the first Col_str.
 	/// Note that the other Col_strs could have a different number of (contracted) quarks.
 	/// (Intended for tree-level Col_ams with only one Col_str.)
 	int n_quark() const;
 
 	/// Returns the number of quarks in the Col_amp after checking that each Col_str
 	/// has the same number of quarks.
 	int n_quark_check() const;
 
 	/// Returns the number of gluons in the Col_amp after checking that each Col_str
 	/// has the same number of gluons.
 	int n_gluon_check() const;
 
 	/// Returns the length of the longest Quark_line in any Col_str.
 	int longest_quark_line() const;
 
 	// Functions for manipulating the Col_amp
 
 	/// Remove Col_strs with quark_lines with just 1 gluon, they are 0 as Tr[t^a]=0.
 	void remove_1_rings();
 
-	/// Remove quark_lines with no gluons, they are N if closed, and defined to be 1 if open.
+	/// Remove quark_lines with no gluons, they are Nc if closed, and defined to be 1 if open.
 	void remove_0_rings();
 
 	/// Removes empty Col_strs, an empty Col_str means that all indices have been contracted,
 	/// so the Col_str is equal to its Polynomial, which is moved to the scalar part
 	/// of the Col_amp.
 	void remove_empty_Col_strs();
 
-	/// Compares col_strs in a Col_amp, to collect similar col_strs,
+	/// Compares col_strs in a Col_amp to collect similar col_strs
 	/// and only store once in ca.
 	void collect_col_strs();
 
 	/// Normal orders all col_strs in ca.
 	void normal_order_col_strs();
 
 	/// Normal orders the individual col_strs and then
 	/// orders the Col_strs using the order defined in
-	/// the Col_str function smallest.
+	/// the Col_str member function smallest.
 	void normal_order();
 
 	/// Function for simplifying an amplitude,
 	/// removes 0 and 1-rings,
 	/// compares col_strs,
 	/// removes Col_strs multiplying 0 and
 	/// simplifies Polynomials of the individual Col_strs.
 	void simplify();
 
 	/// Function for taking the conjugate of the Col_amp
 	/// by conjugating each Col_str in ca and the
 	/// Polynomial member Scalar.
 	void conjugate();
 
 	/// Contracts up to next to neighboring gluons in each Quark_line
 	/// in each Col_str in each Col_amp, only intended for closed Quark_lines.
 	void contract_next_neighboring_gluons( );
 
 	/// Contract closed Quark_lines with only 2 gluons in
 	/// each Quark_line in each Col_str in the Col_amp.
 	/// This removes the 2-ring, replaces one of the gluon indices and
-	/// multiplies with a factor tr[t^a t^a]=(1/2) (no sum).
+	/// multiplies with a factor tr[t^a t^a]=TR (no sum).
+	/// only intended for fully contractable Col_strs.
 	void contract_2_rings( );
 
 	/// Function for contracting gluon indices within the Quark_lines.
-	/// Checks only for ONE pair in each Quark_line, i.e.,
-	/// if several gluon indices appear, only one pair is contracted
-	/// in each Quark_line, only intended for closed Quark_lines.
+	/// Checks only for ONE pair in each Quark_line.
 	void contract_Quark_line_gluons( );
 
 	/// Contracts one gluon, the first gluon in first Quark_line (in each Col_str),
 	/// only intended for closed Quark_lines.
 	void contract_a_gluon( );
 
 	/// Function for contracting all gluon indices in a Col_amp,
 	/// only intended for closed Quark_lines.
 	void contract_all_gluons( );
 
 	/// Function for contracting the (anti-)quarks in Ca1 with those
 	/// in Ca2. The results is saved in this Col_amp.
 	void contract_quarks( const Col_amp & Ca1, const Col_amp & Ca2 );
 
 private:
 
 
 	/// Contracts one gluon, the first gluon in first Quark_line, only intended
 	/// for closed Quark_lines. This function is a member of Col_amp as
 	/// the result is contained in this Col_amp.
 	void contract_a_gluon( Col_str & Cs );
 
 	/// Function for contracting gluon indices within the same Quark_line.
 	/// Checks only for ONE pair, i.e. if several gluon indices appear
-	/// within the Quark_line, only one pair is contracted.
-	/// Only intended for closed Quark_lines.
+	/// within the Quark_line, only one pair is contracted,
+	/// only intended for closed Quark_lines.
 	/// This function is a member of Col_amp as the result is a Col_amp.
 	void contract_Quark_line_gluons( Quark_line & Ql );
 
 	/// Function for contracting gluon indices within the same Quark_line.
 	/// Checks only for ONE pair in each Quark_line in each Col_str,
 	/// i.e. if several gluon indices appear within the Quark_line,
 	/// only one pair is contracted.
 	/// The function is only intended for closed Quark_lines.
 	/// This function is a member of Col_amp as it saves the result in
 	/// this Col_amp.
 	void contract_Quark_line_gluons( Col_str & Cs );
 
 	/// Function for contracting all gluon indices in a Col_str,
 	/// assumes quarks already contracted and is only intended for
 	/// closed Quark_lines. This function is a member of Col_amp as
 	/// the result is contained in this Col_amp.
 	void contract_all_gluons( Col_str & Cs );
 
 	/// Converts a text string to a Col_amp,
 	/// used by string constructor, and by read_in_Col_amp.
 	/// The string should be of form
 	/// Polynomial1* col_str1 + Polynomial2 col_str2,
 	/// for example:
 	/// Col_amp Ca("13*Nc*[(1,3,4,2)] +2 TR 5 Nc^(-3) [(1,4) (3,2)]").
 	void Col_amp_of_str( const std::string str );
 
 };
 
 // Define operators involving Col_amp
 
 /// Define the operator << for col_amp
 std::ostream& operator<<( std::ostream& out, const col_amp & ca );
 
 /// Define the operator << for Col_amp.
 std::ostream& operator<<( std::ostream& out, const Col_amp & Ca );
 
 /// Define the operator == for two Col_amps.
 bool operator==( const Col_amp & Ca1, const Col_amp & Ca2 );
 
 /// Define the operator != for two Col_amps.
 bool operator!=( const Col_amp & Ca1, const Col_amp & Ca2 );
 
 /// Define the operator + for Col_amp and Col_str, adds Col_str Cs to ca.
 Col_amp operator+( const Col_amp & Ca, const Col_str & Cs );
 
 /// Define the operator + for Col_str and Col_amp, adds Col_str Cs to ca.
 Col_amp operator+( const Col_str & Cs, const Col_amp & Ca );
 
 /// Define the operator + for two Col_amps.
 /// Adds Scalars, and adds Col_strs.
 Col_amp operator+( const Col_amp & Ca1, const Col_amp & Ca2 );
 
+/// Define the operator += for two Col_amp+=Col_str.
+Col_amp operator+=( Col_amp & Ca, const Col_str & Cs );
+
 /// Define the operator += for two Col_amps.
 Col_amp operator+=( Col_amp & Ca1, const Col_amp & Ca2 );
 
 /// Define the operator - for two Col_amps.
 /// Subtract Scalar of Ca2 from Ca1, and subtracts (=appends with minus sign) Col_strs.
 Col_amp operator-( const Col_amp & Ca1, const Col_amp & Ca2 );
 
+/// Define the operator - for Col_amp-Col_str.
+Col_amp operator-( const Col_amp & Ca, const Col_str & Cs );
+
+/// Define the operator - for Col_str-Col_amp.
+Col_amp operator-( const Col_amp & Ca, const Col_str & Cs );
+
 /// Define the operator * for Col_amps and integers.
 Col_amp operator*( const Col_amp & Ca, const int i );
 
 /// Define the operator * for integers number and Col_amp.
 Col_amp operator*( const int i, const Col_amp & Ca );
 
 /// Define the operator * for Col_amps and complex number.
 Col_amp operator*( const Col_amp & Ca, const cnum c );
 
 /// Define the operator * for complex number and Col_amp.
 Col_amp operator*( const cnum c, const Col_amp & Ca );
 
 /// Define the operator * for Col_amp and double.
 Col_amp operator*( const Col_amp & Ca, const double d );
 
 /// Define the operator * for double and Col_amp.
 Col_amp operator*( const double d, const Col_amp & Ca );
 
 /// Define the operator * for Col_amp and Monomial.
 Col_amp operator*( const Col_amp & Ca, const Monomial & Mon );
 
 /// Define the operator * for Monomial and Col_amp.
 Col_amp operator*( const Monomial & Mon, const Col_amp & Ca );
 
 /// Define the operator * for Col_amp and Polynomial.
 Col_amp operator*( const Col_amp & Ca, const Polynomial & Poly );
 
 /// Define the operator * for Monomial and Col_amp.
 Col_amp operator*( const Polynomial & Poly, const  Col_amp & Ca );
 
-/// Define the operator *= for Col_amp and Col_str.
+/// Define the operator * for Col_amp and Quark_line.
+Col_amp operator*( const Col_amp & Ca, const Quark_line & Ql );
+
+/// Define the operator * for Quark_line and Col_amp.
+Col_amp operator*( const Quark_line & Ql, const Col_amp & Ca );
+
+/// Define the operator * for Col_amp and Col_str.
 Col_amp operator*( const Col_amp & Ca, const Col_str & Cs );
 
-/// Define the operator * for Col_amp and Col_str.
+/// Define the operator * for Col_str and Col_amp.
 Col_amp operator*( const Col_str & Cs, const Col_amp & Ca );
 
 /// Define the operator * for Col_amps.
 Col_amp operator*( const Col_amp & Ca1, const Col_amp & Ca2 );
 
 /// Define the operator *= for two Col_amps.
 Col_amp operator*=( Col_amp & Ca1, const Col_amp & Ca2 );
 
 }// end namespace ColorFull
 
 #endif /* COLORFULL_Col_amp_h */
diff --git a/MatrixElement/Matchbox/ColorFull/Col_basis.cc b/MatrixElement/Matchbox/ColorFull/Col_basis.cc
--- a/MatrixElement/Matchbox/ColorFull/Col_basis.cc
+++ b/MatrixElement/Matchbox/ColorFull/Col_basis.cc
@@ -1,1036 +1,1065 @@
 // -*- C++ -*-
 /*
  * Col_basis.cc
  * Contains definition of the base class Col_basis and associated types and operators.
  * Created on: Aug 9, 2012
  * Author: Malin Sjodahl
  */
 
 #include "Col_basis.h"
 #include "parameters.h"
 #include <cassert>
 #include <fstream>
 #include <iostream>
 #include <algorithm>
 #include <iomanip>
 
 
 namespace ColorFull {
 
+
+void Col_basis::append( col_basis cb_in ) {
+	for (uint m = 0; m < cb_in.size(); m++) {
+		cb.push_back( cb_in.at(m) );
+	}
+}
+
 void Col_basis::scalar_product_matrix_no_mem(){
 	if(ng+nq>6){
 		std::cout << "Col_basis::scalar_product_matrix: nq+ng=" << nq+ng << " is large, consider using numerical and/or memory version.  "  << std::endl;
 		std::cout.flush();
 	}
 	return scalar_product_matrix( true, true, false );
 }
 
 
 void Col_basis::scalar_product_matrix(){
 	return scalar_product_matrix( true, true, true );
 }
 
 
 void Col_basis::scalar_product_matrix_num_no_mem(){
 	return scalar_product_matrix( false, true, false );
 }
 
 
 void Col_basis::scalar_product_matrix_num(){
 	return scalar_product_matrix( false, true, true );
 }
 
 void Col_basis::leading_scalar_product_matrix(){
 
 	if( cb.size()==0 ) {
 		std::cerr << "Col_basis::leading_scalar_product_matrix: There are no basis vectors in this basis, consider using create_basis or read_in_Col_basis." << std::endl;
 		std::cerr.flush();
 		return ;
 	}
 
 	if( P_spm.empty() ) {
 		scalar_product_matrix( true, true, true );
 	}
 
 	leading_P_spm = Col_fun.leading( P_spm );
 	leading_d_spm = Col_fun.double_num( leading_P_spm );
 
 }
 
 
 std::string Col_basis::basis_file_name() const{
 
 	// First construct filename
 	std::ostringstream ss;
 	std::string filename;
 	ss << "ColorResults";
 	ss << '/';
 	// ColorFull
 	ss << "CF_";
 	// Basis Type
 	if( trace_basis )  ss << "TB_";
 	else if ( tree_level_gluon_basis ) ss << "TGB_";
 	else if ( orthogonal_basis ) ss << "OB_";
 	else  ss << "CB_";
 	ss << "q_";
 	ss << nq;
 	ss << "_g_";
 	ss << ng;
 	// If Nc is not 3, append Nc info
 	if( Col_fun.get_Nc() != 3 ){
 		ss << "_Nc_";
 		ss << Col_fun.get_Nc();
 	}
 	// If TR is not 1/2, append TR info
 	if( Col_fun.get_TR() != 0.5 ){
 		ss << "_TR_";
 		ss << Col_fun.get_TR();
 	}
 
 	filename=ss.str();
 	return filename.c_str();
 }
 
 
 std::string Col_basis::spm_file_name(const bool leading, const bool poly ) const{
 
 	// First construct filename
 	std::ostringstream ss;
 	std::string filename;
 	ss << "ColorResults";
 	ss << '/';
 	// CF as in ColorFull
 	ss << "CF_";
 	// Prefix according to basis type
 	if( trace_basis ) ss << "TB_";
 	else if ( tree_level_gluon_basis ) ss << 	"TGB_";
 	else if ( orthogonal_basis ) ss << 	"OB_";
 	else ss << "CB_";
 	// Polynomial or numerical matrix?
 	if( poly )ss << "P_";
 	else ss << "d_";
 	ss << "spm_q";
 	ss << nq;
 	ss << "_g";
 	ss << ng;
 	if ( leading ) ss << "_l";
 	if ( Col_fun.get_full_CF() ) ss << "_cff";
 	else ss << "_cfl";
 
 	if(Col_fun.get_Nc() != 3 ){
 		ss << "_Nc_";
 		ss << Col_fun.get_Nc();
 	}
 	if(Col_fun.get_TR() != 0.5 ){
 		ss << "_TR_";
 		ss << Col_fun.get_TR();
 	}
 	filename=ss.str();
 	return filename;
 }
 
 
 void Col_basis::write_out_Col_basis() const{
 	write_out_Col_basis( basis_file_name() );
 }
 
 
 void Col_basis::write_out_Col_basis( std::string filename ) const {
 
 	if ((cb.size() == 0)) {
 		std::cerr
 		<< "Col_basis::write_out_Col_basis(filename): There are no basis vectors in this basis, consider using create_basis or read_in_Col_basis."
 		<< std::endl;
 		return;
 	}
 
 	std::ofstream outfile(filename.c_str());
 
 	if ( !outfile )
 	std::cerr << "Col_basis::write_out_Col_basis: Cannot write out basis as the file \""
 		<< filename.c_str() << "\" could not be opened. (Does the directory exist? Consider creating the directory.)" << std::endl;
 
 
 	outfile << std::setprecision(16);
 
 	for ( uint m = 0; m < cb.size(); m++ ) {
 		outfile << m << "      " << cb.at(m) << std::endl;
 	}
 	outfile.flush();
 }
 
-
-void Col_basis::write_out_Col_basis_to_cout() const{
+std::ostream& Col_basis::write_out_Col_basis_to_stream( std::ostream& out ) const{
 
 	if(  (cb.size()==0 ) ) {
 		std::cerr << "Col_basis::write_out_Col_basis(): There are no basis vectors in this basis, consider using create_basis or read_in_Col_basis." << std::endl;
 		std::cerr.flush();
-		return ;
 	}
 
 	for (uint m = 0; m < cb.size(); m++) {
-		std::cout << m << "      "<< cb.at(m) << std::endl;
+		out << m << "      "<< cb.at(m) << std::endl;
 	}
+	return out;
 }
 
-
 void Col_basis::write_out_d_spm( std::string filename ) const{
 
 	Col_fun.write_out_dmatr( d_spm, filename );
 
 }
 
 
 void Col_basis::write_out_d_spm( ) const{
 
 	std::string filename = spm_file_name( false, false );
 	write_out_d_spm( filename );
 }
 
 
 void Col_basis::write_out_P_spm( std::string filename ) const{
 
 	P_spm.write_out_Poly_matr( filename );
 }
 
 
 void Col_basis::write_out_P_spm( ) const{
 
 	std::string filename = spm_file_name( false, true );
 	write_out_P_spm( filename );
 }
 
 
 void Col_basis::write_out_leading_d_spm( std::string filename ) const{
 
 	Col_fun.write_out_dmatr( leading_d_spm, filename );
 }
 
 
 void Col_basis::write_out_leading_d_spm( ) const{
 
 	std::string filename = spm_file_name( true, false );
 	write_out_leading_d_spm( filename );
 }
 
 
 void Col_basis::write_out_leading_P_spm( std::string filename ) const{
 
 	leading_P_spm.write_out_Poly_matr( filename );
 }
 
 
 void Col_basis::write_out_leading_P_spm( ) const{
 
 	std::string filename = spm_file_name( true, true );
 
 	write_out_leading_P_spm( filename );
 }
 
 
 void Col_basis::read_in_Col_basis( std::string filename ) {
 
 	// Read in file
 	std::ifstream fin(filename.c_str());
 
 	// Check that file exists
 	if( !fin ){
 		std::cerr << "Col_basis::read_in_Col_basis: The file "
 				<< filename << " could not be opened." << std::endl;
 		assert( 0 );
 	}
 
 	// Erase current information
 	cb.clear();
 
 	// Copy info from file to string
 	std::string str((std::istreambuf_iterator<char>(fin)), std::istreambuf_iterator<char>());
 
+	// Skip lines starting with #
+	while( str.at(0)== '#' ){
+		while (str.at(0) != '\n'){
+			str.erase(str.begin());
+		}
+		// erase endl sign(s)
+		while(str.at(0)== '\n'){
+			str.erase(str.begin());
+		}
+	}
+
+	// Remove endl chars at the end of the file
+	while( str.at(str.size()-1) == '\n' ) str.erase(str.size()-1);
+
 	Col_basis_of_str( str );
 
 }
 
 
 void Col_basis::read_in_d_spm( std::string filename){
 
 	d_spm= Col_fun.read_in_dmatr( filename );
 
 }
 
 
 void Col_basis::read_in_d_spm( ){
 
 	d_spm=Col_fun.read_in_dmatr( spm_file_name( false, false ).c_str() );
 
 }
 
 
 void Col_basis::read_in_leading_d_spm( std::string filename){
 
 	leading_d_spm=Col_fun.read_in_dmatr( filename );
 
 }
 
 
 void Col_basis::read_in_leading_d_spm( ){
 
 	leading_d_spm=Col_fun.read_in_dmatr( spm_file_name( true, false ).c_str() );
 }
 
 
 void Col_basis::read_in_P_spm( std::string filename ){
 
 	P_spm.read_in_Poly_matr( filename );
 }
 
 
 void Col_basis::read_in_P_spm( ){
 
 	P_spm.read_in_Poly_matr( spm_file_name( false, true) );
 
 }
 
 
 void Col_basis::read_in_leading_P_spm( std::string filename){
 
 	leading_P_spm.read_in_Poly_matr( filename );
 
 }
 
 
 void Col_basis::read_in_leading_P_spm( ){
 
 	leading_P_spm.read_in_Poly_matr( spm_file_name( true, true) );
 }
 
 
 int Col_basis::n_quark_check() const {
 
 	if (empty()) return 0;
 	int nq=cb.at(0).n_quark_check();
 	for( uint n=0; n< cb.size(); n++ )
 		if( cb.at(n).n_quark_check() != nq) {
 			std::cerr << "Col_basis::n_quark_check: The Col_amps in " << cb << " have differently many quarks." << std::endl;
 		}
 
 	return nq;
 }
 
 
 int Col_basis::n_gluon_check() const {
 
 	if ( empty()) return 0;
 	int nq=cb.at(0).n_gluon_check();
 	for( uint n=0; n< cb.size(); n++ )
 		if( cb.at(n).n_gluon_check() != nq) {
 			std::cerr << "Col_basis::n_gluon_check: The Col_amps in " << cb << " have differently many gluons." << std::endl;
 		}
 	return nq;
 }
 
 
 void Col_basis::simplify(){
 
 	for( uint i=0; i< cb.size(); i++ ){
 		cb.at(i).simplify();
 	}
 }
 
 
-Poly_vec Col_basis::decompose( const Col_amp & ){
+Poly_vec Col_basis::decompose( const Col_amp & Ca ){
+
+	// This line is to avoid compiler warnings
+	// Ca should be an argument despite that it's not used
+	(void) Ca;
 
 	std::cerr << "Col_basis::decompose: This function is not implemented for the Col_basis class. Try using a derived class (such as Trace_basis). " << std::endl;
 
 	Poly_vec Pv;
 	assert( 0 );
 
 	return Pv;
 }
 
 
 Col_amp Col_basis::exchange_gluon( uint vec, int p1, int p2 ) {
 
 	if(  (cb.size()==0 ) ) {
 		std::cerr << "Col_basis::exchange_gluon: There are no basis vectors in this basis, consider using create_basis or read_in_Col_basis." << std::endl;
 		std::cerr.flush();
 		assert( 0 );
 	}
 
 	// Check that the basis vector exists
 	if ( vec >= cb.size() ) {
 		std::cerr << "Col_basis::exchange_gluon: Basis vector number "<< vec
 				<< " does not exist, as the basis only have " << cb.size()
 				<< " basis vectors." << std::endl;
 		assert( 0 );
 	}
 
 	return Col_fun.exchange_gluon( cb.at(vec), p1, p2);
 
 }
 
-Poly_matr Col_basis::Col_gamma( int p1, int p2 ) {
+Poly_matr Col_basis::color_gamma( int p1, int p2 ) {
 
 	if(  (cb.size()==0 ) ) {
-		std::cerr << "Col_basis::Col_gamma: There are no basis vectors in this basis, consider using create_basis or read_in_Col_basis." << std::endl;
+		std::cerr << "Col_basis::color_gamma: There are no basis vectors in this basis, consider using create_basis or read_in_Col_basis." << std::endl;
 		std::cerr.flush();
 		assert( 0 );
 	}
 
 	// Function not available for Tree_level_gluon basis
 	if( tree_level_gluon_basis ) {
-		std::cerr << "Col_basis::Col_gamma: This function is not available for Tree_level_gluon_basis "
+		std::cerr << "Col_basis::color_gamma: This function is not available for Tree_level_gluon_basis "
 				<< "as the vector resulting after gluon exchange contains vectors which are not in the basis. "
 				<< "Consider using Trace_basis."<< std::endl;
 		std::cerr.flush();
 		assert( 0 );
 	}
 
 	// Function should only be used for Orthogonal_basis and Trace_basis
 	if( ( !trace_basis ) and (! orthogonal_basis) ) {
-		std::cerr << "Col_basis::Col_gamma: This function is only implemented for Trace_basis and Orthogonal_basis. "
+		std::cerr << "Col_basis::color_gamma: This function is only implemented for Trace_basis and Orthogonal_basis. "
 				<< "If your basis is not orthogonal, the result will not be correct. "
 				<< "If your basis is orthogonal, consider using Orthogonal_basis."
 				<< std::endl;
 		std::cerr.flush();
 	}
 
 	// To contain the resulting matrix
 	Poly_matr gamma_res;
 	// Fill gamma_res with 0s
 	Polynomial Zero;
 	Zero=Zero*0;
 	for( uint i=0; i < cb.size(); i++ ){
 		Poly_vec rowi;
 		for( uint j=0; j < cb.size(); j++ ){
-			rowi.push_back(Zero);
+			rowi.append(Zero);
 		}
-		gamma_res.push_back(rowi);
+		gamma_res.append(rowi);
 	}
 
 	// To contain the Col_amp after gluon exchange
 	Col_amp Ca_ae;
 
 	// First exchange a gluon between partons p1 and p2 in the vector v1
 	for ( uint vi=0; vi < cb.size(); vi++ ){
 
 		Ca_ae=exchange_gluon( vi, p1, p2 );
 
 		// Then decompose the result into the basis,
 		Poly_vec col_vi = decompose( Ca_ae );
 
-		// This gives the vi:th column in Col_gamma
+		// This gives the vi:th column in color_gamma
 		// Loop over rows in that column
 		for ( uint vj=0; vj < cb.size(); vj++ ){
 			gamma_res.at(vj).pv.at(vi) = col_vi.at(vj);
 		}
 	}
 
 
 	return gamma_res;
 }
 
 
 void Col_basis::Col_basis_of_str( std::string str ){
 
 	if (str.size() == 0) {
 		std::cerr << "Col_basis::Col_basis_of_str: The basis string is empty. This should not happen." << std::endl;
 		assert( 0 );
 	}
 
 	// Skip lines starting with #
 	while(str.at(0)== '#'){
 		while (str.at(0) != '\n'){
 			str.erase( str.begin() );
 		}
 		// erase endl sign(s)
 		while(str.at(0)== '\n'){
 			str.erase(str.begin());
 		}
 	}
 
 	// First char in string should be '0'
 	if (str.at(0) != '0') {
 		std::cerr
 		<< "Col_basis::Col_basis_of_str: First char in basis data file after comments should be '0', as in basis vector 0 as in vector number 0, but it was: "
 		<< str.at(0) << std::endl;
 		assert( 0 );
 	}
 
 	// Read the string, starting from 0th element
 	uint i = 0;
 	while (i < str.size() - 2) {
 		//i += 1; testing to move down 130917
 
 		// We may have some white spaces
 		while (i< str.size()-2 &&(str.at(i) == ' ')) i++;
 
 		// After white spaces there should be a number, the vector number
 		while (i< str.size()-2 &&(str.at(i) == '0' or str.at(i) == '1' or str.at(i) == '2' or str.at(i) == '3' or str.at(i) == '4' or str.at(i) == '5' or str.at(i) == '6' or str.at(i) == '7' or str.at(i) == '8' or str.at(i) == '9') ) i++;
 
 		// We may have some more white spaces
 		while (i< str.size()-2 &&(str.at(i) == ' ')) i++;
 
 
 		// String to make a Col_amp of
 		std::string Ca_str;
 		Ca_str.clear();
 
 		// Keep reading the Ca_str while not '\n which marks new vector
 		//while ( i< str.size()-1 && (str.at(i) != '\n') )
 		while ( i< str.size() && (str.at(i) != '\n') ){
 			Ca_str.push_back(str.at(i));
 			i++;
 		}
 
 		// Make the Col_amp (basis vector)
 		Col_amp Ca( Ca_str );
 
 		// Simplify, for example move Polynomials to multiply Col_strs, rather than Quark-lines
 		Ca.simplify();
 
-		push_back(Ca);
+		append(Ca);
 		i++;
 	}
 
 	// Check that the basis is not empty
 	if( empty()){
 		std::cerr << "Col_basis::Col_basis_of_str: The basis is empty. " << std::endl;
 		assert( 0 );
 	}
 
 	// Check that first vector is not empty
 	if(cb.at(0).ca.empty()){
 		std::cerr << "Col_basis::Col_basis_of_str: The first Col_amp (vector) in the basis is empty. " << std::endl;
 		assert( 0 );
 	}
 
 	// Check that first col_str in first vector is not empty
 	if(cb.at(0).ca.at(0).cs.empty()){
 		std::cerr << "Col_basis::Col_basis_of_str: The first Col_str in the first basis vector is empty. " << std::endl;
 		assert( 0 );
 	}
 
 	// Check that first quark_line in the first col_str in first vector is not empty
 	if(cb.at(0).ca.at(0).cs.at(0).ql.empty()){
 		std::cerr << "Col_basis::Col_basis_of_str: The first Quark_line in the first Col_str in the first basis vector is empty. " << std::endl;
 		assert( 0 );
 	}
 
 	// Find the number of quarks and gluons
 	nq=n_quark_check();
 	ng=n_gluon_check();
 
 	// Test if it's a trace basis
 	if( trace_basis ){
 		bool is_trace_basis=true;
 		for ( uint j=0; j< cb.size(); j++ ){
 			if( cb.at(j).size() !=1 ) is_trace_basis=false;
 
 			if(! is_trace_basis ){
 				std::cerr << "Col_basis::Col_basis_of_str: You are trying to read in a non-trace basis to a trace basis object. "
 						<<"The length of the Col_amp " << cb.at(j) << " is not 1."
 						<< std::endl;
 				assert( 0 );
 			}
 		}
 	}
 }
 
 
 void Col_basis::read_in_Col_basis( ) {
 
 	read_in_Col_basis( basis_file_name() );
 }
 
 
 void Col_basis::scalar_product_matrix( bool save_P_spm, bool save_d_spm, bool use_mem ) {
 
 	if(  (cb.size()==0 ) ) {
 		std::cerr << "Col_basis::scalar_product_matrix: There are no basis vectors in this basis, consider using create_basis or read_in_Col_basis." << std::endl;
 		std::cerr.flush();
 		return ;
 	}
 
 	// Simplify the basis vectors
 	simplify();
 
 	// If the P_spm and d_spm have already been calculated, erase them
 	if( !P_spm.empty() ) P_spm.clear();
 	if( !d_spm.empty() ) d_spm.clear();
 
 	// Check that all Polynomials are real
 	// (check doesn't cover the case of complex Poly in a Quark_line)
 	// but if an entry is not real this will be discovered as the d_spm is calculated
 	for ( uint cbi=0; cbi < cb.size(); cbi++){
 		for ( uint j=0; j< cb.at(cbi).size(); j++){
 			if( imag (Col_fun.cnum_num(  cb.at(cbi).at(j).Poly  )) > accuracy ){
 				std::cerr << "Col_basis::scalar_product_matrix: ColorFull expects real Polynomial multiplying the color structure, but the Polynomial\n"
 						<< cb.at(cbi).at(j).Poly  << std::endl
 						<< " appearing in front of the Col_str " << cb.at(cbi).at(j).cs
 						<< " in basis vector number " << cbi << " is not real."<< std::endl << std::endl;
 				std::cerr.flush();
 				assert( 0 );
 			}
 		}
 	}
 
 	// For remembering already calculated topologies
 	std::map<std::string, std::shared_ptr<Polynomial> > mem_map;
 
 	// Loop over basis vectors in Basis
 	for( uint i=0; i < cb.size(); i++){
 
 		// To contain a row of the resulting scalar product matrix
 		Poly_vec rowi;
 
 		// Loop over basis vectors in Basis, normally over all vectors,
 		// but for orthogonal_basis only for i==j
 		uint minj=0, maxj=cb.size();
 
 		for( uint j=minj; j< maxj; j++){
 			Polynomial ijRes;
 			ijRes=ijRes*0;
 			if(use_mem){
 
 				// Loop over Col_strs in first Ca
 				for( uint Ca1i=0; Ca1i< cb.at(i).size(); Ca1i++){
 
 					// Loop over Col_strs in second Ca
 					for( uint Ca2i=0; Ca2i< cb.at(j).size(); Ca2i++){
 
 						// To contain the contribution to the ij-th entry if memoization is used
 						std::shared_ptr<Polynomial> ijEntry_contr;
 
 						// Rename indices, and make string of new col_strs, to use in map
 						// strip off Polynomial information to make the map minimal
 						Col_str Cs1, Cs2;
 						Cs1.append(cb.at(i).at(Ca1i).cs);
 						Cs2.append(cb.at(j).at(Ca2i).cs);
 
 						rename_indices( Cs1, Cs2 );
 
 						std::ostringstream Cs_string;
 						Cs_string << Cs1 << Cs2;
 
 						// Calculate element contribution to the ij:th element in scalar product matrix
 						// If this has scalar product has occurred before, reuse old value
 						if (mem_map.count( Cs_string.str() ) > 0) {
 							ijEntry_contr = mem_map[Cs_string.str()];
 						}
 						// Otherwise, calculate value and save topology
 						else {
 							if( !tree_level_gluon_basis ){
 								Polynomial p = Col_fun.scalar_product(Cs1, Cs2);
-								ijEntry_contr = shared_ptr<Polynomial> (new Polynomial(p));
+								ijEntry_contr = std::shared_ptr<Polynomial> (new Polynomial(p));
 								mem_map[Cs_string.str()] = ijEntry_contr;
 
 							}
 							else if( tree_level_gluon_basis ){
 								int sign = (ng % 2 ? -1 : 1);
 								Col_str Cs2_conj=Cs2;
 								Cs2_conj.conjugate();
 								Polynomial P = 2* Col_fun. scalar_product( Cs1, Cs2 )
 										+ sign*2*Col_fun. scalar_product( Cs1, Cs2_conj );
-								ijEntry_contr = shared_ptr<Polynomial> (new Polynomial(P));
+								ijEntry_contr = std::shared_ptr<Polynomial> (new Polynomial(P));
 								mem_map[Cs_string.str()] = ijEntry_contr;
 							}
 						}
 						// Sum up all the contributions to one Polynomial, recall to multiply with Polynomials
 						Polynomial ijEntry_contr_poly=(*ijEntry_contr)* cb.at(i).at(Ca1i).Poly*cb.at(j).at(Ca2i).Poly;
 
 						// If Polynomial version is not needed convert all algebraic information
 						// to numerical in the vectors
 						if( !save_P_spm ) {
 							double ijEntry_contr_d= Col_fun.double_num( ijEntry_contr_poly );
 							Monomial Mon( ijEntry_contr_d );
 							ijRes+= Mon;
 						}
 						else ijRes += ijEntry_contr_poly;
 
 					} // end looping over Cs in first Ca
 				} // end looping over Cs in 2nd Ca
 
 				// If Polynomial result is wanted, simplify
 				if ( save_P_spm ) ijRes.simplify();
 
 				// Otherwise convert to numerical
 				else {
 					double num_ijRes= Col_fun.double_num(ijRes);
 					ijRes.clear();
 					Monomial Mon( num_ijRes );
-					ijRes.push_back(Mon);
+					ijRes.append(Mon);
 				}
 
-				rowi.push_back( ijRes );
+				rowi.append( ijRes );
 
 			} // end if ( use_mem )
 			else{
 				// Calculate element ij in scalar product matrix
 				ijRes=ij_entry( i, j );
-				rowi.push_back( ijRes );
+				rowi.append( ijRes );
 
 				// Convert to numerical if not saving Polynomial version
 				if ( ! save_P_spm ) {
 					double num_ijRes= Col_fun.double_num(ijRes);
 					ijRes.clear();
 					Monomial Mon( num_ijRes );
-					ijRes.push_back(Mon);
+					ijRes.append(Mon);
 				}
 
 			} //end if (not mem)
 		}
-		P_spm.push_back(rowi);
+		P_spm.append(rowi);
 	}
 
 	// For saving and checking symmetry of numerical version
 	// d_spm has to be calculated even if it's not saved to facilitate
 	// symmetry check
 	d_spm= Col_fun.double_num( P_spm );
 
 	// Making consistency checks (needs double version)
 	check_spm();
 
 	// Erasing the double spm
 	if( ! save_d_spm ) {
 		d_spm.clear();
 	}
 	// Erasing the Polynomial spm
 	if( !save_P_spm ) {
 		P_spm.clear();
 	}
 
 	return;
 }
 
 
 Polynomial Col_basis::ij_entry( const int i, const int j ) const{
 
 	Polynomial ijEntry;
 	ijEntry=Col_fun.scalar_product(cb.at(i), cb.at(j));
 	ijEntry.simplify();
 	return ijEntry;
 }
 
 
 bool Col_basis::check_symmetry( const dmatr & matr ) const {
 
 	if( matr.size()==0 ){
 		std::cout << "Col_basis::check_symmetry( dmatr ): The numerical matrix is empty..." << std::endl;
 	}
 	else{
 		//std::cout << "Col_basis::check_symmetry( dmatr ): Numerically verifying symmetry of matrix...";
 	}
 	// Verifying that the matrix is symmetric to accuracy "accuracy",
 	// if not sym is put to false
 	bool sym=true;
 	// Loop over basis vectors in Basis
 	for (uint i = 0; i < d_spm.size(); i++) {
 		Poly_vec rowi;
 		// Loop over basis vectors in Basis
 		for (uint j = 0; j <=i; j++) {
 			if ((fabs(d_spm.at(i).at(j) / d_spm.at(j).at(i) - 1.0) > accuracy) && (d_spm.at(i).at(j) > accuracy) && (d_spm.at(j).at(i) > accuracy)) {
 				sym=false;
 				std::cerr
 				<< "Col_basis::check_symmetry( dmatr ): Error, the resulting scalar product matrix is not symmetric. \n "
 				<< "Element " << i << "," << j << ": "
 				<< d_spm.at(i).at(j) << ", Element " << j << "," << i
 				<< ": " << d_spm.at(j).at(i) << std::endl
 				<< "This indicates an error in calculation of scalar products. " << std::endl;
 			}
 		}
 	}
 	//if( matr.size() !=0  and sym ) std::cout << " done." << std::endl;
 	return sym;
 }
 
 
 bool Col_basis::check_diagonal( const dmatr & matr ) const{
 
 	if( matr.size()==0 ){
 		std::cerr << "Col_basis::check_diagonal( dmatr ): The numerical matrix is empty...";
 		std::cout.flush();
 	}
 	else{
 		//std::cout << "Col_basis::check_diagonal( dmatr ): Numerically checking if the matrix is diagonal...";
 		//std::cout.flush();
 	}
 
 	// Verifying that the matrix is diagonal
 	// if not sym is put to false
 	bool diag=true;
 	// Loop over basis vectors in Basis
 	for (uint i = 0; i < matr.size(); i++) {
 
 		Poly_vec rowi;
 		// Loop over basis vectors in Basis
 		for (uint j = 0; j <=i; j++) {
 			// If non-diagonal elements are sufficiently large write warning
 			if ( std::abs( matr.at(i).at(j) ) > accuracy and i!=j ) {
 				diag=false;
 				if( !(trace_basis or tree_level_gluon_basis) ){
 					std::cout
 					<< "Col_basis::check_diagonal( matr ): Warning, the matrix is not diagonal. \n "
 					<< "Element " << i << "," << j << ": "
 					<< matr.at(i).at(j) << std::endl;
 				}
 			}
 		}
 	}
 	if (! diag ){
 		std::cout << "Col_basis::check_diagonal: the matrix is not diagonal." << std::endl;
 	}
 	//else if (diag) std::cout << " done." << std::endl;
 
 	return diag;
 }
 
 
 void Col_basis::check_spm() const{
 
 	// Verifying that the matrix is symmetric to accuracy
 	bool sym=check_symmetry(d_spm);
 
 	if( !sym ) {
 		std::cerr <<"Col_basis::check_spm(): scalar product matrix not symmetric. Please report bug." << std::endl;
 		std::cerr.flush();
 		assert( 0 );
 	}
 
 	// Verifying that the leading terms only sit on the diagonal
 	bool diagonal=true;
 	if( !leading_d_spm.empty() ){
 		diagonal=check_diagonal(leading_d_spm);
 	}
 	if(!diagonal and ( trace_basis or tree_level_gluon_basis ) ) {
 		std::cout <<"Col_basis::check_spm(): Leading terms appear of the diagonal. This should not happen in a trace type basis."
 				<< " For numerical bases it can appear to happen as powers of Nc may hide in numerical constants." << std::endl;
 		std::cout.flush();
 	}
 }
 
 
 void Col_basis::rename_indices(Col_str & Cs1, Col_str & Cs2) const{
 
 	/*
      This is a two-step process:
      1) Compute new indices
      2) Replace indices
 
      The new indices are stored in a vector named new_indices, such that
      old_index should be replaced by new_indices[old_index]
 	 */
 
 	std::vector<int> new_indices;
 	uint n_indices_total = 2*Cs1.n_quark() + Cs1.n_gluon();
 	new_indices.resize(n_indices_total+1);
 	assert(2*Cs1.n_quark() + Cs1.n_gluon() == 2*Cs1.n_quark() + Cs1.n_gluon());
 	int new_ind=0; // The new index
 	uint Nql= Cs1.cs.size();
 	// Loop over Quark_lines in Cs1
 	for(uint i=0; i< Nql; i++ ){
 		Quark_line & Ql_i = Cs1.cs.at(i);
 		uint Nind = Ql_i.ql.size();
 		// Loop over indices in the Quark_line
 		for(uint j=0; j< Nind; j++ ){
 			new_ind++;
 			// The old index in Cs1, to be replaced also in Cs2
 			uint old_ind=Ql_i.ql.at(j);
 			// Replace index in Cs1
 			Ql_i.ql.at(j) = new_ind;
 			// Insert into replacement map
 			// If the assert fails, we have not allocated enough space, and will fail.
 			assert(old_ind <= n_indices_total);
 			new_indices[old_ind] = new_ind;
 		}
 	}
 	// Loop over Quark_lines in Cs2
 	Nql= Cs2.cs.size();
 	for(uint i=0; i< Nql; i++ ){
 		Quark_line & Ql_i = Cs2.cs.at(i);
 		uint Nind = Ql_i.ql.size();
 		// Loop over indices in the Quark_line
 		for(uint j=0; j< Nind; j++ ){
 			// Replace index in Cs2
 			Ql_i.ql.at(j) = new_indices[Ql_i.ql.at(j)];
 		}
 	}
 }
 
 
 Polynomial Col_basis::scalar_product( const Col_amp & Ca1, const Col_amp & Ca2 )  {
 
 
 	// Check that we have a basis
 	if(cb.size()==0){
 		std::cerr << "Col_basis::scalar_product: The basis vector cb is empty, consider using create_basis or read in basis." << std::endl;
 		assert( 0 );
 	}
 
 	// Check that the Polynomial scalar product matrix is calculated, if not calculate it
 	if( P_spm.size() != cb.size() ) {
 		std::cerr << "Col_basis::scalar_product: This function uses the scalar product matrix which has not yet been calculated." << std::endl;
 		assert( 0 );
 	}
 
 	// To contain the resulting Polynomial
 	Polynomial Poly_res;
 	Poly_res=Poly_res*0;
 
 	// Decompose the Col_amps
 	Poly_vec Polyv1=decompose(Ca1);
 	Polyv1.conjugate();
 	Poly_vec Polyv2=decompose( Ca2 );
 
 	// Then add contributions
 	for ( uint m1=0; m1< cb.size(); m1++ ){
 		// Diagonal terms
-		Poly_res=Poly_res+Polyv1.at(m1) *Polyv2.at(m1) *P_spm.at(m1).at(m1);
+		Poly_res+= Polyv1.at(m1) *Polyv2.at(m1) *P_spm.at(m1).at(m1);
 		for (uint m2=0; m2< m1; m2++){
 			// Other terms, use symmetry of scalar product matrix
-			Poly_res=Poly_res+ ( Polyv1.at(m1) *Polyv2.at(m2)+Polyv1.at(m2) *Polyv2.at(m1) ) *P_spm.at(m1).at(m2);
+			Poly_res+= ( Polyv1.at(m1) *Polyv2.at(m2)+Polyv1.at(m2) *Polyv2.at(m1) ) *P_spm.at(m1).at(m2);
 		}
 	}
 	return Poly_res;
 }
 
 
 cnum Col_basis::scalar_product_num( const Col_amp & Ca1, const Col_amp & Ca2 )  {
 
 
 	// Check that we have a basis
 	if(cb.size()==0){
 		std::cerr << "Col_basis::scalar_product_num: The basis vector cb is empty consider using create_basis or read in basis." << std::endl;
 		assert( 0 );
 	}
 
 	// Check that the Polynomial scalar product matrix is calculated, if not calculate it
 	if( d_spm.size() != cb.size() ) {
 		std::cerr << "Col_basis::scalar_product_num: This function uses the numerical scalar product matrix which has not yet been calculated." << std::endl;
 		assert( 0 );
 	}
 	// To contain the resulting Polynomial
 	cnum res=0;
 	uint basis_size=cb.size();
 
 	// Decompose the Col_amps
 	Poly_vec Polyv1, Polyv2;
 	Polyv1=decompose(Ca1);
 	if( &Ca1==&Ca2 ) Polyv2=Polyv1;
 	else Polyv2=decompose(Ca2);
 
 	// Conjugate first arg
 	Polyv1.conjugate();
 
 	// Make ordinary vectors to speed up multiplication
 	cvec v1, v2;
 	v1.reserve( basis_size );
 	for (uint i=0; i< basis_size; i++){
 		v1.push_back( Col_fun.cnum_num( Polyv1.at(i) ) );
 	}
 
 	if (false) v2=v1;
 	else{
 		v2.reserve(basis_size);
 		for (uint i=0; i< basis_size; i++) v2.push_back( Col_fun.cnum_num( Polyv2.at(i) ) );
 	}
 
 	// Then add contributions
 	cnum v1m1, v2m1;
 	dvec row;
 	for (uint m1=0; m1< basis_size; m1++){
 		v1m1=v1.at(m1);
 		v2m1=v2.at(m1);
 		row=d_spm.at( m1 );
 		// Diagonal terms
 		res=res+ v1m1 *v2.at(m1) *row.at(m1);
 		for (uint m2=0; m2< m1; m2++){
 			res += (v1m1*v2.at(m2) +v1.at(m2)*v2m1 ) *row.at(m2);
 
 		}
 	}
 
 	return res;
 
 }
 
 
 cnum Col_basis::scalar_product_num( const cvec & v1, const cvec & v2) {
 
 	if( v1.size()!= v2.size() ){
 		std::cerr << "Col_basis::scalar_product_num: Size of first vector "
 				<< v1.size() << " does not agree with size of second vector "
 				<< v2.size() << std::endl;
 		assert( 0 );
 	}
 	if( v1.size()!= d_spm.size() ){
 		std::cerr << "Col_basis::scalar_product_num: Size of vectors "
 				<< v1.size() << " does not agree with size of d_spm matrix "
 				<< d_spm.size() << std::endl;
 		assert( 0 );
 	}
 
 	uint basis_size=v1.size();
 
 	// To contain the result
 	cnum res=0;
 	cnum tmp=0, tmp2=0;
 
 	// Add contributions
 	cnum v1m1, v2m1;
 	for (uint m1=0; m1< basis_size; m1++){
 		v1m1= conj( v1.at(m1) );
 		v2m1=v2.at(m1);
 		const dvec &row = d_spm.at(m1);
 		// Diagonal parts
 		res += v1m1 *v2.at(m1) *row.at(m1);
 		tmp = 0;
 		tmp2=0;
 		for (uint m2=0; m2< m1; m2++){
 			tmp += (v1m1*v2[m2]+v2m1*conj(v1[m2])) *row[m2];
 		}
 		res+=tmp;
 	}
 
 	return res;
 }
 
 
 cnum Col_basis::scalar_product_num_diagonal( const cvec & v1, const cvec & v2 ) {
 
 	if(v1.size()!= v2.size()){
 		std::cerr << "Col_basis::scalar_product_num_diagonal: Size of first vector "
 				<< v1.size() << " does not agree with size of second vector "
 				<< v2.size() << std::endl;
 		assert( 0 );
 	}
 	if(v1.size()!= d_spm.size()){
 		std::cerr << "Col_basis::scalar_product_num_diagonal: Size of vectors "
 				<< v1.size() << " do not agree with size of d_spm matrix "
 				<< d_spm.size() << std::endl;
 		assert( 0 );
 	}
 
 	// To contain the result
 	cnum res=0;
 
 	// Check dimension
 	uint basis_size=v1.size();
 
 	// Then add contributions
 	for (uint m1=0; m1< basis_size; m1++){
 		res=res+ conj( v1.at(m1) ) *v2.at(m1) *d_spm.at(m1).at(m1);
 	}
 
 	return res;
 }
 
 
+std::ostream& operator<<( std::ostream& out, const Col_basis & Cb ) {
+
+	return Cb.write_out_Col_basis_to_stream( out );
+}
+
+
 std::ostream& operator<<( std::ostream& out, const col_basis & cb ) {
 	int max = cb.size();
 	for (int i = 0; i < max; i++) {
 		out <<",  " << cb.at(i);
 	}
 	return out;
 }
 
 }
diff --git a/MatrixElement/Matchbox/ColorFull/Col_basis.h b/MatrixElement/Matchbox/ColorFull/Col_basis.h
--- a/MatrixElement/Matchbox/ColorFull/Col_basis.h
+++ b/MatrixElement/Matchbox/ColorFull/Col_basis.h
@@ -1,396 +1,405 @@
 // -*- C++ -*-
 /*
  * Col_basis.h
  * Contains the declarations of the class Col_basis, related types and operators.
  * Created on: Aug 9, 2012
  * Author: Malin Sjodahl
  */
 
 #ifndef COLORFULL_Col_basis_h
 #define COLORFULL_Col_basis_h
 
 
 #include "Col_functions.h"
 
 
 namespace ColorFull {
 
 /// Define a type to store all basis vectors.
 typedef std::vector<Col_amp> col_basis;
 
 /// To contain a color basis, where each basis vector is a Col_amp.
 /// Technically the color information is contained
 /// in the member cb, which is a vector of Col_amps, a col_basis.
 class Col_basis {
 
 public:
 
 	/// Default constructor
 	Col_basis(){
 		nq=0;
 		ng=0;
 		trace_basis = false;
 		tree_level_gluon_basis = false;
 		orthogonal_basis = false;
 	}
 
 	/// Destructor.
 	virtual ~Col_basis(){}
 
-	/// The number of quarks, initially set to 0 and (possibly)
+	/// The number of qqbar-pairs, initially set to 0 and (possibly)
 	/// changed with create_basis, or while reading in the basis.
 	int nq;
 
 	/// The number of gluons, initially set to 0 and (possibly)
 	/// changed with create_basis, or while reading in the basis.
 	int ng;
 
 	/// To actually contain the info about the basis vectors cb= vector1, vector2... .
 	/// Technically cb is a col_basis, a vector of Col_amps.
 	col_basis cb;
 
 	/// To contain the Polynomial version of the scalar product matrix.
 	Poly_matr P_spm;
 
 	/// To contain the Polynomial version of the leading part of the scalar product matrix.
 	Poly_matr leading_P_spm;
 
 	/// To contain the double version of the scalar product matrix.
 	dmatr d_spm;
 
 	/// To contain the double version of the leading part of the scalar product matrix.
 	dmatr leading_d_spm;
 
 	/// To contain the set of Col_functions used.
-	/// As a pointer to a Col_functions object is used,
-	/// several bases may share the same functions for
-	/// numerical evaluation etc.
 	Col_functions Col_fun;
 
 	/// Is it a Trace_basis?
 	bool  is_Trace_basis() const {return trace_basis;}
 
 	/// Is it an Orthogonal_basis?
 	bool  is_Orthogonal_basis() const {return orthogonal_basis;}
 
 	/// Is it a Tree_level_gluon_basis?
 	bool  is_Tree_level_gluon_basis() const {return tree_level_gluon_basis;}
 
 	/// Returns the number of basis vectors.
 	uint size() const {return cb.size();}
 
 	/// Returns the Col_amp (basis vector) at place i.
 	const Col_amp & at( const int i ) const{return cb.at(i);}
 
 	/// Returns the Col_amp (basis vector) at place i.
 	Col_amp & at( const int i ) {return cb.at(i);}
 
 	/// Is the col_basis empty?
 	bool empty() const { return cb.empty(); }
 
 	/// Erase the basis, stored in cb.
 	void clear() { cb.clear(); }
 
 	/// Appends a Col_amp to the basis, stored in cb.
-	void push_back( Col_amp Ca ) { cb.push_back( Ca ); }
+	void append( Col_amp Ca ) { cb.push_back( Ca ); }
+
+	/// Appends the Col_amps in cb_in to the col_basis member cb.
+	void append( col_basis cb_in );
 
 
 	/******************** Functions for scalar products **********************/
 
 
 	/// Function for calculating the scalar products matrix.
 	/// This function loops over all basis vectors and stores the
 	/// value of the scalar product between basis vector
 	/// i and basis vector j in the i,j -entry in P_spm and d_spm.
 	/// The calculation is done using memoization.
 	/// The symmetry of the scalar product matrix is not used
 	/// for the calculation, instead it is checked that the
 	/// resulting matrix is indeed symmetric.
 	void scalar_product_matrix();
 
 	/// This function works as scalar_product_matrix, but does the
-	/// calculation numerically. It hence only saves (and writes out) d_spm.
+	/// calculation numerically. It hence only calculates d_spm.
 	void scalar_product_matrix_num();
 
 	/// This function works like scalar_product_matrix, but does
 	/// not use memoization.
 	virtual void scalar_product_matrix_no_mem();
 
 	/// This function works like scalar_product_matrix_num, but does
 	/// not use memoization.
 	void scalar_product_matrix_num_no_mem();
 
 	/// Finds the leading Nc scalar product matrices,
 	/// leading_P_spm and leading_d_spm.
 	/// If the polynomial scalar product matrix, P_spm has
 	/// been calculated, P_spm is used, otherwise P_spm is first calculated
 	/// and the leading Nc limit is then taken of P_spm.
 	void leading_scalar_product_matrix();
 
 	/// Function for calculating scalar products algebraically
-	/// knowing the basis and the scalar product matrix (Poly_matr) in the basis.
+	/// using the basis and the scalar product matrix (Poly_matr) in the basis.
 	/// (Does add implicit conjugated part for Tree_level_gluon_basis,
 	/// as these terms are contained in the matrix of scalar products.)
 	virtual Polynomial scalar_product( const Col_amp & Ca1, const Col_amp & Ca2 );
 
 	/// Function for calculating scalar products numerically, knowing the basis
 	/// and the scalar product matrix in numerical form.
 	/// (Does add implicit conjugated part for Tree_level_gluon_basis,
 	/// as these terms are contained in the matrix of scalar products.)
 	virtual cnum scalar_product_num( const Col_amp & Ca1, const Col_amp & Ca2 );
 
 	/// Calculates the scalar product between numerical (complex) amplitudes v1, V2
 	/// using the numerical scalar product matrix, d_spm.
 	/// The vectors thus needs to be expressed in the basis contained in cb.
 	/// (Does add implicit conjugated part for Tree_level_gluon_basis,
 	/// as these terms are contained in the matrix of scalar products.)
 	virtual cnum scalar_product_num( const cvec & v1, const cvec & v2 );
 
 	/// Calculates the scalar product between numerical (complex) amplitudes v1, v2
 	/// using the numerical scalar product matrix, d_spm.
 	/// Assumes that there are only diagonal contributions.
 	/// This is useful for calculations in leading Nc limit.
 	/// (Does add implicit conjugated part for Tree_level_gluon_basis,
 	/// as these terms are contained in the matrix of scalar products.)
 	cnum scalar_product_num_diagonal( const cvec & v1, const cvec & v2 );
 
 
 	/******************** Functions for reading and writing **********************/
 
 	// Functions for naming files
 
 	/// Returns a standard filename, used for writing out
 	/// the basis to a file.
 	std::string basis_file_name() const;
 
 	/// Returns a standard filename, used for writing out
 	/// scalar product matrices.
 	/// If leading is true, "_l" is appended to the filename.
 	/// If "poly" is true "P_" is added to the filename, and if it is
 	/// false "d_", as in double, is added to the filename.
 	std::string spm_file_name( const bool leading,  const bool poly) const;
 
 	/// Function for reading in the basis from the file filename.
 	/// The basis should be in human readable format, of form:<br>
 	/// 0  [{1,3,4,2}]<br>
 	/// 1  [{1,4,3,2}]<br>
 	/// 2  [{1,2}(3,4)]<br>
 	/// i.e. first basis vector number 0,1,2..., then
 	/// the Col_amp corresponding to the basis vector in question.
 	/// The Col_amps may consist of several Col_strs, for example<br>
 	/// 0  [(1,2,3,4)]+[(1,4,3,2)]<br>
 	/// 1  [(1,2,4,3)]+[(1,3,4,2)]<br>
 	///	2  [(1,3,4,2)]+[(1,2,4,3)]<br>
 	/// and each Col_str may also contain a Polynomial.
 	/// (The Polynomial should multiply the whole col_str,
-	/// rather than a quark_line inside the [] brackets.)
+	/// rather than a quark_line inside the []-brackets.)
 	virtual void read_in_Col_basis( std::string filename );
 
 	/// Function for reading in the basis from default filename
 	/// (see basis_file_name).
 	virtual void read_in_Col_basis();
 
 	/// Read in a numerical matrix from a file filename
 	/// (see spm_file_name) and save it as a double matrix, dmatr,
 	/// in the member variable d_spm.
 	/// The file should be in the format<br>
 	/// {{d11,...,d1n},<br>
 	/// ...,<br>
 	/// {dn1,....dnn}},<br>
 	/// and may contain comment lines starting with # at the top.
 	void read_in_d_spm( std::string filename );
 
 	/// Read in a numerical matrix from a file with default filename
 	/// (see spm_file_name) and save it as a double matrix, dmatr,
 	/// in the member variable d_spm.
 	/// The file should be in the format
 	/// {{d11,...,d1n},<br>
 	/// ...,<br>
 	/// {dn1,....dnn}},<br>
 	/// and may contain comment lines starting with # at the top.
 	void read_in_d_spm( );
 
 	/// Read in a numerical matrix from the file filename and save it as a double matrix, dmatr,
 	/// in the member variable leading_d_spm.
 	/// The file should be in the format<br>
 	/// {{d11,0,...,0},<br>
 	/// ...,<br>
 	/// {0,0,....dnn}},<br>
 	/// and may contain comment lines starting with # at the top.
 	void read_in_leading_d_spm( std::string filename );
 
 	/// Read in a numerical matrix from a file with default filename (see spm_file_name)
 	/// and save it as a double matrix, dmatr, in the member variable leading_d_spm.
 	/// The file should be in the format<br>
 	/// {{d11,0,...,0},<br>
 	/// ...,<br>
 	/// {0,0,....dnn}},<br>
 	/// and may contain comment lines starting with # at the top.
 	void read_in_leading_d_spm( );
 
 	/// Read in a Polynomial matrix from the file filename and save it as a Poly_matr
 	/// in the member variable P_spm.
 	/// The file should be in the format<br>
 	/// {{Poly11,...,Poly1n}, <br>
 	/// ...,<br>
 	/// {Polyn1,...,Polynn}},<br>
 	/// and may contain comment lines starting with # at the top.
 	void read_in_P_spm( std::string filename );
 
 	/// Read in a Polynomial matrix from a file with default filename (see spm_file_name)
 	/// and save it as a Poly_matr in the member variable P_spm.
 	/// The file should be in the format<br>
 	/// {{Poly11,...,Poly1n},<br>
 	/// ...,<br>
 	/// {Polyn1,...,Polynn}},<br>
 	/// and may contain comment lines starting with # at the top.
 	void read_in_P_spm( );
 
 	/// Read in a Polynomial matrix from a file with default filename
 	/// (see spm_file_name)  and save it as a Poly_matr
 	/// in the member variable leading_P_spm.
 	/// The file should be in the format<br>
 	/// {{Poly11,0...,0},<br>
 	/// ...,<br>
 	/// {0,...,Polynn}},<br>
 	/// and may contain comment lines starting with # at the top.
 	void read_in_leading_P_spm( std::string filename );
 
 	/// Reads in a Polynomial matrix from default filename (see spm_file_name)
 	/// and save it as a Poly_matr in the member variable leading_P_spm.
 	/// The file should be in the format<br>
 	/// {{Poly11,0...,0},<br>
 	/// ...,<br>
 	/// {0,...,Polynn}},<br>
 	/// and may contain comment lines starting with # at the top.
 	void read_in_leading_P_spm(  );
 
 
 	// Functions for writing
 
 	/// Function for writing out the basis to a file with name filename.
 	virtual void write_out_Col_basis( std::string filename) const;
 
 	/// Function for writing out the basis to a file
 	/// with default name (see basis_file_name).
 	virtual void write_out_Col_basis() const;
 
-	/// Function for writing out the basis in a human readable
-	/// format to cout.
-	virtual void write_out_Col_basis_to_cout() const;
-
-	/// Writes out d_spm to file filename.
+	/// Writes out d_spm to the file filename.
 	void write_out_d_spm( std::string filename ) const;
 
 	/// Writes out d_spm to the standard filename, see spm_file_name.
 	void write_out_d_spm( ) const;
 
-	/// Writes out P_spm to file filename.
+	/// Writes out P_spm to the file filename.
 	void write_out_P_spm( std::string filename ) const;
 
 	/// Writes out P_spm to the standard filename, see spm_file_name.
 	void write_out_P_spm( ) const;
 
-	/// Writes out leading_d_spm to file filename.
+	/// Writes out leading_d_spm to the file filename.
 	void write_out_leading_d_spm( std::string filename ) const;
 
 	/// Writes out leading_d_spm to the standard filename, see spm_file_name.
 	void write_out_leading_d_spm( ) const;
 
 	/// Writes out leading_P_spm to the file filename.
 	void write_out_leading_P_spm( std::string filename ) const;
 
 	/// Writes out leading_P_spm to the standard filename, see spm_file_name.
 	void write_out_leading_P_spm( ) const;
 
 	/******************** Other functions **********************/
 
-	/// Simplify all the basis vectors by using simplify on the
+	/// Simplifies all the basis vectors by using simplify on the
 	/// individual Col_amps in the basis.
 	void simplify();
 
 	/// Each type of color basis has to implement a function for decomposing
 	/// an amplitude in the color basis.
-	virtual Poly_vec decompose( const Col_amp & Ca ) ;
+	virtual Poly_vec decompose( const Col_amp & Ca );
 
 	/// Function for finding the resulting Col_amp after exchanging
 	/// a gluon between parton p1 and parton p2 in the
 	/// basis vector vec.
-	Col_amp exchange_gluon( uint vec, int p1, int p2 ) ;
+	Col_amp exchange_gluon( uint vec, int p1, int p2 );
 
 	/// Function for calculating the color structure part of the soft anomalous
 	/// dimension matrix. First calculates the effect of gluon exchange on a
 	/// basis vector and then decomposes the result into the basis.
 	/// For this to work the basis must clearly contain all resulting
-	/// bases vectors, meaning for example that it can not be
+	/// basis vectors, meaning for example that it can not be
 	/// used for Tree_level_gluon_basis.
 	/// The function is only available for the Trace_basis
 	/// and the Orthogonal_basis classes.
-	Poly_matr Col_gamma( int p1, int p2 );
+	/// The ij-component of the resulting matrix gives the amplitude
+	/// for ending up in component i if starting in component j.
+	Poly_matr color_gamma( int p1, int p2 );
 
 	/// Returns the number of quarks in the Col_basis after
 	/// checking that each Col_str in each Col_amp
 	/// has the same number of quarks.
 	int n_quark_check() const;
 
 	/// Returns the number of gluons in the Col_basis after
 	/// checking that each Col_str in each Col_amp
 	/// has the same number of gluons.
 	int n_gluon_check() const;
 
 	/// A function to rename the indices in two Col_strs, such that in the first
 	/// they are called 1,2,3..., and in the second the relative order is kept.
 	void rename_indices( Col_str & Cs1, Col_str & Cs2 ) const;
 
 	/******************** Internal functions **********************/
 
 protected:
 
 	bool trace_basis;
 	bool tree_level_gluon_basis;
 	bool orthogonal_basis;
 
 	/// The underlying function for calculation of scalar product
 	/// matrices. Calculation depends on the arguments:
 	/// save_P_spm, save_d_spm and use_mem.
 	/// If save_P_spm is true the Polynomial scalar product
 	/// matrix is saved to P_spm.
 	/// If save_d_spm is true, the numerical scalar product matrix
 	/// is saved to d_spm.
 	/// The leading_d_spm is only calculated and written out if save_P_spm is true.
 	/// If use_mem is true memoization is used
 	/// in order to calculate a color topology only once.
 	virtual void scalar_product_matrix( bool save_P_spm, bool save_d_spm, bool use_mem );
 
 	/// Calculates element i,j in scalar product matrix using the scalar product.
 	virtual Polynomial ij_entry( const int i, const int j ) const;
 
 	/// Checking that a numerical (double) matrix is diagonal.
 	/// Used for the leading version of the scalar product matrix.
 	/// Returns true if the matrix is diagonal and false otherwise.
 	bool check_diagonal( const dmatr & matr ) const;
 
 	/// Checking that a numerical (double) matrix (the scalar product matrix)
 	/// is symmetric.
 	/// Returns true if the matrix is symmetric and false otherwise.
 	bool check_symmetry( const dmatr & matr ) const;
 
 	/// Makes consistency checks on the scalar product matrix.
 	void check_spm() const;
 
 	/// Converts a text string (in a file) to a basis,
 	/// used by the read_in_basis functions.
 	void Col_basis_of_str( std::string str );
 
+	/// Function for writing out the basis in a human readable
+	/// format to an ostream.
+	virtual std::ostream&  write_out_Col_basis_to_stream( std::ostream&  out ) const;
+
+	/// The operator << for Col_basis operator must be able to access the
+	/// write_out_Col_basis_to_stream operator.
+	friend std::ostream& operator<<( std::ostream& out, const Col_basis & Cb );
+
 };// end class Col_basis
 
 
 /// Define the operator << for col_basis.
 std::ostream& operator<<( std::ostream& out, const col_basis & cb );
 
 
+/// Define the operator << for Col_basis.
+std::ostream& operator<<( std::ostream& out, const Col_basis & Cb );
+
 }// end namespace ColorFull
 
 
 #endif /* COLBASIS_H_ */
 
diff --git a/MatrixElement/Matchbox/ColorFull/Col_functions.cc b/MatrixElement/Matchbox/ColorFull/Col_functions.cc
--- a/MatrixElement/Matchbox/ColorFull/Col_functions.cc
+++ b/MatrixElement/Matchbox/ColorFull/Col_functions.cc
@@ -1,1833 +1,1918 @@
 /*
  * Col_functions.cc
  *	Contains definitions of functions and operators used for treating the color structure
  *  Created on: Jul 8, 2010
  *      Author: malin
  */
 
 #include "Col_functions.h"
 #include "parameters.h"
 #include <cassert>
 #include <fstream>
 #include <iostream>
 #include <limits>
 
 namespace ColorFull {
 
 int  Col_functions::leading_Nc_pow( const Polynomial & Poly ) const{
 	if( Poly.poly.empty()) {
 		if( double_num(Poly)!=0 ) return 0;
 		else return std::numeric_limits<int>::min();
 	}
 	int leading_pow=Poly.at(0).pow_Nc + Poly.at(0).pow_CF;
 
 	// Loop over non-zero Monomials
 	for (uint i=0; i<Poly.poly.size(); i++){
 		if( Poly.at(i).pow_Nc + Poly.at(i).pow_CF > leading_pow && Poly.at(i).int_part!=0 )
 			leading_pow=Poly.at(i).pow_Nc + Poly.at(i).pow_CF;
 	}
 	return leading_pow;
 }
 
 int  Col_functions::leading_Nc_pow( const Poly_vec & Pv ) const{
 
 	int leading_pow=leading_Nc_pow( Pv.at(0) );
 
 	// Loop over Polynomials
 	for (uint p=0; p<Pv.size(); p++){
 		if ( leading_Nc_pow( Pv.at(p) ) > leading_pow )
 			leading_pow=leading_Nc_pow( Pv.at(p) );
 	}
 
 	return leading_pow;
 }
 
+/*
 int  Col_functions::leading_Nc_pow( const std::vector< shared_ptr<Polynomial> > & Pvp) const{
 	int leading_pow=leading_Nc_pow( *(Pvp.at(0)) );
 
 	// Loop over Polynomials
 	for (uint p=1; p<Pvp.size(); p++){
 		if ( leading_Nc_pow( *(Pvp.at(p)) ) > leading_pow )
 			leading_pow=leading_Nc_pow( *(Pvp.at(p)) );
 	}
 
 	return leading_pow;
 }
+*/
 
 Polynomial Col_functions::leading( const Polynomial & Poly ) const{
 
 
 	// If the Polynomial is empty=1, or it it has only one term,
 	// just return the Poly itself
 	if( Poly.empty() ) return Poly;
 
 	// Candidate for highest power of Nc+CF
 	int cand_pow = Poly.at(0).pow_Nc + Poly.at(0).pow_CF;
 
 	// For containing the leading Nc Polynomial
 	Polynomial Leading_pol;
-	Leading_pol.push_back(Poly.at(0));
+	Leading_pol.append(Poly.at(0));
 
 	// If only one term, keep that term
 	if( Poly.size()==1 ) Leading_pol=Poly;
 
 	// If more than one term, look for higher powers
 	// Looks for Monomials with highest Nc power
 	if( Poly.size()>1 ){// found bug for Polynomials with one term 13 07 12
 		for (int k = 1; k < Poly.size(); k++) {
 
 			// If power higher
 			if ((Poly.at(k).pow_Nc + Poly.at(k).pow_CF) > cand_pow) {
 				cand_pow = Poly.at(k).pow_Nc + Poly.at(k).pow_CF;
 				Leading_pol.clear();
 				Leading_pol = Leading_pol * 0;
 				Leading_pol = Leading_pol + Poly.at(k);
 			}
 			// If power equal
 			else if (Poly.at(k).pow_Nc + Poly.at(k).pow_CF == cand_pow) {
 				Leading_pol = Leading_pol + Poly.at(k);
 			}
 		}
 	}
 	// now Leading_pol contains terms with maximal power of CF plus Nc
 
 	// If the variable full_CF is false (default), CF should be replaced with TR*Nc.
 	// If numerical evaluation is done after this, CF will thus be evaluated to TR Nc.
 	// If full_cf is true, CF will be replaced by  CF(Nc).
 	if ( ! full_CF ) {
 		// Loop over terms and replace CF with the Nc -> infinity limit of CF =TR*Nc
 		for (int i = 0; i < Leading_pol.size(); i++) {
 			int pow_CF = Leading_pol.at(i).pow_CF;
 			Leading_pol.at(i).pow_Nc += pow_CF;
 			Leading_pol.at(i).pow_TR += pow_CF;
 			Leading_pol.at(i).pow_CF = 0;
 		}
 	}
 
 	Leading_pol.simplify();
 	return Leading_pol;
 }
 
 Poly_vec Col_functions::leading( const Poly_vec & Pv ) const{
 
 	// To contain the result
 	Poly_vec Pv_res;
 
 	// Take the leading part of each Polynomial
 	// after this all Monomials in the SAME Polynomial have the same Nc power
 	for (uint i = 0; i < Pv.size(); i++) {
 		// Take the leading terms in each component
-		Pv_res.push_back( leading( Pv.at(i) ) );
+		Pv_res.append( leading( Pv.at(i) ) );
 	}
 
 	// Find the leading power
 	int leading_pow = leading_Nc_pow(Pv_res);
 
 	// Loop over entries and keep only those with maximal power
 	for (uint p = 0; p < Pv_res.size(); p++) {
 		if (leading_Nc_pow(Pv_res.at(p)) != leading_pow) {
-			Pv_res.at(p) = 0 * Pv_res.at(p);
+			Pv_res.at(p) *= 0;
 			Pv_res.at(p).simplify();
 		}
 	}
 
 	return Pv_res;
 }
 
 Poly_matr Col_functions::leading( const Poly_matr & Pm )  const{
 
 	// To contain the result
 	Poly_matr Pm_res;
 	Pm_res.pm.reserve(Pm.pm.size());
 	// Loop over Poly_vecs, and take the leading part of each Poly_vec
 	for (uint i = 0; i < Pm.size(); i++) {
 		// Take the leading terms in each Poly_vec
 		Poly_vec Pvl= leading( Pm.at(i) );
-		Pm_res.push_back( Pvl );
+		Pm_res.append( Pvl );
 	}
 	int cand_pow = leading_Nc_pow( Pm.at(0).pv );
 
 	// Loop over Poly_vecs to locate highest power
 	for (uint k = 0; k < Pm_res.size(); k++) {
 	  int pow_at_k = leading_Nc_pow(Pm_res.at(k).pv);
 		if (pow_at_k > cand_pow)
 			cand_pow = pow_at_k;
 	}
 
 	// In all Polynomials, in all Poly_vec's,
 	// put all elements which doesn't have highest power to 0
 	for (uint k = 0; k < Pm_res.size(); k++) {
 		// In each Poly_vec, loop over all Polynomials
 		for (uint p = 0; p < Pm_res.at(k).size(); p++) {
 			if (leading_Nc_pow(Pm_res.at(k).at(p)) != cand_pow) {
 				//Pm_res.at(k).pv.at(p) = Pm_res.at(k).pv.at(p) * 0;
 				Pm_res.at( k,p )=Pm_res.at(k).at(p) * 0;
 				Pm_res.at(k,p).simplify();
 			}
 		}
 	}
 
 	return Pm_res;
 }
 
-
+/*
 Poly_vec Col_functions::leading( const std::vector<shared_ptr<Polynomial> >  & Pvp )  const{
 	Poly_vec Pv_res;
 
 	// Loop over entries in vector (Poly_vecs), and take the leading part of each Polynomial
 	// after this each Monomial has the same Nc+CF-power
 	for (uint i = 0; i < Pvp.size(); i++) {
 		// Take the leading terms in each component
-		shared_ptr<Polynomial> the_pointer=Pvp.at(i);
+		std::shared_ptr<Polynomial> the_pointer=Pvp.at(i);
 		Pv_res.push_back( leading( (*the_pointer) ) );
 	}
 
 	// Find the leading power
 	int leading_pow = leading_Nc_pow(Pv_res);
 
 	// Loop over entries and keep only those with maximal power
 	for (uint p = 0; p < Pv_res.size(); p++) {
 		if (leading_Nc_pow(Pv_res.at(p)) != leading_pow) {
-			Pv_res.at(p) = 0 * Pv_res.at(p);
+			Pv_res.at(p) *= 0;
 			Pv_res.at(p).simplify();
 		}
 	}
 
 	return Pv_res;
 }
+*/
 
-
+/*
 dmatr Col_functions::leading( const std::vector< std::vector< shared_ptr<Polynomial> > > & Ppm ) const {
 
 	// To contain the result as a matrix of double
 	dmatr res;
 	res.reserve( Ppm.size() );
 
 	int cand_pow = leading_Nc_pow( Ppm.at(0) );
 
 	// Loop over Poly_vecs to locate highest power
 	for (uint k = 0; k < Ppm.size(); k++) {
 		int the_pow=leading_Nc_pow(Ppm.at(k));
 		if ( the_pow > cand_pow )
 			cand_pow = the_pow;
 	}
 
 	// In all Polynomials, in all Poly_vec's,
 	// put all elements which doesn't have highest power to 0
 	for (uint k = 0; k < Ppm.size(); k++) {
 		dvec dummy;
 		res.push_back(dummy); // Not to run out of range
 		// In each Poly_vec, loop over all Polynomials
 		for (uint p = 0; p < Ppm.at(k).size(); p++) {
 			Polynomial the_poly=*Ppm.at(k).at(p);
 			leading_Nc_pow( the_poly );
 			if ( leading_Nc_pow( the_poly ) != cand_pow ) {res.at(k).push_back(0);}
 			else res.at(k).push_back( double_num(leading(the_poly)) );
 		}
 	}
 
 	return res;
 }
-
-std::map< std::string, Polynomial > Col_functions::leading( const std::map< std::string, Polynomial > & mem_map  )  const{
-
-	// To contain (string, leading(Polynomial))
-	std::map< std::string, Polynomial > res;
-
-    // Find the highest power of Nc+CF
-    int pow_cand=leading_Nc_pow( mem_map.begin()->second );
-    for( auto iter =  mem_map.begin(); iter !=  mem_map.end(); ++iter ) {
-    	Polynomial Poly= (iter->second);
-    	if( leading_Nc_pow(Poly) > pow_cand ) pow_cand=leading_Nc_pow(Poly);
-    }
-
-    for( auto iter =  mem_map.begin(); iter !=  mem_map.end(); ++iter ) {
-
-    	// Insert pair of string and the leading versions of the Polynomial
-    	Polynomial lead_Poly= leading( (iter->second) );
-    	if ( leading_Nc_pow(lead_Poly) != pow_cand ) lead_Poly=lead_Poly*0;
-
-    	res.insert( make_pair( iter->first, lead_Poly ) );
-    } // After this only the leading part of each Polynomial contributes
-
-	return res;
-}
+*/
 
 cnum Col_functions::cnum_num( const Monomial & Mon ) const {
 
 	cnum res=Mon.cnum_part*static_cast<double>(Mon.int_part);
 	for ( int ix=0; ix<Mon.pow_Nc; ix++ )
 		res *= Nc;
 	for ( int ix=0; ix<Mon.pow_CF; ix++ )
 		res *= CF;
 	for ( int ix=0; ix<Mon.pow_TR; ix++ )
 		res *= TR;
 	for ( int ix=0; ix>Mon.pow_Nc; ix-- )
 		res /= static_cast<double>(Nc);
 	for ( int ix=0; ix>Mon.pow_CF; ix-- )
 		res /= static_cast<double>(CF);
 	for ( int ix=0; ix>Mon.pow_TR; ix-- )
 		res /= static_cast<double>(TR);
 	//cnum res=pow(Nc, Mon.pow_Nc)*pow(CF, Mon.pow_CF)*pow(TR, Mon.pow_TR)*Mon.int_part* Mon.cnum_part;
 
 	return res;
 }
 
 double  Col_functions::double_num( const Monomial & Mon ) const{
 
 	double im=imag( cnum_num(Mon) );
 	double re=real( cnum_num(Mon) );
 
 	// Warn if the complex number has significant imaginary parts
 	if( im!=0.0 and re!=0.0 ) {
 		double ratio =im/re;
 		if( ratio > accuracy )
 			std::cerr << "Col_functions::double_num(Mon): Warning keeping only real part of complex number, the ratio im/re was " << ratio << std::endl;
 	}
 	else if ( im!=0.0 and re==0.0 ){
 					std::cerr << "Col_functions::double_num(Mon): Warning keeping only real part of complex number, imaginary part was " << im << std::endl;
 	}
 
 	return re;
 }
 
 cnum Col_functions::cnum_num( const Polynomial & Poly ) const {
 
 	// An empty Polynomial has numerical value 1
 	if( Poly.empty() ) return 1.0;
 
 	cnum res = 0;
 
 	// Add contributions from Monomials
 	for ( int k = 0; k < Poly.size(); k++ ) {
 		cnum part_k;
 		part_k=cnum_num( Poly.at(k) );
 		res = res + part_k;
 	}
 
 	return res;
 }
 
 double Col_functions::double_num( const Polynomial & Poly ) const{
 	double im=imag( cnum_num(Poly) );
 	double re=real( cnum_num(Poly) );
 
 	// Warn if the complex number has significant imaginary parts
 	if( im!=0.0 and re!=0.0 ) {
 		double ratio =im/re;
 		if( ratio > accuracy )
 			std::cerr << "Col_functions::double_num: Warning keeping only real part of complex number, the ratio im/re was " << ratio << std::endl;
 	}
 	else if ( im!=0.0 and re==0.0 ){
 		std::cerr << "Col_functions::double_num: Warning keeping only real part of complex number, imaginary part was " << im << std::endl;
 	}
 
 	return re;
 }
 
 
 Col_amp Col_functions::emit_gluon( const Col_str & in_Col_str, int emitter, int g_new ) const{
 
   // Locate the emitter in the Col_str
   std::pair<int, int> place=in_Col_str.find_parton(emitter);
 
   // Find what kind, q qbar or g, the emitter is
   std::string kind=in_Col_str.find_kind(emitter);
 
   // Defining Col_str to return (two needed in case of g)
   Col_str out_Col_str1=in_Col_str;
   Col_str out_Col_str2=in_Col_str;
   // Defining Col_amp to return
   Col_amp out_Col_amp;
 
   // If the emitter is a quark
   if( kind =="q" ){
     // Add new parton index at second first place in relevant quark_line
     out_Col_str1.insert( place.first, place.second+1, g_new );
     out_Col_amp.ca.push_back( out_Col_str1 );
   }
   // If the emitter is an anti-quark
   else if( kind =="qbar" ){
     // Add new gluon before the qbar
     out_Col_str1.insert( place.first, place.second, g_new );
     // Change sign
     out_Col_str1.Poly=out_Col_str1.Poly*(-1);
     // Making a Col_amp to return
     out_Col_amp.ca.push_back( out_Col_str1 );
   }
   // If the emitter is a g
   else if( kind =="g" ){
     // If the emitter is a gluon a new gluon line should be inserted in two
     // different places, before and after the emitter
 
     // -sign when inserting the gluon before
     // Change sign Poly for first term
     Monomial Mon_tmp;
     Mon_tmp.int_part=-1;
-    out_Col_str1.Poly=out_Col_str1.Poly*Mon_tmp;
+    out_Col_str1.Poly *= Mon_tmp;
 
     // Inserting the gluon before
     out_Col_str1.insert( place.first, place.second, g_new );
     // Inserting the gluon after
     out_Col_str2.insert( place.first, place.second+1, g_new );
     // Appending result to out_Col_amp
     out_Col_amp.ca.push_back( out_Col_str1 );
     out_Col_amp.ca.push_back( out_Col_str2 );
     // Normal order
     out_Col_amp.normal_order();
   }
   out_Col_amp.simplify();
 
   return out_Col_amp;
 }
 
 
 Col_amp Col_functions::emit_gluon( const Col_amp & Ca_in, int emitter, int g_new ) const{
 
 	Col_amp Ca_out;
 
 	// Emit from each Col_str, and append to new Col_amp
 	for( uint m=0; m< Ca_in.ca.size(); m++ ){
 		Col_amp part_m=emit_gluon(Ca_in.ca.at(m), emitter, g_new);
 		Ca_out.append(part_m.ca);
 	}
 
 	return Ca_out;
 }
 
+Col_amp Col_functions::split_gluon(const Col_str & in_Col_str, int g_old,
+		int q_new, int qbar_new) const {
+
+	// Locate the splitting gluon in the Col_str
+	std::pair<int, int> place = in_Col_str.find_parton(g_old);
+
+	// Find what kind, q qbar or g, the emitter is
+	std::string kind = in_Col_str.find_kind(g_old);
+	if (kind != "g"){
+		std::cerr
+				<< "Col_functions::split_gluon: The splitting parton must be a gluon but was a "
+				<< kind << "." << std::endl;
+		assert( 0 );
+	}
+
+	// Quark_line to be treated
+	Quark_line Ql = in_Col_str.at(place.first);
+
+	// To contain the resulting Col_amp
+	Col_amp out_Col_amp;
+
+	// If the Ql is open we should get two open Qls
+	if (Ql.open) {
+
+		// Col_strs to return in Col_amp
+		Col_str out_Col_str1 = in_Col_str;
+		Col_str out_Col_str2 = in_Col_str;
+
+		// Define Quark_lines, to contain the two new Quark_lines after splitting
+		// For leading part
+		Quark_line Ql1 = in_Col_str.at(place.first);
+		Quark_line Ql2 = in_Col_str.at(place.first);
+		// For suppressed part
+		Quark_line Ql3;
+
+		// Take first part up to place of gluon
+		Ql1 = Ql.before(place.second);
+		// and append qbar_new
+		Ql1.append(qbar_new);
+		Ql1.open = true;
+
+		// Take 2nd part after place of gluon
+		Ql2 = Ql.after(place.second);
+		// and prepend q_new
+		Ql2.prepend(q_new);
+		Ql2.open = true;
+
+		// In the Col_str, replace old Quark_line with two new
+		out_Col_str1.erase(place.first);
+		out_Col_str1 = out_Col_str1 * Ql1 * Ql2;
+
+		// Multiply with TR
+		Monomial Mon1;
+		Mon1.pow_TR=1;
+		out_Col_str1 = out_Col_str1 * Mon1;
+
+
+		// Erase the gluon
+		out_Col_str2.erase(place);
+		// Add quark_line with just qqbar pair
+		Ql3.append(q_new);
+		Ql3.append(qbar_new);
+		out_Col_str2= out_Col_str2*Ql3;
+		// Multiply with -TR/Nc
+		Monomial Mon2;
+		Mon2.pow_TR=1;
+		Mon2.pow_Nc=-1;
+		Mon2*=-1;
+		out_Col_str2 = out_Col_str2 * Mon2;
+
+		// Add parts in resulting Col_amp
+		out_Col_amp.append(out_Col_str1);
+		out_Col_amp.append(out_Col_str2);
+
+	}
+	// If the Ql is closed
+	else {
+
+		Quark_line new_Ql;
+		Col_str out_Col_str = in_Col_str;
+
+		// Leftmost we should have the new quark
+		new_Ql.prepend(q_new);
+
+		// After this should follow the segment after the splitting gluon
+		new_Ql.append(Ql.after(place.second).ql);
+
+		// and after that the first part of the old Ql
+		new_Ql.append(Ql.before(place.second).ql);
+
+		// Rightmost we should have the new anti-quark
+		new_Ql.append(qbar_new);
+
+		// We should not forget the polynomial factor of the old Ql
+		new_Ql.Poly = in_Col_str.at(place.first).Poly;
+
+		// ... and we get a factor TR from the gluon contraction
+		out_Col_str = out_Col_str*Monomial("TR");
+
+		// In the Col_str, replace old Quark_line with new
+		out_Col_str.at(place.first) = new_Ql;
+
+		out_Col_amp.append(out_Col_str);
+	}
+
+	// Normal order
+	out_Col_amp.normal_order();
+
+	out_Col_amp.simplify();
+
+	return out_Col_amp;
+}
+
+
+
+Col_amp Col_functions::split_gluon( const Col_amp & in_Col_amp, int g_old, int q_new, int qbar_new ) const{
+
+	Col_amp Ca_out;
+
+	// Split each Col_str, and append to new Col_amp
+	for( uint m=0; m< in_Col_amp.ca.size(); m++ ){
+		Col_amp Cam = split_gluon( in_Col_amp.ca.at(m), g_old, q_new, qbar_new );
+		Ca_out= Ca_out + Cam;
+	}
+
+	return Ca_out;
+}
+
 
 // See my general color structure paper
 Col_amp Col_functions::exchange_gluon( const Col_str & Cs, int p1, int p2 )  const{
 
 	Col_str Cs_copy=Cs;
 
 	// Find out kind and location of partons
 	std::string kind1 = Cs_copy.find_kind(p1);
 	std::string kind2 = Cs_copy.find_kind(p2);
 	std::pair<int, int> place1 = Cs_copy.find_parton(p1);
 	std::pair<int, int> place2 = Cs_copy.find_parton(p2);
 
 
 
 	// To contain result
 	Col_amp Ca;
 
 	// Make sure the col_f in multiplying participating Ql's are 0
 	Polynomial Poly1; // For comparing Poly is 1, all powers are 0
 	if (!(Poly1 == Cs_copy.cs.at(place1.first).Poly)) {
 		// Move factor of Quark_line to Col_str
 		Cs_copy.Poly = Cs_copy.Poly * Cs_copy.cs.at(place1.first).Poly;
 		Cs_copy.cs.at(place1.first).Poly = Poly1;
 	}
 	if (!(Cs_copy.cs.at(place2.first).Poly == Poly1)) {
 		// Move factor of Quark_line to Col_str
 		Cs_copy.Poly = Cs_copy.Poly * Cs_copy.cs.at(place2.first).Poly;
 		Cs_copy.cs.at(place2.first).Poly = Poly1;
 	}
 
 	//	sign
 	if ( place1.first == place2.first && place1.second == place2.second ) {
 
 		Monomial mon;
 		// For qq or qbar qbar
 		// If the qs are the same, the result is just CF*old for q and qbar
 		// there are 0 minus signs for quarks and 2 for anti-quarks
 		if (kind1 == "q" or kind1 == "qbar")
 			mon.pow_CF = 1;
 		// for gluons
 		else{
 			mon.pow_Nc = 1;
 			// There is a factor TR from the contracted gluon,
 			// The sign can be checked by writing out four terms
 			// corresponding to inserting the new gluon
 			// first/first, first/last, last/first, last/last
 			mon.pow_TR+=1;
 			mon.int_part*=2;
 		}
-		Cs_copy.Poly = Cs_copy.Poly * mon;
+		Cs_copy.Poly *=  mon;
 		Ca.ca.push_back( Cs_copy );
 		return Ca;
 	}
 
 	// Exchange between qq or qbar qbar
 	if ((kind1 == "q" && kind2 == "q") or (kind1 == "qbar" && kind2 == "qbar")) {
 
 		Col_str Cs2 = Cs_copy;
 
 		// The q's normally sit on different quark_lines
 
 		// The leading Nc-tems has the q's exchanged
 		Cs_copy.cs.at(place1.first).ql.at(place1.second) = p2;
 		Cs_copy.cs.at(place2.first).ql.at(place2.second) = p1;
 		// Multiply with TR
 		Monomial Mon;
 		Mon.pow_TR = 1;
 
-		Cs_copy.Poly = Cs_copy.Poly * Mon;
+		Cs_copy.Poly *= Mon;
 
 		// The suppressed term is a copy of the old term,
 		// but multiplied with -TR /Nc
 		Mon.pow_TR = 1;
 		Mon.int_part = -1;
 		Mon.pow_Nc = -1;
-		Cs2.Poly = Cs2.Poly * Mon;
+		Cs2.Poly *= Mon;
 
 		Ca.ca.push_back(Cs_copy);
 		Ca.ca.push_back(Cs2);
 	}
 
 	// Exchange between q qbar
 	if ((kind1 == "q" && kind2 == "qbar") or (kind1 == "qbar" && kind2 == "q")) {
 
 	  std::pair<int, int> q_place;
 	  std::pair<int, int> qbar_place;
 		int the_q=-1;
 		int the_qbar=-1;
 
 		if ((kind1 == "q" && kind2 == "qbar")) {
 			q_place = place1;
 			qbar_place = place2;
 			the_q = p1;
 			the_qbar = p2;
 		} else if ((kind1 == "qbar" && kind2 == "q")) {
 			q_place = place2;
 			qbar_place = place1;
 			the_q = p2;
 			the_qbar = p1;
 		}
 
 		Col_str Cs2 = Cs_copy;
 
 		// If q and qbar are not part of same ql
 		if (q_place.first != qbar_place.first) {
 			// The non-suppressed term, obtained by erasing q qbar and joining rest
 			Cs_copy.erase(q_place);
 			Cs_copy.erase(qbar_place);
 
 			// In the ql of the qbar, append the ql of the q, then erase the ql of the q
 			Cs_copy.cs.at(qbar_place.first).append(Cs_copy.cs.at(q_place.first).ql);
 			// and erase the ql of the q
 			Cs_copy.erase(q_place.first);
 		}
 		// If q and qbar sit on same ql
 		else {
 			// The non-suppressed term, obtained by erasing q qbar and joining rest to a ring
 			Cs_copy.erase(qbar_place);
 			Cs_copy.erase(q_place);
 			Cs_copy.cs.at(q_place.first).open = false;
 			// If only one quark remains the term should be 0
 		}
 
 		// q and qbar must be found
 		assert( the_q!=-1);
 		assert( the_qbar!=-1);
 
 		// Construct Quark_line={q,qbar}, and append it
 		Quark_line Ql;
 		Ql.open = true;
-		Ql.push_back( the_q );
-		Ql.push_back( the_qbar );
-		Cs_copy.push_back(Ql);
+		Ql.append( the_q );
+		Ql.append( the_qbar );
+		Cs_copy.append(Ql);
 
 		// Multiply with TR
 		Monomial Mon;
 		Mon.pow_TR = 1;
-		Cs_copy.Poly = Cs_copy.Poly * Mon;
+		Cs_copy.Poly *= Mon;
 
 		// The suppressed term is a copy of the old term,
 		// but multiplied with -TR / Nc
 		Mon.pow_TR=1;
 		Mon.int_part = -1;
 		Mon.pow_Nc = -1;
-		Cs2.Poly = Cs2.Poly * Mon;
+		Cs2.Poly *= Mon;
 
 		// Construct  the resulting color_amplitude and return
 		// Make sure there is not only one or 0 gluons in a closed ql
 		// Append Cs to ca if >=2 gluons
 		// if open, append
 		if (Cs_copy.cs.at(q_place.first).open)
 			Ca.ca.push_back(Cs_copy);
 		// if closed but >= 2 gluons, append
 		else if (Cs_copy.cs.at(q_place.first).ql.size() >= 2 && !Cs_copy.cs.at(
 				q_place.first).open)
 			Ca.ca.push_back(Cs_copy);
 		// If 1 gluon, the term is 0 and is not appended
 
 		// If 0 gluons the empty colsed ql is equivalent to multiplying with Nc, obtained after simplification
 		else if (Cs_copy.cs.at(q_place.first).empty()
 				&& !Cs_copy.cs.at(q_place.first).open) {
 			// return 2nd term * (1-Nc^2)
 			Ca.ca.push_back(Cs_copy);
 			Ca.ca.push_back(Cs2);
 			Ca.simplify();
 			return Ca;
 		}
 		Ca.ca.push_back(Cs2);
 	}
 
 	// Exchange between q g
 	if ((kind1 == "q" && kind2 == "g") or (kind1 == "g" && kind2 == "q")) {
 
 	  std::pair<int, int> q_place;
 	  std::pair<int, int> g_place;
 		int the_q=0;
 		int the_g=0;
 
 		if (kind1 == "q" && kind2 == "g") {
 			q_place = place1;
 			g_place = place2;
 			the_q = p1;
 			the_g = p2;
 		} else if (kind1 == "g" && kind2 == "q") {
 			q_place = place2;
 			g_place = place1;
 			the_q = p2;
 			the_g = p1;
 		}
 
 		// For containing Quark_lines
 		Quark_line Ql11;
 		Quark_line Ql12;
 		Quark_line Ql21;
 		Quark_line Ql22;
 
 		Col_str Cs1 = Cs_copy;
 		Col_str Cs2 = Cs_copy;
 
 		// If the q and the g are not part of same ql
 		if (g_place.first != q_place.first) {
 
 			// Take split the Ql with the gluon after the gluon
 			Quark_line Qlg_start = Cs_copy.cs.at(g_place.first).before( g_place.second );
 
 			Quark_line Qlg_end = Cs_copy.cs.at(g_place.first).after( g_place.second );
 			Quark_line Qlq_end = Cs_copy.cs.at(q_place.first).after( q_place.second );
 
 			// First part, + sign
 			// First part, first Ql
 			Ql11 = Qlg_end;
 			Ql11.prepend(the_g);
 			Ql11.prepend(the_q);
 
 			// First part, second Ql
 			Ql12 = Qlg_start;
 			Ql12.append(Qlq_end.ql);
 
 			// If the ql of the gluon was closed account for this by gluing qls together
 			if (!Qlg_start.open) {
 				Ql11.append(Ql12.ql);
 				Ql11.open = true;
 			};
 
 			// Second part, first Ql
 			Ql21 = Qlg_end;
 			Ql21.prepend(the_q);
 
 			// Second part, second Ql
 			Ql22 = Qlg_start;
 			Ql22.append(the_g);
 			Ql22.append(Qlq_end.ql);
 
 			// If the ql of the gluon was closed account for this by gluing qls together
 			if (!Qlg_start.open) {
 				Ql21.append(Ql22.ql);
 				Ql21.open = true;
 			};
 
 			// Replace Ql's in the Col_str
 			Cs1.cs.at(q_place.first) = Ql11;
 			Cs2.cs.at(q_place.first) = Ql21;
 
 			// There is only one ql if the ql of the gluon was closed
 			if (Qlg_start.open) {
 				Cs1.cs.at(g_place.first) = Ql12;
 				Cs2.cs.at(g_place.first) = Ql22;
 			} else { // Erase 2nd ql
 				Cs1.erase(g_place.first);
 				Cs2.erase(g_place.first);
 			}
 
 		}
 		// If q and g are part of same ql
 		else {
 
 			Quark_line Ql1 = Cs_copy.cs.at(g_place.first).before( g_place.second );
 			Ql1.ql.erase(Ql1.ql.begin());
 			Quark_line Ql2 = Cs_copy.cs.at(g_place.first).after( g_place.second);
 
 			// First term, First ql
 			Ql11 = Ql1;
 			Ql11.open = false;
 
 			// First term, 2nd ql
 			Ql12 = Ql2;
 			Ql12.prepend(the_g);
 			Ql12.prepend(the_q);
 
 			// 2nd term, 1st ql
 			Ql21 = Ql1;
 			Ql21.append(the_g);
 			Ql21.open = false;
 
 			// 2nd term 2nd ql
 			Ql22 = Ql2;
 			Ql22.prepend(the_q);
 
 			// Replace Ql's in the Col_str
 			Cs1.cs.at(q_place.first) = Ql11;
 			Cs1.cs.insert(Cs1.cs.begin() + q_place.first + 1, Ql12);
 
 			// Replace Ql's in the Col_str
 			Cs2.cs.at(q_place.first) = Ql21;
 			Cs2.cs.insert(Cs2.cs.begin() + q_place.first + 1, Ql22);
 
 		}
 
 		// Multiply first part with TR
 		Monomial Mon_tmp;
 		Mon_tmp.pow_TR = 1;
-		Cs1.Poly = Cs1.Poly * Mon_tmp;
+		Cs1.Poly *= Mon_tmp;
 
 		// Multiply second part with -TR
 		Monomial Mon_tmp2;
 		Mon_tmp2.pow_TR = 1;
 		Mon_tmp2.int_part = -1;
-		Cs2.Poly = Cs2.Poly * Mon_tmp2;
+		Cs2.Poly *= Mon_tmp2;
 
 
 		// Add to result
 		Ca.ca.push_back(Cs1);
 		Ca.ca.push_back(Cs2);
 	}// end exchange between q g
 
 
 	// Exchange between qbar g (q and g in my paper)
 	if ((kind1 == "qbar" && kind2 == "g") or (kind1 == "g" && kind2 == "qbar")) {
 
 	  std::pair<int, int> qbar_place;
 	  std::pair<int, int> g_place;
 		int the_qbar=0;
 		int the_g=0;
 
 		if (kind1 == "qbar" && kind2 == "g") {
 			qbar_place = place1;
 			g_place = place2;
 			the_qbar = p1;
 			the_g = p2;
 		} else if (kind1 == "g" && kind2 == "qbar") {
 			qbar_place = place2;
 			g_place = place1;
 			the_qbar = p2;
 			the_g = p1;
 		}
 
 		// For containing Quark_lines
 		Quark_line Ql11, Ql12, Ql21, Ql22;
 
 		// For containing resulting Col_str's
 		Col_str Cs1 = Cs_copy;
 		Col_str Cs2 = Cs_copy;
 
 		// If ql and g on different quark_lines
 		if (g_place.first != qbar_place.first) {
 			// Split ql's into parts
 			Quark_line Qlg_start = Cs_copy.cs.at(g_place.first).before( g_place.second) ;
 			Quark_line Qlg_end = Cs_copy.cs.at(g_place.first).after( g_place.second );
 			Quark_line Qlqbar_start =  Cs_copy.cs.at( qbar_place.first ).before(qbar_place.second);
 
 			// First part, + sign, first Ql
 			Ql11 = Qlqbar_start;
 			Ql11.append(the_g);
 			Ql11.append(Qlg_end.ql);
 
 			// First part,  + sign, second Ql
 			Ql12 = Qlg_start;
 			Ql12.append(the_qbar);
 
 			// If the ql of the gluon was closed account for this by gluing qls together
 			if (!Qlg_start.open) {
 				Ql11.append(Ql12.ql);
 				Ql11.open = true;
 			};
 
 			// Second part, - sign, first Ql
 			Ql21 = Qlqbar_start;
 			Ql21.append(Qlg_end.ql);
 
 			// Second part, - sign,  second Ql
 			Ql22 = Qlg_start;
 			Ql22.append(the_g);
 			Ql22.append(the_qbar);
 
 			// If the ql of the gluon was closed account for this by gluing qls together
 			if (!Qlg_start.open) {
 				Ql21.append(Ql22.ql);
 				Ql21.open = true;
 			};
 
 			// Replace Ql's in the Col_str
 			Cs1 = Cs_copy;
 			Cs2 = Cs_copy;
 			if (Qlg_start.open) {
 				Cs1.cs.at(qbar_place.first) = Ql11;
 				Cs1.cs.at(g_place.first) = Ql12;
 				Cs2.cs.at(qbar_place.first) = Ql21;
 				Cs2.cs.at(g_place.first) = Ql22;
 			} else { // If the ql of the g was closed, there is only one ql, erase 2nd ql
 				Cs1.cs.at(qbar_place.first) = Ql11;
 				Cs1.erase(g_place.first);
 
 				Cs2.cs.at(qbar_place.first) = Ql21;
 				Cs2.erase(g_place.first);
 			}
 		}
 		// If qbar and g are part of same quark_line
 		else {
 
 			Quark_line Ql1 = Cs_copy.cs.at(g_place.first).before(g_place.second );
 			Quark_line Ql2 = Cs_copy.cs.at(g_place.first).after( g_place.second );
 			Ql2.ql.erase(Ql2.ql.end() - 1);
 
 			// First term, First ql
 			Ql11 = Ql1;
 			Ql11.append(the_qbar);
 
 			// First term, 2nd ql
 			Ql12 = Ql2;
 			Ql12.prepend(the_g);
 			Ql12.open = false;
 
 			// 2nd term, 1st ql
 			Ql21 = Ql1;
 			Ql21.append(the_g);
 			Ql21.append(the_qbar);
 
 			// 2nd term 2nd ql
 			Ql22 = Ql2;
 			Ql22.open = false;
 
 			// Replace Ql's in the Col_str
 			Cs1 = Cs_copy;
 			Cs1.cs.at(qbar_place.first) = Ql11;
 			Cs1.cs.insert(Cs1.cs.begin() + qbar_place.first + 1, Ql12);
 
 			// Replace Ql's in the Col_str
 			Cs2 = Cs_copy;
 			Cs2.cs.at(qbar_place.first) = Ql21;
 			Cs2.cs.insert(Cs2.cs.begin() + qbar_place.first + 1, Ql22);
 		}
 		// Multiply with TR
 		Monomial Mon_tmp;
 		Mon_tmp.pow_TR = 1;
-		Cs1.Poly = Cs1.Poly * Mon_tmp;
+		Cs1.Poly *= Mon_tmp;
 
 		// Multiply with -TR
 		Monomial Mon_tmp2;
 		Mon_tmp2.pow_TR = 1;
 		Mon_tmp2.int_part = -1;
-		Cs2.Poly = Cs2.Poly * Mon_tmp2;
+		Cs2.Poly *= Mon_tmp2;
 
 		Ca.ca.push_back(Cs1);
 		Ca.ca.push_back(Cs2);
 
 	}
 
 	// Exchange between g g
 	if (kind1 == "g" && kind2 == "g") {
 
 		// For containing resulting Col_str's
 		Col_str Cs1 = Cs_copy;
 		Col_str Cs2 = Cs_copy;
 		Col_str Cs3 = Cs_copy;
 		Col_str Cs4 = Cs_copy;
 
 		// For containing Quark_lines
 		Quark_line Ql11, Ql12, Ql21, Ql22, Ql31, Ql32, Ql41, Ql42;
 
 		// If g's on different Ql's
 		if (place1.first != place2.first) {
 
 			// Split both ql's into parts
 			Quark_line Ql1_start = Cs_copy.cs.at(place1.first).before( place1.second );
 			Quark_line Ql1_end = Cs_copy.cs.at(place1.first).after( place1.second );
 			Quark_line Ql2_start = Cs_copy.cs.at(place2.first).before( place2.second );
 			Quark_line Ql2_end = Cs_copy.cs.at(place2.first).after( place2.second );
 
 			// First term, both quarks on 2nd ql, First ql
 			Ql11 = Ql1_start;
 			Ql11.append(Ql2_end.ql);
 			// First term, 2nd ql
 			Ql12 = Ql2_start;
 			Ql12.append(p2);
 			Ql12.append(p1);
 			Ql12.append(Ql1_end.ql);
 
 			// 2nd term, g1 on ql1, g2 on ql2, 1st ql
 			Ql21 = Ql1_start;
 			Ql21.append(p1);
 			Ql21.append(Ql2_end.ql);
 			// 2nd term, 2nd ql
 			Ql22 = Ql2_start;
 			Ql22.append(p2);
 			Ql22.append(Ql1_end.ql);
 
 			// 3rd term, g2 on ql1, g1 on ql2,1st ql
 			Ql31 = Ql1_start;
 			Ql31.append(p2);
 			Ql31.append(Ql2_end.ql);
 			// 3rd term, 2nd ql
 			Ql32 = Ql2_start;
 			Ql32.append(p1);
 			Ql32.append(Ql1_end.ql);
 
 			// last term, both quarks on 1st ql,1st ql
 			Ql41 = Ql1_start;
 			Ql41.append(p1);
 			Ql41.append(p2);
 			Ql41.append(Ql2_end.ql);
 
 			// last term, 2nd ql
 			Ql42 = Ql2_start;
 			Ql42.append(Ql1_end.ql);
 
 			// Replace Ql's in the Col_str
 			// If both Ql's are open
 			if (Cs_copy.cs.at(place1.first).open && Cs_copy.cs.at(place2.first).open) {
 				Cs1.cs.at(place1.first) = Ql11;
 				Cs1.cs.at(place2.first) = Ql12;
 
 				Cs2.cs.at(place1.first) = Ql21;
 				Cs2.cs.at(place2.first) = Ql22;
 
 				Cs3.cs.at(place1.first) = Ql31;
 				Cs3.cs.at(place2.first) = Ql32;
 
 				Cs4.cs.at(place1.first) = Ql41;
 				Cs4.cs.at(place2.first) = Ql42;
 			}
 			// If string where closed glue together ends
 			// If first ql closed
 			else if (!Cs_copy.cs.at(place1.first).open) {
 				Ql12.append(Ql11.ql);
 				Ql22.append(Ql21.ql);
 				Ql32.append(Ql31.ql);
 				Ql42.append(Ql41.ql);
 
 				//The result should be open/closed if the ql2 was open/closed
 				Ql12.open = Cs_copy.cs.at(place2.first).open;
 				Ql22.open = Cs_copy.cs.at(place2.first).open;
 				Ql32.open = Cs_copy.cs.at(place2.first).open;
 				Ql42.open = Cs_copy.cs.at(place2.first).open;
 
 				//The reslut contaied int Qlx2 sould be used for the Color structure
 				// Replace Ql's in the Col_str
 				Cs1.cs.at(place2.first) = Ql12;
 				Cs2.cs.at(place2.first) = Ql22;
 				Cs3.cs.at(place2.first) = Ql32;
 				Cs4.cs.at(place2.first) = Ql42;
 
 				Cs1.erase(place1.first);
 				Cs2.erase(place1.first);
 				Cs3.erase(place1.first);
 				Cs4.erase(place1.first);
 			}
 			// if only 2nd ql closed
 			if (!Cs_copy.cs.at(place2.first).open && Cs_copy.cs.at(place1.first).open) {
 				Ql11.append(Ql12.ql);
 				Ql21.append(Ql22.ql);
 				Ql31.append(Ql32.ql);
 				Ql41.append(Ql42.ql);
 
 				// The result should be open
 				Ql11.open = true;
 				Ql21.open = true;
 				Ql21.open = true;
 				Ql21.open = true;
 
 				//The result contained int Qlx1 should be used for the Color structure
 				// Replace Ql's in the Col_str
 				Cs1.cs.at(place2.first) = Ql11;
 				Cs2.cs.at(place2.first) = Ql21;
 				Cs3.cs.at(place2.first) = Ql31;
 				Cs4.cs.at(place2.first) = Ql41;
 
 				Cs1.erase(place1.first);
 				Cs2.erase(place1.first);
 				Cs3.erase(place1.first);
 				Cs4.erase(place1.first);
 
 			}
 		}
 		// If g's on same ql's
 		if (place1.first == place2.first) {
 
 		  Quark_line Ql_start = Cs_copy.cs.at(place1.first).before( std::min(place2.second, place1.second));
 			// the part between the g's
 			Quark_line Ql_between = Cs_copy.cs.at(place1.first).before(std::max(
 					place2.second, place1.second));
 			Ql_between = Ql_between.after( std::min(place2.second, place1.second) );
 
 			// the end after 2nd g
 			Quark_line Ql_end = Cs_copy.cs.at(place1.first).after( std::max(place2.second,
 					place1.second));
 
 			// we have to know what g is first to put them back in right order
 			int first_g, last_g;
 			if( place1.second < place2.second ) {
 				first_g=p1;
 				last_g=p2;
 			}
 			else {
 				first_g=p2;
 				last_g=p1;
 			}
 
 
 			// First term, both gluons inbetween
 			Ql11 = Ql_start;
 			Ql11.append(Ql_end.ql);
 			// First term, part between quarks
 			Ql12 = Ql_between;
 			Ql12.append( last_g );
 			Ql12.append( first_g );
 			Ql12.open = false;
 
 			// 2nd term, g1 after first part, g2 after 2nd
 			Ql21 = Ql_start;
 			Ql21.append( first_g );
 			Ql21.append(Ql_end.ql);
 			// First term, part between quarks
 			Ql22 = Ql_between;
 			Ql22.append( last_g );
 			Ql22.open = false;
 
 			// 3rd term, g2 after first part, g1 after 2nd
 			Ql31 = Ql_start;
 			Ql31.append( last_g);
 			Ql31.append(Ql_end.ql);
 			// First term, part between quarks
 			Ql32 = Ql_between;
 			Ql32.append( first_g );
 			Ql32.open = false;
 
 			// 4th term, g2 after first part, g1 after 2nd
 			Ql41 = Ql_start;
 			Ql41.append( first_g );
 			Ql41.append( last_g );
 			Ql41.append(Ql_end.ql);
 			// First term, part between quarks
 			Ql42 = Ql_between;
 			Ql42.open = false;
 
 			Cs1.cs.at(place1.first) = Ql11;
 			Cs1.cs.insert(Cs1.cs.begin() + place1.first + 1, Ql12);
 			Cs2.cs.at(place1.first) = Ql21;
 			Cs2.cs.insert(Cs2.cs.begin() + place1.first + 1, Ql22);
 			Cs3.cs.at(place1.first) = Ql31;
 			Cs3.cs.insert(Cs3.cs.begin() + place1.first + 1, Ql32);
 			Cs4.cs.at(place1.first) = Ql41;
 			Cs4.cs.insert(Cs4.cs.begin() + place1.first + 1, Ql42);
 
 		}
 
 		// Multiplying with TR where appropriate
 		Monomial Mon_tmp;
 		Mon_tmp.pow_TR = 1;
 
-		Cs2.Poly = Cs2.Poly * Mon_tmp;
-		Cs3.Poly = Cs3.Poly * Mon_tmp;
+		Cs2.Poly *= Mon_tmp;
+		Cs3.Poly *= Mon_tmp;
 
 		// Multiplying with -TR where appropriate
 		Mon_tmp.pow_TR = 1;
 
 		Mon_tmp.int_part = -1;
-		Cs1.Poly = Cs1.Poly * Mon_tmp;
-		Cs4.Poly = Cs4.Poly * Mon_tmp;
+		Cs1.Poly *= Mon_tmp;
+		Cs4.Poly *=  Mon_tmp;
 
 		Ca.ca.push_back(Cs1);
 		Ca.ca.push_back(Cs2);
 		Ca.ca.push_back(Cs3);
 		Ca.ca.push_back(Cs4);
 
 	}
 
 	// Simplify Col_amp
 	Ca.simplify();
 
 	return Ca;
 
 }
 
 
 Col_amp Col_functions::exchange_gluon( const  Col_amp & Ca, int p1, int p2 ) const{
 
   // Final col_amp to return
   Col_amp Ca_out;
 
   // Exchange in each Col_str, and append to new Col_amp
   for(uint m=0; m< Ca.ca.size(); m++ ){
     // Exchange in Col_str m
     Col_amp part_m=exchange_gluon( Ca.ca.at(m), p1, p2 );
     // Append result
     Ca_out.append(part_m.ca);
   }
 
   return Ca_out;
 }
 
 /*
-Col_str Col_functions::contract_quarks( Col_str Cs1, Col_str Cs2 )  const{
-
-	std::vector<int> q_place;
-	std::vector<int> q_place2;
-
-	// The conjugate of Cs1
-	Col_str conj_Cs1 = Cs1;
-	conj_Cs1.conjugate();
-
-	// The total color structure
-	Col_str Cs = conj_Cs1*Cs2;
-
-	// Count how many quarks should be contracted
-	int n_q = Cs.n_quark();
-
-	// As long as there are quark_lines left to contract
-	while (n_q > 0) {
-		// Find first quark in Cs1 by looping over Quark_lines
-		for (int i = 0; (n_q>0 && i <  static_cast<int>(Cs.cs.size()) ); i++) {
-			// Check if the quark-line is open, in which case it has a q
-			if (Cs.cs.at(i).open) {
-				// The first quark is located and has position
-				q_place.clear();
-				q_place.push_back(i);
-				q_place.push_back(0);
-				// and number
-				int q = Cs.at(q_place.at(0), q_place.at(1));
-
-				// Locate same quark a second time
-				// Loop over Quark_lines
-				q_place2.clear();
-				int i2 = i + 1; // Quark_line of second occurrence
-				while (q_place2.empty()) { // As long as quark not found a second time
-					if (Cs.cs.at(i2).at(Cs.cs.at(i2).ql.size() - 1) == q) {// If quark found, store place
-						q_place2.push_back(i2);
-						q_place2.push_back(Cs.cs.at(i2).ql.size() - 1);
-					}
-					i2++;
-				}
-				if (q_place2.empty()) {
-					std::cerr << "Col_functions::contract_quarks(Cs1, Cs2): Found q " << q
-							<< " only once in " << Cs << std::endl;
-				}
-
-				// Prepare new Quark_line
-				// to be inserted at the place of found open Quark_line
-				Quark_line new_Quark_line;
-				Quark_line part2_new_Quark_line;
-				// The first part of the new Quark_line should be the Quark_line
-				// containing q in the conjugate
-				new_Quark_line = Cs.cs.at(q_place2.at(0));
-
-				// Erasing q in the end
-				new_Quark_line.ql.erase(--new_Quark_line.ql.end());
-				part2_new_Quark_line = Cs.cs.at(q_place.at(0));
-
-				// Erasing the q in the beginning of second part
-				part2_new_Quark_line.ql.erase(part2_new_Quark_line.ql.begin());
-
-				new_Quark_line.append(part2_new_Quark_line.ql);
-
-				// So far we have not included the Polynomial of part2_new_Quark_line
-				new_Quark_line.Poly=new_Quark_line.Poly*part2_new_Quark_line.Poly;
-
-				// If the first q index and the last qbar index in the new
-				// Quark_line is the same (and the Quark_line is "open"), the indices
-				// should be removed and the Quark_line should be closed
-				if (new_Quark_line.ql.at(0) == new_Quark_line.ql.at(
-						new_Quark_line.ql.size() - 1) && new_Quark_line.open) {
-					// The string is closed
-					new_Quark_line.open = false;
-					// Remove last and first index
-					new_Quark_line.ql.erase(--new_Quark_line.ql.end(),
-							new_Quark_line.ql.end());
-					new_Quark_line.ql.erase(new_Quark_line.ql.begin());
-				}
-
-				// Inserting new Quark_line in the place of the old
-				Cs.cs.at(i) = new_Quark_line;
-
-				// Remove quark_line with q in Cs
-				Cs.cs.erase((Cs.cs.begin() + q_place2.at(0)));
-				i=-1; // reset to keep looking from the beginning in the new Cs (i will be increased to 0)
-			}// end of if (open)
-
-			n_q = Cs.n_quark();
-
-		} // end of for, loop over quark_lines
-
-	}
-
-	return Cs;
-
-}
-
-
-Col_amp Col_functions::contract_quarks( Col_amp Ca1, Col_amp Ca2 ) const{
-
-	if(Ca1.empty()){
-		std::cerr << "Col_functions::contract_quarks: Expects non-empty Col_amps, got first argument "
-				<< Ca1 << std::endl;
-		assert(0);
-	}
-	if(Ca2.empty()){
-		std::cerr << "Col_functions::contract_quarks: Expects non-empty Col_amps, got second argument "
-				<< Ca2 << std::endl;
-		assert(0);
-	}
-
-	Col_amp Ca_res;
-
-	// Make sure the Col_strs are not empty "[]"=1, as all indices contracted
-	Ca1.remove_empty_Col_strs();
-	Ca2.remove_empty_Col_strs();
-
-	// Loop over Col_strs, and contract quarks between all possible combinations
-	  // Loop over Col_strs in Ca1
-	  for(uint m1=0; m1 < Ca1.ca.size(); m1++ ){
-	    // Loop over Col_strs in Ca2
-	    for(uint m2=0; m2 < Ca2.ca.size(); m2++ ){
-	    	Col_str Cs_tmp;
-	    	Cs_tmp.contract_quarks( Ca1.ca.at(m1), Ca2.ca.at(m2));
-	      Ca_res.ca.push_back( Cs_tmp );
-	    }
-	  }
-
-	  return Ca_res;
-}
-*/
-
 std::map< std::string, double > Col_functions::double_num( const std::map< std::string, Polynomial > & mem_map )  const{
 
 	std::map< std::string, double > res;
 
 	for( auto iter =  mem_map.begin(); iter !=  mem_map.end(); ++iter) {
 		// Insert pair of string and the leading versions of the Polynomial
 		double_num( (iter->second) );
 		res.insert(std::make_pair( iter->first, double_num((iter->second)) ));
 	}
 
 	return res;
 }
-
+*/
 
 Polynomial Col_functions::Polynomial_cnum_num( const Polynomial & Poly ) const{
 
 	// Store content in numerical part of the Monomial
 	Monomial Mon;
 	Mon.cnum_part = cnum_num(Poly);
 
 	Polynomial res;
-	res = res * Mon;
+	res *= Mon;
 
 	return res;
 }
 
 
 cvec Col_functions::cnum_num( const Poly_vec & Pv )  const{
 
 	// To contain the numerical result
 	cvec res;
 
 	// Loop over Polynomials in the vector, and add the numerical value
 	// to the vector to return
 	for (uint p = 0; p < Pv.size(); p++) {
 		res.push_back(cnum_num(Pv.at(p)));
 	}
 	return res;
 }
 
 
 dvec Col_functions::double_num( const Poly_vec & Pv )  const{
 
 	// To contain the numerical result
 	dvec res;
 
 	// Loop over Polynomials in the vector, and add the numerical value
 	// to the vector to return
 	for (uint p = 0; p < Pv.size(); p++) {
 		res.push_back(double_num( Pv.at(p)) );
 	}
 	return res;
 }
 
 
 dmatr Col_functions::double_num( const Poly_matr & Pm )  const{
 	// To contain the numerical result
 	dmatr res;
 
 	// Loop over Poly_vecs in the vector, and add the numerical value
 	// to the vector to return
 	for (uint pv = 0; pv < Pm.size(); pv++) {
 		res.push_back(double_num( Pm.at(pv).pv ) );
 	}
 	return res;
 }
 
 
+/*
 dvec Col_functions::double_num( const std::vector<shared_ptr<Polynomial> > & Pv )  const{
 
 	// To contain the numerical result
 	dvec res;
 
 	// Loop over Polynomials in the vector, and add the numerical value
 	// to the vector to return
 	for (uint p = 0; p < Pv.size(); p++) {
 		shared_ptr<Polynomial>  the_pointer=Pv.at(p);
 		// Want double of the polynomial which the pointer points at
 		res.push_back( double_num(*the_pointer) );
 	}
 	return res;
 }
+*/
 
 Poly_vec Col_functions::Poly_vec_cnum_num( const Poly_vec & Pv)  const{
 
 	// To contain the result
 	Poly_vec res;
 
 	// Loop over Polynomials in the vector, put each Polynomial to its numerical value
 	for (uint p = 0; p < Pv.size(); p++) {
-		res.push_back( Polynomial_cnum_num( Pv.at( p ) ) );
+		res.append( Polynomial_cnum_num( Pv.at( p ) ) );
 	}
 	return res;
 }
 
 
 Poly_matr Col_functions::Poly_matr_cnum_num( const Poly_matr & Pm ) const {
 
 	// To contain the result
 	Poly_matr res_matr;
 
 	// Loop over Polynomials in the matrix
 	// and change each Polynomial to its numerical version
 	for (uint v = 0; v < Pm.size(); v++) {
-		res_matr.push_back( Poly_vec_cnum_num( Pm.at( v ).pv ));
+		res_matr.append( Poly_vec_cnum_num( Pm.at( v ).pv ));
 	}
 
 	return res_matr;
 }
 
 
 cmatr Col_functions::cnum_num( const Poly_matr & Pm )  const{
 
 	// To contain the numerical result
 	cmatr  res;
 
 	// Loop over Polynomials in the vector, and add the numerical value
 	// to the vector to return
 	for (uint v = 0; v < Pm.size(); v++) {
 		res.push_back(cnum_num( Pm.at(v).pv ));
 	}
 	return res;
 }
 
-
+/*
 dmatr Col_functions::double_num( const std::vector<std::vector<shared_ptr<Polynomial> > > & Pm )  const{
 
 	// To contain the numerical result
 	dmatr  res;
 
 	// Loop over Polynomials in the vector, and add the numerical value
 	// to the vector to return
 	for (uint v = 0; v < Pm.size(); v++) {
 		res.push_back(double_num(Pm.at(v)));
 	}
 	return res;
 }
-
+*/
 
 Polynomial Col_functions::scalar_product( const Col_amp & Ca1 , const Col_amp & Ca2 ) const{
 	//std::cout << "Col_functions::scalar_product, incoming Ca1 " << Ca1 <<" and Ca2 " << Ca2 << std::endl;
 
 	if( !Ca1.Scalar.empty() and ( cnum_num(Ca1.Scalar).real()!=0 or cnum_num(Ca1.Scalar).imag()!=0 ) ){
 		std::cerr << "Col_functions::scalar_product(Ca1,Ca2): "
 				<< "Expects Col_amps with empty Scalar parts, but the Scalar of the first Col_amp was " <<
 				Ca1.Scalar << std::endl;
 		assert(0);
 	}
 	if( !Ca2.Scalar.empty() and ( cnum_num(Ca2.Scalar).real()!=0 or cnum_num(Ca2.Scalar).imag()!=0 ) ){
 		std::cerr << "Col_functions::scalar_product(Ca1,Ca2): "
 				<< "Expects Col_amps with empty Scalar parts, but the Scalar of the second Col_amp was " <<
 				Ca2.Scalar << std::endl;
 		assert(0);
 	}
+
 	// To contain the result
 	Col_amp Ca_res;
 
 	// Contract the quarks
-	//Ca_res = contract_quarks(Ca1, Ca2);
 	Ca_res.contract_quarks( Ca1, Ca2 );
-	//std::cout << "Col_functions::scalar_product, contracted quarks " << Ca_res << std::endl;
 
 	// Look for simple simplifications
 	Ca_res.simplify();
-	//Ca_res.simplify(); // why twice
-
-	//std::cout << "Col_functions::scalar_product, simplified " << Ca_res << std::endl;
 
 	// Contract the gluons
 	Ca_res.contract_all_gluons();
 
 	if (!Ca_res.empty()) {
 		std::cerr << "Col_functions::scalar_product: terminating due to non-contracted indices."
 				<< std::endl;
 		std::cerr << "The Col_amp is " << Ca_res << std::endl;
 	    std::cerr.flush();
 		assert( 0 );
 		return Ca_res.Scalar;
 	}
 	else
 		return Ca_res.Scalar;
 }
 
 
 Polynomial  Col_functions::scalar_product( const Col_str & Cs1, const Col_str & Cs2 ) const{
 
 	Col_str Cs_tmp;
 
 	// Contract the quarks
 	Cs_tmp.contract_quarks( Cs1, Cs2 );
 
 	Col_amp Ca_tmp(Cs_tmp);
 
 	// Contract the gluons
 	Ca_tmp.contract_all_gluons();
 
 	if ( !Ca_tmp.empty() ){
 		std::cerr << "Col_functions::scalar_product: terminating due to non-contracted quark indices." <<std::endl;
 		std::cerr << "The col_amp is " << Ca_tmp << std::endl;
 		assert( 0 );
 	}
 
 	return Ca_tmp.Scalar;
 }
 
 
-Polynomial Col_functions::color_correlator( const Col_amp Ca, int p1, int p2, int g_new ) const{
+Polynomial Col_functions::color_correlator( const Col_amp Ca, int p1, int p2 ) const{
+
+	// Dummy gluon index to be used
+	int dummy=999;
+
+	bool unique=false;
+
+	while ( unique == false )
+	{
+		// Doesn't matter what number we start from
+		dummy++;
+
+		// Check that the index is not already in use
+		bool was_found = false;
+
+		// Loop over Col_strs
+		for (uint i = 0; i < Ca.size(); i++) {
+			Col_str Cs = Ca.at(i);
+			// Loop over all Quark_lines
+			for ( uint i = 0; i < Cs.size(); i++ ) {
+				// Loop over all places in the Quark_lines
+				for (uint j = 0; j < Cs.at(i).ql.size(); j++) {
+					if ( Cs.at(i).ql.at(j) == dummy ) was_found = true;
+				}
+			}
+		}
+		if ( ! was_found  ) unique = true;
+	}
 
 	// The amplitudes after emission
-	Col_amp Cai = emit_gluon(Ca, p1, g_new);
-	Col_amp Caj = emit_gluon(Ca, p2, g_new);
+	Col_amp Cai = emit_gluon(Ca, p1, dummy );
+	Col_amp Caj = emit_gluon(Ca, p2, dummy);
 
 	Polynomial res=0;
 
 	res = scalar_product( Cai, Caj );
 
 	return res;
 }
 
 
 int Col_functions::factorial( int i ) const{
 	if(i<0) {
 		std::cerr << "Col_functions::factorial: intended for int >=0, argument was " << i << std::endl;
 		std::cerr.flush();
 		assert( 0 );
 	}
 	if (i==0) return 1;
 	return factorial(i-1)*i; // Recursive call
 }
 
 
+std::map<int, int> Col_functions::default_parton_numbers( const Col_str & Cs, int g_old, int q_new, int qbar_new ) const{
+
+
+	// First check that all parton numbers except g_old, but including q_new, qbar_new
+	// can be found in the Col_str
+	Cs.find_parton( q_new );
+	Cs.find_parton( qbar_new );
+	int n_partons=2*Cs.n_quark() + Cs.n_gluon();
+	// The two highest numbers are missing (instead q_new, qbar_new)
+	for ( int p = 1; p < n_partons-2; p++ ) {
+		if(p != g_old) Cs.find_parton(p);
+	}
+
+
+	// To contain the replacements to be done
+	std::map <int, int> replacements;
+
+	// Find replacing numbers for q_new and qbar_new and insert in map
+	int new_q_new = 2*Cs.n_quark() - 1;
+	int new_qbar_new = 2*Cs.n_quark();
+	replacements.insert( std::make_pair( q_new, new_q_new) );
+	replacements.insert( std::make_pair(qbar_new, new_qbar_new) );
+
+
+	// Loop over old qs and qbars and make sure numbers don't change
+	for ( int p = 1; p <= Cs.n_quark()*2-2; p++ ) {
+		replacements.insert( std::make_pair( p, p ) );
+	}
+
+
+	// Gluons with numbers smaller than g_old should have indices
+	// shifted twice (once for q, once for qbar)
+	for ( int p = Cs.n_quark()*2-1; p < g_old; p++ ) {
+		replacements.insert( std::make_pair( p, p+2) );
+	}
+
+
+	// Gluons with numbers larger than g_old should have indices
+	// shifted once (for qbar)
+	for ( int p = g_old+1; p <= n_partons-1; p++ ) {
+		replacements.insert( std::make_pair( p, p+1) );
+	}
+
+	return replacements;
+}
+
+
+Col_str Col_functions::rename_partons( const Col_str & in_Col_str, const std::map <int, int> replacements ) const{
+
+
+	Col_str out_Col_str = in_Col_str;
+
+	// Loop over Quark_lines
+	for( uint i=0; i < in_Col_str.size(); i++ ){
+		// Loop over partons in Quark_line
+		for( uint j=0; j < in_Col_str.at(i).size(); j++ ){
+			// Find parton number in map and replace
+			out_Col_str.at(i).ql.at(j) = replacements.at(in_Col_str.at(i,j));;
+		}
+	}
+
+	return out_Col_str;
+}
+
+
+Col_amp Col_functions::rename_partons( const Col_amp & in_Col_amp, const std::map <int, int> replacements ) const{
+
+
+	Col_amp out_Col_amp;
+
+	// Loop over Col_strs
+	for( uint i=0; i < in_Col_amp.size(); i++ ){
+		out_Col_amp.append( rename_partons( in_Col_amp.at(i), replacements) );
+	}
+
+	out_Col_amp.normal_order();
+
+
+	return out_Col_amp;
+}
+
+
 void Col_functions::write_out_dvec( const dvec & dv, std::string filename ) const {
 
 	std::ofstream outfile(filename.c_str() );
 	outfile << dv;
 }
 
 
 dmatr Col_functions::read_in_dmatr( std::string filename ) const {
 
 
 	// Read in file
 	std::ifstream fin(filename.c_str());
 
 	// Check that file exists
 	if( !fin ){
 		std::cerr << "Col_functions::read_in_dmatr: The file "
 				<< filename << " could not be opened." << std::endl;
 		assert( 0 );
 
 	}
 
 	// Copy info from file to string
 	std::string str((std::istreambuf_iterator<char>(fin)), std::istreambuf_iterator<char>());
 
 	// Skip lines starting with #
 	while(str.at(0)== '#'){
 		while (str.at(0) != '\n'){
 			str.erase(str.begin());
 		}
 		// erase endl sign(s)
 		while(str.at(0)== '\n'){
 			str.erase(str.begin());
 		}
 	}
 
 	// First char in file should be '{'
 	if (str.at(0) != '{') {
 		std::cerr
 		<< "Col_functions::read_in_dmatr: First char in matrix data file after comments should be '{', it was: "
 		<< str.at(0) << std::endl;
 		assert( 0 );
 	}
 
 	// Check that only allowed characters
 	uint j = 0;
 	while (j < str.size()) {
 
 		if (!(str.at(j) == '+' or str.at(j) == '-' or str.at(j) == '.'
 				or str.at(j) == '{' or str.at(j) == '}' or str.at(j) == '\n'
 						or str.at(j) == ',' or str.at(j) == ' ' or str.at(j) == '0'
 								or str.at(j) == '1' or str.at(j) == '2' or str.at(j) == '3'
 										or str.at(j) == '4' or str.at(j) == '5' or str.at(j) == '6'
 												or str.at(j) == '7' or str.at(j) == '8' or str.at(j) == '9')) {
 			std::cerr
 			<< "Col_functions::read_in_dmatr: A disallowed characters encountered in string for dmatr: "
 			<< str.at(j) << ", in file " << filename <<  std::endl;
 			std::cerr << "Col_functions::read_in_dmatr expects a numerical matrix." << std::endl;
 			assert( 0 );
 		}
 		j++;
 	}
 
 
 	// Row to contain numbers
 	dvec row;
 
 	// To contain matrix of scalar products
 	dmatr matr;
 
 	// Read the string, starting from 0th element
 	uint i = 0;
 	while (i < str.size() - 2) {
 		i += 1;
 
 		// We may have to skip some chars
 		while (i< str.size()-2 &&(str.at(i) == ',' or str.at(i) == '}' or str.at(i) == ' ' or str.at(i) == '\n' or str.at(i) == ' ' or str.at(i) == '{') ) i++;
 
 		// String to make a number of, and double to contain number
 		std::string num_str;
 		num_str.clear();
 		double num;
 
 		// Keep reading the number while not ',' or '}'
 		while ( i< str.size()-2 && (str.at(i) != ',' && str.at(i) != '}') )
 		{
 			num_str.push_back(str.at(i));
 			i++;
 		}
 
 		// num_str contains the string to make a number of
 		std::istringstream parton_str_st( num_str );
 		parton_str_st >> num;
 
 		// Add number to vector
 		row.push_back(num);
 
 		// If we have a new row
 		if( i< str.size()-2 && str.at(i)=='}'){
 			// Save row in matrix, and empty row
 			matr.push_back(row);
 			row.clear();
 
 			// We may have to skip some chars
 			while (i< str.size()-2 &&(str.at(i) == ',' or str.at(i) == '}' or str.at(i) == ' ' or str.at(i) == '\n' ) ) {
 				i++;
 			}
 		}
 		// Otherwise just keep on reading the next number in row
 	}
 
 	return matr;
 }
 
 
 dvec Col_functions::read_in_dvec( std::string filename ) const {
 
 	// Read in file
 	std::ifstream fin(filename.c_str());
 
 	// Check that file exists
 	if( !fin ){
 		std::cerr << "Col_functions::read_in_dvec: The file "
 				<< filename << " could not be opened." << std::endl;
 		assert( 0 );
 	}
 
 	// Copy info from file to string
 	std::string str((std::istreambuf_iterator<char>(fin)), std::istreambuf_iterator<char>());
 
 	// Skip lines starting with #
 	while(str.at(0)== '#'){
 		while (str.at(0) != '\n'){
 			str.erase(str.begin());
 		}
 		// erase endl sign(s)
 		while(str.at(0)== '\n'){
 			str.erase(str.begin());
 		}
 	}
 
 	// First char in file should be '{'
 	if (str.at(0) != '{') {
 		std::cerr
 		<< "Col_functions::read_in_dvec: First char in matrix data file after comments should be '{', it was: "
 		<< str.at(0) << std::endl;
 		assert( 0 );
 	}
 
 
 	// Check that only allowed characters
 	uint j = 0;
 	while (j < str.size()) {
 
 		if (!(str.at(j) == '+' or str.at(j) == '-' or str.at(j) == '.'
 				or str.at(j) == '{' or str.at(j) == '}' or str.at(j) == '\n'
 						or str.at(j) == ',' or str.at(j) == ' ' or str.at(j) == '0'
 								or str.at(j) == '1' or str.at(j) == '2' or str.at(j) == '3'
 										or str.at(j) == '4' or str.at(j) == '5' or str.at(j) == '6'
 												or str.at(j) == '7' or str.at(j) == '8' or str.at(j) == '9')) {
 			std::cerr
 			<< "Col_functions::read_in_dvec: A disallowed character encountered in string for dmatr: "
 			<< str.at(j) << ", in file " << filename <<  std::endl;
 			std::cerr << "Col_functions::read_in_dvec expects a numerical matrix." << std::endl;
 			assert( 0 );
 		}
 		j++;
 	}
 
 	// Row to contain numbers
 	dvec row;
 
 	// To contain matrix of scalar products
 	dmatr matr;
 
 	// Read the string, starting from 0th element
 	unsigned int i = 0;
 	while (i < str.size() - 1) {
 		i += 1;
 
 		// We may have to skip some chars
 		while (i< str.size()-2 &&(str.at(i) == ',' or str.at(i) == '}' or str.at(i) == ' ' or str.at(i) == '\n' or str.at(i) == ' ' or str.at(i) == '{') ) i++;
 
 		// String to make a number of, and double to contain number
 		std::string num_str;
 		num_str.clear();
 		double num;
 
 		// Keep reading the number while not ',' or '}'
 		while ( i< str.size()-1 && (str.at(i) != ',' && str.at(i) != '}') )
 		{
 			num_str.push_back(str.at(i));
 			i++;
 		}
 		// now, at(i), there is either , or }
 
 		// num_str contains the string to make a number of
 		std::istringstream num_str_st( num_str );
 		num_str_st >> num;
 
 		// Add number to vector
 		row.push_back(num);
 
 		// Skip signs in end and make sure not to enter loop one extra time
 		while( i<str.size() and ( str.at(i)==' ' or str.at(i)=='\n' or str.at(i)=='}' ) ) i++;
 	}
 
 	return row;
 
 }
 
 
 void Col_functions::write_out_dmatr( const dmatr & matr, std::string filename ) const {
 	std::ofstream outfile(filename.c_str());
 	outfile << matr;
 }
 
 
 std::list<int>::iterator operator+( std::list<int>::iterator x, int n ) {
 
   while(n>0){
     x++;
     n--;
   }
   while(n<0){
     x--;
     n++;
   }
   return x;
 }
 
 std::list<int>::iterator operator-( std::list<int>::iterator x, int n ) {
 
   while(n>0){
     x--;
     n--;
   }
   while(n<0){
     x++;
     n++;
   }
   return x;
 }
 
 
 std::list< Quark_line  >::iterator operator+( std::list < Quark_line >::iterator x, int n ){
 
   while(n>0){
     x++;
     n--;
   }
   while(n<0){
     x--;
     n++;
     }
   return x;
 }
 
 col_str::iterator operator-( col_str::iterator x, int n ){
 
   while(n>0){
     x--;
     n--;
   }
   while(n<0){
     x++;
     n++;
   }
   return x;
 }
 
 
 std::ostream& operator<<( std::ostream& out, const std::vector<int> & vec ){
   int max=vec.size();
   if(max==0)  out <<"{}";
   else{
     out <<"{";
     for (int i=0; i<max-1; i++){
       out << vec.at(i) << ",";
     }
     out << vec.at(max-1) <<"}";
   }
   return out;
 }
 
 
 std::ostream& operator<<( std::ostream& out, const cvec & cv ) {
 
 	out << "{";
 	// Loop over entries
 	for (uint i = 0; i < cv.size(); i++) {
 		// Print element
 		std::cout.width(6);
 		std::ostringstream outstr;
 		outstr << cv.at(i);
 		out << outstr.str();
 		// If not last element print ","
 		if (i < (cv.size() -1 )) out << ", ";
 	}
 	out << "}";
 	return out;
 }
 
 
 std::ostream& operator<<(std::ostream& out, const dvec & dv) {
 
 	out << "{";
 	// Loop over entries
 	for (uint i = 0; i < dv.size(); i++) {
 		// Print element
 		std::cout.width(6);
 		std::ostringstream outstr;
 		outstr << dv.at(i);
 		out << outstr.str();
 		// If not last element print ","
 		if (i < (dv.size() -1 )) out << ", ";
 	}
 	out << "}";
 	return out;
 }
 
 
 std::ostream& operator<<( std::ostream& out, const cmatr & cm ){
 
 	out <<"{" << std::endl;
 	// Loop over rows
 	for(uint i=0; i< cm.size(); i++ ){
 		out <<"{";
 		// Loop over columns
 		for(uint j=0; j< cm.at(i).size(); j++ ){
 			// Print element
 			std::cout.width( 6 );
 			std::ostringstream outstr;
 			outstr << cm.at(i).at(j);
 			// If not last element print ","
 			if (j<cm.at(i).size()-1 ) outstr << ",";
 			out << outstr.str();
 			//out << Poly_m.at(i).at(j) << "";
 		}
 		out <<"}";
 		// If not last row, print ","
 		if (i<cm.at(i).size()-1 ) out << ",";
 		out << std::endl;
 	}
 	out <<"}" << std::endl;
   return out;
 }
 
 
 std::ostream& operator<<( std::ostream& out, const dmatr & matr ){
 
   out <<"{" << std::endl;
   // Loop over rows
   for(uint i=0; i< matr.size(); i++ ){
     out <<"{";
     // Loop over columns
     for(uint j=0; j< matr.at(i).size(); j++ ){
       // Print element
       std::ostringstream outstr;
       outstr.width( 20 );
       outstr.precision(16);
       // If the result is larger than accuracy print it out
       if( std::abs( matr.at(i).at(j) )> accuracy ){
     	  outstr << std::fixed << matr.at(i).at(j);
       }
       // otherwise is should probably be 0
       else
 		  outstr << std::fixed << 0;
       // If not last element print ","
       if (j<matr.at(i).size()-1 ) outstr << ",";
       out << outstr.str();
     }
     out <<"}";
     // If not last row, print ","
     if (i<matr.at(i).size()-1 ) out << ",";
     out << std::endl;
   }
   out <<"}" <<std::endl;
   return out;
 }
 
 
 std::ostream& operator<<( std::ostream& out, std::pair<int, int> pair ) {
 
 	out << "(";
 	out << pair.first;
 	out << ", ";
 	out << pair.second;
 	out << ")";
 
 	return out;
 }
 
 
 } //end namespace ColorFull
diff --git a/MatrixElement/Matchbox/ColorFull/Col_functions.h b/MatrixElement/Matchbox/ColorFull/Col_functions.h
--- a/MatrixElement/Matchbox/ColorFull/Col_functions.h
+++ b/MatrixElement/Matchbox/ColorFull/Col_functions.h
@@ -1,317 +1,357 @@
 // -*- C++ -*-
 /*
  * Col_functions.h
  * Contains declarations of the class Col_str and associated types and operators
  * Author: Malin Sjodahl
  */
 
 #ifndef COLORFULL_Col_functions_h
 #define COLORFULL_Col_functions_h
 
 
 #include "Col_amp.h"
 #include "Poly_matr.h"
 #include <list>
 #include <map>
 #include <memory>
 
 namespace ColorFull {
 
 using std::shared_ptr;
 
 /// Library class containing functions for index contraction and
 /// numerical evaluation.
 /// This is where the parameters Nc, TR and CF are contained.
 class Col_functions {
 
 private:
 
-/// The number of colors, used in numerical results. Change here for different value.
+/// The number of colors, used in numerical results,
+/// changed by using set_Nc.
 double Nc;
 
 /// The trace convention Tr( t^a t^a )=TR (no sum).
-/// The normalization of the SU(Nc) generators, to be used in numerical evaluation.
+/// The normalization of the SU(Nc) generators, to be used in numerical evaluation,
+/// changed by using set_TR.
 /// The value 1/2 corresponds to the Gell-Mann normalization.
 double TR;
 
-/// The value of CF=TR (Nc^2-1)/(Nc).
+/// The value of CF=TR*Nc-TR/Nc, changed by using set_CF.
 /// Note that CF can be changed independently of Nc.
 double CF;
 
 /// While evaluating leading terms one may want to keep the full value of CF for
-/// Nc=3, (TR(Nc^2-1)/Nc), or only keep the leading Nc term =TR*Nc (default).
+/// TR(Nc^2-1)/Nc, or only keep the leading Nc term =TR*Nc (default).
 /// full_CF is used by the Polynomial version of leading
 /// (and hence also Poly_vec and Poly_matr versions etc).
 /// The leading functions replaces CF by TR*Nc if full_CF is false (default)
 /// while evaluating the leading terms.
 /// If full_CF is true, CF is replaced by TR(Nc^2-1)/Nc.
 /// Clearly this affects the result of subsequent numerical evaluation.
 /// In the Col_basis class (and derived) the matrix version of leading
 /// is used to evaluate scalar product matrices.
 bool full_CF;
 
 
 public:
 
 /// Default constructor.
 Col_functions()
   : Nc(3.0), TR(0.5), CF(4.0/3.0), full_CF( false )  {}
 
 /// Set the number of colors.
 /// The value of CF is adjusted accordingly.
 void set_Nc( double n) {
   Nc = n;
   CF = TR*(Nc*Nc-1.)/Nc;
 }
 
 /// Set the normalization of the generators.
 /// The value of CF is adjusted accordingly.
 void set_TR( double tr) {
   CF *= tr/TR;
   TR = tr;
 }
 
 /// Set the value of CF.
 /// The value of Nc is NOT adjusted accordingly.
 void set_CF( double cf) {
   CF = cf;
 }
 
 /// Switch on/off full_CF.
 void set_full_CF( bool is_full ) { full_CF = is_full; }
 
-/// Get the number of colors.
+/// Returns the number of colors.
 double get_Nc() const { return Nc; }
 
-// Returns the normalization of the generators,
+/// Returns the normalization of the generators,
 /// tr(t^a t^b)=TR*delta^{a,b}.
 double get_TR() const { return TR; }
 
-/// Get the number of colors.
+/// Returns the value of CF.
 double get_CF() const { return CF; }
 
-/// Return true, if full CF is used
+/// Returns true, if full CF is used.
 bool get_full_CF() const { return full_CF; }
 
 
 /****************** Functions for leading terms *************************/
 // The functions called leading(...) depend on the variable full_CF.
 // As it would be messy to let each Polynomial carry around
 // its own full_CF, these functions are kept here.
 
 /// Function for finding the leading power of Nc in a Poly_vec,
 /// i.e., the power of Nc plus the power of CF.
 int  leading_Nc_pow( const Polynomial & Poly ) const;
 
 /// Function for finding the leading power of Nc in a Poly_vec.
 int  leading_Nc_pow( const Poly_vec & Pv ) const;
 
+/*
 /// Function for finding the leading power of Nc in a
-/// vector of pointer to Polynomials.
+/// vector of pointers to Polynomials.
 int  leading_Nc_pow( const std::vector< shared_ptr<Polynomial> > & Pvp) const;
+*/
 
 /// Takes the leading Nc terms of a Polynonmial, i.e. Monomials with highest
 /// power of Nc+CF. If full_CF is false (default), CF is replaced by TR Nc.
 /// If full_CF is true CF is replaced by TR(Nc^2-1)/Nc.
 Polynomial leading( const Polynomial & Poly ) const;
 
 /// Take the leading part of a Poly_vec.
-/// Keeps only Monomials with maximal power of CF + Nc.
-/// Uses leading( const Polynomial & Poly).
+/// Keeps only Monomials with maximal power of CF plus Nc,
+/// uses leading( const Polynomial & Poly).
 /// If full_CF is false (default), CF is replaced by TR Nc.
 /// If full_CF is true CF is replaced by TR(Nc^2-1)/Nc.
 /// Note that taking the leading terms of a Poly_vec is not
 /// the same as taking the leading terms in each Polynomial.
 // Used only by Poly_matr version of leading
 Poly_vec leading( const Poly_vec & Pv ) const;
 
 /// Takes the leading part of a matrix of Polynomials,
-/// keeping only those with maximal power of CF + Nc.
+/// keeping only those with maximal power of CF plus Nc.
 /// If full_CF is false (default), CF is replaced by TR Nc.
 /// If full_CF is true CF is replaced by TR(Nc^2-1)/Nc.
 /// Note that taking the leading terms of a Poly_matr is not
 /// the same as taking the leading terms in each Poly_vec.
 // Used only once in Col_basis
 Poly_matr leading( const Poly_matr & Pm ) const;
 
+/*
 /// Take the leading part of a Poly_vec, given a vector of pointers to the Polynomials.
-/// Keeps only Monomials with maximal power of CF + Nc.
+/// Keeps only Monomials with maximal power of CF plus Nc.
 // Currently never used
 Poly_vec leading( const std::vector<shared_ptr<Polynomial> > & Pvp) const;
 
 /// Take the leading part of a Poly_matr, given a vector of vector of pointers to the Polynomials.
 /// Loops over Monomials in all Polynomials
-/// and keeps only those with maximal power of CF + Nc.
+/// and keeps only those with maximal power of CF plus Nc.
 // used only by scalar_product_matrix_mem in Col_functions
 dmatr leading( const std::vector< std::vector< shared_ptr<Polynomial> > > & Pm ) const;
-
-/// To keep only leading terms in a map.
-// used only on Col_functions by scalar product_matrix_mem_2 and radiation_amplitude_matrix
-std::map< std::string, Polynomial > leading( const std::map< std::string, Polynomial > & mem_map ) const;
-
+*/
 
 /********************* Functions for numerical evaluation *************************/
 // These functions has to be kept in Col_functions class as they need numerical
 // values for evaluation. Letting each Polynomial carry around its own Nc etc.
 // would be messy.
 
-/// To take the numerical value of a map.
-std::map< std::string, double > double_num( const std::map< std::string, shared_ptr<Polynomial> > & mem_map ) const;
 
-/// Numerically evaluates a Monomial using the Nc and CF variables;
+/// Numerically evaluates a Monomial using the Nc, TR and CF data members.
 cnum cnum_num( const Monomial & Mon ) const;
 
-// Numerically evaluates a Monomial to a double.
-double double_num( const Monomial & Mon ) const;
-
-/// Numerically evaluates a Polynomial, using the CF and Nc variables.
+/// Numerically evaluates a Polynomial, using the Nc, TR and CF data members.
 cnum cnum_num( const Polynomial & Poly ) const;
 
-/// Numerically evaluates a Polynomial using the data members Nc, CF and TR.
-double double_num( const Polynomial & Poly ) const;
-
-/// To take the numerical value of a map.
-std::map< std::string, double > double_num(const std::map< std::string, Polynomial > & mem_map) const;
-
-/// Numerically evaluates a Poly_vec (vector of Polynomial) for Nc=3.
-dvec double_num( const Poly_vec & Pv ) const;
-
-/// Returns a double value. The argument is a vector of pointers to Polynomials.
-dvec double_num( const std::vector<shared_ptr<Polynomial> > & Pv ) const;
-
-/// Returns a double value. The argument is a vector of vector of pointers to Polynomials.
-dmatr double_num( const std::vector<std::vector<shared_ptr<Polynomial> > > & Pm ) const;
-
-/// Numerically evaluates a Polynomial for Nc=3,
-/// and stores in the format of a Polynomial with only one term with only a numerical part.
-Polynomial Polynomial_cnum_num( const Polynomial & Poly ) const;
-
 /// Numerically evaluates a Poly_vec (vector of Polynomial),
 /// using cnum_num (Polynomial).
 cvec cnum_num( const Poly_vec & Pv ) const;
 
+/// Numerically evaluates a Poly_matr (vector of Poly_vec),
+/// using cnum_num( Poly_vec ) for each Poly_vec.
+cmatr cnum_num( const Poly_matr & Pm ) const;
+
+/// Numerically evaluates a Monomial to a double using the Nc, TR and CF data members.
+double double_num( const Monomial & Mon ) const;
+
+/// Numerically evaluates a Polynomial to a double using the Nc, TR and CF data members.
+double double_num( const Polynomial & Poly ) const;
+
+/// Numerically evaluates a Poly_vec (vector of Polynomial)
+/// using the Nc, TR and CF data members.
+dvec double_num( const Poly_vec & Pv ) const;
+
+/// Numerically evaluates a Poly_matr (vector of Poly_vec),
+/// using the Nc, TR and CF data members.
+dmatr double_num( const Poly_matr & Pm ) const;
+
+/*
+/// Returns a double vector. The argument is a vector of pointers to Polynomials.
+dvec double_num( const std::vector<std::shared_ptr<Polynomial> > & Pv ) const;
+
+/// Returns a double matrix. The argument is a vector of vector of pointers to Polynomials.
+// (not used 14 06 08)
+dmatr double_num( const std::vector<std::vector<std::shared_ptr<Polynomial> > > & Pm ) const;
+
+/// To take the numerical value of a map.
+// (not used 14 06 08)
+std::map< std::string, double > double_num( std::map< std::string, std::shared_ptr<Polynomial> > mem_map ) const;
+
+/// To take the numerical value of a map.
+// (not used 14 06 08)
+std::map< std::string, double > double_num( std::map< std::string, Polynomial > mem_map ) const;
+*/
+
+/// Numerically evaluates a Polynomial using the value of the data member Nc,
+/// and stores in the format of a Polynomial with only one term with only a numerical part.
+Polynomial Polynomial_cnum_num( const Polynomial & Poly ) const;
+
 /// Numerically evaluates a Poly_vec (vector of Polynomial)
 /// and stores in the form of a Poly_vec, uses polynomial_cnum_num( Pv.at( p ) ).
 /// for each Polynomial.
 Poly_vec Poly_vec_cnum_num( const Poly_vec & Pv ) const;
 
 /// Numerically evaluates a Poly_matr (vector of Poly_vec)
 /// and stores in the form of a Poly_matr.
 Poly_matr Poly_matr_cnum_num( const Poly_matr & Pm ) const;
 
-/// Numerically evaluates a Poly_matr (vector of Poly_vec),
-/// using cnum_num( Poly_vec ) for each Poly_vec.
-cmatr cnum_num( const Poly_matr & Pm ) const;
-
-/// Numerically evaluates a Poly_matr (vector of Poly_vec).
-dmatr double_num( const Poly_matr & Pm ) const;
 
 /****************** Functions for scalar products *************************/
 
-/// Function for calculating scalar products between Col_amps.
+/// Function for calculating the scalar products between Col_amps.
 /// Does not add implicit state in the gluons only case.
 Polynomial scalar_product( const Col_amp & Ca1, const Col_amp & Ca2 ) const;
 
-/// Function for calculating scalar product between two Col_strs.
+/// Function for calculating the scalar product between two Col_strs.
 /// Does not add implicit state in the gluons only case.
 Polynomial scalar_product( const Col_str & Cs1, const Col_str & Cs2 ) const;
 
 
-/****************** Functions for gluon emission and exchange *************/
+/****************** Functions for gluon emission exchange, and splitting *************/
 
 /// Function for emitting a gluon from a Col_str.
 /// When the gluon is inserted before the emitter in a Quark_line,
 /// the amplitude comes with a minus sign.
 Col_amp emit_gluon( const Col_str & in_Col_str, int emitter, int g_new ) const;
 
 /// Function for emitting a gluon from a Col_amp.
 /// When the gluon is inserted before the emitter in a Quark_line,
 /// the amplitude comes with a minus sign.
 Col_amp emit_gluon( const Col_amp & Ca_in, int emitter, int g_new ) const;
 
+/// Function for splitting the gluon g_old in a Col_str to a qqbar pair.
+Col_amp split_gluon( const Col_str & in_Col_str, int g_old, int q_new, int qbar_new ) const;
+
+/// Function for splitting the gluon g_old in a Col_amp to a qqbar pair.
+Col_amp split_gluon( const Col_amp & in_Col_amp, int g_old, int q_new, int qbar_new ) const;
+
+
 /// Function for exchanging a gluon between the partons p1 and p2 in the Col_str Cs.
 /// When the gluon is inserted before the emitter in a Quark_line,
 /// the amplitude comes with a minus sign.
 Col_amp exchange_gluon( const Col_str & Cs, int p1, int p2 ) const;
 
 /// Function for exchanging a gluon between two partons p1 and p2 in the Col_amp Ca.
 /// When the gluon is inserted before the emitter in a Quark_line,
 /// the amplitude comes with a minus sign.
-/// (The incoming amplitude is what it is, there is no special
-/// treatment of glons only cases.)
+/// (There is no special treatment of the glons only cases.)
 Col_amp exchange_gluon( const Col_amp & Ca, int p1, int p2 ) const;
 
-/// Calculates < M | T^(i) T^(j) | M >, the "color correlator"
+/// Calculates < M | T_i T_j | M >, the "color correlator"
 /// relevant for coherent gluon emission of gluon g_new from
 /// parton i and parton j, or gluon exchange between i and j.
-/// The Ca should thus be | M >, g_new should be a unique dummy index,
+/// The Ca should thus be | M >,
 /// and i and j are the partons involved in the emission (exchange).
 /// (The incoming amplitude is what it is, there is no special
 /// treatment of gluons only cases.)
-Polynomial color_correlator( const Col_amp Ca, int i, int j, int g_new ) const;
+Polynomial color_correlator( const Col_amp Ca, int i, int j ) const;
 
 
 /********************* Other functions *************************/
 
 // As dvec and dmatr are not classes some read and write functions
 // are contained here.
 
-/// Read in a numerical matrix from filename and save it as a double matrix, dmatr.
-/// The file should be in the format
-/// {d11,...,d1n}.
+/// Reads in a numerical vector and save it as a double vector, dvec.
+/// The file should be of the format
+/// {d11,...,d1n},
+/// and may contain comment lines starting with # at the top.
 dvec read_in_dvec( std::string filename ) const;
 
-/// Read in a numerical matrix from filename and save it as a double matrix, dmatr.
-/// The file should be in the format
+/// Reads in a numerical matrix and save it as a double matrix, dmatr.
+/// The file should be of the format
 /// {{d11,...,d1n},
 /// ...,
 /// {dn1,...,dnn}},
 /// and may contain comment lines starting with # at the top.
 dmatr read_in_dmatr( std::string filename ) const;
 
 /// Function for writing out a numerical vector,
 /// to the file filename.
 void write_out_dvec( const dvec & dv, std::string filename ) const;
 
 /// Writes out the double version of a (scalar product) matrix
 /// to the file filename.
 void write_out_dmatr( const dmatr & matr, std::string filename ) const;
 
 /// The factorial of an int, 0! is defined as 1.
 int factorial( int i ) const;
 
+/// Function that finds the default parton numbers for a Col_str.
+/// The default numbers are 1,...,N_parton, where quarks have the first
+/// odd numbers, anti-quarks have the first even numbers, and gluons have
+/// subsequent numbers. The intended usage is after gluon splitting, where
+/// the gluon g_old has split into q_new and qbar_new, and the parton numbers
+/// before splitting are assumed to be default.
+std::map<int, int> default_parton_numbers( const Col_str &, int g_old, int q_new, int qbar_new ) const;
+
+
+/// Function that renames the partons in a Col_str using a map where, in each pair,
+/// the first number is to be replaced by the second. (The Col_functions member
+/// function default_parton_numbers returns a map where the partons are given
+/// default numbers.)
+Col_str rename_partons( const Col_str &, const std::map <int, int> replacements ) const;
+
+
+/// Function that renames the partons in a Col_amp using a map where, in each pair,
+/// the first number is to be replaced by the second. (The Col_functions member
+/// function default_parton_numbers returns a map where the partons are given
+/// default numbers.)
+Col_amp rename_partons( const Col_amp &, const std::map <int, int> replacements ) const;
+
+
 }; // end class Col_functions
 
 
 /////////////////////// DECLEARING OPERATORS /////////////////////
 
 /// Defining + operator to be able to erase elements at place
 std::list<int>::iterator operator+( std::list<int>::iterator x, int n );
 
 std::list<int>::iterator operator-( std::list<int>::iterator x, int n );
 
 /// Defining + operator to be able to erase elements at place
 std::list< Quark_line >::iterator operator+( std::list < Quark_line >::iterator x, int n );
 
 col_str::iterator operator-( col_str::iterator x, int n );
 
 /// Define the operator << for vector of int.
 std::ostream& operator<<( std::ostream& out, const std::vector<int> & vec );
 
 /// Define the operator << for cvec.
 std::ostream& operator<<( std::ostream& out, const cvec & cv );
 
 /// Define the operator << for dvec.
 std::ostream& operator<<( std::ostream& out, const dvec & dv );
 
 /// Define the operator << for cmatr.
 std::ostream& operator<<( std::ostream& out, const cmatr & cm );
 
 /// Define the operator << for dmatr.
 std::ostream& operator<<( std::ostream& out, const dmatr & matr );
 
 /// Define the operator << for std::pair<int, int>.
 std::ostream& operator<<( std::ostream& out, std::pair<int, int> pair );
 } // end namespace ColorFull
 
 #endif /* COLORFULL_Col_functions_h */
diff --git a/MatrixElement/Matchbox/ColorFull/Col_str.cc b/MatrixElement/Matchbox/ColorFull/Col_str.cc
--- a/MatrixElement/Matchbox/ColorFull/Col_str.cc
+++ b/MatrixElement/Matchbox/ColorFull/Col_str.cc
@@ -1,954 +1,976 @@
 // -*- C++ -*-
 /*
  *  Col_str.cc
  *	Contains definition of the class Col_str and associated types and operators.
  *  Created on: Jul 7, 2010
  *  Author: Malin Sjodahl
  */
 
 #include "Col_str.h"
 #include <cassert>
 #include <fstream>
 #include <iostream>
 
 
 namespace ColorFull {
 
 Col_str::Col_str( const std::string str ) {
 	Col_str_of_str( str );
 }
 
 
 void Col_str::Col_str_of_str( const std::string str ) {
 
 	// First split the string into Col_str and Polynomial part
 	uint j=0;
 
 	// Check that left and right normal brackets match up
 	j=0;
 	int left_brackets=0,right_brackets=0;
 	while (j < str.size()) {
 		if(str.at(j)=='(') left_brackets++;
 		if(str.at(j)==')') right_brackets++;
 		j++;
 	}
 	if(left_brackets != right_brackets){
 		std::cerr << "Col_str::Col_str_of_str: The normal brackets, (), in the Col_str\"" << str <<"\" do not seem to match up. There were "
 				<< left_brackets <<" left bracket(s) and "<< right_brackets << " right bracket(s)." << std::endl;
 		assert( 0 );
 	}
 
 	// Check that left and right curly brackets match up
 	left_brackets=0,right_brackets=0;
 	j=0;
 	while (j < str.size()) {
 		if(str.at(j)=='{') left_brackets++;
 		if(str.at(j)=='}') right_brackets++;
 		j++;
 	}
 	if(left_brackets != right_brackets){
 		std::cerr << "Col_str::Col_str_of_str: The curly brackets in the Col_str\"" << str <<"\" do not seem to match up. There were "
 				<< left_brackets <<" left bracket(s) and "<< right_brackets << " right bracket(s)." << std::endl;
 		assert( 0 );
 	}
 
 	// Check that left and right [] brackets match up
 	j=0;
 	left_brackets=0, right_brackets=0;
 	while (j < str.size()) {
 		if(str.at(j)=='[') left_brackets++;
 		if(str.at(j)==']') right_brackets++;
 		j++;
 	}
 	if(left_brackets != right_brackets){
 		std::cerr << "Col_str::Col_str_of_str: The square brackets, [], in the string \"" << str <<"\" do not seem to match up. There were "
 				<< left_brackets <<" left bracket(s) and "<< right_brackets << " right bracket(s)." << std::endl;
 		assert( 0 );
 	}
 
 
 	if( left_brackets != 1){
 		std::cerr << "Col_str::Col_str_of_str: Found " << left_brackets << " squared, [], left brackets in the string " << str
 				<<" but there should be 1;" << std::endl;
 		assert( 0 );
 	}
 
 	// Read in the Polynomial until a [ is found
 	j=0;
 	std::string  Poly_string;
 	Poly_string.empty();
 	while( j<str.size() and str.at(j)!='['){
 		Poly_string.push_back(str.at(j));
 		j++;
 	}
 
 	// Then read in the col_str
 	std::string  col_string;
 	col_string.empty();
 	while( j< str.size() and str.at(j)!=']'){
 		col_string.push_back( str.at(j) );
 		j++;
 	}
 
 	// Get the final ], In this way the final sign will be ]
 	col_string.push_back( str.at(j) );
 
 	Poly=Polynomial( Poly_string );
 
 	col_str_of_str( col_string );
 }
 
 
 void Col_str::col_str_of_str(std::string str) {
 	// First sign should be '['
 	if (str.at(0) != '[') {
 		std::cerr
 		<< "Col_str::col_str_of_str: First char in col_str should be '[', it was: "
 		<< str.at(0) << std::endl;
 		std::cerr.flush();
 		assert( 0 );
 	}
 
 	uint i = 0; // set i to 0 to start at position 1 after adding 1
 	while (i < str.size() - 2) {
 		// To contain the argument to the Quark_line constructor
 		std::string Ql_arg;
 		Ql_arg.clear();
 
 		// Increase i with 1, to compensate for ')'
 		i += 1;
 
 		// Make argument to the Quark_line constructor
 		// Keep reading while not ')' or '}'
 		while (str.at(i) != ')' && str.at(i) != '}') {
 			Ql_arg.push_back(str.at(i));
 			i++;
 			//cout << "Col_str::Col_str(str): For " << i << " The str is: " << Ql_arg << std::endl;
 		}
 		// Append last char ')' or '}'
 		Ql_arg.push_back(str.at(i));
 		Quark_line Ql(Ql_arg);
 		cs.push_back(Ql_arg);
 	}
 
 	// Last sign should be ']'
 	if (str.at(str.size() - 1) != ']') {
 		std::cerr
 		<< "Col_str::col_str_of_str: Last char in col_str should be ']', it was: "
 		<< str.at(str.size() - 1) << std::endl;
 		std::cerr.flush();
 		assert( 0 );
 	}
 }
 
 
 void Col_str::read_in_Col_str( std::string filename ) {
 
 	// Read in file
 	std::ifstream fin(filename.c_str() );
 
 	// Check that file exists
 	if( !fin ){
 		std::cerr << "Col_str::read_in_Col_str: The file "
 				<< filename << " could not be opened." << std::endl;
 		assert( 0 );
 	}
 
 	// Copy info from file to string
 	std::string str((std::istreambuf_iterator<char>(fin)), std::istreambuf_iterator<char>());
+
+	// Skip lines starting with #
+	while( str.at(0)== '#' ){
+		while (str.at(0) != '\n'){
+			str.erase(str.begin());
+		}
+		// erase endl sign(s)
+		while(str.at(0)== '\n'){
+			str.erase(str.begin());
+		}
+	}
+
+	// Remove endl chars at the end of the file
+	while( str.at(str.size()-1) == '\n' ) str.erase(str.size()-1);
 	Col_str_of_str( str );
 }
 
 
 void Col_str::write_out_Col_str( std::string filename ) const {
 
 	if ((cs.size() == 0)) {
 		std::cout
 		<< "Col_str::write_out_Col_str: The Col_str is empty."
 		<< std::endl;
 		std::cout.flush();
 		return;
 	}
 
 	std::ofstream outfile(filename.c_str());
 
 
 	if ( !outfile )
 	std::cerr << "Col_str::write_out_Col_str: Cannot write out Col_str as the file \""
 		<< filename.c_str() << "\" could not be opened. (Does the directory exist? Consider creating the directory.)" << std::endl;
 
 
 	outfile << *this;
 }
 
 
 int Col_str::at( int i, int j ) const {
 	if (i < 0) {
 		std::cout << "Col_str::at: First argument <0\n";
 		std::cerr.flush();
 		assert( 0 );
 	} else if (i >= static_cast<int>(cs.size()) ) {
 		std::cerr << "Col_str::at: First argument > size -1\n";
 		std::cerr.flush();
 		assert( 0 );
 	}
 	if (j < 0) {
 		std::cerr << "Col_str::at: Second argument <0 \n";
 		std::cerr.flush();
 		assert( 0 );
 	} else if (j >= static_cast<int>(cs.at(i).ql.size())) {
 		std::cerr << "Col_str::at: Second argument > size -1\n";
 		std::cerr.flush();
 		assert( 0 );
 	}
 
 	return cs.at(i).ql.at(j);
 }
 
 
 void Col_str::erase( int i ) {
 	cs.erase(cs.begin() + i);
 }
 
 
 void Col_str::erase( int i, int j ) {
 	cs.at(i).ql.erase(cs.at(i).ql.begin() + j);
 }
 
   
   void Col_str::erase( std::pair<int, int> place ) {
     
     erase(place.first, place.second);
 }
 
 
 void Col_str::insert( int i, int j, int part_num ) {
 	// Checking that location is within range
 	if (i < 0) {
 		std::cerr << "Col_str::insert: First argument <0\n";
 		std::cerr.flush();
 		assert( 0 );
 	} else if (i >= static_cast<int> (cs.size()) ) {
 		std::cerr << "Col_str::insert: First argument > size -1\n";
 		std::cerr.flush();
 		assert( 0 );
 	}
 	if (j < 0) {
 		std::cerr << "Col_str::insert: Second argument <0\n";
 		std::cerr.flush();
 		assert( 0 );
 	} else if (j > static_cast<int>( cs.at(i).ql.size()) ) {
 		std::cerr << "Col_str::insert: Second argument > size, was " << j << std::endl;
 		std::cerr.flush();
 		assert( 0 );
 	}
 	// Inserting element at place given by iterator itj
 	quark_line::iterator itj = cs.at(i).ql.begin() + j;
 	cs.at(i).ql.insert(itj, part_num);
 }
 
 
 void Col_str::append( col_str cs_in ) {
 	for (uint j = 0; j < cs_in.size(); j++) {
 		cs.push_back(cs_in.at(j));
 	}
 }
 
 
 std::pair<int, int> Col_str::find_parton( int part_num ) const {
 
 	// Loop over all Quark_lines
 	for (uint i = 0; i < cs.size(); i++) {
 		// Loop over all places in the Quark_lines
 		for (uint j = 0; j < cs.at(i).ql.size(); j++) {
 			if (cs.at(i).ql.at(j) == part_num) {
 				// cout << j<< "\n";
 			  return std::make_pair(i, j);
 			}
 		}
 	}
 	// Assert parton found
 	std::cerr
 	<< "Col_str::find_parton: The function find_parton did not find the parton "
 	<< part_num << "in \n" << cs;
 	std::cerr.flush();
 	assert( 0 );
 	return std::make_pair(-1, -1);
 }
 
 
 bool Col_str::neighbor(int p1,int p2) const{
 
 	// The places
   std::pair<int, int> place1 = find_parton(p1);
   std::pair<int, int> place2 = find_parton(p2);
 
 	// First make sure the partons are in the same Quark_line
 	if( place1.first!=place2.first ) return false;
 	if( place2.second==place1.second + 1 or place2.second==place1.second - 1) return true;
 
 	return false;
 }
 
 
 bool Col_str::right_neighbor(int p1,int p2) const{
 
   return left_neighbor(p2,p1);
 
 }
 
 
 bool Col_str::left_neighbor(int p1,int p2) const{
 
 	// The places
   std::pair<int, int> place1 = find_parton(p1);
   std::pair<int, int> place2 = find_parton(p2);
 
 	// First make sure the partons are in the same Quark_line
 	if( place1.first!=place2.first ) return false;
 	bool closed = !at(place1.first).open;
 	int length = at(place1.first).size();
 	if ( !(place1.second-place2.second == 1 ||
 	       (place1.second-place2.second == 1 - length && closed)) ) return false;
 
 	return true;
 }
 
 
 void Col_str::replace(int old_ind, int new_ind) {
 
 	// First, locate the index to replace
   std::pair<int, int> place = find_parton(old_ind);
 
 	// Then erase the index at that place
 	erase(place.first, place.second);
 
 	// Then insert the new index
 	insert(place.first, place.second, new_ind);
 }
 
 
-std::string Col_str::find_kind( int part_num ) const {
+std::string Col_str::find_kind( int p ) const {
 
 	// Locate the parton in the Col_str
-  std::pair<int, int> place = find_parton(part_num);
+  std::pair<int, int> place = find_parton(p);
 
 	// Check if the quark-line is closed
 	// If the parton is in a closed quark line it's a g
 	if (!at(place.first).open) {
 		return "g";
 	}
 	// If the parton is first in an open quark-line it's a q
 	// (the first relevant place is place 1)
 	else if (place.second == 0) {
 		return "q";
 	}
 	// If the parton is last in an open quark-line it's a qbar
 	// To find location, subtract the number of characters it takes to write part_num
 	else if (place.second == static_cast<int> (cs.at(place.first).ql.size()) - 1) {
 		return "qbar";
 	}
 	// add warning if not found?
 	// If the parton wasn't found, it must be a gluon
 	else {
 		return "g";
 	}
 }
 
 
 bool Col_str::gluons_only() const {
 	// Loop over Quark_lines
 	for (uint i = 0; i < cs.size(); i++) {
 		if (cs.at(i).open)
 			return false;
 	}
 	// If no Ql was open, the Cs has gluons only
 	return true;
 }
 
 
 int Col_str::n_gluon() const {
 	int ng = 0;
 
 	// Loop over Quark_lines
 	for (uint i = 0; i < cs.size(); i++) {
 		// If the ql is closed, all partons are gluons
 		// if it is open, all -2 are gluons
 		ng = ng+at(i).ql.size();
 		if (at(i).open) ng = ng - 2;
 	}
 	return ng;
 }
 
 
 int Col_str::n_quark() const {
 	int nq = 0;
 	// Loop over Quark_lines
 	for (uint i = 0; i < cs.size(); i++) {
 		// If the ql is closed, there is no gluon
 		// If it is open, there is one quark (and one anti-quark)
 		if (at(i).open) nq++;
 	}
 	return nq;
 }
 
 
 void Col_str::normal_order() {
 
 	// All individual quark_lines should be normal_ordered
 	for (uint i = 0; i < cs.size(); i++) {
 		cs.at(i).normal_order();
 	}
 
 	// Loop over the ql's which are candidates to move
 	for (uint i = 1; i < cs.size(); i++) {
 
 		// How many steps to the left should the ql be moved?
 		int steps_left = 0;
 		while (steps_left <= static_cast<int>(i) - 1 && compare_quark_lines(i, i - steps_left - 1) == static_cast<int>(i))
 			steps_left++;
 
 		if (steps_left != 0) {
 			// Insert ql in new place
 			cs.insert(cs.begin() + i - steps_left, cs.at(i));
 			// Eras in old
 			cs.erase(cs.begin() + i + 1);
 		}
 
 	}
 }
 
 
 int Col_str::smallest( const Col_str & Cs1, const Col_str & Cs2 ) const{
 
 	// First order Col_strs according to how many Quark_lines they have
 	// The Col_str with fewest Quark_lines is "smallest"
 	if ( Cs1.size() < Cs2.size() ) return 1;
 	else if( Cs2.size() < Cs1.size() ) return 2;
 
 	// First judge depending on if the Qls are open or not
 	// open ql's are "smaller"
 	for( uint i=0; i< std::min( Cs1.cs.size(), Cs2.cs.size() ); i++ ){
 		// The "smallest" Ql at place i
 		if (Cs1.cs.at(i).open &&  !Cs2.cs.at(i).open) return 1;
 		else if (Cs2.cs.at(i).open &&  !Cs1.cs.at(i).open) return 2;
 	}
 
 	// Then, judge depending on size of the Ql's
 	// longer qls are "smaller", should stand first
 	for( uint i=0; i< std::min( Cs1.cs.size(), Cs2.cs.size() ); i++ ){
 		// The "longest" Ql at place i
 		if (     Cs1.cs.at(i).ql.size() > Cs2.cs.at(i).ql.size() ) return 1;
 		else if (Cs2.cs.at(i).ql.size() > Cs1.cs.at(i).ql.size() ) return 2;
 	}
 
 	// Then, loop over the Quark_lines to see which ql is "smaller", taking index ordering into account
 	// First different index decides, ql with smallest index is smaller
 	for( uint i=0; i< std::min( Cs1.cs.size(), Cs2.cs.size() ); i++ ){
 		// The "smallest" Ql at place i
 		int OneOrTwo=Cs1.cs.at(i).smallest( Cs1.cs.at(i), Cs2.cs.at(i) );
 
 		if     ( OneOrTwo==1 ) return 1;
 		else if( OneOrTwo==2 ) return 2;
 	}
 
 	//If the col_str's are identical, return 0
 	return 0;
 }
 
 
 int Col_str::longest_quark_line() const{
 
 	int length=0;
 	for ( uint j = 0; j < cs.size(); j++ ) {
 		if( static_cast<int> ( at(j).size() )> length ) length=static_cast<int> ( at(j).size() );
 	}
 
 	return length;
 }
 
 
 void Col_str::remove_1_rings() {
 	// Loop over quarl_lines
 	for (uint j = 0; j < cs.size(); j++) {
 		// If a quark_line contains only one gluon, replace whole Col_str with a 0-monomial
 		if (cs.at(j).ql.size() == 1) {
 			// If the quark_line is closed the Col_str is 0
 			if (!cs.at(j).open) {
 				// Remove irrelevant Polynomial and col_str
 				// The col_str is now multiplying 0
 				cs.clear();
 				Poly.clear();
 				Monomial Mon0;
 				Mon0.int_part = 0;
-				Poly.push_back(Mon0);
+				Poly.append(Mon0);
 			}
 
 			// If the Ql is open and has only one element, something is wrong
 			else if (cs.at(j).open) {
 				std::cerr
 				<< "Col_str::remove_1_rings: An open quark_line cannot have only one parton, but it had in \n"
 				<< cs << std::endl;
 				std::cerr.flush();
 				assert( 0 );
 			}
 		}
 	}
 }
 
 
 void Col_str::remove_0_rings() {
 	// Loop over Quark_lines
 	for (int j = 0; j < static_cast<int>(cs.size()); j++) {
 		// If a quark_line contains no gluons and is closed
 		// it is equal to Nc, move factor Nc to the Polynomial of the Col_str
 		if (cs.at(j).ql.size() == 0) {
 			// Move color factor of the Quark_line to the Polynomial of the Col_str
 			Poly = Poly * cs.at(j).Poly;
 			// Multiply with Nc if the quark_line is closed
 			if (!cs.at(j).open) {
 				Monomial Mon_tmp;
 				Mon_tmp.pow_Nc = 1;
-				Poly = Poly * Mon_tmp;
+				Poly *=  Mon_tmp;
 			}
 			// If the ql is open and has 0 elements,
 			// it is defined as 1 and can be removed
 			// Erase the Ql
 			erase(j);
 
 			// In order to check all elements, decrease j when Ql removed
 			// j may get to -1, so can not be seen as uint
 			j--;
 		}
 	}
 }
 
 
 void Col_str::simplify() {
 	remove_1_rings();
 	remove_0_rings();
 
 	// Move factors multiplying the individual Ql's to multiply
 	// the Col_str instead
 	for (uint i = 0; i < cs.size(); i++) {
 		Poly = Poly * cs.at(i).Poly;
 		cs.at(i).Poly.clear();
 	}
 
 	// Simplify Polynomial of Col_str
 	Poly.simplify();
 
 	// Normal order
 	normal_order();
 }
 
 
 void Col_str::conjugate(){
 
 	// Conjugating Polynomial
 	Poly.conjugate();
 
 	// Take conjugate of cs by conjugating each Quark_line
 	for (uint i=0; i < cs.size(); i++ ){
 		cs.at(i).conjugate();
 	}
 }
 
 
 int Col_str::compare_quark_lines( int i1, int i2 ) const {
 
 	int OneOrTwo= cs.at(i1).smallest( cs.at(i1), cs.at(i2) );
 	if ( OneOrTwo==1 ) return i1;
 	else if ( OneOrTwo==2 ) return i2;
 	// If ql's are equal, return i1
 	else if ( OneOrTwo==0 ) return i1;
 	else{
 		std::cerr << "Col_str::compare_quark_lines: cannot decide on ordering of quark_lines "
 				<< cs.at(i1) << " and " << cs.at(i2);
 		return 0;
 	}
 
 }
 
 void Col_str::contract_2_rings( ) {
 
 	// Contract gluons from 2-ring, this gives only one term
 	// For storing place of two-ring
 	std::vector<int> place1;
 	// For storing place of gluon with same index as second gluon in two-ring
 	// i.e. the gluon to be replaced with the first index in the 2-ring
 	std::vector<int> place2;
 	// The second index in two-ring, to be removed
 	int the_g;
 
 	// Loop over Quark_lines to find a two-ring
-	for (uint i = 0; i < cs.size(); i++) {
+	for ( uint i = 0; i < cs.size(); i++ ) {
 		place1.clear();
 		place2.clear();
 		// Search for 2-rings
 		// A gluon 2-ring has length 2 and is closed
 		if ( cs.at(i).ql.size() == 2 && !cs.at(i).open ) {
 
 			// Save place of two-ring
 			place1.push_back(i);
 			// Pick second gluon (for no good reason)
 			// this index should be replaced by first index
 			// in the other place where it occurs, and the 2-ring should be removed
 			place1.push_back(1);
 
 			the_g = at(place1.at(0), place1.at(1));
 
 			// Now, in all Quark_lines, look for same the_g until found
 			for ( uint i2 = 0; i2 < size(); i2++ ) {
 				for (uint j2 = 0; j2 < at(i2).ql.size(); j2++) {
 					// If the_g was found at a DIFFERENT place, (not same g again)
 					if ((i2 != i or j2 != 1) && at(i2, j2) == the_g) {
 						place2.push_back(i2);
 						place2.push_back(j2);
 					}
 				}
 			}
 
 			// Check that the gluon index was found again
 			if (place2.empty()) {
 				std::cerr << "Col_str:contract_2_rings: Only found the index " << the_g
 						<< " once in " << *this << std::endl;
 				assert( 0 );
 			}
 
 			// If the_g was found twice in the same ql
-			if (place1.at(0) == place2.at(0)) {
+			if ( place1.at(0) == place2.at(0) ) {
 				// Keep the Monomial
 				// Multiply with Nc Mon from the contraction
 				Monomial Mon_tmp;
 				Mon_tmp.pow_Nc = 1;
 				Mon_tmp.pow_CF = 1;
 				// Multiply the Poly of the Col_str with the Poly of the ql
 				// and the color factor from the contraction
-				Poly = Poly * cs.at(place1.at(0)).Poly * Mon_tmp;
+				Poly = Poly* cs.at(place1.at(0)).Poly * Mon_tmp;
 				// Erase the ql
 				erase(place1.at(0));
 			}
-			else{
+			else if ( !place2.empty() ){
 				// That index should be changed to the index of the first gluon
 				// in the 2-ring
 				cs.at(place2.at(0)).ql.at(place2.at(1))
 							= at(place1.at(0), 0);
 				// Multiply the Poly of the Col_str with the Poly of the ql
 				// and the color factor from the contraction
 				Monomial Mon_tmp;
 				Mon_tmp.pow_TR = 1;
-				Poly = Poly * Mon_tmp*cs.at(place1.at(0)).Poly;
+				Poly =  Poly * Mon_tmp*cs.at(place1.at(0)).Poly;
 				// The two ring should be removed
 				cs.erase( cs.begin() + i);
 			}
+			//else {i++;}; // Compensate for i--
 			i--; // if we found a 2-ring, we also erased it
 		} // end if we found a 2-ring
 	}// end looping over Quark_lines
 	// One-rings may have been created
 	remove_1_rings();
 
 	return;
 }
 
 void Col_str::contract_quarks( const Col_str Cs1, const Col_str Cs2 ) {
 
 	if( !cs.empty() or Poly.size()!=0 ){
 		std::cerr
 		<< "Col_str::contract_quarks(Cs1,Cs2): This member function "
 		<< "stores the result from contracting quarks in the Col_str itself. "
 		<< "It therefore expects an empty initially Col_str, but it was:" << *this << std::endl;
 	}
 
 	std::vector<int> q_place;
 	std::vector<int> q_place2;
 
 	// The conjugate of Cs1
 	Col_str conj_Cs1 = Cs1;
 	conj_Cs1.conjugate();
 
 	// The total color structure
 	*this = conj_Cs1*Cs2;
 
 	// Count how many quarks should be contracted
 	int n_q = n_quark();
 
 	// As long as there are quark_lines left to contract
 	while (n_q > 0) {
 		// Find first quark in Cs1 by looping over Quark_lines
 		for (int i = 0; (n_q>0 && i <  static_cast<int>( size()) ); i++) {
 			// Check if the quark-line is open, in which case it has a q
 			if ( cs.at(i).open ) {
 				// The first quark is located and has position
 				q_place.clear();
 				q_place.push_back(i);
 				q_place.push_back(0);
 				// and number
 				int q = at(q_place.at(0), q_place.at(1));
 
 				// Locate same quark a second time
 				// Loop over Quark_lines
 				q_place2.clear();
 				int i2 = i + 1; // Quark_line of second occurrence
 				while (q_place2.empty()) { // As long as quark not found a second time
 					if ( cs.at(i2).at( cs.at(i2).ql.size() - 1) == q) {// If quark found, store place
 						q_place2.push_back(i2);
 						q_place2.push_back( cs.at(i2).ql.size() - 1);
 					}
 					i2++;
 				}
 				if (q_place2.empty()) {
 					std::cerr << "Col_functions::contract_quarks(Cs1, Cs2): Found q " << q
 							<< " only once in " << *this << std::endl;
 				}
 
 				// Prepare new Quark_line
 				// to be inserted at the place of found open Quark_line
 				Quark_line new_Quark_line;
 				Quark_line part2_new_Quark_line;
 				// The first part of the new Quark_line should be the Quark_line
 				// containing q in the conjugate
 				new_Quark_line = cs.at(q_place2.at(0));
 
 				// Erasing q in the end
 				new_Quark_line.ql.erase(--new_Quark_line.ql.end());
 				part2_new_Quark_line = cs.at(q_place.at(0));
 
 				// Erasing the q in the beginning of second part
 				part2_new_Quark_line.ql.erase(part2_new_Quark_line.ql.begin());
 
 				new_Quark_line.append(part2_new_Quark_line.ql);
 
 				// So far we have not included the Polynomial of part2_new_Quark_line
 				new_Quark_line.Poly=new_Quark_line.Poly*part2_new_Quark_line.Poly;
 
 				// If the first q index and the last qbar index in the new
 				// Quark_line is the same (and the Quark_line is "open"), the indices
 				// should be removed and the Quark_line should be closed
 				if (new_Quark_line.ql.at(0) == new_Quark_line.ql.at(
 						new_Quark_line.ql.size() - 1) && new_Quark_line.open) {
 					// The string is closed
 					new_Quark_line.open = false;
 					// Remove last and first index
 					new_Quark_line.ql.erase(--new_Quark_line.ql.end(),
 							new_Quark_line.ql.end());
 					new_Quark_line.ql.erase(new_Quark_line.ql.begin());
 				}
 
 				// Inserting new Quark_line in the place of the old
 				cs.at(i) = new_Quark_line;
 
 				// Remove quark_line with q in Cs
 				cs.erase(( cs.begin() + q_place2.at(0)));
 				i=-1; // reset to keep looking from the beginning in the new Cs (i will be increased to 0)
 			}// end of if (open)
 
 			n_q = n_quark();
 
 		} // end of for, loop over quark_lines
 	} // end while (n_q > 0)
 	return;
 }
 
 
 
 void  Col_str::contract_next_neighboring_gluons( ) {
 
   // Loop over Quark_lines and remove neighboring and next to neighboring
   // gluon indices
   for( uint i=0; i < cs.size(); i++ ){
 
     // Create a Quark_line to use as argument
     Quark_line Ql= at(i);
 
     Ql.contract_next_neighboring_gluons( );
 
     // Collect Polynomial in Cs Polynomial
     Poly=Poly*Ql.Poly;
     // and put powers in Ql to 0
     Ql.Poly.clear();
 
     cs.insert( cs.begin() +i, Ql);
 
     // Erase old version of Quark_line (now at place i+1)
     cs.erase( cs.begin() +i + 1 );
   }
   // Remove 1 and 0-rings, simplify Poly and normal order
   simplify();
 
   return;
 }
 
-bool operator==(const col_str & cs1, const col_str & cs2){
+bool operator==( const col_str & cs1, const col_str & cs2 ){
 
 	// col_str's must have equal length
 	if( cs1.size() != cs2.size() ) return false;
 
-	// Individual ql's be be equal
+	// Individual Ql's be be equal
 	for ( uint i=0; i< cs1.size(); i++){
-		if(cs1.at(i).ql != cs2.at(i).ql ) return false; // Equal color structure
-		if(cs1.at(i).Poly != cs2.at(i).Poly ) return false; // Equal polynomial structure
+		if(cs1.at(i) != cs2.at(i) ) return false;
 	}
 	//If all ql's equal the cs are considered equal
 	return true;
 }
 
 
-bool operator!=(const col_str & cs1, const col_str & cs2){
+bool operator!=( const col_str & cs1, const col_str & cs2 ){
 	if(cs1==cs2) return false;
 	else return true;
 }
 
 
-std::ostream& operator<<(std::ostream& out, const col_str & cs) {
+std::ostream& operator<<( std::ostream& out, const col_str & cs ) {
 	int max = cs.size();
 	if (max == 0)
 		out << "[]";
 	else {
 		out << "[";
 		for (int i = 0; i < max - 1; i++) {
 			out << cs.at(i);
 		}
 		out << cs.at(max - 1) << "]"; //<< std::endl;
 	}
 	return out;
 }
 
 
 Col_str operator*( const Col_str & Cs, const int i){
 	Col_str Cs_res=Cs;
 	Cs_res.Poly=Cs.Poly*i;
 	return Cs_res;
 }
 // Define the operator * for int and Col_str
-Col_str operator*( const int i, const Col_str & Cs){
+Col_str operator*( const int i, const Col_str & Cs ){
 	Col_str Cs_res=Cs;
 	Cs_res.Poly=Cs.Poly*i;
 	return Cs_res;
 }
 
 
-Col_str operator*( const Col_str & Cs, const double d){
+Col_str operator*( const Col_str & Cs, const double d ){
 	// Multiply Polynomial of Col_str with the double
 	Col_str Cs_res=Cs;
-	Cs_res.Poly=Cs.Poly*d;
+	Cs_res.Poly *= d;
 	return Cs_res;
 }
-Col_str operator*( const double d, const Col_str & Cs){
+Col_str operator*( const double d, const Col_str & Cs ){
 	Col_str Cs_res=Cs;
 	Cs_res.Poly=Cs.Poly*d;
 	return Cs_res;
 }
 
 
 
-Col_str operator*(const Col_str & Cs, const cnum c){
+Col_str operator*(const Col_str & Cs, const cnum c ){
 	Col_str Cs_res=Cs;
 	Cs_res.Poly=Cs.Poly*c;
 	return Cs_res;
 	return Cs;
 }
-Col_str operator*(const cnum c, const Col_str & Cs){
+Col_str operator*( const cnum c, const Col_str & Cs ){
 	Col_str Cs_res=Cs;
 	Cs_res.Poly=Cs.Poly*c;
 	return Cs_res;
 }
 
 
-Col_str operator*(const Col_str & Cs, const Monomial & Mon){
+Col_str operator* (const Col_str & Cs, const Monomial & Mon ){
 	Col_str Cs_res=Cs;
-	Cs_res.Poly=Cs.Poly*Mon;
+	Cs_res.Poly =Cs.Poly*Mon;
 	return Cs_res;
 }
-Col_str operator*( Monomial & Mon, const Col_str & Cs){
+Col_str operator*( Monomial & Mon, const Col_str & Cs ){
 	Col_str Cs_res=Cs;
 	Cs_res.Poly=Cs.Poly*Mon;
 	return Cs_res;
 }
 
 
 Col_str operator*( const Col_str & Cs, const Polynomial & Poly ){
 	Col_str Cs_res=Cs;
 	Cs_res.Poly=Cs.Poly*Poly;
 	return Cs_res;
 }
 Col_str operator*( const Polynomial & Poly, const Col_str & Cs ){
 	Col_str Cs_res=Cs;
 	Cs_res.Poly=Cs.Poly*Poly;
 	return Cs_res;
 }
 
 
 Col_str operator*( const Col_str & Cs, const Quark_line & Ql){
 
 	// Col_str to return
 	Col_str out_Cs=(Cs);
 
 	// Quark_line copy
 	Quark_line out_Ql(Ql);
 
 	//  Multiplying Polynomials
 	out_Cs.Poly = out_Ql.Poly*Cs.Poly;
 
 	// Remove Polynomial info from Quark_line (put to 1),
 	// as this info is stored in Polynomial of Col_str instead
 	out_Ql.Poly.clear();
 
 	// Append Quark_line (without multiplicative polynomial) to out_Col_str
 	out_Cs.cs.push_back( out_Ql );
 
 	return out_Cs;
 }
 Col_str operator*( const Quark_line & Ql , const Col_str & Cs){
 	return Cs*Ql;
 }
 
 
 Col_str operator*( const Col_str & Cs1, const Col_str & Cs2 ){
 
 	// Col_str to return
 	Col_str out_Cs=Cs1;
 
 	//  Multiplying Polynomials
 	out_Cs.Poly = Cs1.Poly*Cs2.Poly;
 
 	// Looping over Quark_lines in Cs2 to add to Cs1
 	for (uint i=0; i < Cs2.cs.size(); i++ ){
 		// Append i:th Quark_line at i:th place in out_Col_str
 		out_Cs.cs.push_back( Cs2.cs.at(i) );
 	}
 
 	return out_Cs;
 }
 
+Col_str operator*( const Quark_line & Ql1, const Quark_line & Ql2 ){
+
+	// Col_str to return
+	Col_str out_Cs(Ql1);
+	out_Cs.simplify();
+
+	return out_Cs*Ql2;
+}
 
 std::ostream& operator<<(std::ostream& out, const Col_str & Cs){
 
 	// Write out polynomial if it is not 1, or if the cs has no structure
 	Polynomial Poly1; // For comparison, the default Polynomial=1
 
 	if( Cs.Poly!=Poly1 or Cs.cs.size()==0 ) out << Cs.Poly;
 	out << Cs.cs;
 	return out;
 }
 
 
 bool operator==(const Col_str & Cs1, const Col_str & Cs2){
 
 	// col_str's be equal
 	if( Cs1.cs != Cs2.cs ) return false;
 
 	// Poly's must be equal
 	if( Cs1.Poly != Cs2.Poly ) return false;
 
 	//If all col_strs and all Polynomials are equal the Col_strs are considered equal
 	return true;
 }
 
 
 bool operator!=( const Col_str & Cs1, const Col_str & Cs2){
 	if( Cs1==Cs2 ) return false;
 	else return true;
 }
 
 } //end namespace ColorFull
diff --git a/MatrixElement/Matchbox/ColorFull/Col_str.h b/MatrixElement/Matchbox/ColorFull/Col_str.h
--- a/MatrixElement/Matchbox/ColorFull/Col_str.h
+++ b/MatrixElement/Matchbox/ColorFull/Col_str.h
@@ -1,274 +1,277 @@
 // -*- C++ -*-
 /*
  *  Col_str.h
  *	Contains declaration of the class Col_str and associated types and operators.
  *  Created on: Jul 7, 2010
  *  Author: Malin Sjodahl
  */
 
 #ifndef COLORFULL_Col_str_h
 #define COLORFULL_Col_str_h
 
 #include "Quark_line.h"
 
 namespace ColorFull {
 
 /// For containing a vector (or list) of Quark_lines
 /// the color information part of a Col_str.
-/// The col_str is a direct product of Quark_lines,
+/// The col_str is a product of Quark_lines,
 /// contained in a vector of quark-lines.
 typedef std::vector < Quark_line > col_str;
 
 
 /// A class to contain ONE color structure, a direct product of Quark_lines,
 /// multiplying a Polynomial, Poly.
 /// The Quark_lines are stored as components in a vector, a col_str.
 class Col_str {
 public:
 
-	/// Default constructor, sets nothing.
+	/// Default constructor, leaves cs empty.
 	Col_str(){};
 
 	/// Constructor for setting the color structure using a string.
 	/// Should be used as:
 	/// "Col_str Cs("2*Nc*TR^(3) [{1,2,3,4}(5,6)(7,8)(9,10,11,12)]");",
 	/// i.e. the argument should be a Polynomial * col_str.
 	/// (The Polynomial should multiply the whole col_str,
 	/// rather than a quark_line inside the [] brackets.)
 	Col_str( const std::string str );
 
 	/// Make a Col_str of a Quark_line.
 	Col_str( Quark_line Ql ) {cs.push_back(Ql);}
 
-	/// For containing the info on color structure,
+	/// For containing the information about the color structure,
 	/// a direct product of Quark_lines,
 	/// contained in a vector of quark-lines.
 	col_str cs;
 
-	/// Polynomial factor multiplying the whole color structure.
+	/// Polynomial factor multiplying the whole product of quark-lines.
 	Polynomial Poly;
 
 	/// Returns the Quark_line at place i.
 	const Quark_line & at( int i ) const {return cs.at(i);}
 
 	/// Returns the Quark_line at place i.
 	Quark_line & at( int i ) {return cs.at(i);}
 
-	/// Returns the parton at place j in in Quark_line i.
+	/// Returns the parton at place j in Quark_line i.
 	int at( int i, int j ) const;
 
 	/// The size of the col_str
 	uint size() const{ return cs.size(); }
 
 	/// Is the col_str empty?
 	bool empty() const { return cs.empty(); }
 
 	/// Erase information in col_str.
 	void clear() { cs.clear(); }
 
 	/// Erases the Quark_line at place i.
 	void erase( int i );
 
 	/// Erases the parton at place i, j.
 	void erase( int i, int j );
 
 	/// Erases a parton at location place.
 	void erase(std::pair<int, int> place);
 
 	/// Appends a Quark_line to data member cs.
-	void push_back( Quark_line Ql ) { cs.push_back( Ql ); }
+	void append( Quark_line Ql ) { cs.push_back( Ql ); }
 
 	/// To insert the parton part_num in quark_line i
 	/// at place j.
 	void insert( int i, int j, int part_num );
 
 	/// Append the content of a col_str to the cs of the Col_str.
 	void append( col_str cs_in );
 
 	/// Function for reading in the Col_str from the file filename.
 	void read_in_Col_str( std::string filename );
 
 	/// Function for writing out the Col_str to a file
 	/// with name filename.
 	void write_out_Col_str( std::string filename ) const;
 
 	/// Locates the parton with number part_num in a Col_str.
 	std::pair<int, int> find_parton( int part_num ) const;
 
 	/// Function for telling if the partons p1 and p2 are neighbors.
 	bool neighbor( int p1, int p2 ) const;
 
 	/// Function for telling if parton p2 stands to the right of parton p1.
 	bool right_neighbor( int p1, int p2 ) const;
 
 	/// Function for telling if parton p2 stands to the left of parton p1.
 	bool left_neighbor( int p1, int p2 ) const;
 
 	/// Replaces the parton index old_ind with new_ind.
 	void replace( int old_ind, int new_ind );
 
-	/// Finds out if a parton is a q, qbar or g,
+	/// Finds out if a parton is a quark, anti-quark or a gluon,
 	/// returns "q", "qbar" or "g" respectively.
 	/// This function does NOT loop over all partons, but assumes
 	/// that the parton is a gluon if the Quark_line is closed,
-	/// or if the Quark_line is open, but the parton cannot be found in the ends.
-	std::string find_kind( int part_num ) const;
+	/// or if the Quark_line is open, but p cannot be found in the ends.
+	std::string find_kind( int p ) const;
 
 	/// Checks if the amplitude only has gluons, i.e. if all Quark_lines are closed.
 	bool gluons_only() const;
 
 	/// Counts the number of gluons in a Col_str.
-	/// Counts all gluon indices, both free and contracted.
+	/// Counts all gluon indices, both free and contractable.
 	int n_gluon() const;
 
 	/// Counts the number of quarks (=number of anti-quarks) in a Col_str.
 	/// Counts all quark indices, both free and contracted.
 	int n_quark() const;
 
 	/// Normal orders the Col_str by first
 	/// normal order individual Quark_lines
 	/// and then normal order different Quark_lines in the cs.
 	/// For the ordering see the member function smallest in this
 	/// class and in the Quark_line class.
 	void normal_order();
 
 	/// Finds out the "smallest" Col_str of two Col_strs, i.e.
-	/// which Col_str should stand first in a normal ordered Col_amp or a basis.
+	/// which Col_str should stand first in a normal ordered Col_amp or basis.
 	/// Returns 1, if Cs1 should stand before Cs2
 	/// and 2 if Cs2 should stand before Cs1.
 	/// Both Col_strs have to be normal ordered for the result to be unique.
 	/// The Col_strs are ordered by
-	/// (1) Number of Quark_lines
-	/// (2) if the Quark_line at place 0,1,2... is open or not.
+	/// (1) number of Quark_lines
+	/// (2) if the Quark_line at place 0,1,2... is open or not
 	/// (3) the size of the Quark_line at place 1,2,3...
 	/// (4) the parton numbers in the Quark_lines at place 1,2,3...,
 	/// i.e. first the first parton in the first Quark_line is checked
 	/// and last the last parton in the last Quark_line.
 	/// The function returns 0 if Cs1=Cs2.
 	int smallest( const Col_str & Cs1, const Col_str & Cs2 ) const;
 
 	/// Returns the length of the longest Quark_line in the Col_str.
 	int longest_quark_line() const;
 
 	/// Removes Quark_lines with only one gluon as Tr(t^a)=0.
 	void remove_1_rings();
 
 	/// Removes Quark_lines without partons, equal to Nc (closed) or 1 (open).
 	void remove_0_rings();
 
 	/// Removes 0 and 1-rings,
 	/// moves factors multiplying the individual Quark_lines to
 	/// multiply the col_str instead (i.e., being stored in Poly)
-	/// simplifys the Polnomial and normal orders the quark_lines.
+	/// simplifies the Polynomial and normal orders the quark_lines.
 	void simplify();
 
 	/// Function for conjugating the Col_str by conjugating each Quark_line in cs,
 	/// as well as the Polynomial Poly.
 	void conjugate();
 
 	/// Contracts neighboring and next to neighboring gluons in each
 	/// Quark_line in the Col_str, starting with contracting neighbors.
 	/// This function should only be used on Col_strs with only closed Quark_lines.
 	void contract_next_neighboring_gluons( );
 
 	/// Function for contracting gluon indices in closed Quark_lines with only 2 gluons.
-	/// This removes the 2-ring, replaces one of the gluon indices and
-	/// multiplies with a factor tr[t^a t^a]=TR (no sum),
-	/// only intended for closed Quark_lines.
+	/// This removes the 2-ring, replaces one of the gluon indices,,
+	/// and multiplies with a factor tr[t^a t^a]=TR (no sum),
+	/// only intended for fully contractable Col_strs.
 	void contract_2_rings( );
 
 	/// Function for contracting quarks between two color structures Cs1 and Cs2.
 	/// The result is stored in the Col_str itself.
 	void contract_quarks( const Col_str Cs1, const Col_str Cs2 );
 
 
-
 private:
 
 	/// Function to tell which quark_line should stand first in normal order.
 	/// The quark_lines at place i1 and i2 are compared.
 	/// Returns i1 if i1 should stand first, i2 if i2 should stand first
 	/// and i1 if the quark_lines are equal.
 	int compare_quark_lines( int i1, int i2 ) const;
 
 	/// Function to allow setting the color structure by using a string.
 	/// Used by string constructor and by
 	void Col_str_of_str( const std::string str  );
 
 	/// Setting the col_str member cs
 	/// (i.e. the non-Polynomial information) using a string,
 	/// used by Col_str_of_str and read_in_Col_str.
 	void col_str_of_str( std::string );
 
 }; //end class Col_str
 
 
 /// Define the operator == for two col_str's.
 /// The col_str's must have equal length and
 /// all Quark_lines must be the same
 /// (i.e. have same Polynomial and same parton ordering).
 /// The quark_lines are NOT normal ordered before comparison.
 bool operator==(const col_str & cs1, const col_str & cs2);
 
 /// Define the operator != for two col_str's.
-/// Returns fals if cs1==cs2 and false otherwise.
+/// Returns false if cs1==cs2 and false otherwise.
 bool operator!=(const col_str & cs1, const col_str & cs2);
 
 /// Define the operator << for col_str
-std::ostream& operator<<(std::ostream& out, const col_str & cs);
+std::ostream& operator<<( std::ostream& out, const col_str & cs );
 
 /// Define the operator * for Col_str and int.
 Col_str operator*( const Col_str & Cs, const int i );
 
 /// Define the operator * for int and Col_str.
 Col_str operator*( const int i, const Col_str & Cs );
 
 /// Define the operator * for Col_str and double.
 Col_str operator*( const Col_str & Cs, const double d );
 
 /// Define the operator * for double and Col_str.
 Col_str operator*( const double d, const Col_str & Cs );
 
 /// Define the operator * for Col_str and cnum.
 Col_str operator*( const Col_str & Cs, const cnum c);
 
 /// Define the operator * for cnum and Col_str.
 Col_str operator*( const cnum c, const Col_str & Cs );
 
 /// Define the operator * for Col_str and Monomial.
 Col_str operator*( const Col_str & Cs, const Monomial & Mon );
 
 /// Define the operator * for Monomial and Col_str.
 Col_str operator*( const Monomial & Mon, const Col_str & Cs);
 
 /// Define the operator * for Col_str and Polynomial.
 Col_str operator*( const Col_str & Cs, const Polynomial & Poly );
 
 /// Define the operator * for Polynomial and Col_str.
 Col_str operator*( const Polynomial & Poly, const Col_str & Cs );
 
 /// Define the operator * for a Col_str and a Quark_line, adding Ql and multiplying Polynomial info.
 Col_str operator*( const Col_str & Cs, const Quark_line & Ql);
 
 /// Define the operator * for a Quark_line and a Col_str, adding Ql and multiplying Polynomial info.
 Col_str operator*( const Quark_line & Ql, const Col_str & Cs );
 
 /// Define the operator * for two Col_str's, adding Ql and multiplying Polynomial info.
 Col_str operator*( const Col_str & Cs1, const Col_str & Cs2 );
 
+/// Define the operator * for two Quark_lines. Clearly the result cannot be contained in
+/// a Quark_line, but needs (at least) a Col_str.
+Col_str operator*( const Quark_line & Ql1, const Quark_line & Ql2 );
+
 /// Define the operator << for Col_str.
 std::ostream& operator<<(std::ostream& out, const Col_str & Cs);
 
 /// Define the operator == for two Col_str's
 /// the col_strs must be equal, and the
 /// Polynomials must be equal. Note that for Polynomials cf+Nc!=Nc+cf.
 /// Function does NOT first normal order Col_strs.
 bool operator==( const Col_str & Cs1, const Col_str & Cs2 );
 
 /// Define the operator != for two Col_str's, the negation of ==.
 /// Function does NOT first normal order Col_strs.
 bool operator!=( const Col_str & Cs1, const Col_str & Cs2 );
 
 }
 
 #endif /* COLORFULL_Col_str_h */
diff --git a/MatrixElement/Matchbox/ColorFull/Monomial.cc b/MatrixElement/Matchbox/ColorFull/Monomial.cc
--- a/MatrixElement/Matchbox/ColorFull/Monomial.cc
+++ b/MatrixElement/Matchbox/ColorFull/Monomial.cc
@@ -1,522 +1,571 @@
 // -*- C++ -*-
 /*
  * Monomial.cc
  *	Contains definition of the class Monomial and associated types and operators
  *  Created on: Jul 7, 2010
  *  Author: Malin Sjodahl
  */
 #include "Monomial.h"
 #include "parameters.h"
 #include <cassert>
 #include <fstream>
 #include <iostream>
 
 namespace ColorFull {
 
 
 Monomial::Monomial( std::string str ){
 	Monomial_of_str( str );
 }
 
 
 void Monomial::Monomial_of_str( std::string str ) {
 	//std::cout << "Monomial::Monomial: got string \"" << str << "\"" << std::endl;
 
 	// Strings to contain various parts
 	std::string num_str, Nc_pow_str, TR_pow_str, CF_pow_str, int_part_str;
 	// Is it in denominator?
 	bool denominator=0;
 
 	// Start with setting to default
 	pow_TR = pow_Nc = pow_CF = 0;
 	int_part = 1;
 	cnum_part = 1.0;
 
 	// Check that left and right brackets match up
 	int left_brackets=0, right_brackets=0;
 	uint j=0;
 	while (j < str.size()) {
 		if(str.at(j)=='(') left_brackets++;
 		if(str.at(j)==')') right_brackets++;
 		j++;
 	}
 	if(left_brackets != right_brackets){
 		std::cerr << "Monomial::Monomial_of_str: The brackets in the monomial\"" << str <<"\" do not seem to match up. There were "
 				<< left_brackets <<" left bracket(s) and "<< right_brackets << " right bracket(s)." << std::endl;
 		assert( 0 );
 	}
 
 	// Check that only allowed signs
 	j = 0;
 	while (j < str.size()) {
 
 		if (!(str.at(j) == '+' or str.at(j) == '-' or str.at(j) == '.' or str.at(j) == '\n'
 				or str.at(j) == '*' or str.at(j) == '/' or str.at(j) == '^'
 						or str.at(j) == 'T' or str.at(j) == 'R' or str.at(j) == 'N'
 								or str.at(j) == 'c' or str.at(j) == 'C' or str.at(j) == 'F'
 										or str.at(j) == '('
 												or str.at(j) == ')' or str.at(j) == ' ' or str.at(j) == '0'
 														or str.at(j) == '1' or str.at(j) == '2' or str.at(j) == '3'
 																or str.at(j) == '4' or str.at(j) == '5' or str.at(j) == '6'
 																		or str.at(j) == '7' or str.at(j) == '8' or str.at(j) == '9')) {
 			std::cerr
 			<< "Monomial::Monomial_of_str: A disallowed sign encountered in string for Monomial constructor: "
 			<< str.at(j) << std::endl;
 			assert( 0 );
 
 		}
 
 		num_str.push_back( str.at(j) );
 		j++;
 	}
 
 	// Read the string, starting from 0th element
 	uint i = 0;
 
 	// We may have to skip some chars containing spaces
 	while (i < str.size() && (str.at(i) == ' ' or str.at(i) == '\n'  or str.at(i) == '*' or str.at(i) == '(' or str.at(i) == ')')) i++;
 	// Check plus or minus
 	if (i < str.size() and str.at(i) == '+') {
 		i++;
 	}
 	// Pick up the sign
 	if (i < str.size()  and str.at(i) == '-' ) {
 		int_part = int_part * (-1);
 		i++;
 	}
 
 	while (i < str.size()) {
 
 		// Clear strings as we may loop around many times
 		num_str.clear();
 		Nc_pow_str.clear();
 		TR_pow_str.clear();
-
+		CF_pow_str.clear();
 
 		// We may have to skip some chars containing spaces and *
 		while (i < str.size() && (str.at(i) == ' ' or str.at(i) == '\n' or str.at(i) == '*' or str.at(i) == '(' or str.at(i) == ')')) i++;
 
 		// look for denominator "/"
 		if(i< str.size() and  str.at(i) == '/') {
 
 			if (denominator) {
 				std::cerr << "Monomial::Monomial_of_str: Can only handle one / "
 						<< "but got " << str;
 				assert( 0 );
 			};
 			denominator=true;
 			i++;
 		}
 
 		// If a number is encountered which is not *-1 or *(-1)
 		while (i< str.size() and ( str.at(i) == '.' or str.at(i) == '0' or str.at(i) == '1'
 				or str.at(i) == '2' or str.at(i) == '3' or str.at(i) == '4'
 						or str.at(i) == '5' or str.at(i) == '6' or str.at(i) == '7'
 								or str.at(i) == '8' or str.at(i) == '9')  ) {
 			num_str.push_back(str.at(i));
 			i++;
 		}
 
 		// If the num_str contains something, save
 		if (!num_str.empty()) {
 			double num_fac=1.0;
 
 			// Make a number of the string
 			std::istringstream num_str_st(num_str);
 			// Set the num member variable
 			num_str_st >> num_fac;
 
 			if(denominator) cnum_part=cnum_part/num_fac;
 			else { // factor is in numerator, try to put in int-part if it looks like an int
 				int num_fac_int=static_cast<int>(floor(num_fac + 0.50));
 				if( std::abs(num_fac_int-num_fac) < accuracy )
 					int_part= int_part*num_fac_int;
 				else // put factor in numeric part
 					cnum_part=cnum_part*num_fac;
 			}
 		}
 
 		// If TR is encountered (T should always be followed by R)
 		if (i< str.size() and (str.at(i) == 'T' and (i==str.size()-1  or str.at(i + 1) != 'R')) ){
 			std::cerr << "Monomial::Monomial_of_str: Got a string containing T, but T was not followed by R (as in TR). " << std::endl;
 			assert( 0 );
 		}
 		if (i< str.size() and (str.at(i) == 'T' and str.at(i + 1) == 'R') ) {
 			i++;
 			i++;
 			// If there is no ^, the power of TR is 1
 			int pow_cont=1;
 
 			// If ^, start reading in power of TR
 			if (i < str.size() and str.at(i) == '^') {
 				i++;
 
 				// If we have something in a bracket
 				if(i < str.size() and  str.at(i)=='('){
 					i++;
 					// keep reading until end-bracket
 					while(i < str.size() and str.at(i)!=')'){
 						TR_pow_str.push_back(str.at(i));
 						i++;
 					}
 					// Skip the )
 					if(i < str.size() and  str.at(i)==')') i++;
 				}
 				// otherwise, as long as we have numbers
 				else while (i< str.size() and (str.at(i) == '0' or str.at(i) == '1' or str.at(i) == '2'
 						or str.at(i) == '3' or str.at(i) == '4'
 								or str.at(i) == '5' or str.at(i) == '6'
 										or str.at(i) == '7' or str.at(i) == '8'
 												or str.at(i) == '9' or str.at(i) == '-')) {
 					TR_pow_str.push_back(str.at(i));
 					i++;
 				}
 				// Make a number of the string
 				std::istringstream TR_pow_str_st(TR_pow_str);
 				// Set the TR_pow member variable
 				TR_pow_str_st >> pow_cont;
 			}
 
 			if(denominator) pow_cont=-pow_cont;
 			pow_TR=pow_TR + pow_cont;
 
 		}
 
 		// If Nc is encountered
 		if (i < str.size() and (str.at(i) == 'N')) {
 			if( i+1< str.size() and str.at(i + 1) == 'c') i++; // get to c
 			else{// allow only Nc
-				std::cerr << "Monomial::Monomial_of_str: got a string containing N, but N was not followed by c (as in Nc). " << std::endl;
+				std::cerr << "Monomial::Monomial_of_str: got a string containing N, " << str <<", but N was not followed by c (as in Nc). " << std::endl;
 				assert( 0 );
 			}
 			i++; // get to next sign
 
 			int Nc_pow = 1;
 			//if(i < str.size())  std::cout << "Monomial::Monomial: " <<  str.at(i) << endl;
 			// If ^, start reading in power of Nc
 			if (i< str.size() and str.at(i) == '^') {
 				i++; // compensate for ^
 
 				// If we have something in a bracket
 				if(i < str.size() and  str.at(i)=='('){
 					i++;
 					// keep reading until end-bracket
 					while(i < str.size() and  str.at(i)!=')'){
 						Nc_pow_str.push_back(str.at(i));
 						i++;
 					}
 					// Skip the )
 					if(i < str.size() and str.at(i)==')') i++;
 				}
 				// as long as we have numbers or -
 				else while (i< str.size() and  (str.at(i) == '0' or str.at(i) == '1' or str.at(i) == '2'
 						or str.at(i) == '3' or str.at(i) == '4'
 								or str.at(i) == '5' or str.at(i) == '6'
 										or str.at(i) == '7' or str.at(i) == '8'
 												or str.at(i) == '9' or str.at(i) == '-')){
 					Nc_pow_str.push_back(str.at(i));
 					i++;
 				}
 				// Make a number of the string
 				std::istringstream Nc_pow_str_st(Nc_pow_str);
 				Nc_pow_str_st >>  Nc_pow ;
 			}
 			if (denominator) pow_Nc=pow_Nc-Nc_pow;
 			else pow_Nc=pow_Nc + Nc_pow;
 		}
 
 		// If CF is encountered
 		if (i < str.size() and (str.at(i) == 'C')) {
 			std::cout.flush();
 			if( i+1< str.size() and str.at(i + 1) == 'F') i++; // get to f
 			i++; // get to next sign
 
 			int CF_pow = 1;
 			std::cout.flush();
 			// If ^, start reading in power of CF
 			if (i< str.size() and str.at(i) == '^') {
 				i++; // compensate for ^
 
 				// If we have something in a bracket
 				if(i < str.size() and  str.at(i)=='('){
 					i++; // Skip the (
 					// keep reading until end-bracket
 					while(i < str.size() and  str.at(i)!=')'){
 						CF_pow_str.push_back(str.at(i));
 						i++;
 					}
 					// Here we may need to skip some spaces as well
 					if(i < str.size() and str.at(i)==' ') i++;
 					// Skip the )
 					if(i < str.size() and str.at(i)==')') i++;
 				}
 				// as long as we have numbers
 				else while (i< str.size() and  (str.at(i) == '0' or str.at(i) == '1' or str.at(i) == '2'
 						or str.at(i) == '3' or str.at(i) == '4'
 								or str.at(i) == '5' or str.at(i) == '6'
 										or str.at(i) == '7' or str.at(i) == '8'
 												or str.at(i) == '9' or str.at(i) == '-')){
 					CF_pow_str.push_back(str.at(i));
 					i++;
 				}
 				// Make a number of the string
 				std::istringstream CF_pow_str_st(CF_pow_str);
 				CF_pow_str_st >>  CF_pow ;
 			}
 			if (denominator) pow_CF=pow_CF-CF_pow;
 			else pow_CF=pow_CF+ CF_pow;
 		}
 
 		// If *-1
 		if ((i < str.size() and str.at(i) == '-') and  ( (i-1>0) and str.at(i-1)=='*')  ) {
 			i++; //skip the -
 			std::cout.flush();
 
 			// Keep reading in while numbers
 			while (i< str.size() and  (str.at(i) == '0' or str.at(i) == '1' or str.at(i) == '2'
 					or str.at(i) == '3' or str.at(i) == '4'
 							or str.at(i) == '5' or str.at(i) == '6'
 									or str.at(i) == '7' or str.at(i) == '8'
 											or str.at(i) == '9')){
 				int_part_str.push_back(str.at(i));
 				i++;
 			}
 			int n_fac=1;
 			std::istringstream n_str(int_part_str);
 			n_str >> n_fac;
 			int_part=int_part * n_fac*(-1);
 		}
 		// If *(-1)
 		if ((i < str.size() and str.at(i) == '-') and (  ( ( (i-2> 0) and str.at(i-1)=='(') and  str.at(i-2)=='*') )) {
 			i++; //skip the -
 			i++; //skip the (
 			std::cout.flush();
 
 			// Keep reading in while numbers
 			while (i< str.size() and  (str.at(i) == '0' or str.at(i) == '1' or str.at(i) == '2'
 					or str.at(i) == '3' or str.at(i) == '4'
 							or str.at(i) == '5' or str.at(i) == '6'
 									or str.at(i) == '7' or str.at(i) == '8'
 											or str.at(i) == '9')){
 				int_part_str.push_back(str.at(i));
 				i++;
 			}
 			int n_fac=1;
 			std::istringstream n_str(int_part_str);
 			n_str >> n_fac;
 			int_part=int_part * n_fac*(-1);
 			// Skip potential white spaces
 			while (i< str.size() and  str.at(i) == ' ') i++;
 			// Make sure we have a closing )
 			if(str.at(i)==')') i++;
 			else {
 				std::cerr << "Monomial::Monomial_of_str: Expects final ) in *(number)"
 						<< " got " << str.at(i) << std::endl;
 				assert( 0 );
 			}
 		}
 
 		// We may have to skip some spaces
 		while (i < str.size() && str.at(i) == ' ') {i++;}
 		std::cout.flush();
 
 	}
 }// end Monomial_of_str
 
 
 void Monomial::read_in_Monomial( std::string filename ) {
 
 	// Read in file
 	std::ifstream fin( filename.c_str() );
 
 	// Check that file exists
 	if( !fin ){
 		std::cerr << "Monomial::read_in_Monomial: The file "
 				<< filename << " could not be opened." << std::endl;
 		assert( 0 );
 	}
 
 	// Copy info from file to string
 	std::string str((std::istreambuf_iterator<char>(fin)), std::istreambuf_iterator<char>());
-	str.erase(str.size()-1);
+
+	// Skip lines starting with #
+	while( str.at(0)== '#' ){
+		while (str.at(0) != '\n'){
+			str.erase(str.begin());
+		}
+		// erase endl sign(s)
+		while(str.at(0)== '\n'){
+			str.erase(str.begin());
+		}
+	}
+
+	// Remove endl chars at the end of the file
+	while( str.at(str.size()-1) == '\n' ) str.erase(str.size()-1);
 	Monomial_of_str( str );
 }
 
 
+void Monomial::write_out_Monomial( std::string filename ) const {
+
+	std::ofstream outfile(filename.c_str());
+
+	if ( !outfile )
+	std::cerr << "Monomial::write_out_Monomial: Cannot write out Monomial as the file \""
+		<< filename.c_str() << "\" could not be opened. (Does the directory exist? Consider creating the directory.)" << std::endl;
+
+	outfile << *this;
+}
+
 std::ostream& operator<<( std::ostream& out, const Monomial & Mon ){
 
 	// If multiplied by 0, the whole Monomial is 0
 	if (Mon.int_part == 0 ) out << "0";
 	else{
 		// If real, print only real part
 		if( imag( Mon.cnum_part )==0 ) {
 			// If both int and numeric parts are 1, print 1
 			if( Mon.int_part==1 && Mon.cnum_part.real() ==1 ) out << "1";
 			// If int part is 1, print numeric part if >0 (minus signs gives problems)
 			else if( Mon.int_part==1 && Mon.cnum_part.real() > 1 ) out << Mon.cnum_part.real();
 			// If numeric part is 1, print int part if >0 (minus signs gives problems)
 			else if( Mon.int_part > 1 && Mon.cnum_part.real() ==1 ) out << Mon.int_part;
 			else out << real( Mon.cnum_part ) << "*" << Mon.int_part;
 		}
 		// else print full complex number
 		else out << Mon.cnum_part  << "*" << Mon.int_part;
 
 		if( Mon.pow_TR !=0 ) {
 			if( Mon.pow_TR ==1 ) out << " TR";
 			else out << " TR^" <<"(" << Mon.pow_TR <<")";
 		}
 		if( Mon.pow_Nc !=0 ){
 			if( Mon.pow_Nc ==1 ) out << " Nc";
 			else out <<" Nc^" << "(" << Mon.pow_Nc <<")";
 		}
 		if( Mon.pow_CF !=0 ) {
 			if( Mon.pow_CF ==1 ) out << " CF";
 			else out << " CF^" << "(" << Mon.pow_CF <<")";
 		}
 	}
 	return out;
 }
 
 
 Monomial operator*( const Monomial & Mon, const int i ){
 	Monomial out_Mon(Mon);
 	out_Mon.int_part=out_Mon.int_part*i;
 	return out_Mon;
 }
 
 
 Monomial operator*( const int i, const Monomial & Mon){
 	return Mon*i;
 }
 
+Monomial operator*=( Monomial & Mon, const int i ){
+	return Mon.int_part*=i;
+}
 
-Monomial operator*(const Monomial & Mon, const cnum c){
+
+Monomial operator*( const Monomial & Mon, const cnum c ){
 	Monomial out_Mon(Mon);
 	out_Mon.cnum_part=out_Mon.cnum_part*c;
 	return out_Mon;
 }
 
 
-Monomial operator*(const cnum c, const Monomial & Mon){
+Monomial operator*( const cnum c, const Monomial & Mon ){
   return Mon*c;
 }
 
+Monomial operator*=( Monomial & Mon, const cnum c ){
+	Mon.cnum_part*=c;
+	return Mon;
+}
 
 Monomial operator*(const Monomial & Mon, const double d){
 		Monomial out_Mon(Mon);
 		out_Mon.cnum_part=out_Mon.cnum_part*d;
 		return out_Mon;
 }
 
-
 Monomial operator*(const double d, const Monomial & Mon){
 	return Mon*d;
 }
 
+Monomial operator*=( Monomial & Mon, const double d ){
+	Mon.cnum_part*=d;
+	return Mon;
+}
 
 Monomial operator*(const Monomial & Mon1, const Monomial & Mon2){
   Monomial Mon_out;
 
-  // Adding powers to get total power of 2, N and CF
+  // Adding powers to get total power of TR, Nc and CF
   Mon_out.pow_TR = Mon1.pow_TR + Mon2.pow_TR;
   Mon_out.pow_Nc = Mon1.pow_Nc + Mon2.pow_Nc;
   Mon_out.pow_CF = Mon1.pow_CF + Mon2.pow_CF;
 
   // Multiplying factors
   Mon_out.int_part=Mon1.int_part * Mon2.int_part;
   Mon_out.cnum_part=Mon1.cnum_part * Mon2.cnum_part;
   return Mon_out;
 }
 
+Monomial operator*=( Monomial & Mon1, const Monomial & Mon2){
+
+  // Adding powers to get total power of TR, Nc and CF
+  Mon1.pow_TR += Mon2.pow_TR;
+  Mon1.pow_Nc += Mon2.pow_Nc;
+  Mon1.pow_CF += Mon2.pow_CF;
+
+  // Multiplying factors
+  Mon1.int_part *= Mon2.int_part;
+  Mon1.cnum_part *= Mon2.cnum_part;
+  return Mon1;
+}
+
+
 bool operator==(const Monomial & Mon1 , const Monomial & Mon2){
 
   // If both are 0
   if(Mon1.int_part == 0  && Mon2.int_part == 0) return true;
 
   // all factors should be same in order for Monomial's to be same
   if(Mon1.pow_TR != Mon2.pow_TR ) return false;
   if(Mon1.pow_Nc != Mon2.pow_Nc ) return false;
   if(Mon1.pow_CF != Mon2.pow_CF ) return false;
   if(Mon1.int_part != Mon2.int_part ) return false;
 
   // For comparing numerical part use an accuracy, as numbers may be small, compare ratio
   const double r1 = real(Mon1.cnum_part);
   const double r2 = real(Mon2.cnum_part);
   const double i1 = imag(Mon1.cnum_part);
   const double i2 = imag(Mon2.cnum_part);
 
   if( r2 != 0 and i2 != 0 ) {
     if( r1/r2  < (1-accuracy) or r1/r2  > (1+accuracy) ) return false;
     if( i1/i2  < (1-accuracy) or i1/i2  > (1+accuracy) ) return false;
   }
   else if( r2 == 0 and i2 != 0 )  { 
     if( r1 != 0 ) return false;
     if( i1/i2  < (1-accuracy) or i1/i2  > (1+accuracy) ) return false;
   }
   else if ( r2 != 0 and i2 == 0 ) { 
     if( r1/r2  < (1-accuracy) or r1/r2  > (1+accuracy) ) return false;
     if( i1 != 0 ) return false;
   }
   else { // both r2,i2 are zero
     if( r1 != 0 ) return false;
     if( i1 != 0 ) return false;
   }
 
   return true;
 }
 
 
 bool operator!=(const Monomial & Mon1 , const Monomial & Mon2){
   if( Mon1==Mon2) return false;
   else return true;
 }
 
 
 bool operator<(const Monomial & Mon1, const Monomial & Mon2) {
 
 	// If different Nc+CF power
 	if (Mon1.pow_Nc + Mon1.pow_CF < Mon2.pow_Nc + Mon2.pow_CF)
 		return true;
 	else if (Mon1.pow_Nc + Mon1.pow_CF > Mon2.pow_Nc + Mon2.pow_CF)
 		return false;
 	else {	  // same total Nc power
 		// if different powers of N
 		if (Mon1.pow_Nc < Mon2.pow_Nc)
 			return true;
 		else if (Mon1.pow_Nc > Mon2.pow_Nc)
 			return false;
 		else { // same pow_Nc+pow_CF and same pow_Nc
 			// order according to cnum_part*int_part
 			if ( (Mon1.int_part)*(abs(Mon1.cnum_part)) < (Mon2.int_part)*(abs(Mon2.cnum_part)))
 				return true;
 			else if ( (Mon1.int_part)*(abs(Mon1.cnum_part)) > (Mon2.int_part)*(abs(Mon2.cnum_part)))
 				return false;
 			else { // same pow_Nc+pow_CF and same pow_Nc, and same numerical cnum_part*int_part
 				// order according to int_part
 				if (Mon1.int_part < Mon2.int_part)
 					return true;
 				else if (Mon1.int_part < Mon2.int_part)
 					return false;
 				else {// same pow_Nc+pow_CF and same pow_Nc, and same numerical cnum_part*int_part, and same int_part
 					// order according to pow_TR
 					if (Mon1.pow_TR < Mon2.pow_TR)
 						return true;
 					else if (Mon1.pow_TR < Mon2.pow_TR)
 						return false;
 					else { // The Monomials are equal
 						return false;
 					}
 				}
 			}
 		}
 
 	}
 	std::cerr << "Monomial::operator<: Could not decide on Monomial ordering of "
 			<< Mon1 << " and " << Mon2 << ". This should not happen, report bug."
 			<< std::endl;
 	assert( 0 );
 	return false;
 
 }
 
 } // end namespace ColorFull
diff --git a/MatrixElement/Matchbox/ColorFull/Monomial.h b/MatrixElement/Matchbox/ColorFull/Monomial.h
--- a/MatrixElement/Matchbox/ColorFull/Monomial.h
+++ b/MatrixElement/Matchbox/ColorFull/Monomial.h
@@ -1,161 +1,185 @@
 // -*- C++ -*-
 /*
  * Monomial.h
  *	Contains declaration of the class Monomial and associated types and operators
  *  Created on: Jul 7, 2010
  *  Author: Malin Sjodahl
  */
 
 #ifndef COLORFULL_Monomial_h
 #define COLORFULL_Monomial_h
 
 #include "types.h"
 
 
 namespace ColorFull {
 
 
 /// A class to contain the factor of form TR^a*Nc^b*CF^c*int_part*cnum_part,
 /// where the powers a, b and c may be negative.
 /// A default Monomial is defined to be 1, and has int_part and cnum_part=1.
 /// A 0-Monomial has int_part=0.
 /// A polynomial is a sum of Monomials.
 class Monomial {
 public:
 
-	/// Default constructor sets int_part and cnum_part=1, and Pow_Nc=pow_TR=pow_CF=0.
+	/// Default constructor sets int_part=cnum_part=1, and pow_Nc=pow_TR=pow_CF=0.
 	Monomial(){
 		pow_TR=pow_Nc=pow_CF=0;
 		int_part=1;
 		cnum_part=1.0;
 	}
 
 	/// Constructor using a double.
 	/// The cnum_part member is set to contain the value.
 	Monomial( double dnum ){
 	    pow_TR=pow_Nc=pow_CF=0;
 	    int_part=1;
 		cnum_part.real(dnum);
 	}
 
 	/// Constructor using an int.
 	/// The int_part member is set to contain the value.
 	Monomial( int num ){
 	    pow_TR=pow_Nc=pow_CF=0;
 	    int_part=num;
 	    cnum_part=1.0;
 	}
 
 	/// Constructor taking a string as argument.
-	/// The argument should be of the form given in form (for example)
+	/// The argument should be of the form in for example
 	/// -(20*TR^5)/Nc or -20 TR^(5)/Nc or 20 / TR^(-5)Nc^(1) CF^(3).
 	/// NOTE: All spaces and * are ignored, except in  "*(-1)" and *-1, which
 	/// is understood as (*-1).
 	/// EVERYTHING standing after / is
 	/// divided with, whereas everything standing before is multiplied with.
 	/// Parentheses are ignored unless they appear in powers,
-	/// i.e, directly after ^.
+	/// i.e., directly after ^.
 	/// No spaces are allowed inside the powers.
 	/// If the string contains no info or is empty the Monomial is put to 1,
 	/// pow_TR = pow_Nc = pow_CF = 0, int_part = 1, cnum_part = 1.0.
 	/// (Expanded Mathematica 8 expressions are in this form.)
 	Monomial( std::string str );
 
 	/// Power of TR in Monomial.
 	int pow_TR;
 
 	/// Power of the number of colors.
 	int pow_Nc;
 
-	/// Power of CF=TR (Nc^2-1)/(Nc)
+	/// Power of CF=TR (Nc^2-1)/Nc.
 	int pow_CF;
 
-	/// Integer multiplying monomial, can be 0.
+	/// Integer multiplying the monomial, can be 0.
 	int int_part;
 
-	/// Complex number multiplying monomial.
+	/// Complex number multiplying the monomial.
 	cnum cnum_part;
 
 	/// Take the complex conjugate.
 	/// Note that this changes the Monomial itself.
 	void conjugate() {
 		cnum_part=conj( cnum_part );
 	}
 
 	/// Function for reading in the Monomial from the file filename,
 	/// uses Monomial_of_str.
 	void read_in_Monomial( std::string filename );
 
 
+	/// Function for writing out the Monomial to a file
+	/// with name filename.
+	void write_out_Monomial( std::string filename ) const;
+
+
 private:
 
 	/// Function for makinga a Monomial from a string.
 	/// The argument should be of the form given in form (for example)
 	/// -(20*TR^5)/Nc or -20 TR^(5)/Nc or 20 / TR^(-5)Nc^(1) CF^3.
 	/// NOTE: All spaces and * are ignored, except in  "*(-1)" and *-1, which
 	/// is understood as (*-1).
 	/// EVERYTHING standing after / is
 	/// divided with, whereas everything standing before is multiplied with.
 	/// Parentheses are ignored unless they appear in powers,
 	/// i.e, directly after ^.
 	/// No spaces are allowed inside the powers.
-	/// If the string contains no info or is empty the Monomial is put to 1,
+	/// If the string contains no information or is empty, the Monomial is set to 1,
 	/// pow_TR = pow_Nc = pow_CF = 0, int_part = 1, cnum_part = 1.0.
 	void Monomial_of_str( std::string str );
 
 
 };
 
 
 /// Define the operator << for Monomial
 std::ostream& operator<<( std::ostream& out, const Monomial & Mon );
 
 /// Operator * for Monomial and int.
 /// The int_part member is multiplied by i, whereas other
 /// members are kept constant.
 Monomial operator*( const Monomial & Mon,  const int i );
 
 /// Operator * for int and Monomial.
 /// Returns Mon*i.
 Monomial operator*( const int i, const Monomial & Mon );
 
 /// Operator * for Monomial and cnum. The member Mon.cnum_part
 /// is multiplied by c, whereas other members are kept
 /// the same.
 Monomial operator*( const Monomial & Mon, const cnum c );
 
 /// Operator * for cnum and Monomial, returns Mon*c.
 Monomial operator*( const cnum c, const Monomial & Mon );
 
 /// Operator * for Monomial and double. The member Mon.cnum_part
 /// is multiplied by c, whereas other members are kept
 /// the same.
 Monomial operator*( const Monomial & Mon, const double d );
 
 /// Operator * for double and Monomial, returns Mon*d.
 Monomial operator*( const double d, const Monomial & Mon );
 
 /// Operator * for Monomials. The powers, pow_TR, pow_Nc
 /// and pow_CF are added, and the numbers int_part and mon
 /// are multiplied.
 Monomial operator*( const Monomial & Mon1, const Monomial & Mon2 );
 
+/// Operator *= for Monomial and int.
+/// The int_part member is multiplied by i, whereas other
+/// members are kept constant.
+Monomial operator*=( Monomial & Mon,  const int i );
+
+/// Operator *= for Monomial and cnum.
+/// The cnum_part member is multiplied by c, whereas other
+/// members are kept constant.
+Monomial operator*=( Monomial & Mon, const cnum c );
+
+/// Operator *= for Monomial and double.
+/// The cnum_part member is multiplied by d, whereas other
+/// members are kept constant.
+Monomial operator*=( Monomial & Mon, const double d );
+
+/// Operator *= for Monomials. Mon1 is changed by being multipled with
+/// Mon2.
+Monomial operator*=( Monomial & Mon1, const Monomial & Mon2);
+
 /// Operator == for Monomials, all parts must be equal.
 /// For the numerical part, an accuracy is used for the ratio.
 bool operator==( const Monomial & Mon1, const Monomial & Mon2 );
 
 /// Define the operator != Monomial. Returns false if Mon1==Mon2,
 /// and true otherwise.
 bool operator!=( const Monomial & Mon1, const Monomial & Mon2 );
 
 /// Operator to find the "smallest" of two Monomials.
 /// The Monomials are ordered first according to pow_Nc+pow_CF,
 /// then according to pow_Nc (for same pow_Nc+pow_CF)
 /// then according to int_part*abs(cnum_part), then according to int_part, and finally according to pow_TR.
 /// NOTE: this ordering does not agree with ordering according to numerical value.
 /// NOTE: If the Monomials are equal, Mon1 is not smaller so false will be returned.
 bool operator<( const Monomial & Mon1, const Monomial & Mon2 );
 
 }
 
 #endif /* COLORFULL_Monomial_h */
diff --git a/MatrixElement/Matchbox/ColorFull/Orthogonal_basis.cc b/MatrixElement/Matchbox/ColorFull/Orthogonal_basis.cc
--- a/MatrixElement/Matchbox/ColorFull/Orthogonal_basis.cc
+++ b/MatrixElement/Matchbox/ColorFull/Orthogonal_basis.cc
@@ -1,500 +1,500 @@
 /*
  * Orthogonal_basis.cc
  * Contains the definitions of the class Orthogonal_basis, related types and operators.
  *  Created on: May 25, 2013
  *      Author: Malin Sjodahl
  */
 
 #include "Orthogonal_basis.h"
 #include "parameters.h"
 #include <cassert>
 #include <fstream>
 #include <iostream>
 
 
 namespace ColorFull {
 
 
 void Orthogonal_basis::scalar_product_matrix(){
 	if( ng+nq>5 ){
 		std::cout << "Orthogonal_basis::scalar_product_matrix: nq+n_g0=" << nq+ng << " is large, consider using numerical and/or memory version.  "  << std::endl;
 		std::cout.flush();
 	}
 	return scalar_product_matrix( true, true, false );
 }
 
 
 void Orthogonal_basis::diagonal_scalar_product_matrix( bool save_P_diagonal_spm, bool save_d_diagonal_spm, bool use_mem ){
 
 	// If the diagonal_P_spm and diagonal_d_spm have already been calculated, erase them
 	diagonal_P_spm.clear();
 	diagonal_d_spm.clear();
 
 	if(  (cb.size()==0 ) ) {
 		std::cout << "Orthogonal_basis::diagonal_scalar_product_matrix: There are no basis vectors in this basis, consider using read_in_basis." << std::endl;
 		std::cout.flush();
 		return ;
 	}
 
 
 	// Check that all Polynomials are real
 	// (check doesn't cover the case of complex Polynomial in a Quark_line)
 	// but if an entry is not real this will be discovered as the d_spm is calculated
 	for ( uint cbi=0; cbi < cb.size(); cbi++){
 		for ( uint j=0; j< cb.at(cbi).size(); j++){
 			if( imag (Col_fun.cnum_num(  cb.at(cbi).at(j).Poly  )) > accuracy ){
 				std::cerr << "Orthogonal_basis::diagonal_scalar_product_matrix: ColorFull expects real Polynomial multiplying the color structure, but the Polynomial\n"
 						<< cb.at(cbi).at(j).Poly  << std::endl
 						<< " appearing in front of the Col_str " << cb.at(cbi).at(j).cs
 						<< " in basis vector number " << cbi << " is not real."<< std::endl << std::endl;
 				std::cerr.flush();
 				assert( 0 );
 			}
 		}
 	}
 
 	// For remembering already calculated topologies
 	std::map<std::string, std::shared_ptr<Polynomial> > mem_map;
 
 	// Loop over basis vectors in Basis
 	for( uint i=0; i < cb.size(); i++){
 
 		// To contain the result of vector i square
 		Polynomial iiRes;
 		iiRes=iiRes*0;
 
 		if(use_mem){
 
 			// Loop over Col_strs in first Ca
 			for( uint Ca1i=0; Ca1i< cb.at(i).size(); Ca1i++){
 
 				// Loop over Col_strs in second Ca
 				for( uint Ca2i=0; Ca2i< cb.at(i).size(); Ca2i++){
 
 					// To contain the contribution to the ii-th entry if memoization is used
 					std::shared_ptr<Polynomial> iiEntry_contr;
 
 					// Rename indices, and make string of new col_strs, to use in map
 					// strip off Polynomial information to make the map minimal
 					Col_str Cs1, Cs2;
 					Cs1.append(cb.at(i).at(Ca1i).cs);
 					Cs2.append(cb.at(i).at(Ca2i).cs);
 
 					rename_indices( Cs1, Cs2 );
 
 					std::ostringstream Cs_string;
 					Cs_string << Cs1 << Cs2;
 
 					// Calculate element contribution to the ijth element in scalar product matrix
 					// If this has scalar product has occurred before, reuse old value
 					if (mem_map.count( Cs_string.str() ) > 0) {
 						iiEntry_contr = mem_map[Cs_string.str()];
 					}
 					// Otherwise, calculate value and save topology
 					else {
 						Polynomial p = Col_fun.scalar_product(Cs1, Cs2);
-						iiEntry_contr = shared_ptr<Polynomial> (new Polynomial(p));
+						iiEntry_contr = std::shared_ptr<Polynomial> (new Polynomial(p));
 						mem_map[Cs_string.str()] = iiEntry_contr;
 
 					}
 
 					// Sum up all the contributions to one Polynomial, recall to multiply with Polynomials
 					Polynomial iiEntry_contr_poly=(*iiEntry_contr)* cb.at(i).at(Ca1i).Poly*cb.at(i).at(Ca2i).Poly;
 
 
 					if( !save_P_diagonal_spm ) {
 						double iiEntry_contr_d= Col_fun. double_num( iiEntry_contr_poly );
 						Monomial Mon( iiEntry_contr_d );
 						iiRes+= Mon;
 					}
 					else iiRes += iiEntry_contr_poly;
 
 
 				} // end looping over Cs in first Ca
 			} // end looping over Cs in 2nd Ca
 			// If Polynomial result is wanted, simplify
 			if ( save_P_diagonal_spm ) iiRes.simplify();
 
 			// Otherwise convert to numerical
 			else {
 				double num_iiRes= Col_fun. double_num( iiRes );
 				iiRes.clear();
 				Monomial Mon( num_iiRes );
-				iiRes.push_back(Mon);
+				iiRes.append(Mon);
 			}
 
-			diagonal_P_spm.push_back( iiRes );
+			diagonal_P_spm.append( iiRes );
 
 		} // end if ( use_mem )
 		else{
 			// Calculate element ij in scalar product matrix
 			Polynomial iiRes=Col_fun.scalar_product(cb.at(i), cb.at(i));
 
 			iiRes.simplify();
-			diagonal_P_spm.push_back( iiRes );
+			diagonal_P_spm.append( iiRes );
 
 		} //end if (not mem)
 
 	}// end looping over i
 
 	if ( save_d_diagonal_spm ){
 		diagonal_d_spm=Col_fun.double_num(diagonal_P_spm);
 	}
 
 	if (! save_P_diagonal_spm){
 		diagonal_P_spm.clear();
 	}
 
 	return;
 }
 
 
 void Orthogonal_basis::scalar_product_matrix( bool save_P_spm, bool save_d_spm, bool use_mem ) {
 
 	// If the P_spm and d_spm have already been calculated, erase them
 	P_spm.clear();
 	d_spm.clear();
 
 	// First calculate diagonal version
 	diagonal_scalar_product_matrix( save_P_spm, save_d_spm, use_mem );
 
 	// Then copy content to matrix
 	if( save_P_spm  ){
 		// First empty P_spm
 		P_spm.clear();
 
 		Polynomial Zero;
-		Zero=0*Zero;
+		Zero*=0;
 		for (uint i=0; i< diagonal_P_spm.size(); i++ ){
 			Poly_vec rowi;
 			for (uint j=0; j< diagonal_P_spm.size(); j++ ){
 				if(i==j){// diagonal entries
-					rowi.push_back( diagonal_P_spm.at(i));
+					rowi.append( diagonal_P_spm.at(i));
 				}
 				else{// non-diagonal parts
-					rowi.push_back(Zero);
+					rowi.append(Zero);
 				}
 			}
-			P_spm.push_back(rowi);
+			P_spm.append(rowi);
 
 		}
 	}
 	if( save_d_spm  ){
 		// First empty P_spm
 		d_spm.clear();
 		for (uint i=0; i< diagonal_d_spm.size(); i++ ){
 			dvec rowi;
 			for (uint j=0; j< diagonal_d_spm.size(); j++ ){
 				if(i==j){// diagonal entries
 					rowi.push_back( diagonal_d_spm.at(i));
 				}
 				else{// non-diagonal parts
 					rowi.push_back( 0 );
 				}
 			}
 			d_spm.push_back(rowi);
 		}
 	}
 
 }
 
 
 Poly_vec Orthogonal_basis::decompose( const Col_amp & Ca ) {
 
 	// Check that we have a basis
 	if(cb.size()==0){
 		std::cerr << "Orthogonal_basis::decompose: The basis vector cb is empty consider reading in basis." << std::endl;
 		assert( 0 );
 	}
 
 	// Check that quark and gluon content agree with that in Col_amp
 	else if(Ca.size()>0 ){
 		if(Ca.at(0).n_quark() != nq)
 		{
 			std::cerr << "Orthogonal_basis::decompose: The number of quarks in the argument Col_amp, " <<  Ca.at(0).n_quark()
 					<< ", does not fit the number of quarks in the basis "
 					<< nq << std::endl;}
 		if(Ca.at(0).n_gluon() != ng )
 		{
 			std::cerr << "Orthogonal_basis::decompose: The number of gluons in the argument Col_amp " << Ca.at(0).n_gluon()
 						<< " does not fit the number of gluons in the basis "
 						<< nq << std::endl;
 		}
 
 	}
 
 	// This version of decompose (as opposed to trace type versions)
 	// need scalar product matrix
 	// If P_spm is not empty, but has wrong size
 	if(  P_spm.size() != cb.size() and  !P_spm.empty()  ){
 		std::cerr << "Orthogonal_basis::decompose: The size of the scalar product matrix and the basis do not agree." << std::endl;
 	assert( 0 );
 	}
 	// If diagonal_P_spm is not empty, but has wrong size
 	if( diagonal_P_spm.size() != cb.size() and !diagonal_P_spm.empty() ){
 		std::cerr << "Orthogonal_basis::decompose: The size of the diagonal scalar product matrix and the basis do not agree." << std::endl;
 	assert( 0 );
 	}
 	// If both are empty, calculate diagonal version
 	if( P_spm.empty() and diagonal_P_spm.empty() ){
 		diagonal_scalar_product_matrix(true, true, true);
 	}
 
 	// Use matrix information if diagonal spm is empty
 	if( diagonal_P_spm.empty() ){
 		for ( uint i=0; i< P_spm.size(); i++ ){
-			diagonal_P_spm.push_back( P_spm.at(i).at(i) );
+			diagonal_P_spm.append( P_spm.at(i).at(i) );
 		}
 		diagonal_d_spm=Col_fun.double_num(diagonal_P_spm);
 	}
 
 	// To contain the decomposed vector
 	Poly_vec Decv;
 
 	// Loop over all vectors in cb and calculate projection
 	for (uint i = 0; i < cb.size(); i++) {
 		double inv_norm=1.0/diagonal_d_spm.at(i);
 		//Decv.at(i)= Col_fun.scalar_product( cb.at(i) , Ca )*inv_norm;
-		Decv.push_back( Col_fun.scalar_product( cb.at(i) , Ca )*inv_norm );
+		Decv.append( Col_fun.scalar_product( cb.at(i) , Ca )*inv_norm );
 	}
 
 	return Decv;
 }
 
 
 std::string Orthogonal_basis::diagonal_spm_file_name(const bool leading, const bool poly ) const{
 
 	// First construct filename
 	std::ostringstream ss;
 	std::string filename;
 	ss << "ColorResults";
 	ss << '/';
 	// CF as in ColorFull
 	ss << "CF_";
 	// Prefix according to basis type
 	ss << 	"OB_";
 	// diagonal version
 	ss << 	"diagonal_";
 	// Polynomial or numerical matrix?
 	if( poly )ss << "P_";
 	else ss << "d_";
 	ss << "spm_q";
 	ss << nq;
 	ss << "_g";
 	ss << ng;
 	// is the result leading, and if so, how?
 	if ( leading ) ss << "_l";
 	if ( Col_fun.get_full_CF() ) ss << "_cff";
 	else ss << "_cfl";
 	if( Col_fun.get_Nc() != 3 ){
 		ss << "_Nc_";
 		ss << Col_fun.get_Nc();
 	}
 	if(Col_fun.get_TR() != 0.5 ){
 		ss << "_TR_";
 		ss << Col_fun.get_TR();
 	}
 	filename=ss.str();
 	return filename;
 }
 
 
 void Orthogonal_basis::write_out_diagonal_d_spm( std::string filename ) const{
 
 	Col_fun.write_out_dvec( diagonal_d_spm, filename );
 
 }
 
 
 void Orthogonal_basis::write_out_diagonal_d_spm( ) const{
 
 	std::string filename = diagonal_spm_file_name( false, false );
 	write_out_diagonal_d_spm( filename );
 }
 
 
 void Orthogonal_basis::write_out_diagonal_P_spm( std::string filename ) const{
 
 	diagonal_P_spm.write_out_Poly_vec( filename );
 }
 
 
 void Orthogonal_basis::write_out_diagonal_P_spm( ) const{
 
 	std::string filename = diagonal_spm_file_name( false, true );
 	write_out_diagonal_P_spm( filename );
 }
 
 
 Polynomial Orthogonal_basis::scalar_product( const Col_amp & Ca1, const Col_amp & Ca2 )  {
 
 	// Check that we have a basis
 	if(cb.size()==0){
 		std::cerr << "Orthogonal_basis::scalar_product: The basis vector cb is empty consider using create_basis or read_in_basis." << std::endl;
 		assert( 0 );
 	}
 
 	// Check that size of P_spm is consistent (if calculated)
 	if( (P_spm.size() != cb.size()) and  P_spm.size() !=0 ) {
 		std::cerr << "Orthogonal_basis::scalar_product: Size of scalar product matrix P_spm and color basis cb do not agree." << std::endl;
 		assert( 0 );
 	}
 
 	// Check that size of diagonal_P_spm is consistent (if calculated)
 	if( (diagonal_P_spm.size() != cb.size()) and  diagonal_P_spm.size() !=0 ) {
 		std::cerr << "Orthogonal_basis::scalar_product: Size of diagonal_P_spm and color basis cb do not agree." << std::endl;
 		assert( 0 );
 	}
 
 	// Check if at least one of P_spm and diagonal_P_spm exist,
 	// If non exist, calculate diagonal
 	if( P_spm.empty() and diagonal_P_spm.empty() ){
 		diagonal_scalar_product_matrix(true, true, true);
 	}
 	// If matrix form, but not diagonal exist, copy diagonal entries
 	else if(diagonal_P_spm.empty() ){
 		for( uint i=0; i< P_spm.size(); i++ ){
-			diagonal_P_spm.push_back(P_spm.at(i).at(i));
+			diagonal_P_spm.append(P_spm.at(i).at(i));
 		}
 	}
 
 	// To contain the resulting Polynomial
 	Polynomial Poly_res;
 	Poly_res=Poly_res*0;
 
 	// Decompose the Col_amps
 	Poly_vec Polyv1=decompose(Ca1);
 	Polyv1.conjugate();
 	Poly_vec Polyv2=decompose( Ca2 );
 
 	// Then add contributions
 	for (uint m1=0; m1< cb.size(); m1++){
 		// Diagonal terms
-		Poly_res=Poly_res+Polyv1.at(m1) *Polyv2.at(m1) *diagonal_P_spm.at(m1);
+		Poly_res+=Polyv1.at(m1) *Polyv2.at(m1) *diagonal_P_spm.at(m1);
 	}
 	return Poly_res;
 }
 
 
 cnum Orthogonal_basis::scalar_product_num( const Col_amp & Ca1, const Col_amp & Ca2 )  {
 
 	// Check that we have a basis
 	if(cb.size()==0){
 		std::cerr << "Orthogonal_basis::scalar_product_num: The basis vector cb is empty consider using create_basis or read_in_basis." << std::endl;
 		assert( 0 );
 	}
 
 	// Check that size of d_spm is consistent (if calculated)
 	if( (d_spm.size() != cb.size()) and  d_spm.size() !=0 ) {
 		std::cerr << "Orthogonal_basis::scalar_product_num: Size of scalar product matrix d_spm and color basis cb do not agree." << std::endl;
 		assert( 0 );
 	}
 
 	// Check that size of diagonal_d_spm is consistent (if calculated)
 	if( (diagonal_d_spm.size() != cb.size()) and  diagonal_d_spm.size() !=0 ) {
 		std::cerr << "Orthogonal_basis::scalar_product_num: Size of diagonal_d_spm and color basis cb do not agree." << std::endl;
 		assert( 0 );
 	}
 
 	// Check if at least one of d_spm and diagonal_d_spm exist,
 	// If non exist, calculate diagonal version
 	if( d_spm.empty() and diagonal_d_spm.empty() ){
 		diagonal_scalar_product_matrix(false, true, true);
 	}
 	// If matrix form, but not diagonal exist, copy diagonal entries
 	else if(diagonal_d_spm.empty() ){
 		for( uint i=0; i< d_spm.size(); i++ ){
 			diagonal_d_spm.push_back(d_spm.at(i).at(i));
 		}
 	}
 
 	// To contain the result
 	double res=0;
 
 	// Decompose the Col_amps
 	Poly_vec Polyv1=decompose(Ca1);
 	Polyv1.conjugate();
 	Poly_vec Polyv2=decompose( Ca2 );
 	dvec v1=Col_fun.double_num( Polyv1 );
 	dvec v2=Col_fun.double_num( Polyv2 );
 
 
 	// Then add contributions
 	for (uint m1=0; m1< cb.size(); m1++){
 		// Diagonal terms
 		res=res+v1.at(m1) *v2.at(m1) *diagonal_d_spm.at(m1);
 	}
 	return res;
 }
 
 
 cnum Orthogonal_basis::scalar_product_num( const cvec & v1, const cvec & v2) {
 
 	if(v1.size()!= v2.size()){
 		std::cerr << "Orthogonal_basis::scalar_product_num: Size of first vector "
 		<< v1.size() << " does not agree with size of second vector "
 		<< v2.size() << std::endl;
 		assert( 0 );
 	}
 
 	// Check that size of d_spm is consistent (if calculated)
 	if( ( d_spm.size() != cb.size()) and  d_spm.size() !=0 ) {
 		std::cerr << "Orthogonal_basis::scalar_product_num: Size of scalar product matrix d_spm and color basis cb do not agree." << std::endl;
 		assert( 0 );
 	}
 
 	// Check that size of diagonal_d_spm is consistent (if calculated)
 	if( ( diagonal_d_spm.size() != cb.size()) and  diagonal_d_spm.size() !=0 ) {
 		std::cerr << "Orthogonal_basis::scalar_product_num: Size of diagonal_d_spm and color basis cb do not agree." << std::endl;
 		assert( 0 );
 	}
 
 	// Check if at least one of d_spm and diagonal_d_spm exist,
 	// If non exist, calculate diagonal version
 	if( d_spm.empty() and diagonal_d_spm.empty() ){
 		diagonal_scalar_product_matrix(false, true, true);
 	}
 	// If matrix form, but not diagonal exist, copy diagonal entries
 	else if(diagonal_d_spm.empty() ){
 		for( uint i=0; i< d_spm.size(); i++ ){
 			diagonal_d_spm.push_back(d_spm.at(i).at(i));
 		}
 	}
 
 	uint basis_size=v1.size();
 
 	// To contain the result
 	cnum res=0;
 
 	// Add contributions, diagonal parts only
 	for (uint m1=0; m1< basis_size; m1++){
 		res += conj( v1.at(m1) ) *v2.at(m1) *diagonal_d_spm.at(m1);
 	}
 
 	return res;
 }
 
 
 void Orthogonal_basis::write_out_diagonal_spm( const dvec & dv, const bool leading ) const{
 
 	std::string filename = diagonal_spm_file_name( leading, false );
 	std::ofstream outfile(filename.c_str());
 
 	if ( !outfile )
 	std::cerr << "Orthogonal_basis::write_out_diagonal_spm: Cannot write out diagonal scalar products as the file \""
 		<< filename.c_str() << "\" could not be opened. (Does the directory exist? Consider creating the directory.)" << std::endl;
 
 
 	outfile << dv;
 }
 
 
 void Orthogonal_basis::write_out_diagonal_spm( const Poly_vec & Pv, const bool leading ) const{
 
 	std::string filename = diagonal_spm_file_name( leading, true );
 	std::ofstream outfile(filename.c_str());
 	outfile << Pv;
 }
 
 
 } //end namespace ColorFull
diff --git a/MatrixElement/Matchbox/ColorFull/Orthogonal_basis.h b/MatrixElement/Matchbox/ColorFull/Orthogonal_basis.h
--- a/MatrixElement/Matchbox/ColorFull/Orthogonal_basis.h
+++ b/MatrixElement/Matchbox/ColorFull/Orthogonal_basis.h
@@ -1,127 +1,128 @@
 /*
  * Orthogonal_basis.h
  * Contains the declarations of the class Orthogonal_basis, related types and operators.
  * Created on: May 25, 2013
  * Author: Malin Sjodahl
  */
 
 #ifndef COLORFULL_Orthogonal_basis_h
 #define COLORFULL_Orthogonal_basis_h
 
 
 #include "Col_basis.h"
 
 
 namespace ColorFull {
 
 /// This class is for containing orthogonal bases,
 /// i.e. bases where the scalar product matrix is diagonal.
 /// ColorFull has (currently) no functionality for creating
 /// orthogonal bases, but orthogonal bases
 /// can be read in using read_in _Col_basis.
 class Orthogonal_basis:public Col_basis {
+
 public:
-
-	/// Default constructor.
+	/// Default constructor, puts private variable orthogonal_basis=true
+	/// and calls the constructor of Col_basis.
 	Orthogonal_basis():Col_basis(){
 		orthogonal_basis = true;
 	}
 
 	/// To contain information about scalar products as a dvec,
-	/// entry i is the square of vector i.
+	/// i.e., entry i is the square of vector i.
 	dvec diagonal_d_spm;
 
 	/// To contain information about scalar products as a Poly_vec,
 	/// i.e., entry i is the square of vector i.
 	Poly_vec diagonal_P_spm;
 
 
 	/******************** Functions for scalar products **********************/
 
 	/// Calculates the scalar product matrix assuming the basis to be orthogonal.
 	/// Calculates both the double (d_spm) and the Polynomial (P_spm) matrices and
 	/// saves to default file names.
 	void scalar_product_matrix();
 
 	/// Calculates the diagonal entries in the scalar product matrix,
 	/// and (depending on arguments), saves them to the member variables
 	/// diagonal_P_spm and diagonal_d_spm.
 	/// This function is used by the Orthogonal_basis version of
 	/// scalar_product_matrix.
 	void diagonal_scalar_product_matrix( bool save_P_diagonal_spm, bool save_d_diagonal_spm, bool use_mem );
 
 	/// The decomposition of a Col_amp in an orthogonal basis is done
 	/// by calculating scalar products and dividing out the norm.
 	/// The norm is evaluated numerically.
 	Poly_vec decompose( const Col_amp & Ca );
 
 	/// Function for calculating scalar products
 	/// given the information about the basis and the scalar product matrix in the basis.
 	/// The Col_amps are first decomposed using decompose,
 	/// and then squared using the scalar product matrix P_spm.
 	/// An orthogonal scalar product matrix is assumed.
 	Polynomial scalar_product( const Col_amp & Ca1, const Col_amp & Ca2 );
 
 	/// Function for calculating scalar products
 	/// given the information about the basis
 	/// and the scalar product matrix in numerical form.
 	/// The Col_amps are first decomposed using decompose,
 	/// and then squared using diagonal_d_spm.
 	/// For Orthogonal_basis, an orthogonal scalar product matrix is assumed.
 	cnum scalar_product_num( const Col_amp & Ca1, const Col_amp & Ca2 );
 
 	/// Calculates the scalar product between decomposed amplitudes v1, V2
 	/// using the diagonal_d_spm diagonal numerical scalar product matrix.
 	/// The vectors needs to be expressed in the basis contained in cb,
 	/// i.e., the decomposition has to be known.
 	cnum scalar_product_num( const cvec & v1, const cvec & v2 );
 
 
 	/******************** Functions for reading and writing **********************/
 
 	/// Creates a default filename for writing out diagonal scalar products.
 	/// The boolean variable leading should be true if the name is for a leading
 	/// Nc variable. The filename is then modified accordingly.
 	std::string diagonal_spm_file_name( const bool leading, const bool poly ) const;
 
-	/// Writes out diagonal_d_spm to file filename.
+	/// Writes out diagonal_d_spm to the file filename.
 	void write_out_diagonal_d_spm( std::string filename ) const;
 
 	/// Writes out diagonal_d_spm to the standard filename, see diagonal_spm_file_name.
 	void write_out_diagonal_d_spm( ) const;
 
-	/// Writes out diagonal_P_spm to file filename.
+	/// Writes out diagonal_P_spm to the file filename.
 	void write_out_diagonal_P_spm( std::string filename ) const;
 
 	/// Writes out diagonal_P_spm to the standard filename, see diagonal_spm_file_name.
 	void write_out_diagonal_P_spm( ) const;
 
 	/// Function for writing out a dvec (the diagonal scalar products, diagonal_d_spm)
 	/// to a file with standard filename given by diagonal_spm_file_name.
 	/// The boolean variable leading should be true if dv only has leading
 	/// Nc contributions. The filename is then modified accordingly.
 	void write_out_diagonal_spm( const dvec & dv, const bool leading ) const;
 
 	/// Function for writing out a Poly_vec (the diagonal scalar products, diagonal_d_spm)
 	/// to a file with standard filename given by diagonal_spm_file_name.
 	/// The boolean variable leading should be true if Poly_vec only has leading
 	/// Nc contributions. The filename is then modified accordingly.
 	void write_out_diagonal_spm( const Poly_vec & pv, const bool leading ) const;
 
 private:
 
 	/// Function for calculating the scalar products matrix.
 	/// This function uses diagonal_scalar_product_matrix
 	/// and saved the value of the diagonal scalar products between basis vector
 	/// i and basis vector j in the i,j -entry in
 	/// P_spm (if save P_spm is true) and d_spm (if save_d_spm is true).
 	/// If use_mem is true, memoization is used.
 	void scalar_product_matrix( bool save_P_spm, bool save_d_spm, bool use_mem );
 
 
 };// end class Orthogonal_basis
 
 }// end namespace ColorFull
 
 
 #endif /* COLORFULL_Orthogonal_basis_h */
diff --git a/MatrixElement/Matchbox/ColorFull/Poly_matr.cc b/MatrixElement/Matchbox/ColorFull/Poly_matr.cc
--- a/MatrixElement/Matchbox/ColorFull/Poly_matr.cc
+++ b/MatrixElement/Matchbox/ColorFull/Poly_matr.cc
@@ -1,173 +1,192 @@
 // -*- C++ -*-
 
 /*
  * Poly_matr.cc
  * Contains the definition of the class Poly_matr and related operators.
  * Created on: Aug 5, 2013
  * Author: Malin Sjodahl
  */
 
 #include "Poly_matr.h"
 #include <cassert>
 #include <fstream>
 #include <iostream>
 
 
 namespace ColorFull{
 
 
 std::ostream& operator<<(std::ostream& out, const poly_matr & pm){
 
 	out <<"{" <<std::endl;
 	// Loop over rows
 	for(uint i=0; i< pm.size(); i++ ){
 		out <<"{";
 		// Loop over columns
 		for(uint j=0; j< pm.at(i).size(); j++ ){
 			// Print element
 			std::cout.width( 20 );
 			std::ostringstream outstr;
 			outstr << pm.at(i).at(j);
 			// If not last element print ","
 			if (j<pm.at(i).size()-1 ) outstr << ",";
 			out << outstr.str();
 			//out << pm.at(i).at(j) << "";
 		}
 		out <<"}";
 		// If not last row, print ","
 		if (i<pm.at(i).size()-1 ) out << ",";
 		out << std::endl;
 	}
 	out <<"}" <<std::endl;
 	return out;
 }
 
 
 void Poly_matr::remove_CF()  {
 
 	// Loop over vectors matrix
 	for ( uint i = 0; i < pm.size(); i++ ) {
 		// Remove CF in each term
 		pm.at(i).remove_CF();
 	}
 }
 
 
 std::ostream& operator<<(std::ostream& out, const Poly_matr & Pm){
 	out << Pm.pm;
 	return out;
 }
 
 
+bool operator==( const Poly_matr & Pm1, const Poly_matr & Pm2 ){
+
+	if( Pm1.size() != Pm2.size() ) return false;
+
+	// All terms should be the same
+	for ( uint i=0; i < Pm1.size(); i++ ){
+		if( Pm1.at(i) != Pm2.at(i ) ) return false;
+	}
+
+	return true;
+}
+
+bool operator!=(  const Poly_matr & Pm1, const Poly_matr & Pm2 ){
+	if( Pm1==Pm2 ) return false;
+	else return true;
+}
+
+
+
 void Poly_matr::normal_order( ) {
 
 	// Loop over vectors in matrix
 	for ( uint i = 0; i < pm.size(); i++ ) {
 		// Remove CF in each Poly_vec
 		pm.at(i).normal_order() ;
 	}
 }
 
 
 void Poly_matr::simplify( ) {
 
 	// Loop over vectors in matrix
 	for ( uint i = 0; i < pm.size(); i++ ) {
 		// Remove CF in each term
 		pm.at(i).simplify();
 	}
 
 }
 
 
 void Poly_matr::conjugate( ) {
 
   for ( uint i=0; i < pm.size(); i++ ){
 	  pm.at(i).conjugate();
   }
 }
 
 
 void Poly_matr::read_in_Poly_matr( std::string filename ) {
 
 	// Read in file
 	std::ifstream fin( filename.c_str() );
 
 	// Check that file exists
 	if( !fin ){
 		std::cerr << "Poly_matr::read_in_Poly_matr: The file "
 				<< filename << " could not be opened." << std::endl;
 		assert(0);
 	}
 
 	// Copy info from file to string
 	std::string str((std::istreambuf_iterator<char>(fin)),
 			std::istreambuf_iterator<char>());
 
 	// Skip lines starting with #
 	while(str.at(0)== '#'){
 		while (str.at(0) != '\n'){
 			str.erase(str.begin());
 		}
 		// erase endl sign(s)
 		while(str.at(0)== '\n'){
 			str.erase(str.begin());
 		}
 	}
 
 	// First char in file should be '{'
 	if (str.at(0) != '{') {
 		std::cerr
 		<< "Poly_matr::read_in_Poly_matr: First char in matrix data after comments file should be '{', it was: "
 		<< str.at(0) << std::endl;
 		assert( 0 );
 	}
 
 	// Row to contain numbers
 	Poly_vec row;
 
 	// Read the string, starting from 0th element
 	uint i = 0;
 	while (i < str.size() - 2) {
 
 		// To contain the Polynomial string
 		std::string Poly_str;
 		Poly_str.clear();
 
 		// We may have to skip some spaces, end-lines and {
 		while (i < str.size() - 2 && (str.at(i) == ' ' or str.at(i) == '\n' or str.at(i) == '{'))
 			i++;
 
 		// Read next Polynomial, until , or {
 		// Keep reading the number while not ',' or '}'
 		while (i < str.size() - 2 && (str.at(i) != ',' && str.at(i) != '}')) {
 			Poly_str.push_back(str.at(i));
 			i++;
 		}
 
 		Polynomial Poly( Poly_str );
-		row.push_back( Poly );
+		row.append( Poly );
 
 		// If we have a new row
 		if (i < str.size() - 2 && str.at(i) == '}') {
 			// Save row in matrix, and empty row
 			pm.push_back(row);
 			row.clear();
 
 			// We may have to skip some chars
 			while (i< str.size()-2 &&(str.at(i) == ',' or str.at(i) == '}' or str.at(i) == ' ' or str.at(i) == '\n' ) ) i++;
 		}
 		i++;
 	}
 }
 
 void Poly_matr::write_out_Poly_matr( std::string filename ) const {
 	std::ofstream outfile( filename.c_str() );
 
 	if ( !outfile )
 	std::cerr << "Poly_matr::write_out_Poly_matr: Cannot write out Polynomial matrix as the file \""
 		<< filename.c_str() << "\" could not be opened. (Does the directory exist? Consider creating the directory.)" << std::endl;
 	outfile << pm;
 }
 
 }// end namespace ColorFull
diff --git a/MatrixElement/Matchbox/ColorFull/Poly_matr.h b/MatrixElement/Matchbox/ColorFull/Poly_matr.h
--- a/MatrixElement/Matchbox/ColorFull/Poly_matr.h
+++ b/MatrixElement/Matchbox/ColorFull/Poly_matr.h
@@ -1,102 +1,106 @@
 // -*- C++ -*-
 
 /*
  * Poly_matr.h
  * Contains the declaration of the class Poly_matr and related types and operators.
  * Created on: Aug 5, 2013
  * Author: Malin Sjodahl
  */
 
 #ifndef COLORFULL_Poly_matr_h
 #define COLORFULL_Poly_matr_h
 
 
 
 #include "Poly_vec.h"
 
 
 namespace ColorFull {
 
 /// To contain a matrix of Polynomials, a vector of Poly_vec.
 typedef std::vector< Poly_vec > poly_matr;
 
 
 /// Class for containing a Polynomial matrix, and functions
 /// for Polynomial matrices.
 class Poly_matr {
 
 public:
 
-	/// Default constructor, sets nothing.
+	/// Default constructor, leaves pm empty.
 	Poly_matr() {}
 
-	/// To actually contain the polynomial information.
+	/// To actually contain the matrix of Polynomials.
 	poly_matr pm;
 
 	/// Returns the Poly_vec at place i.
 	const Poly_vec& at( int i ) const {return pm.at(i);}
 
 	/// Returns the Poly_vec at place i.
 	Poly_vec& at( int i ) {return pm.at(i);}
 
 	/// Returns the matrix element at i, j.
 	Polynomial& at( int i, int j ) { return pm.at(i).pv.at(j);}
 
 	/// Returns the matrix element at i, j.
 	const Polynomial& at( int i, int j ) const { return pm.at(i).pv.at(j);}
 
 	/// Is the matrix, stored in pm, empty?
 	bool empty( ) const {return pm.empty();}
 
 	/// Returns the size of the matrix, the number of Poly_vec's
 	/// in the member pm.
 	uint size( ) const {return pm.size();}
 
 	/// Erases the matrix information.
 	void clear()  {pm.clear();}
 
-	/// Appends a Poly_vec constructed from a poly_vec to the data member pm.
-	void push_back( poly_vec pv ) {pm.push_back( Poly_vec(pv) );}
-
 	/// Appends a Poly_vec to data member pm.
-	void push_back( Poly_vec Pv ) {pm.push_back( Pv );}
+	void append( Poly_vec Pv ) {pm.push_back( Pv );}
 
 	/// Remove CF in the poly_matr member pm, i.e., replace CF by
 	/// TR (Nc^2-1)/Nc.
 	void remove_CF();
 
-	/// Normal orders all polynomials in the poly_matr member pm.
-	/// (Uses Polynomial.normal_order.)
+	/// Normal orders all polynomials in the poly_matr member pm,
+	/// (uses Polynomial.normal_order.)
 	void normal_order();
 
-	/// Simplifies all polynomials in the poly_matr member pm.
-	/// (Uses Polynomial.simplify.)
+	/// Simplifies all polynomials in the poly_matr member pm,
+	/// (uses Polynomial.simplify.)
 	void simplify();
 
 	/// Conjugates the matrix.
 	void conjugate();
 
 	/// Reads in the matrix from the file filename.
-	/// The file should be in the format
+	/// The file should be of the format
 	/// {{Poly11,...,Poly1n},
 	/// ...,
 	/// {Polyn1,...,Polynn}},
 	/// and may contain comment lines starting with # at the top.
 	void read_in_Poly_matr( std::string filename );
 
 	/// Writes out the matrix to the file filename.
 	void write_out_Poly_matr( std::string filename ) const;
 
 };
 
 /// Operator << for poly_matr.
 std::ostream& operator<<( std::ostream& out, const poly_matr & pm );
 
 /// Operator << for poly_vec.
 std::ostream& operator<<( std::ostream& out, const Poly_matr & Pm );
 
+/// Define the operator == for Poly_matr,
+/// each Poly_vec has to be identical.
+bool operator==( const Poly_matr & Pm1, const Poly_matr & Pm2 );
+
+/// Define the operator == for Poly_matr,
+/// each Poly_vec has to be identical.
+bool operator!=( const Poly_matr & Pm1, const Poly_matr & Pm2 );
 
 }
 
 
 #endif /* COLORFULL_Poly_matr_h */
diff --git a/MatrixElement/Matchbox/ColorFull/Poly_vec.cc b/MatrixElement/Matchbox/ColorFull/Poly_vec.cc
--- a/MatrixElement/Matchbox/ColorFull/Poly_vec.cc
+++ b/MatrixElement/Matchbox/ColorFull/Poly_vec.cc
@@ -1,157 +1,174 @@
 // -*- C++ -*-
 
 /*
  * Poly_vec.cc
  * Contains the definition of the class Poly_vec related operators.
  * Created on: Aug 5, 2013
  * Author: Malin Sjodahl
  */
 
 #include "Poly_vec.h"
 #include <cassert>
 #include <fstream>
 #include <iostream>
 
 namespace ColorFull{
 
 
 std::ostream& operator<<(std::ostream& out, const poly_vec & poly_v ){
 	out <<"{";
 	// Loop over entries
 	for( uint i=0; i< poly_v.size(); i++ ){
 		out << poly_v.at(i);
 		// If not last element print ","
 		if (i<poly_v.size()-1 ) out << ", ";
 	}
 	out <<"}";
 	return out;
 }
 
 
 std::ostream& operator<<(std::ostream& out, const Poly_vec & Pv ){
 	out << Pv.pv;
 	return out;
 }
 
+bool operator==( const Poly_vec & Pv1, const Poly_vec & Pv2 ){
+
+	if( Pv1.size() != Pv2.size() ) return false;
+
+	// All terms should be the same
+	for ( uint i=0; i < Pv1.size(); i++ ){
+		if( Pv1.at(i) != Pv2.at(i ) ) return false;
+	}
+
+	return true;
+}
+
+bool operator!=(  const Poly_vec & Pv1, const Poly_vec & Pv2 ){
+	if( Pv1==Pv2 ) return false;
+	else return true;
+}
 
 void Poly_vec::remove_CF()  {
 
 	// Loop over entries in vector (Polynomials)
 	for ( uint i = 0; i < pv.size(); i++ ) {
 		// Remove CF in each term
 		pv.at(i).remove_CF();
 		//std::cout << "Col_functions::remove_CF: Pv_res.at(i)" << Pv_res.at(i) << std::endl;
 	}
 }
 
 
 void Poly_vec::normal_order()  {
 
 	// Loop over entries in vector (Polynomials)
 	for ( uint i = 0; i < pv.size(); i++ ) {
 		// Normal order each term
 		pv.at(i).normal_order();
 	}
 }
 
 
 void Poly_vec::simplify( ) {
 
 	// Loop over entries in vector (poly_vec)
 	for ( uint i = 0; i < pv.size(); i++ ) {
 		// Remove CF in each term
 		pv.at(i).simplify();
 	}
 }
 
 
 void Poly_vec::conjugate( ) {
 
 	for ( uint i=0; i < pv.size(); i++ ){
 		pv.at(i).conjugate();
 	}
 }
 
 
 void Poly_vec::read_in_Poly_vec( std::string filename ) {
 
 	// Read in file
 	std::ifstream fin(filename.c_str() );
 
 	// Check that file exists
 	if( !fin ){
 		std::cerr << "Poly_vec::read_in_Poly_vec: The file "
 				<< filename << " could not be opened." << std::endl;
 		assert(0);
 	}
 
 	// Copy info from file to string
 	std::string str((std::istreambuf_iterator<char>(fin)),
 			std::istreambuf_iterator<char>());
 
 	// Skip lines starting with #
 	while( str.at(0)== '#' ){
 		while (str.at(0) != '\n'){
 			str.erase(str.begin());
 		}
 		// erase endl sign(s)
 		while(str.at(0)== '\n'){
 			str.erase(str.begin());
 		}
 	}
 
 	// First char in file should be '{'
 	if ( str.at(0) != '{' ) {
 		std::cerr
 		<< "Poly_vec::read_in_Poly_vec: First char in vector data after comments should be '{', it was: "
 		<< str.at(0) << std::endl;
 		assert(0);
 	}
 
 	// Row to contain numbers
 	Poly_vec row;
 
 	// Read the string, starting from 0th element
 	unsigned int i = 0;
-	while ( i < str.size() - 2 ) {
+	while ( i < str.size() - 1 ) {
 
 		// To contain the Polynomial string
 		std::string Poly_str;
 		Poly_str.clear();
 
 		// We may have to skip some spaces, end-lines and {
-		while (i < str.size() - 2 && (str.at(i) == ' ' or str.at(i) == '\n' or str.at(i) == '{'))
+		while (i < str.size() - 1 && (str.at(i) == ' ' or str.at(i) == '\n' or str.at(i) == '{'))
 			i++;
 
 		// Keep reading the number while not ',' or '}'
-		while (i < str.size() - 2 && (str.at(i) != ',' && str.at(i) != '}')) {
+		// Last char }, is at place size -1
+		while (i < str.size() - 1 && (str.at(i) != ',' && str.at(i) != '}')) {
 			Poly_str.push_back(str.at(i));
 			i++;
 		}
 
 		Polynomial Poly( Poly_str );
 		pv.push_back( Poly );
 
 		// If we have a new row
-		if (i < str.size() - 2 && str.at(i) == '}') { i++;}
+		if (i < str.size() - 1 && str.at(i) == '}') { i++;}
 		i++;
 	}
 }
 
 
 void Poly_vec::write_out_Poly_vec( std::string filename ) const {
 	std::ofstream outfile( filename.c_str() );
 
 	if ( !outfile )
 	std::cerr << "Poly_vec::write_out_Poly_vec: Cannot write out vector of Polynomials as the file \""
 		<< filename.c_str() << "\" could not be opened. (Does the directory exist? Consider creating the directory.)" << std::endl;
 
 
 	outfile << pv;
 }
 
 } // end namespace ColorFull
 
 
 
 
diff --git a/MatrixElement/Matchbox/ColorFull/Poly_vec.h b/MatrixElement/Matchbox/ColorFull/Poly_vec.h
--- a/MatrixElement/Matchbox/ColorFull/Poly_vec.h
+++ b/MatrixElement/Matchbox/ColorFull/Poly_vec.h
@@ -1,94 +1,100 @@
 // -*- C++ -*-
 
 /*
  * Poly_vec.h
  * Contains the declaration of the class Poly_vec related types and operators.
  * Created on: Aug 5, 2013
  * Author: Malin Sjodahl
  */
 
 #ifndef COLORFULL_Poly_vec_h
 #define COLORFULL_Poly_vec_h
 
 
 #include "Polynomial.h"
 
 
 namespace ColorFull {
 
 /// To contain a vector of Polynomials.
 typedef std::vector< Polynomial> poly_vec;
 
 
 /// Class for containing vector of Polynomials, and functions
 /// for Polynomial vectors.
 class Poly_vec {
 
 
 public:
 
-	/// Default constructor, sets nothing.
+	/// Default constructor, leaves pv empty.
 	Poly_vec() {}
 
-	/// Make a Poly_vec of a poly_vec.
+	/// Makes a Poly_vec of a poly_vec.
 	Poly_vec( poly_vec poly_v ){pv=poly_v;}
 
 	/// To actually contain the polynomial information.
 	poly_vec pv;
 
-	/// Returning Polynomial at place i.
+	/// Returns the Polynomial at place i.
 	const Polynomial& at( int i ) const { return pv.at(i); }
 
-	/// Returning Polynomial at place i.
+	/// Returns the Polynomial at place i.
 	Polynomial& at( int i ) { return pv.at(i); }
 
 	/// Return the number of Polynomials in the vector,
 	/// i.e., the size of the member pv.
 	uint size() const { return pv.size(); }
 
-	/// Erase information in vector.
+	/// Erases the information in vector.
 	void clear() { pv.clear(); }
 
 	/// Appends a Polynomial to data member pv.
-	void push_back( Polynomial Poly ) { pv.push_back( Poly ); }
+	void append( Polynomial Poly ) { pv.push_back( Poly ); }
 
 	/// Is the vector empty?
 	bool empty() const { return pv.empty(); }
 
 	/// Remove CF in the poly_vec member pv, i.e., replace CF by
-	/// TR (Nc^2-1)/(2 Nc).
+	/// TR*Nc -TR/Nc.
 	void remove_CF();
 
-	/// Normal order all Polynomials in the poly_vec member pv.
-	/// (Uses the Polynomial.normal_order function.)
+	/// Normal order all Polynomials in the poly_vec member pv
+	/// (uses the Polynomial.normal_order function.)
 	void normal_order();
 
-	/// Simplifies all polynomials in the poly_vec member pv.
-	/// (Uses the simplify member function in Polynomial).
+	/// Simplifies all polynomials in the poly_vec member pv
+	/// (uses the simplify member function in Polynomial).
 	void simplify();
 
 	/// Conjugates the Poly_vec.
 	void conjugate();
 
 	/// Reads in a Polynomial vector of form {Poly1, Poly2,...}
 	/// to the member pv from the file filename.
 	/// Comments starting with # are allowed
 	/// at the top of the file.
 	void read_in_Poly_vec( std::string filename );
 
 	/// Writes out the vector to the file filename.
 	void write_out_Poly_vec( std::string filename ) const;
-
 };
 
 /// Operator << for poly_vec.
 std::ostream& operator<<( std::ostream& out, const poly_vec & poly_v );
 
 /// Operator << for Poly_vec.
 std::ostream& operator<<( std::ostream& out, const Poly_vec & Pv );
 
+/// Define the operator == for Poly_vec,
+/// each Polynomial has to be identical.
+bool operator==( const Poly_vec & Pv1, const Poly_vec & Pv2 );
+
+/// Define the operator != for Poly_vec,
+/// each Polynomial has to be identical.
+bool operator!=( const Poly_vec & Pv1, const Poly_vec & Pv2 );
 
 }
 
 
 #endif /* COLORFULL_Poly_vec_h */
diff --git a/MatrixElement/Matchbox/ColorFull/Polynomial.cc b/MatrixElement/Matchbox/ColorFull/Polynomial.cc
--- a/MatrixElement/Matchbox/ColorFull/Polynomial.cc
+++ b/MatrixElement/Matchbox/ColorFull/Polynomial.cc
@@ -1,781 +1,878 @@
 // -*- C++ -*-
 /* Polynomial.cc
  *	Contains definition of the class Polynomial and associated types and operators
  *  Created on: Jul 7, 2010
  *  Author: Malin Sjodahl
  */
 #include "Polynomial.h"
 #include "parameters.h"
 #include <limits>
 #include <cassert>
 #include <fstream>
 #include <iostream>
 
 
 namespace ColorFull {
 
 Polynomial::Polynomial( double dnum ) {
 
 	Monomial Mon;
 	Mon.cnum_part.real(dnum);
 	poly.push_back(Mon);
 
 }
 
 
 Polynomial::Polynomial( int num ) {
 	Monomial Mon;
 	Mon.int_part= num ;
 	poly.push_back(Mon);
 }
 
 
 Polynomial::Polynomial( const std::string str ) {
 	Polynomial_of_str( str );
 }
 
 
 void Polynomial::Polynomial_of_str( const std::string str ) {
 
 	// Special case of empty string
 	if( str.empty() ) {
 		polynomial empty;
 		poly=empty;
 		return;
 	}
 
 	uint i = 0, j=0;
 	std::string Mon_str;
 
 	int left_brackets=0, right_brackets=0;
 	// Check that left and right brackets match up
 	while (j < str.size()) {
 		if(str.at(j)=='(') left_brackets++;
 		if(str.at(j)==')') right_brackets++;
 		j++;
 	}
 	if(left_brackets != right_brackets){
 		std::cerr << "Polynomial::Polynomial_of_str: The brackets in the polynomial\"" << str <<"\" do not seem to match up. There were "
 				<< left_brackets <<" left bracket(s) and "<< right_brackets << " right bracket(s)." << std::endl;
 		assert( 0 );
 	}
 
 	// Skip potential spaces
 	while (i < str.size() && (str.at(i) == ' ')) i++;
 
 	// Skip initial left bracket(s) surrounding polynomial
 	// there are left brackets-right brackets such brackets,
 	// we many have ((TR+Nc))
 	int found_left_brackets=0;
 
 	// if we have a surplus of left_brackets before we have a + or -
 	// then (with some exceptions) it's an overall bracket
 	int right_before_plus=0, left_before_plus=0;
 	j=0;
 	bool new_term=false;
 	while ( j<str.size() and !new_term ){
 
 		// we should allow brackets like (2TR)+4
 		// but remove overall brackets, like (2 TR+4)
 		// a + or - can means that we may have reached a new term
 		// and should stop looking for overall brackets
 		if(str.at(j)=='-'){
 			// we can allow - inside powers, i.e. after ^(, ^(- or ^-
 			if( j>0 ){
 				// if (- continue, (this is not a new term)
 				if(str.at(j-1)=='('){}
 				// if ^- continue, (this is not a new term)
 				else if(str.at(j-1)=='^'){}
 				// if *- continue, (this is not a new term)
 				else if(str.at(j-1)=='*'){}
 				else new_term=true;
 			}
 			else new_term=true;
 		}
 
 		// a plus sign could mean that it's a new term
 		if(str.at(j)=='+'){
 			// we can allow - inside powers, i.e. after ^(, ^(- or ^-
 			if( j>0 ){
 				// if (+ continue, (this is not a new term)
 				if(str.at(j-1)=='('){}
 				// if ^+ continue, (this is not a new term)
 				else if(str.at(j-1)=='^'){}
 				// if *+ continue, (this is not a new term)
 				else if(str.at(j-1)=='*'){}
 				else new_term=true;
 			}
 			else new_term=true;
 		}
 
 		if(str.at(j)== '(') left_before_plus++;
 		if(str.at(j)== ')') right_before_plus++;
 		j++;
 	}
 
 	int extra_left_brackets =  left_before_plus-right_before_plus;
 
 	while (i < str.size() and ( str.at(i)=='(' or str.at(i)==' ')  and found_left_brackets < extra_left_brackets ) {
 		if(str.at(i)== '(') found_left_brackets++;
 		i++;
 	}
 
 	int Moncount=0;
 
 	// Look for Monomials until the end of the string
 	while (i < str.size()) {
 		Mon_str.clear();
 		Moncount++;
 
 		// Check for one + or - for each Monomial
 		while (i < str.size() && (str.at(i) == '+' or str.at(i) == '-' )){
 			Mon_str.push_back(str.at(i));
 			i++;
 		}
 
 		// Look for more factors in same Monomial
 		while (i < str.size()) {
 
 			// There should be no surplus of ) in the Monomial
 			left_brackets=right_brackets=0;
 
 			// Check for Monomials
 			// Everything but + and - should go to Monomail
 			// Read until another + or - while making sure we don't get final )'s
 			if ( i < str.size() ){
 				if( str.at(i) != '+' and str.at(i) != '-' ){
 					Mon_str.push_back(str.at(i));
 				i++;
 				}
 			}
 
 			// we can allow - after (, "(-"for example inside powers
 			if ( i < str.size() and  str.at(i) == '-'){
 				// removed i-1>= 0 as always true, no check that read inside
 				if(( str.at(i-1)=='(')){
 					Mon_str.push_back(str.at(i));
 					i++;
 				}
 			}
 
 			// We can also allow for - after*, for example 0.5*-1
 			if (i < str.size() and  str.at(i) == '-' and ( (i>= 2) and str.at(i-1)=='*'))  {
 				// read in sign
 				Mon_str.push_back(str.at(i));
 				i++; // skip sign
 				// Keep reading in while numbers
 				while (i< str.size() and  (str.at(i) == '0' or str.at(i) == '1' or str.at(i) == '2'
 						or str.at(i) == '3' or str.at(i) == '4'
 								or str.at(i) == '5' or str.at(i) == '6'
 										or str.at(i) == '7' or str.at(i) == '8'
 												or str.at(i) == '9')){
 					Mon_str.push_back(str.at(i));
 					i++;
 				}
 			}
 
+			// We can also allow for - after^, for example TR^-1
+			// added 14 11 26
+			if (i < str.size() and  str.at(i) == '-' and ( (i>= 1) and str.at(i-1)=='^'))  {
+				// read in sign
+				Mon_str.push_back(str.at(i));
+				i++; // skip sign
+				// Keep reading in while numbers
+				while (i< str.size() and  (str.at(i) == '0' or str.at(i) == '1' or str.at(i) == '2'
+						or str.at(i) == '3' or str.at(i) == '4'
+								or str.at(i) == '5' or str.at(i) == '6'
+										or str.at(i) == '7' or str.at(i) == '8'
+												or str.at(i) == '9')){
+					Mon_str.push_back(str.at(i));
+					i++;
+				}
+			}
+
 			// We can also allow for - after ( as in (-1)
 			if (i < str.size() and str.at(i) == '-' and (i>= 3) and str.at(i-1)=='(') {
 				// read in sign
 				Mon_str.push_back(str.at(i));
 				i++; // skip sign
 
 				// Keep reading in while numbers
 				while (i< str.size() and  (str.at(i) == '0' or str.at(i) == '1' or str.at(i) == '2'
 						or str.at(i) == '3' or str.at(i) == '4'
 								or str.at(i) == '5' or str.at(i) == '6'
 										or str.at(i) == '7' or str.at(i) == '8'
 												or str.at(i) == '9')){
 					Mon_str.push_back(str.at(i));
 					i++;
 				}
 
 				// Skip spaces
 				while ( i< str.size() and str.at(i) == ' ') i++;
 
 				// Look for closing )
 				if(str.at(i)==')') {
 					// read in )
 					Mon_str.push_back(str.at(i));
 					i++;}
 				else {
 					std::cerr << "Polynomial::Polynomial_of_str: Expects final ) in *(number)"
 							<< " got " << str.at(i) << std::endl;
 					assert( 0 );
 				}
 			}// Stop looking for (-
 
 			// Break if we have + or - and not a special case
 			if ( i == str.size() ) break;
 			if ( str.at(i)== '+' ) break;
 			if (str.at(i) == '-'
 					and !(
 					(i < str.size() and  str.at(i) == '-'
 							and ( ( i-3 > 0 and str.at(i-1)=='(' and str.at(i-2)=='^')
 							or ( i-2> 0 and  str.at(i-1)=='^' )	))
 					// We can also allow for - after*, for example 0.5*-1
 					or (i < str.size() and  str.at(i) == '-' and ( (i-2> 0) and str.at(i-1)=='*'))
 					// We can also allow for - after 0.5*(-1)
 					or (i < str.size() and str.at(i) == '-' and (i-3> 0) and str.at(i-1)=='(' and str.at(i-2)=='*')) ) break;
 		} // end of while (i < str.size()), i.e. now keep looking for factors in same Monomial
 		// Then make a Monomial out of the str
 
 
 		// Check that left and right brackets match up
 		left_brackets=right_brackets=0;
 		for ( uint j=0; j< Mon_str.size(); j++ ){
 			if(Mon_str.at(j)=='(') left_brackets++;
 			if(Mon_str.at(j)==')') right_brackets++;
 		}
 
 		int brack_diff=right_brackets-left_brackets;
 		// Remove (-brackets in the end until they match ), i.e. brack_diff==0.
 		uint j=1;
 		while( ( Mon_str.at( Mon_str.size()-j )==')' or Mon_str.at( Mon_str.size()-j )==' ' or Mon_str.at( Mon_str.size()-j )=='*') and brack_diff > 0 ){
 			if( Mon_str.at( Mon_str.size()-j )==')' ) {
 				brack_diff--;
 				Mon_str.at( Mon_str.size()-j )= ' ';
 			}
 			j++;
 		}
 
 		poly.push_back(Monomial(Mon_str));
 
 	} // end of while (i < str.size())
 
 }
 
 
 void Polynomial::read_in_Polynomial( std::string filename) {
 
 	// Read in file
 	std::ifstream fin(filename.c_str());
 
 	// Check that file exists
 	if( !fin ){
 		std::cerr << "Polynomial::read_in_Polynomial: The file "
 				<< filename << " could not be opened." << std::endl;
 		assert( 0 );
 	}
 
 	// Erase current information
 	poly.clear();
 
 	// Copy info from file to string
 	std::string str((std::istreambuf_iterator<char>(fin)), std::istreambuf_iterator<char>());
 	//str.erase(str.size()-1);
+	// Remove endl chars at the end of the file
+	while( str.at( str.size()-1 ) == '\n' ) str.erase(str.size()-1);
+
+	// Skip lines starting with #
+	while( str.at(0)== '#' ){
+		while (str.at(0) != '\n'){
+			str.erase(str.begin());
+		}
+		// erase endl sign(s)
+		while(str.at(0)== '\n'){
+			str.erase(str.begin());
+		}
+	}
+
 	Polynomial_of_str( str );
 }
 
 
 void Polynomial::write_out_Polynomial( std::string filename ) const {
 
 	std::ofstream outfile(filename.c_str());
 
 	if ( !outfile )
-	std::cerr << "Polynomial::write_out_Polynomial: Cannot write out diagonal scalar products as the file \""
+	std::cerr << "Polynomial::write_out_Polynomial: Cannot write out Polynomial as the file \""
 		<< filename.c_str() << "\" could not be opened. (Does the directory exist? Consider creating the directory.)" << std::endl;
 
 	outfile << *this;
 }
 
 
 void Polynomial::conjugate(){
 	// Loop over Monomials and complex conjugate them
 	for(uint i=0; i< poly.size(); i++) poly.at(i).conjugate();
 
 }
 
 
 void Polynomial::simplify() {
 
 	// If empty Polynomial or only one Monomial, do nothing
 	if (poly.size() <= 1)
 		return;
 
 	// Collect different Monomials, keep 0th Monomial
 	polynomial terms;
 	terms.push_back(poly.at(0));
 	poly.erase(poly.begin());
 
 	// Move terms from Polynomial to unique set of terms
 	// as long as terms remain in Polynomial
 	while (poly.size() > 0) {
 		bool was_found = false;
 
 		// Check if term already there
 		for (uint i = 0; (i < terms.size() && !was_found); i++) {
 			// If same powers of TR, Nc and CF
 			if (poly.at(0).pow_TR == terms.at(i).pow_TR && poly.at(0).pow_Nc
 					== terms.at(i).pow_Nc && poly.at(0).pow_CF
 					== terms.at(i).pow_CF) {
 				was_found = true;
 
 				// Change the int_part (if no numerical factor)
 				// or the num factor of term to be added
 
 				// If already stored term, or part to be added, has a numeric part,
 				// store info in numeric part
 				if ( abs(poly.at(0).cnum_part-1.0) > accuracy or abs( terms.at(i).cnum_part -1.0 ) > accuracy) {
 
 					// Float to add to num, put numerical factor, and int_part,
 					// and sign here
 					cnum c_to_add;
 					c_to_add = poly.at(0).cnum_part;
 					c_to_add *= poly.at(0).int_part;
 
 					// Move int-part of existing to numeric part
 					terms.at(i).cnum_part *= terms.at(i).int_part;
 					terms.at(i).int_part = 1;
 
 					// Add cnum from the term
 					terms.at(i).cnum_part += c_to_add;
 				} else { //if no numeric part change the int-part instead
 					terms.at(i).int_part += poly.at(0).int_part;
 				}
 			}
 			// If, after this the i:th term is 0, remove it,
 			// to avoid carrying around 0's
 			if( ( terms.at(i).int_part==0 or terms.at(i).cnum_part==0.0 )  and terms.size()>1 ){
 				terms.erase(terms.begin()+i);
 			}
 
 		}
 		// If term not already there, add term
 		if ( !was_found and poly.at(0).int_part!=0 )
 			terms.push_back(poly.at(0));
 
 		// Erase the term in poly
 		poly.erase(poly.begin());
 	}
 
 	for (uint i = 0; i < terms.size() ; i++) {
 		// If term not already there, add term
 		if ((terms.at(i).int_part == 0 or terms.at(i).cnum_part == 0.0)
 				and terms.size() > 1) {
 			terms.erase(terms.begin() + i);
 		}
 	}
 	poly = terms;
 }
 
 
 void Polynomial::remove_CF() {
 
 	// If empty Polynomial, do nothing
 	if (poly.size() == 0)
 		return;
 	else{//non-empty polynomial
 		polynomial poly_res; // to contain the result
 		// Loop over terms in Polynomial and replace CF
 		for (uint i = 0; i < poly.size(); i++) {
 
 			// If the term contains no CF, simply keep in terms
 			if( poly.at(i).pow_CF == 0 )
 				poly_res.push_back( poly.at(i) );
 
 			// replace CF if raced to positive power
 			// (unless the int part is 0, in which case nothing should be added)
 			else if( poly.at(i).pow_CF > 0 and poly.at(i).int_part != 0){
 
 				// Factors given by binomial theorem
 				// one term for each power (Nc)^power_Nc (-1/Nc)^(pow_CF-power_Nc)
 				// i.e. TR ( (Nc)^power_Nc (-1/Nc)^(pow_CF-power_Nc) )
 				// =TR Nc^(power_Nc-(pow_CF-power_Nc))==TR Nc^(2*power_Nc-pow_CF)
 				Monomial const_fact=poly.at(i); // To contain the factor that was multiplying CF
 				const_fact.pow_CF=0; // replace CF
 				const_fact.pow_TR+=poly.at(i).pow_CF; // we always get a factor TR
 				for ( int power_Nc = 0; power_Nc <= poly.at(i).pow_CF; power_Nc++) {
 
 					Monomial term; // one term in (a+b)^n
 
 					// The corresponding binomial coefficient
 					int bin_coef=factorial( poly.at(i).pow_CF) /factorial( poly.at(i).pow_CF - power_Nc )/factorial( power_Nc );
 
 					term.pow_Nc=2*power_Nc-poly.at(i).pow_CF;
 					term=bin_coef*term*int(pow( -1.0, int( poly.at(i).pow_CF-power_Nc) ));// fix sign
 
 					// if the term is not 0, add it
 					if( term.int_part!=0 && const_fact.int_part!=0 )
 						poly_res.push_back( term*const_fact );
 				}// end looping over binomial factors
 			}// end if pow_CF>0
 
 
 			else if ( poly.at(i).pow_CF < 0 ) {
 				std::cerr << "Polynomial::remove_CF(): Warning: cannot replace negative powers of CF. Leaving Monomial term << "
 						<< poly.at(i) << " as it is." << std::endl;
 				poly_res.push_back( poly.at(i) );
 			}
 
 		}// end looping over Monomials in poly
 
 		// If, after this, poly_res is still empty, this is because nothing was added
 		// and the polynomial should be 0 (can for example happen for 0*CF)
 		if ( poly_res.empty() ) poly_res.push_back(Monomial("0"));
 		poly=poly_res;
 	}
 }
 
 
 void Polynomial::normal_order() {
 
 	// To contain the Polynomial in order
 	polynomial poly_ordered;
 
 	// Order the different Monomials in the Polynomial.
 	// Do this by moving the Monomials one by one to poly_ordered
 	while (poly.size() > 0) {
 		// Next monomial to put in place (the last Monomial in poly)
 		Monomial Mon_next = poly.at( poly.size() - 1 );
 
 		// Then insert the Mon_next among the ordered Monomials
 		// Count how many steps left Mon_next should be moved in poly_ordered
 		uint steps_left = 0;
 		while ( (steps_left < (poly_ordered.size())) && (!(Mon_next < poly_ordered.at(poly_ordered.size()-1-steps_left ))) ==1) {
 			steps_left++;
 		}
 
 		// Insert the Monomial in the right place among the ordered Col_strs
 		polynomial::iterator it=poly_ordered.end()-steps_left;
 		poly_ordered.insert( it, Mon_next);
 
 		// Erase the Monomial from poly
 		poly.erase(  poly.end()-1 ) ;
 	}
 	poly=poly_ordered;
 }
 
 
 int Polynomial::factorial( int i ) const{
 	if(i<0) {
 		std::cerr << "Polynomial::factorial: intended for int >=0, was " << i << std::endl;
 		std::cerr.flush();
 		assert( 0 );
 	}
 	if (i==0) return 1;
 	return factorial(i-1)*i; // Recursive call
 }
 
 
 std::ostream& operator<<( std::ostream& out, const Polynomial & Poly ) {
 
 	if (Poly.size() == 0)
 		out << "1";
 	else if (Poly.size() == 1) out << Poly.at(0);
 	else {
 		if (Poly.size() > 1)
 			out << "(";
 
 		for (int i = 0; i < Poly.size(); i++) {
 			out << Poly.at(i);
 			if (i != Poly.size() - 1)
 				out << " + ";
 		}
 
 		if (Poly.size() > 1)
 			out << ")";
 	}
 	return out;
 }
 
 
 std::ostream& operator<<(std::ostream& out, const polynomial & poly) {
 
 	if (poly.size() == 0)
 		out << "1";
 	else if (poly.size() == 1) out << poly.at(0);
 	else {
 		if (poly.size() > 1)
 			out << "(";
 		for ( uint i = 0; i < poly.size(); i++ ) {
 			out << poly.at(i);
 			if (i != poly.size() - 1)
 				out << " + ";
 		}
 		if (poly.size() > 1)
 			out << ")";
 	}
 	return out;
 }
 
 
 bool operator==( const Polynomial & Poly1, const Polynomial & Poly2){
 
 	if( Poly1.size() != Poly2.size() ) return false;
 
 	// All terms should be the same in order for Polynomials to be the same
 	for (int i=0; i < Poly1.size(); i++ ){
 		if( Poly1.at(i) != Poly2.at(i ) ) return false;
 	}
 
 	return true;
 }
 
 
 bool operator!=( const Polynomial & Poly1, const Polynomial & Poly2){
 	if( Poly1==Poly2) return false;
 	else return true;
 }
 
 
 Polynomial operator+(const Polynomial & Poly, const Monomial & Mon){
 
 	Polynomial out_Poly(Poly);
-	// If original Polynomial was empty=1, push_back dummy Monomial=1
+	// If original Polynomial was empty=1, append dummy Monomial=1
 	// (such that after the addition the Polynomial has indeed two terms)
 	if(out_Poly.empty()){
 		Monomial dummy_Mon;
-		out_Poly.push_back(dummy_Mon);
+		out_Poly.append(dummy_Mon);
 	}
 
 	// Add term unless it's 0
-	if(Mon.int_part != 0) out_Poly.push_back( Mon );
+	if(Mon.int_part != 0) out_Poly.append( Mon );
 
 	return out_Poly;
 }
 
 
 Polynomial operator-( const Polynomial & Poly, const  Monomial & Mon){
 
 	Monomial out_Mon(Mon);
 	// Change sing of Monomial
 	out_Mon.int_part*=(-1);
 	// Add term unless it's 0
 	return Poly+out_Mon;
 }
 
 
 Polynomial operator-(const Monomial & Mon, const Polynomial & Poly){
 
 	Polynomial out_Poly(Poly);
 
 	// If Poly is empty=1, add a default Monomial=1, which can change sign
 	if (out_Poly.empty()) {
 		Monomial dummy_Mon;
-		out_Poly.push_back(dummy_Mon);
+		out_Poly.append(dummy_Mon);
 	}
 
 	// Change sing of Polynomial, by looping over terms
 	for (uint m=0; m < out_Poly.poly.size(); m++)
 		out_Poly.poly.at(m).int_part*=(-1);
 
 	// Add Polynomial and Monomial
 	return out_Poly+Mon;
 }
 
 
 Polynomial operator+(const Monomial & Mon, const Polynomial & Poly ){
 
 	return Poly + Mon;
 }
 
 
 Polynomial operator+=( Polynomial & Poly, const Monomial & Mon ) {
 
-	// If original Poly was empty=1, push_back dummy Monomial=1
+	// If original Poly was empty=1, append dummy Monomial=1
 	// to make the Poly 1.
 	if ( Poly.empty() ) {
 		Monomial dummy_Mon;
-		Poly.push_back( dummy_Mon );
+		Poly.append( dummy_Mon );
 	}
 
-	if(Mon.int_part != 0) Poly.push_back( Mon );
+	if(Mon.int_part != 0) Poly.append( Mon );
 
 	return Poly;
 }
 
 
 Polynomial operator+=( Polynomial & Poly1, const Polynomial & Poly2 ) {
 
 	if (&Poly1 == &Poly2){
 		std::cerr << "operator+=: Polynomials need to have different address, both arguments " << Poly1
 				<< "."<<  std::endl;
 		assert(0);
 	}
 
-	// If original Poly2 was empty=1, push_back dummy Monomial=1
+	// If original Poly2 was empty=1, append dummy Monomial=1
 	// add a dummy Monomial to Poly1
 	if ( Poly2.empty() ) {
 		Monomial dummy_Mon;
-		Poly1.push_back( dummy_Mon );
+		Poly1.append( dummy_Mon );
 	}
 	// otherwise add Monomials from Poly2 to Poly 1
 	else for (int i = 0; i < Poly2.size(); i++) {
-		Poly1.push_back( Poly2.at(i) );
+		Poly1.append( Poly2.at(i) );
 	}
 
 	return Poly1;
 }
 
 
 Polynomial operator+( const Polynomial & Poly1, const Polynomial & Poly2) {
 
 	Polynomial out_Poly1(Poly1);
 	Polynomial out_Poly2(Poly2);
 
-	// If original Poly1 was empty=1, push_back dummy Monomial=1
+	// If original Poly1 was empty=1, append dummy Monomial=1
 	// after adding empty Monomial the Polynomial is still 1
 	if (out_Poly1.empty()) {
 		Monomial dummy_Mon;
-		out_Poly1.push_back(dummy_Mon);
+		out_Poly1.append(dummy_Mon);
 	}
-	// If original Poly2 was empty=1, push_back dummy Monomial=1
+	// If original Poly2 was empty=1, append dummy Monomial=1
 	// after adding empty Monomial the Polynomial is still 1
 	if (out_Poly2.empty()) {
 		Monomial dummy_Mon;
-		out_Poly2.push_back(dummy_Mon);
+		out_Poly2.append(dummy_Mon);
 	}
 
 	// Add terms from Poly2 to Poly1
 	for (int i = 0; i < out_Poly2.size(); i++) {
 		out_Poly1 = out_Poly1 + out_Poly2.at(i);
 	}
 
 	return out_Poly1;
 }
 
 
 Polynomial operator-( const Polynomial & Poly1, const Polynomial & Poly2 ) {
 
 	Polynomial out_Poly2(Poly2);
 
 	// If Poly2 is empty=1 make it contain a Monomial,
 	// as a Monomial by construction is 1
 	if(out_Poly2.empty()) {
 		Monomial dummy_Mon;
-		out_Poly2.push_back(dummy_Mon);
+		out_Poly2.append(dummy_Mon);
 	}
 
 	// Change sing of Poly2, by looping over terms
 	for (uint m=0; m < out_Poly2.poly.size(); m++)
 		out_Poly2.poly.at(m).int_part*=(-1);
 
 	// Now the subtraction is equal to an addition
 	// if Poly1 is empty this is taken care of in + operator
 	return Poly1+out_Poly2;
 }
 
 
 Polynomial operator*( const Polynomial & Poly, const int in ){
 
 	Polynomial out_Poly(Poly);
-	// If initially empty Polynomial=1, append empty Monomial=1, to have something to multiply with
+	// If initially empty Polynomial=1, append default Monomial=1, to have something to multiply with
 	Monomial dummy_Mon;
 	if (out_Poly.empty())
-		out_Poly.push_back(dummy_Mon);
+		out_Poly.append(dummy_Mon);
 
 	// Loop over terms in Polynomial
 	for (int i=0; i< out_Poly.size(); i++){
 		out_Poly.at(i).int_part=out_Poly.at(i).int_part*in;
 	}
 	return  out_Poly;
 }
 
 
 Polynomial operator*( const int i, const Polynomial & Poly ) {
 	return Poly * i;
 }
 
 
 Polynomial operator*( const Polynomial & Poly, const cnum c ) {
 
 	Polynomial out_Poly(Poly);
 
 	// If initially empty Polynomial=1, append empty Monomial=1, to have something to multiply with
 	Monomial dummy_Mon;
 	if (out_Poly.empty())
-		out_Poly.push_back(dummy_Mon);
+		out_Poly.append(dummy_Mon);
 
 	// Loop over terms in Polynomial
 	for (int i = 0; i < out_Poly.size(); i++) {
 		out_Poly.poly.at(i).cnum_part = out_Poly.at(i).cnum_part * c;
 	}
 	return out_Poly;
 }
 Polynomial operator*( const cnum c, const Polynomial & Poly ) {
 	return Poly * c;
 }
 
 
 Polynomial operator*( const Polynomial & Poly, const double d ) {
 
 	Polynomial out_Poly(Poly);
 
 	// If initially empty Polynomial=1, append empty Monomial=1, to have something to multiply with
 	Monomial dummy_Mon;
 	if (out_Poly.empty())
-		out_Poly.push_back(dummy_Mon);
+		out_Poly.append(dummy_Mon);
 
 	// Loop over terms in Polynomial
 	for (int i = 0; i < out_Poly.size(); i++) {
 		out_Poly.poly.at(i).cnum_part = out_Poly.at(i).cnum_part * d;
 	}
 	return out_Poly;
 }
 Polynomial operator*(const double d, const Polynomial & Poly) {
 	return Poly * d;
 }
 
 
 Polynomial operator*( const Polynomial & Poly, const Monomial & Mon ){
 
 	// To contain the result
 	Polynomial Poly_res;
 
 	// Special case that the Polynomial is empty=1
 	if( Poly.empty() ) {
-		Poly_res.push_back(Mon);
+		Poly_res.append(Mon);
 		return Poly_res;
 	}
 	else{
 		for (int i1=0; i1< Poly.size(); i1++){
-			Poly_res.push_back( Poly.at(i1)*Mon );
+			Poly_res.append( Poly.at(i1)*Mon );
 		}
 	}
 	return Poly_res;
 }
 Polynomial operator*( const Monomial & Mon, const Polynomial & Poly ){
 
 	return  Poly*Mon;
 }
 
 
 Polynomial operator*( const Polynomial & Poly1, const Polynomial & Poly2 ){
 
 	// To contain the result
 	Polynomial Poly_res;
 
 	// Special case that the vectors are empty=1, needed for special treatment of sum of 0-monomials
 	// Poly_res is also empty, and thus =1, 1*1=1
 	if(Poly1.empty() && Poly2.empty()){
 		return Poly_res;
 	}
 
 	// If one Poly is empty, =1, return other
 	if(!Poly1.empty() && Poly2.empty() ) return Poly1;
 	else if( Poly1.empty() && !Poly2.empty()) return Poly2;
 	// If both vectors contain info
 	else {
 		for (int i1=0; i1< Poly1.size(); i1++){
 			for (int i2=0; i2< Poly2.size(); i2++){
 				// Add terms if non of them is 0, else just don't add
 				if( Poly1.at(i1).int_part!=0 && Poly2.at(i2).int_part!=0  )
-					Poly_res.push_back(Poly1.at(i1)*Poly2.at(i2));
+					Poly_res.append(Poly1.at(i1)*Poly2.at(i2));
 			}
 		}
 		// If, by now, the Poly_res is empty that's because all terms were 0
 		if( Poly_res.empty() ){
 			Monomial Mon_tmp;
 			Mon_tmp.int_part=0;
-			Poly_res.push_back( Mon_tmp );
+			Poly_res.append( Mon_tmp );
 		}
 	}
 
 	return Poly_res;
 }
 
+
+Polynomial operator*=( Polynomial & Poly, const int in ){
+
+	// If initially empty Polynomial=1, append default Monomial=1, to have something to multiply with
+	Monomial dummy_Mon;
+	if ( Poly.empty())
+		Poly.append(dummy_Mon);
+
+	// Loop over terms in Polynomial
+	for (int i=0; i< Poly.size(); i++){
+		Poly.at(i).int_part*= in;
+	}
+	return  Poly;
+}
+
+
+Polynomial operator*=( Polynomial & Poly, const double d ){
+
+	// If initially empty Polynomial=1, append default Monomial=1, to have something to multiply with
+	Monomial dummy_Mon;
+	if ( Poly.empty())
+		Poly.append(dummy_Mon);
+
+	// Loop over terms in Polynomial
+	for (int i=0; i< Poly.size(); i++){
+		Poly.at(i).cnum_part*= d;
+	}
+	return  Poly;
+}
+
+Polynomial operator*=( Polynomial & Poly, const cnum c ){
+
+	// If initially empty Polynomial=1, append default Monomial=1, to have something to multiply with
+	Monomial dummy_Mon;
+	if ( Poly.empty())
+		Poly.append(dummy_Mon);
+
+	// Loop over terms in Polynomial
+	for (int i=0; i< Poly.size(); i++){
+		Poly.at(i).cnum_part *= c;
+	}
+	return  Poly;
+}
+
+
+Polynomial operator*=( Polynomial & Poly, const Monomial & Mon ){
+
+	// Special case that the Polynomial is empty=1
+	if( Poly.empty() ) {
+		Poly.append(Mon);
+		return Poly;
+	}
+	else{
+		for( int i1=0; i1< Poly.size(); i1++ ){
+			Poly.at(i1)*=Mon;
+		}
+	}
+	return Poly;
+}
+
+Polynomial operator*=( Polynomial & Poly1, const Polynomial & Poly2 ){
+
+	Poly1=Poly1*Poly2;
+	return Poly1;
+}
+
 }// end namespace ColorFull
 
 
 
diff --git a/MatrixElement/Matchbox/ColorFull/Polynomial.h b/MatrixElement/Matchbox/ColorFull/Polynomial.h
--- a/MatrixElement/Matchbox/ColorFull/Polynomial.h
+++ b/MatrixElement/Matchbox/ColorFull/Polynomial.h
@@ -1,205 +1,224 @@
 // -*- C++ -*-
 /*
  * Polynomial.h
  *	Contains declaration of the class Polynomial and associated types and operators.
  *  Created on: Jul 7, 2010
  *  Author: Malin Sjodahl
  */
 
 #ifndef COLORFULL_Polynomial_h
 #define COLORFULL_Polynomial_h
 
 #include "Monomial.h"
 
 namespace ColorFull {
 
 /// For containing the info (as opposed to the functions) of a Polynomial.
 /// The Polynomial is essentially a sum of Monomials, contained in a
 /// vector of Monomials.
 /// Note that a Monomial "is" TR^a Nc^b CF^c* int_part*cnum_part where int_part is an
 /// integer factor and cnum_part a complex numerical factor.
 /// An empty polynomial is defined as 1.
 typedef std::vector < Monomial > polynomial;
 
 
 /// For containing a Polynomial (in Nc, CF and TR), as a sum of Monomials.
 /// Note that a Monomial "is" TR^a*Nc^b*CF^c*int_part*cnum_part where int_part is an
 /// integer factor, cnum_part a complex numerical factor and a,b, and c integers
 /// (not necessarily positive).
 /// An empty Polynomial is defined as 1.
 class Polynomial {
 public:
 
-	/// Default constructor.
+	/// Default constructor, leaves polynomial empty=1.
 	Polynomial(){};
 
 	/// Constructor allow setting the polynomial by using a string.
 	/// Should be used as for example "Polynomial Poly("(-20*TR^(5))/Nc + 28*Nc*TR^(5) - 10*Nc^3*TR^(5)")".
 	/// The Momomials should be separated by + or -, see also the
 	/// Monomial string constructor.
 	Polynomial( const std::string str );
 
-	/// Constructor allow setting the Polynomial using a double,
+	/// Constructor allowing setting the Polynomial using a double.
 	/// The Polynomial gets one Monomial where the real part of
 	/// cnum_part gets the value of dnum.
 	Polynomial( double dnum );
 
-	/// Constructor allow setting the Polynomial using an int,
+	/// Constructor allowing setting the Polynomial using an int.
 	/// The Polynomial gets one Monomial where int_part
 	/// has the value num.
 	Polynomial( int num );
 
 	/// Contains the polynomial, a sum of Monomials, as an std::vector
 	/// of Monomials.
 	/// An empty Polynomial is defined as 1, to get 0, multiply with 0.
 	polynomial poly;
 
 	/// Function for reading in the Polynomial from the file filename,
 	/// uses Polynomial_of_str.
 	void read_in_Polynomial( std::string filename );
 
-	/// Function for writing out the Quark_linePolynomial to a file
+	/// Function for writing out the Polynomial to a file
 	/// with name filename.
 	void write_out_Polynomial( std::string filename ) const;
 
-	/// Returning Monomial at place i.
+	/// Returns Monomial at place i.
 	const Monomial& at( int i ) const {return poly.at(i);}
 
-	/// Returning Monomial at place i.
+	/// Returns Monomial at place i.
 	Monomial& at( int i ) {return poly.at(i);}
 
-	/// Returning number of terms in Polynomial.
+	/// Returns the number of terms in the Polynomial.
 	int size() const {return poly.size();}
 
-	/// Adding Monomial term.
-	void push_back( const Monomial Mon ) {poly.push_back(Mon);}
+	/// Adding a Monomial term.
+	void append( const Monomial Mon ) {poly.push_back(Mon);}
 
-	/// Erase the Monomial at place i.
+	/// Erases the Monomial at place i.
 	void erase( int i ) {poly.erase(poly.begin() + i);}
 
 	/// Is the polynomial empty?
 	bool empty() const {return poly.empty();}
 
-	/// Erase info in polynomial.
+	/// Erases info in polynomial.
 	void clear() {poly.clear();}
 
 	/// Take complex conjugate of the polynomial.
 	/// Note that this changes the Polynomial itself.
 	void conjugate();
 
 	/// Collects terms with same power of TR and Nc and Cf.
 	void simplify();
 
-	/// Replaces CF as TR*Nc-TR/Nc.
+	/// Replaces CF with TR*Nc-TR/Nc.
 	void remove_CF();
 
-	/// Order terms in Polynomial in a unique form,
+	/// Orders terms in Polynomial in a unique form,
 	/// first according to pow_Nc+pow_CF, then according to pow_Nc (for same pow_Nc+pow_CF)
 	/// then according to int_part*num, then according to int_part, and finally according to pow_TR.
 	void normal_order();
 
 private:
 	/// The factorial of an int.
 	int factorial (int i) const;
 
 	/// Function for setting the Polynomial using a string,
 	/// used by string constructor.
 	/// The Momomials should be separated by + or -, see also the
 	/// Monomial string constructor.
 	void Polynomial_of_str( const std::string str );
 
 };
 
 /// Define the operator << for Polynomial.
 std::ostream& operator<<(std::ostream& out, const Polynomial & Poly);
 
 /// Define the operator << for polynomial.
 std::ostream& operator<<(std::ostream& out, const polynomial & poly);
 
 /// Define the operator == for Polynomial
 /// By definition, each Monomial has to be identical,
 /// as order matters 1+2 is not 2+1.
 bool operator==( const Polynomial & Poly1, const Polynomial & Poly2);
 
-
 /// Operator != for Polynomial. Returns false if Poly1==Poly2, and
 /// true otherwise.
 bool operator!=( const Polynomial & Poly1, const Polynomial & Poly2 );
 
 /// Operator + for Polynomial and a single Monomial.
 Polynomial operator+(const Polynomial & Poly, const Monomial & Mon );
 
 /// Operator + for a single Monomial and a Polynomial,
 /// returns Poly+Mon.
 Polynomial operator+(const Monomial & Mon, const Polynomial & Poly );
 
 /// Define the operator += for Polynomials.
 /// The Monomial is appended unless Mon.int_part=0.
 Polynomial operator+=( Polynomial & Poly, const Monomial & Mon );
 
 /// Define the operator += for Polynomials.
 /// This operator appends the Monomials of Poly2 to Poly1.
 Polynomial operator+=( Polynomial & Poly1, const Polynomial & Poly2 );
 
 /// Operator - for Polynomial and a single Monomial.
 /// Changes sign of Monomial by changing int_part and returns Poly+(-Mon).
 Polynomial operator-(const Polynomial & Poly, const Monomial & Mon);
 
 /// Operator - for Polynomial and a single Monomial
 /// changes the sign of Poly by changing int_part,
 /// and then adds Mon to (-Poly).
 Polynomial operator-(const Monomial & Mon, const Polynomial & Poly);
 
 /// Operator + for Polynomials, appends Momomails from Poly2 to Poly1.
 /// If one of the Polynomials is empty=1, this is compensated for by first
 /// appending a Monomial=1 to the empty Polynomial.
 Polynomial operator+( const Polynomial & Poly1, const Polynomial & Poly2 );
 
 /// Operator - for Polynomials,
 /// changes sign of Poly2, and then returns Poly1 + (-Poly2).
 Polynomial operator-(const Polynomial & Poly1, const Polynomial & Poly2);
 
 /// Operator * for Polynomial and int,
 /// loops over Monomials and multiplies int_part with i.
 /// If Poly is empty=1, a default Monomial=1 is first
 /// appended to Poly.
-Polynomial operator*(const Polynomial & Poly, int i);
+Polynomial operator*( const Polynomial & Poly, int i );
 
 /// Operator * for int and Polynomial.
 /// Returns Poly*i.
-Polynomial operator*(int i, const Polynomial & Poly);
+Polynomial operator*( int i, const Polynomial & Poly );
 
 /// Operator * for Polynomial and cnum,
 /// loops over Monomials and multiplies cnum_partwith c.
 /// If Poly is empty=1, a default Monomial=1 is first
 /// appended to poly.
-Polynomial operator*( const Polynomial & Poly, const cnum c);
+Polynomial operator*( const Polynomial & Poly, const cnum c );
 
 /// Operator * for cnum and Polynomial, returns Poly*c.
-Polynomial operator*( const cnum c, const Polynomial & Poly);
+Polynomial operator*( const cnum c, const Polynomial & Poly );
 
 /// Operator * for Polynomial and double,
 /// loops over Monomials and multiplies cnum_partwith d.
 /// If Poly is empty=1, a default Monomial=1 is first
 /// appended to poly.
 Polynomial operator*( const Polynomial & Poly, const double d );
 
 /// Operator * for Polynomial and double, returns Poly*d.
 Polynomial operator*( const double d, const Polynomial & Poly );
 
 /// Operator * for Polynomial and Monomial, loops over Monomials in
 /// Poly, and multiplies each with Mon. If Poly is empty=1,
 /// a Polynomial with one Monomial=Mon is returned.
 Polynomial operator*( const Polynomial & Poly, const Monomial & Mon );
 
 /// Operator * for Monomial and Polynomial,
 /// returns Poly*Mon.
 Polynomial operator*( const Monomial & Mon, const Polynomial & Poly );
 
 /// Operator * for Polynomials. (For details, see code.)
 Polynomial operator*( const Polynomial & Poly1, const Polynomial & Poly2 );
 
+/// Operator *= for Polynomial and int.
+/// Multiplies Poly with i.
+Polynomial operator*=( Polynomial & Poly, const int i );
+
+/// Operator *= for Polynomial and double.
+/// Multiplies Poly with d.
+Polynomial operator*=( Polynomial & Poly, const double d );
+
+/// Operator *= for Polynomial and cnum.
+/// Multiplies Poly with c.
+Polynomial operator*=( Polynomial & Poly, const cnum c );
+
+/// Operator *= for Polynomial and Monomial.
+/// Multiplies Poly with Mon.
+Polynomial operator*=( Polynomial & Poly, const Monomial & Mon );
+
+/// Operator *= for Polynomial and Polynomial.
+/// Multiplies Poly1 with Poly2.
+Polynomial operator*=( Polynomial & Poly1, const Polynomial & Poly2 );
+
 }
 
 
 #endif /* COLORFULL_Polynomial_h */
diff --git a/MatrixElement/Matchbox/ColorFull/Quark_line.cc b/MatrixElement/Matchbox/ColorFull/Quark_line.cc
--- a/MatrixElement/Matchbox/ColorFull/Quark_line.cc
+++ b/MatrixElement/Matchbox/ColorFull/Quark_line.cc
@@ -1,768 +1,799 @@
 // -*- C++ -*-
 /*
  * Quark_line.cc
  *	Contains definitions of the class Quark_line and associated types and operators.
  *  Created on: Jul 7, 2010
  *  Author: Malin Sjodahl
  */
 
 #include "Quark_line.h"
 #include <cassert>
 #include <fstream>
 #include <iostream>
 #include <limits>
 
 
 namespace ColorFull {
 
 Quark_line::Quark_line( const std::string str ) {
 	Quark_line_of_str( str );
 }
 
 
 Quark_line::Quark_line() {
 	// member set just to avoid complaints
 	open=true;
 }
 
 
 int Quark_line::at( int j ) const{
 	int size = ql.size();
 	if (0 <= j and j < size)
 		return ql.at(j);
 	else if ( !open and (size <= j && j < 2 * size) )
 		return ql.at(j - ql.size());
 	else if ( !open and (-size < j and j < 0) )
 		return ql.at(j + size);
 
 	std::cerr << "Quark_line::at(j): j=" << j << " is out of range" << std::endl;
 	std::cerr.flush();
 	assert(0);
 	return 0;
 
 }
 
 
 void Quark_line::Quark_line_of_str( const std::string str ){
 
 	int j=0;
 
 	// Check that the string contains a comma
 	bool contains_comma=false;
 	while (j < (int)str.size()) {
 		if(str.at(j)==',') contains_comma=true;
 		j++;
 	}
 	if( !contains_comma ){
 		std::cerr << "Quark_line::Quark_line_of_str: The string " << str
 				<< " contains no comma. Each quark_line must contain a comma since (g1)=0"
 				<< " and for each quark, there is an anti-quark.";
 		assert(0);
 
 	}
 
 	// Check that left and right brackets match up
 	j=0;
 	int left_brackets=0,right_brackets=0;
 	while (j < (int)str.size()) {
 		if(str.at(j)=='(') left_brackets++;
 		if(str.at(j)==')') right_brackets++;
 		j++;
 	}
 	if(left_brackets != right_brackets){
 		std::cerr << "Quark_line::Quark_line_of_str: The brackets in the Quark_line\"" << str <<"\" do not seem to match up. There were "
 				<< left_brackets <<" left bracket(s) and "<< right_brackets << " right bracket(s)." << std::endl;
 		assert( 0 );
 	}
 
 	// Check that left and right curly brackets match up
 	left_brackets=0,right_brackets=0;
 	j=0;
 	while (j < (int)str.size()) {
 		if(str.at(j)=='{') left_brackets++;
 		if(str.at(j)=='}') right_brackets++;
 		j++;
 	}
 	if(left_brackets != right_brackets){
 		std::cerr << "Quark_line::Quark_line_of_str: The curly brackets in the Quark_line\"" << str <<"\" do not seem to match up. There were "
 				<< left_brackets <<" left bracket(s) and "<< right_brackets << " right bracket(s)." << std::endl;
 		assert( 0 );
 	}
 
 	if( left_brackets > 1){
 		std::cerr << "Quark_line::Quark_line_of_str: Found " << left_brackets << " curly left brackets in the string " << str
 				<<" but there should be at most 1;" << std::endl;
 		assert( 0 );
 	}
 
 	// The string should be split into a part containing the quark_line
 	int i=0;
 	std::string Poly_str, ql_str;
 	Poly_str.clear();
 	ql_str.clear();
 
 	// If there were curly brackets just read until one is found
 	if( left_brackets>0 ) {
 		while( i< (int)str.size() and str.at(i)!='{'){
 			Poly_str.push_back(str.at(i));
 
 			i++;
 		}
 	}
 	// If no curly brackets, look for ,
 	else {
 		// See if the Col_str contains ",",
 		// then we know that we should look backwards
 		// until the ( is found
 		int first_comma=0;
 		j=0;
 		while ( j < (int)str.size() and first_comma==0 ) {
 			if(str.at(j)==',') first_comma=j;
 			j++;
 		}
 
 		if (first_comma>0){
 			j=first_comma;
 			while (j>=0 and str.at(j)!= '(') {
 				j--;
 			}
 		}
 		// We should have found a (
 		if (j==0 and str.at(j)!= '('){
 			std::cerr << "Quark_line::Quark_line_of_str: Found no starting bracket in string" << str << std::endl;
 			assert( 0 );
 		}
 
 		// Now, the quark_line starting ( is at place j
 		i=0;
 		while(i<j){
 			Poly_str.push_back(str.at(i));
 			i++;
 		}
 	}
 
 	// The rest of the string contains the quark_line
 	while( i < (int)str.size() ){
 		ql_str.push_back(str.at(i));
 		i++;
 	}
 
 	// Assigning info
 	Poly=Polynomial(Poly_str);
 	quark_line_of_str(ql_str);
 
 }
 
 
 void Quark_line::read_in_Quark_line( std::string filename ) {
 
 	// Read in file
 	std::ifstream fin( filename.c_str() );
 
 	// Check that file exists
 	if( !fin ){
 		std::cerr << "Quark_line::read_in_Quark_line: The file "
 				<< filename << " could not be opened." << std::endl;
 		assert( 0 );
 
 	}
 
 	// Erase current information
 	ql.clear();
 	Poly.clear();
 
 	// Copy info from file to string
 	std::string str((std::istreambuf_iterator<char>(fin)), std::istreambuf_iterator<char>());
+
+	// Skip lines starting with #
+	while( str.at(0)== '#' ){
+		while (str.at(0) != '\n'){
+			str.erase(str.begin());
+		}
+		// erase endl sign(s)
+		while(str.at(0)== '\n'){
+			str.erase(str.begin());
+		}
+	}
+
+	// Remove endl chars at the end of the file
+	while( str.at(str.size()-1) == '\n' ) str.erase(str.size()-1);
 	Quark_line_of_str( str );
 }
 
 
 //uint Quark_line::size() const{ return ql.size();}
 
 void Quark_line::quark_line_of_str(std::string str) {
 	//std::cout << "quark_line_of_str, got \"" << str.c_str() << "\""<< endl;
 
 	// First char tells if the string is open or not
 	if (str.at(0) == '{')
 		open = true;
 	else if (str.at(0) == '(')
 		open = false;
 	else {
 
 		std::cerr << "Quark_line::quark_line_of_str: First and last char in Quark_line should be '{}' for open or '()' as in closed. It was: "
 				<< str.at(0) << std::endl;
 		std::cerr.flush();
 		assert(0);
 	}
 
 	// Next parton to be added (as string)
 	std::string parton_str;
 	// Next parton to be added (as int)
 	int parton_num;
 
 	// To keep track of the place
 	uint i = 1;
 	// Loop over characters in string, last char is '}' or ')'
 	while (i < str.size() - 1) {
 		// When a ',' is found, write content in parton_str to the
 		// quark_line and
 		if (str.at(i) == ',') {
 			std::istringstream parton_str_st(parton_str);
 			parton_str_st >> parton_num;
 			ql.push_back(parton_num);
 			i++;
 			// Empty parton string to prepare for new content
 			parton_str.clear();
 		}
 		while (i < str.size() - 1 && str.at(i) != ',') {
 			parton_str.push_back(str.at(i));
 			i++;
 		}
 	}
 	// Adding last term
 	std::istringstream parton_str_st(parton_str);
 	parton_str_st >> parton_num;
 	ql.push_back(parton_num);
 
 	if (str.at(str.size() - 1) != ')' && str.at(str.size() - 1) != '}') {
 		std::cerr
 		<< "Quark_line::quark_line_of_str:  Last char in Quark_line should match '{' for open or '(' as for closed. It was: "
 		<< str.at(str.size() - 1) << std::endl;
 		std::cerr.flush();
 		assert(0);
 	}
 }
 
 
 void Quark_line::write_out_Quark_line( std::string filename ) const {
 
 	if ((ql.size() == 0)) {
 		std::cout
 		<< "Quark_line::write_out_Quark_line: The Quark_line is empty."
 		<< std::endl;
 		std::cout.flush();
 		return;
 	}
 
 	std::ofstream outfile(filename.c_str());
 
 	if ( !outfile )
 	std::cerr << "Quark_line::write_out_Quark_line: Cannot write out Quark_line as the file \""
 		<< filename.c_str() << "\" could not be opened. (Does the directory exist? Consider creating the directory.)" << std::endl;
 
 	outfile << *this;
 }
 
 
 void Quark_line::normal_order() {
 	// Do nothing if the quark_line is empty
 	if (ql.empty())
 		return;
 
 	if (!open) {
 		// For storing smallest gluon number (should be first in normal ordering)
 		int smallest = at(0);
 		int place = 0;
 
 		for (uint j = 1; j < ql.size(); j++) {
 			if (at(j) < smallest) {
 				smallest = at(j);
 				place = j;
 			}
 
 			// If indices are equal, check next
 			else if (at(j) == smallest) {
 				// Keep checking next until a difference is found
 				// or all elements are compared
 				int k = 1;
 				while (at(j + k) == at(place + k) && k < static_cast<int>(ql.size()))
 					k++;
 				// Now, at place j+k, the indices are different
 				// Change place if smaler
 				if (at(j + k) < at(place + k)) {
 					place = j;
 				}
 			}
 		}
 		// Not the place of the lowest index is located and the quark_lins should
 		// start with that index
 		// Move elements before place of lowest number to the end
 		for (int j = 0; j < place; j++) {
 			ql.push_back(at(0));
 			ql.erase(ql.begin());
 		}
 	}
 }
 
 
 void Quark_line::conjugate( ) {
 
 	Poly.conjugate();
 
 	// To contain the conjugated quark_line
 	quark_line ql_new;
 
 	// Take conjugate by reversing order of all partons in the Quark_line
 	for (int i=ql.size()-1; i>=0;){
 		ql_new.push_back( ql.at(i) );
 		i--;
 	}
 
 	ql=ql_new;
 }
 
 // Returns a Quark_line with the the elements before j in a Quark_line
 Quark_line Quark_line::before(  int j ) const{
 	//cout << "before( Quark_line Ql, int j ): the size was " << static_cast<int>(Ql.ql.size());
 	//cout << "for the Quark_line " << Ql << endl;
 
 	Quark_line Ql_copy=*this;
 
 	if( j<0 or j> static_cast<int>( ql.size()-1) ){
 		std::cerr << "Quark_line::before( int j ): the size was " << static_cast<int>( ql.size() );
 		std::cerr << "for the quark_line " << *this << std::endl;
 		std::cerr.flush();
 		std::cerr <<"before: the argument must be >=0 and inside vector, was " << j << std::endl;
 		std::cerr.flush();
 		assert(0);
 	}
 
 	// In first part erase everything after and including j
 	quark_line::iterator it1=Ql_copy.ql.begin()+j;
 	quark_line::iterator it2=Ql_copy.ql.end();
 
 
 	Ql_copy.ql.erase(it1, it2);
 
 	return Ql_copy;
 }
 
 
 Quark_line Quark_line::after( int j ) const{
 
 	Quark_line Ql_copy=*this;
 
 	if(j<0 or j> static_cast<int>( ql.size()-1)){
 		std::cerr <<"Quark_line::after: the argument must be >=0 and inside vector, was " << j << std::endl;
 		std::cerr.flush();
 		assert(0);
 	}
 
-	// In first part erase everything after and including j
+	// In first part, erase everything after and including j
 	quark_line::iterator it1=Ql_copy.ql.begin();
 	quark_line::iterator it2=Ql_copy.ql.begin()+j+1;
 	Ql_copy.ql.erase(it1, it2);
 
 	return Ql_copy;
 }
 
 
 void Quark_line::erase( int i ){
 	ql.erase( ql.begin()+i );
 }
 
 
-void Quark_line::append( int p ){
-	ql.insert( ql.end(), p );
-}
-
-
 void Quark_line::append(  const std::vector<int> & in_ql ){
 	for (uint j=0; j<in_ql.size(); j++ ){
 		ql.push_back( in_ql.at(j) );
 	}
 }
 
 
 void Quark_line::prepend( int p){
 	ql.insert( ql.begin(), p );
 }
 
 
-void Quark_line::prepend( std::vector<int> in_ql ){
+void Quark_line::prepend(std::vector <int> in_ql){
 	for (uint j=0; j<ql.size(); j++ ){
 		in_ql.push_back(ql.at(j));
 	}
 	ql=in_ql;
 }
 
 
 void Quark_line::insert( int j, int p ){
 	if( j< static_cast<int> ( ql.size() ) and j>=0 )
 	{
 		quark_line::iterator itj = ql.begin() + j;
 		ql.insert(itj, p);
 	}
 	else if( j>= static_cast<int> ( ql.size() )) {
 		std::cerr << "Quark_line::insert: The size of ql is " << ql.size()
 									<< ", so no parton can be inserted at place " << j
 									<< " in " << *this << std::endl;
 		assert(0);
 	}
 	else if( j<0 ) {
 		std::cerr << "Quark_line::insert: Can not insert at place " << j
 				<< " < 0 in " << *this << std::endl;
 		assert(0);
 	}
 }
 
 
 std::pair< Quark_line, Quark_line > Quark_line::split_Quark_line( int j1, int j2 ) const{
 
 	if(open){
 		std::cerr <<"Quark_line::split_Quark_line: expects a closed quark_line" << std::endl;
 		std::cerr.flush();
 		assert(0);
 	}
 	Quark_line Ql1=*this;
 	Quark_line Ql2=*this;
 
 	// In first part erase everything between j1 and j2
 	quark_line::iterator it1=Ql1.ql.begin()+j1;
 	quark_line::iterator it2=Ql1.ql.begin()+j2;
 	Ql1.ql.erase(it1, it2+1);
 
 	// In second part, erase from j2...
 	it1=Ql2.ql.begin()+j1;
 	it2=Ql2.ql.begin()+j2;
 	Ql2.ql.erase( it2, Ql2.ql.end() );
 	// ... and before j1
 	Ql2.ql.erase( Ql2.ql.begin(), it1+1 );
 
 	return std::make_pair(Ql1,Ql2);
 
 }
 
 int Quark_line::smallest(const Quark_line & Ql1, const Quark_line & Ql2) const {
 
 	// If only one is open, that Ql should stand first
 	if (Ql1.open && !Ql2.open)
 		return 1;
 	else if (Ql2.open && !Ql1.open)
 		return 2;
 
 	// If both are open or both are closed, the longest should stand first
 	else if (Ql1.ql.size() > Ql2.ql.size())
 		return 1;
 	else if (Ql2.ql.size() > Ql1.ql.size())
 		return 2;
 
 	// If the size is the same, the Ql with smallest starting number should stand first
 	// If the first number is the same, check the 2nd number, then the 3rd...
 	else {
 		// Loop over places in the Ql's
 		for (uint j = 0; j < Ql1.ql.size(); j++) {
 			if (Ql1.ql.at(j) < Ql2.ql.at(j))
 				return 1;
 			if (Ql2.ql.at(j) < Ql1.ql.at(j))
 				return 2;
 		}
 		// If the Ql's are equal, return 0
 		return 0;
 	}
 }
 
 
 void Quark_line::contract_neighboring_gluons(int j) {
 
 	if (ql.empty())
 		return;
 
 	if (open) {
 		std::cerr
 				<< "Quark_line::contract_neighboring_gluons(j): Expects a closed Quark_line, got "
 				<< *this << std::endl;
 		assert(0);
 	}
 
 	// If asked for -1st element, check last
 	if (j == -1)
 		j = size() - 1;
 	// If asked for last+1 element, check first
 	if (j == static_cast<int>(ql.size() - 1))
 		j = 0;
 
 	// Keep contracting gluons as long as:
 	// there are at least two gluons to contract
 	// neighbors are equal
 	// and j is not the last parton in the ql
 	while (j < static_cast<int>(size() - 1) && (size()) >= 2
 			&& (at(j)) == at(j + 1)) {
 
 		quark_line::iterator it1 = ql.begin() + j;
 		quark_line::iterator it2 = ql.begin() + j + 2;
 
 		// Removing neighboring gluons
 		ql.erase(it1, it2);
 
 		// This should increase the power of CF
 		Monomial Mon_tmp;
 		Mon_tmp.pow_CF = 1;
-		Poly = Poly * Mon_tmp;
+		Poly *= Mon_tmp;
 		if (j > 2)
 			j = j - 2;
 	}
 
 	// If j is the last parton and the Quark_line is closed and first=last
 	// and there are at least 2 gluons
 	while (static_cast<int>(size()) >= 2 && j == static_cast<int>(size() - 1)
 			&& !open && at(0) == at(size() - 1)) {
 
 		quark_line::iterator it1 = ql.begin();
 		quark_line::iterator it2 = ql.end() - 1;
 		ql.erase(it2);
 		ql.erase(it1);
 
 		// This should increase the power of CF
 		Monomial Mon_tmp;
 		Mon_tmp.pow_CF = 1;
-		Poly = Poly * Mon_tmp;
+		Poly *= Mon_tmp;
 
 		// If now, all gluons are removed and there are no quarks,
 		// increase Nc and open the ql (if not already open)
 		// An open quark-line with no partons is defined as 1
 		if (empty() && !open) {
 			Monomial Mon_tmp;
 			Mon_tmp.pow_Nc = 1;
-			Poly = Poly * Mon_tmp;
+			Poly *= Mon_tmp;
 			open = true;
 		}
 		j = j - 2;
 	}
 }
 
 void  Quark_line::contract_neighboring_gluons( ){
 
 	if( empty() ) return;
 
 	if( open ){
 		std::cerr << "uark_line::contract_neighboring_gluons( ): Expects a closed Quark_line, got "
 				<< *this << std::endl;
 		assert(0);
 	}
 
 	// Counting powers of CF,
 	// Should be increases once for every gluon that is contracted
 	// initially put to dummy value, minimal int
 	int CF_pow_old=std::numeric_limits<int>::min();
 	int CF_pow_new=0;
 
 	// Keep looping over elements as long as CF_pow changes
 	while( CF_pow_old!= CF_pow_new ){
 		CF_pow_old=CF_pow_new;
 
 		// Loop over elements in the Quark_line, starting at first parton
 		// and ending with last
 		for (uint j=0; j < size(); j++){
 			contract_neighboring_gluons( j );
 		}
 		// To see if CF_pow changed, arbitrarily compare 0th element in Polynomial (if existing)
 		// (all pow_CF changes)
 		if( !Poly.empty() )
 			CF_pow_new=Poly.at(0).pow_CF; // put CF_pow_new to current pow
 	}
 
 	return ;
 }
 
 
 void Quark_line::contract_next_neighboring_gluons( int j ) {
 
 	if( ql.empty()) return;
 
 	if( open ){
 		std::cerr << "Quark_line::contract_next_neighboring_gluons( j): Expects a closed Quark_line, got "
 				<< *this << std::endl;
 		assert(0);
 	}
 
 	// If asked for -1st element, check last
 	if(j==-1) j=ql.size()-1;
 	// If asked for -2nd element, check second last
 	if(j==-2) j=ql.size()-2;
 
 	// Keep track of changes in number of gluons
 	// add dummy number '1' to run at least once
 	int old_size=ql.size()+1;
 
 	// Loop over index in quark_line as long as the size keep changing,
 	// or at least once
 	while( old_size!=  static_cast<int>(ql.size()) &&  (ql.size())>=4){
 		old_size=  (ql.size());
 		// There are three cases:
 		// the normal case, and, if the Quark_line is closed,
 		// 2nd last =first (0th) and  last =2nd (1st)
 		bool normal_case=(ql.size()>=4 && static_cast<uint>(j)< ql.size()-2 && ql.at(j)==ql.at(j+2));
 		bool second_last_case=( ql.size()>=4 && !open && static_cast<uint>(j)==ql.size()-2 &&  ql.at(j)==ql.at(0) );
 		bool last_case=(ql.size()>=4 && !open && static_cast<uint>(j)==ql.size()-1 &&  ql.at(j)==ql.at(1));
 		// See if next to neighbors are equal
 		// The point of having a while is to check again if one pair was found
 		while(normal_case or second_last_case or last_case) {
 
 			// Erase the gluons (at places depending on size)
 			quark_line::iterator it1;
 			quark_line::iterator it2;
 			if(normal_case){
 				it1=ql.begin()+j;
 				it2=ql.begin()+j+2;
 			}
 			else if(second_last_case){
 				it1=ql.begin();
 				it2=ql.end()-2;
 			}
 			else if(last_case){
 				it1=ql.begin()+1;
 				it2=ql.end()-1;
 			}
 			// Erase right most gluon first
 			ql.erase(it2);
 			ql.erase(it1);
 
 			// The surviving term comes with -TR/(Nc)
 			Monomial Mon_tmp;
 			Mon_tmp.pow_TR = 1;
 			Mon_tmp.int_part=-1;
 			Mon_tmp.pow_Nc=-1;
-			Poly=Poly*Mon_tmp;
+			Poly *= Mon_tmp;
 
 			// Check if new neighbors are equal
 			uint old_size2=ql.size();
 			// Check if inbetween gluon is now neighbor with itself to the right
 			contract_neighboring_gluons( j );
 			// Check if inbetween gluon is now neighbor with itself to the left
 			contract_neighboring_gluons( j-1 );
 			// if a neighboring pair was removed
 			if(  (ql.size()) != old_size2 ) j=j-2;
 
 			// Two gluons have been erased so to keep looking forward in the
 			// Quark_line j must not be increased
 			j--;
 
 			normal_case=( ql.size()>=4 && static_cast<uint>(j)< ql.size()-2 && ql.at(j)==ql.at(j+2));
 			second_last_case=( ql.size()>=4 && !open && j== static_cast<int>(ql.size())-2 && ql.at(j)==ql.at(0));
 			last_case=( ql.size()>=4 && !open && j== static_cast<int>(ql.size())-1 &&  ql.at(j)==ql.at(1));
 		}
 	}
 	return ;
 }
 
 void Quark_line::contract_next_neighboring_gluons(  ) {
 
 	if( empty() ) return ;
 
 	if( open ){
 		std::cerr << "Quark_line::contract_next_neighboring_gluons: Expects a closed Quark_line, got "
 				<< *this << std::endl;
 		assert(0);
 	}
 
 	// Start with looking for neighbors
 	contract_neighboring_gluons();
 
 	// Keep track of changes in number of gluons
 	// add dummy number '1' to run at least once
 	int old_size= size()+1;
 
 	// Loop over index in quark-line as long as the size keep changing,
 	// or at least once
 	while( old_size!=  static_cast<int>( size()) &&  ( size())>=4){
 		// For seeing if size has changed
 		old_size= size();
 		for (int j=0; j<  static_cast<int>( size()); j++){
 			// Contract next to neighbors starting at place j
 			contract_next_neighboring_gluons( j );
 		}
 	}
 	return ;
 }
 
 
 
 
 Quark_line operator*( const Quark_line & Ql, const int i){
 	Quark_line Ql_out(Ql);
-	Ql_out.Poly=Ql_out.Poly*i;
+	Ql_out.Poly*=i;
 	return Ql_out;
 }
 Quark_line operator*(const int i, const Quark_line & Ql){
 	return Ql*i;
 }
 
 
 Quark_line operator*(const Quark_line & Ql, const cnum c){
 	Quark_line Ql_out(Ql);
-	Ql_out.Poly=Ql_out.Poly*c;
+	Ql_out.Poly*= c;
 	return Ql_out;
 }
 Quark_line operator*(const cnum c, const Quark_line & Ql){
 
 	return Ql*c;
 }
 
 
 Quark_line operator*(const Quark_line & Ql, const double d){
 	Quark_line Ql_out(Ql);
-	Ql_out.Poly=Ql_out.Poly*d;
+	Ql_out.Poly*=d;
 	return Ql_out;
 }
 Quark_line operator*(const double d, const Quark_line & Ql){
 
 	return Ql*d;
 }
 
 
 Quark_line operator*(const Quark_line & Ql, const Monomial & Mon){
 
 	Quark_line Ql_out(Ql);
-	Ql_out.Poly=Ql_out.Poly*Mon;
+	Ql_out.Poly*=Mon;
 	return Ql_out;
 }
 Quark_line operator*(const Monomial & Mon, const Quark_line & Ql){
 
 	return Ql*Mon;
 }
 
 
 Quark_line operator*(const Quark_line & Ql, const Polynomial & Poly){
 
 	Quark_line Ql_out(Ql);
 	Ql_out.Poly=Ql_out.Poly*Poly;
 	return Ql_out;
 }
 Quark_line operator*(const Polynomial & Poly, const Quark_line & Ql){
 
 	return Ql*Poly;
 }
 
+bool operator==( const Quark_line & Ql1, const Quark_line & Ql2 ){
+
+	// Quark_lines's must have equal length
+	if( Ql1.size() != Ql2.size() ) return false;
+
+	// Both must be closed, or both must be open
+	if(! (Ql1.open==Ql2.open ) ) return false;
+
+	// The quark_lines must be equal
+	if( Ql1.ql != Ql2.ql ) return false;
+
+	// The Polynomials must be equal
+	if( Ql1.Poly != Ql2.Poly ) return false;
+
+	return true;
+}
+
+bool operator!=( const Quark_line & Ql1, const Quark_line & Ql2 ){
+	if( Ql1==Ql2 ) return false;
+	else return true;
+}
+
 
 std::ostream& operator<<(std::ostream& out, const Quark_line & Ql) {
 	int max = Ql.ql.size();
 
 	// Write out Polynomial if it is not 1, of if the ql has no structure
 	Polynomial Poly1; // For comparison, the default Polynomial=1
 	if (Ql.Poly != Poly1 or Ql.ql.size() == 0)
 		out << Ql.Poly;
 
 	if (max == 0 && Ql.open)
 		out << "{}";
 	else if (max == 0 && !Ql.open)
 		out << "()";
 	else if (max > 0 && Ql.open)
 		out << "{";
 	else if (max > 0 && !Ql.open)
 		out << "(";
 	for (int i = 0; i < max - 1; i++) {
 		out << Ql.ql.at(i) << ",";
 	}
 	if (max > 0)
 		out << Ql.ql.at(max - 1);
 	if (max > 0 && Ql.open)
 		out << "}";
 	else if (max > 0 && !Ql.open)
 		out << ")";
 
 	return out;
 }
 
 
 } // end namespace ColorFull
diff --git a/MatrixElement/Matchbox/ColorFull/Quark_line.h b/MatrixElement/Matchbox/ColorFull/Quark_line.h
--- a/MatrixElement/Matchbox/ColorFull/Quark_line.h
+++ b/MatrixElement/Matchbox/ColorFull/Quark_line.h
@@ -1,218 +1,225 @@
 // -*- C++ -*-
 /*
  * Quark_line.h
  *	Contains declaration of the class Quark_line and associated types and operators.
  *  Created on: Jul 7, 2010
  *  Author: Malin Sjodahl
  */
 
 #ifndef COLORFULL_Quark_line_h
 #define COLORFULL_Quark_line_h
 
 #include "Polynomial.h"
 
 
 namespace ColorFull {
 
 
 /// Define a type to contain a quark-line with gluons attached,
 /// the actual color information about how quarks are ordered in a
 /// Quark_line.
 typedef std::vector <int> quark_line;
 
 /// A class to contain one quark-line with gluons attached
 /// multiplying a Polynomial, Poly.
 /// The partons are ordered as {q,g1,g2...gn,qbar} for an open quark-line
 /// containing a q and a qbar, or (g1,g2...gn) for a closed
 /// quark-line with only gluons.
 /// The parton numbers are stored as components in a vector, a quark_line,
 /// whereas the member open contains information about it the quark-line is
 /// closed as a trace (true) or open, false.
 class Quark_line {
 
 public:
 
 	/// Constructor used to set the color structure using a string.
 	/// The string should be of form Polynomial*quark_line,
 	/// used as "Quark_line Ql("5*TR*Nc^2 {1,6,7,2}");"
 	/// for an open Quark_line with a quark with
 	/// number 1, two gluons with number 6 and 7, and a qbar with number 2.
 	/// For a closed Quark_line with 3 gluons the syntax is
 	/// "Quark_line Ql("(1,2,3)");".
 	/// The integers should be positive.
-	/// The Polnomial should be in such a shape that it is readable by the
+	/// The Polynomial should be in such a shape that it is readable by the
 	/// Polynomial( std::string ) constructor.
 	Quark_line( const std::string str );
 
 	/// Default constructor.
 	Quark_line();
 
 	/// To actually contain the color information,
 	/// in order {q, g1, ... gn, qbar} or (g1, ..., gn).
 	quark_line ql;
 
 	/// Polynomial factor, multiplying the quark_line.
 	Polynomial Poly;
 
 	/// Is the string open, with a q in the beginning and a qbar in the end, or not?
 	bool open;
 
 	/// Function for reading in the Quark_line from the file filename,
 	/// uses Quark_line_of_str.
 	void read_in_Quark_line( std::string filename );
 
 	/// Function for writing out the Quark_line to a file
 	/// with name filename.
 	void write_out_Quark_line( std::string filename ) const;
 
-	/// The parton at place j.
+	/// Returns the parton at place j.
 	/// For closed quark_lines j may be between -size and 2*size.
 	int at( int j ) const;
 
 	/// The size of the quark_line.
 	uint size() const{ return ql.size();}
 
-	/// Erase information in quark_line.
+	/// Erase information in quark_line ql.
 	void clear() { ql.clear(); }
 
-	/// Appends a parton to data member ql.
-	void push_back( int p ) { ql.push_back( p ); }
-
 	/// Is the quark_line empty?
 	bool empty() const { return ql.empty(); }
 
 	/// If the quark_line is open, there is nothing to do,
 	/// else order with smallest gluon index first
 	/// (use that the trace is cyclic).
 	void normal_order();
 
 	/// To erase the parton at place i.
 	void erase( int i );
 
-	/// Conjugate the Quark_line by reversing the quark_line ql
+	/// Conjugates the Quark_line by reversing the quark_line ql
 	/// and conjugating the Polynomial Poly.
 	void conjugate();
 
-	/// Function for adding parton p to the quark_line.
-	void append( int p );
+	/// Appends parton p to the Quark_line.
+	void append( int p ) { ql.push_back( p ); }
 
-	/// Function for adding a whole quark_line to the quark_line.
+	/// Appends a whole quark_line to the Quark_line.
 	void append( const std::vector<int> & in_ql );
 
-	/// Function for prepending parton p to the quark_line.
+	/// Prepends parton p to the Quark_line.
 	void prepend( int p );
 
-	/// Function for prepending a whole quark_line to the quark_line.
+	/// Prepends a whole quark_line to the Quark_line.
 	void prepend( std::vector<int> in_ql );
 
 	/// Inserting parton p at place j.
 	void insert( int j, int p );
 
-	// Returns a Quark_line with the elements before j in a Quark_line.
+	/// Returns a Quark_line where the ql member is changed to contain
+	/// only partons before place j.
 	Quark_line before( int j ) const;
 
-	// Returns the elements after j in a Quark_line
+	/// Returns a Quark_line where the ql member is changed to contain
+	/// only partons after place j.
 	Quark_line after( int j ) const;
 
-	/// Function for splitting a closed Quark_line into two Quark_lines,
-	/// j1 & j2 are the locations of the gluons to be removed in the split.
+	/// Function for splitting a closed Quark_line into two Quark_lines.
+	/// The gluons at j1 and j2 are removed in the split.
 	/// May create 1-rings and 0-rings.
 	std::pair<Quark_line, Quark_line> split_Quark_line( int j1, int j2 ) const;
 
 	/// Function for finding the "smallest" Quark_line of Ql1 and Ql2,
 	/// used for deciding which Quark_line should stand first while normal ordering.
-	/// Does NOT first normal order quark_lines.
+	/// Does NOT first normal order the Quark_lines.
 	/// If only one is open, that Quark_line should stand first.
 	/// If both are open or both are closed, the longest Quark_line should stand first.
 	/// If the size is the same, the Quark_line with smallest starting number should stand first.
 	/// If the first number is the same, check the 2nd number, then the 3rd...
 	/// 1 is returned if Ql1 should stand first, and 2 if Ql2 should stand first.
 	/// If Ql1==Ql2, 0 is returned.
-	/// If the Ql's are equal, 0 is returned.
 	int smallest( const Quark_line & Ql1 , const Quark_line & Ql2 ) const;
 
-	/// Function to contract neighboring gluons in the Quark_line starting at j,
+	/// Contracts neighboring gluons in the Quark_line starting at j,
 	/// only intended for closed Quark_lines.
 	void contract_neighboring_gluons( int j );
 
-	/// Function to contract neighboring gluons in a Quark_line starting at place 0,
-	/// and looking everywhere, only intended for closed Quark_lines.
+	/// Contracts neighboring gluons in a Quark_line starting at place 0,
+	/// and checking all neighbors, only intended for closed Quark_lines.
 	void contract_neighboring_gluons( );
 
-	/// Function to contract next to neighboring gluons in the Quark_line,
-	/// starting at place j (so gluon j and j+2).
+	/// Contracts neighboring and next to neighboring gluons in the Quark_line,
+	/// starting at place j (i.e. checking gluon j and j+2).
 	/// Also looks for new neighbors, only intended for closed Quark_lines.
 	void contract_next_neighboring_gluons( int j );
 
 	/// Contracts neighboring and next to neighboring gluons in the Quark_line,
 	/// starting with contracting neighbors, only intended for closed Quark_lines.
 	void contract_next_neighboring_gluons( );
 
 
 private:
 
 	/// Function used to set the color structure using a string.
 	/// The string should be of form Polynomial*quark_line,
 	/// used as "Quark_line Ql("Polynomial {5,6,7}");"
 	/// for an open Quark_line with a quark with
 	/// number 5, a gluon with number 6 and a qbar with number 7, and as
 	/// "Quark_line Ql("(5,6,7)");" for 3 gluons attached to a quark line.
-	/// The Polnomial should be in such a shape that it's readable by the
+	/// The Polynomial should be in such a shape that it's readable by the
 	/// Polynomial( std::string ) constructor.
-	void Quark_line_of_str(const std::string str);
+	void Quark_line_of_str( const std::string str );
 
 	/// To make it easy to define a Quark_line using a string,
 	/// used by Quark_line_of_str(std::string str)
 	/// to set the quark_line member ql.
 	void quark_line_of_str( std::string str );
 
 };
 
 /// Define the operator * for Quark_line and int.
 /// The Polynomial of the Quark_line is multiplied with i.
 Quark_line operator*( const Quark_line & Ql, const int i );
 
 /// Define the operator * for Quark_line and int,
 /// returns Ql*i.
 Quark_line operator*( const int i, const Quark_line & Ql );
 
 /// Define the operator * for Quark_line and cnum.
 /// The Polynomial of the Quark_line is multiplied with c.
 Quark_line operator*( const Quark_line & Ql, const cnum c );
 
 /// Define the operator * for Quark_line and cnum,
 /// returns Ql*c.
 Quark_line operator*( const cnum c, const Quark_line & Ql );
 
 /// Define the operator * for Quark_line and double.
 /// The Polynomial of the Quark_line is multiplied with d.
 
 Quark_line operator*( const Quark_line & Ql, const double d );
 /// Define the operator * for Quark_line and double,
 
 /// returns Ql*d.
 Quark_line operator*( const double d, const Quark_line & Ql );
 
 /// Define the operator * for Quark_line and Monomial.
 /// The polynomial of the Quark_line is multipled with Mon.
 Quark_line operator*( const Quark_line & Ql, const Monomial & Mon );
 
 /// Define the operator * for Quark_line and Monomial.
 /// returns Ql*Mon.
 Quark_line operator*( const Monomial & Mon, const Quark_line & Ql );
 
 /// Define the operator * for Quark_line and Polynomial.
 /// The Polynomial of the Quark_line is multiplied with Poly.
 Quark_line operator*( const Quark_line & Ql, const Polynomial & Poly );
+
 /// Define the operator * for Quark_line and Polynomial
-
 /// returns Ql*Poly.
 Quark_line operator*( const Polynomial & Poly, const Quark_line & Ql );
 
+/// Define the operator == for two Quark_lines
+/// the quark_lines must be equal, the member variable open and the
+/// Polynomials must be equal. Note that for Polynomials cf+Nc!=Nc+cf.
+bool operator==( const Quark_line & Ql1, const Quark_line & Ql2 );
+
+/// The negation of the Quark_line operator ==.
+bool operator!=( const Quark_line & Ql1, const Quark_line & Ql2 );
+
+
 /// Define the operator << for Quark_line.
 std::ostream& operator<<( std::ostream& out, const Quark_line & Ql );
 
 
 }// end namespace ColorFull
 
 #endif /* COLORFULL_Quark_line_h */
diff --git a/MatrixElement/Matchbox/ColorFull/TraceBasis.cc b/MatrixElement/Matchbox/ColorFull/TraceBasis.cc
--- a/MatrixElement/Matchbox/ColorFull/TraceBasis.cc
+++ b/MatrixElement/Matchbox/ColorFull/TraceBasis.cc
@@ -1,238 +1,420 @@
 // -*- C++ -*-
 //
 // TraceBasis.cc is a part of ColorFull
 // Copyright (C) 2010-2011 Simon Platzer & Malin Sjodahl
 //
 // ColorFull 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 TraceBasis class.
 //
 
 #include "TraceBasis.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/EventRecord/Particle.h"
 #include "ThePEG/Repository/UseRandom.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace ColorFull;
 
-TraceBasis::TraceBasis() {}
+TraceBasis::TraceBasis() { }
 
 TraceBasis::~TraceBasis() {}
 
 IBPtr TraceBasis::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr TraceBasis::fullclone() const {
   return new_ptr(*this);
 }
 
 void TraceBasis::clear() {
   ColourBasis::clear();
   theBasisMap.clear();
   theScalarProducts.clear();
 }
 
 map<size_t,vector<vector<size_t> > > 
 TraceBasis::basisList(const vector<PDT::Colour>& basisId) const {
 
   map<vector<PDT::Colour>,Trace_basis>::const_iterator bit =
     theBasisMap.find(basisId);
 
   map<size_t,vector<vector<size_t> > > res;
 
   const col_basis& cb = bit->second.cb;
 
   for ( size_t i = 0; i < cb.size(); ++i ) {
 
     vector<vector<size_t> > cstr;
 
     const Col_str& cs = cb.at(i).at(0);
 
     for ( size_t j = 0; j < cs.size(); ++j ) {
 
       const Quark_line& ql = cs.at(j);
       vector<size_t> qline;
 
       for ( size_t k = 0; k < ql.size(); ++k )
 	qline.push_back(ql.at(k)-1);
 
       cstr.push_back(qline);
 
     }
 
     res[i] = cstr;
 
   }
 
   return res;
 
 }
 
 size_t TraceBasis::prepareBasis(const vector<PDT::Colour>& sub) {
 
   useMe();
 
   vector<PDT::Colour> mySub = normalOrder(sub);
 
   if ( theBasisMap.find(mySub) == theBasisMap.end() ) {
 
     int ng = count_if(mySub.begin(),mySub.end(),ColourBasis::matchRep(PDT::Colour8));
     int nq = (mySub.size() - ng)/2;
 
     Trace_basis basis;
     basis.create_basis(nq,ng);
     theBasisMap[mySub] = basis;
 
   }
 
   return theBasisMap[mySub].size();
 
 }
 
 void TraceBasis::readBasisDetails(const vector<PDT::Colour>& sub) {
   prepareBasis(sub);
 }
 
 double TraceBasis::scalarProduct(size_t i, size_t j,
 				 const vector<PDT::Colour>& abBasis) const {
 
   if ( largeN() && i != j )
     return 0.;
 
   map<vector<PDT::Colour>,Trace_basis>::const_iterator bit =
     theBasisMap.find(abBasis);
 
   assert(bit != theBasisMap.end());
 
   const Trace_basis& Basis = bit->second;
   Col_str csi = Basis.cb.at(i).at(0);
   Col_str csj = Basis.cb.at(j).at(0);
 
+
   // Rename indices, and make string of new Col_strs, to use in map
   //pair<Col_str, Col_str> Css_new = Basis.rename_indices(csi,csj);
   Basis.rename_indices(csi,csj);
   Col_str Cs1 = csi;
   Col_str Cs2 = csj;
   ostringstream Cs_string;
   Cs_string << Cs1 << Cs2;
 
   map<string,Polynomial>::iterator pit = theScalarProducts.find(Cs_string.str());
 
   // Add result to map
   if ( pit == theScalarProducts.end() ) {
     Polynomial p = colorFunctions.scalar_product(Cs1, Cs2);
     theScalarProducts.insert(make_pair(Cs_string.str(), p));
     pit = theScalarProducts.find(Cs_string.str());
   }
 
   return
     largeN() ? 
     colorFunctions.double_num(colorFunctions.leading(pit->second)) :
     colorFunctions.double_num(pit->second);
 
 }
 
+
+// m is emitting parton
+// i is new vector number in new large aBasis
+// j is old vector number in old small bBasis
+// k is the new number of the emitter
+// l is the number of the new gluon
+// dict contains the map from old to new numbers of the partons not participating
 double TraceBasis::tMatrixElement(size_t m, size_t i, size_t j,
-				  const vector<PDT::Colour>& aBasis,
-				  const vector<PDT::Colour>& bBasis) const {
+		const vector<PDT::Colour>& aBasis,
+		const vector<PDT::Colour>& bBasis,
+		size_t k, size_t l,
+		const map<size_t,size_t>& dict) const {
 
-  ++m;
+  // Call sMatrixElement if it's a gluon splitting
+  if ( bBasis[m] == PDT::Colour8 && aBasis[k] != PDT::Colour8 ) 
+    return sMatrixElement(m,i,j,aBasis,bBasis,k,l,dict);
 
-  map<vector<PDT::Colour>,Trace_basis>::iterator ait =
-    theBasisMap.find(aBasis);
+	assert( dict.size()+1 == bBasis.size() );
 
+	map<vector<PDT::Colour>,Trace_basis>::const_iterator ait =
+			theBasisMap.find(aBasis);
+	map<vector<PDT::Colour>,Trace_basis>::const_iterator bit =
+			theBasisMap.find(bBasis);
 
-  map<vector<PDT::Colour>,Trace_basis>::const_iterator bit =
-    theBasisMap.find(bBasis);
+	assert(bit != theBasisMap.end());
+	assert(ait != theBasisMap.end());
 
-  assert(bit != theBasisMap.end());
-  assert(ait != theBasisMap.end());
 
+	const Trace_basis& ABasis = ait->second;
+	const Trace_basis& BBasis = bit->second;
 
-  Trace_basis& ABasis = ait->second;
-  const Trace_basis& BBasis = bit->second;
 
-  pair<int,int> newNumbers = ABasis.new_vector_numbers(BBasis.cb.at(j).at(0),m);
+	// Initial Col_amp, before emission
+	Col_amp Ca1 = BBasis.at(j);
 
-  if ( (size_t) newNumbers.first == i )
-    return 1.;
+	int g_new, p_old;
+	p_old = m+1;// ColorFull starts with parton number 1 (normally q or g)
+	int g_old = aBasis.size();//Give the new g an index that isn't used 
 
-  if ( (size_t) newNumbers.second == i )
-    return -1.;
+	// If the emitted parton is not a gluon, this is because
+	// we have backward evolution with a qqbar-> g
+	if( aBasis[l] != PDT::Colour::Colour8 ){
+		// The number of the new gluon is k+1
+		g_new = k+1;
+	} else{ // Standard case, l (+1) is the number of the new gluon
+		g_new = l+1;
+	}
 
-  return 0.;
+	// Color structure after gluon split
+	Col_amp Ca2 = colorFunctions.emit_gluon( Ca1, p_old, g_old);
+
+	// The map should be the dict (containing the map of old non-involved partons)
+	// + g_new mapped to itself and p_old mapped
+	std::map<int, int> map;
+	for ( size_t ii = 0; ii < bBasis.size(); ii++ ){
+		if ( ii  != m ) {// exclude splitting gluon
+			int parton = static_cast<int>( dict.at(ii) );
+			map[ii+1] = parton+1;// Parton numbers one unit higher in ColorFull
+		}
+	}
+	// New parton number mapping
+	map[ g_old ] = g_new;
+	// Old emitter should also be mapped
+	if( aBasis[l] != PDT::Colour::Colour8 ){// Exceptional case
+		map[ p_old ] = l+1;
+	}
+	else{ // Standard case
+		map[ p_old ] = k+1;
+	}
+	// Check the size of the map
+	assert( map.size() == aBasis.size() );
+
+	// Color structure when partons have names in map
+	Col_amp Ca3= colorFunctions.rename_partons( Ca2, map );
+
+	// Check if the new color structure has a component for basis vector i in ABasis
+	// Loop over Col_strs in Col_amp after split
+	for ( uint Csi=0; Csi < Ca3.size(); Csi++ ){
+		if( Ca3.at(Csi).cs == ABasis.at(i).at(0).cs ){// If col_strs are the same
+			return colorFunctions.double_num( Ca3.at(Csi).Poly ); // Return Polynomial coefficient in front of Col_str
+		};
+	}
+
+	// If no component corresponding to vector i is found
+	return 0.;
+
+}
+
+// m is splitting gluon
+// i is new vector number new large aBasis
+// j is old vector number in old small bBasis
+// k is the number of the new emitter after (q or qbar)
+// l is the number of the "emission" (q or qbar)
+// dict contains the map from old to new numbers of the partons not participating
+double TraceBasis::sMatrixElement(size_t m, size_t i, size_t j,
+		const vector<PDT::Colour>& aBasis,
+		const vector<PDT::Colour>& bBasis,
+		size_t k, size_t l,
+		const map<size_t,size_t>& dict) const {
+
+	// Check that dict has the right size (splitting gluon missing, hence +1)
+	assert( dict.size()+1 == bBasis.size() );
+
+	map<vector<PDT::Colour>,Trace_basis>::iterator ait =
+			theBasisMap.find(aBasis);
+	map<vector<PDT::Colour>,Trace_basis>::const_iterator bit =
+			theBasisMap.find(bBasis);
+
+	assert(bit != theBasisMap.end());
+	assert(ait != theBasisMap.end());
+
+
+	Trace_basis& ABasis = ait->second; // New basis
+	const Trace_basis& BBasis = bit->second; // Old basis
+
+
+	// Initial Col_amp, before split
+	Col_amp Ca1 = BBasis.at(j);
+
+
+	int g_old = m+1;// ColorFull starts with parton number 1 (normally q or g)
+	int q_old, q_new, qbar_old, qbar_new;
+	q_old = aBasis.size();// Give the q an index that isn't used
+	qbar_old = aBasis.size()+1;// Give the qbar an index that isn't used
+	if ( aBasis[k] == PDT::Colour::Colour3 && aBasis[l] == PDT::Colour::Colour3bar ) {
+	  q_new = k+1;
+	  qbar_new = l+1;
+	} else if ( aBasis[l] == PDT::Colour::Colour3 && aBasis[k] == PDT::Colour::Colour3bar ) {
+	  q_new = l+1;
+	  qbar_new = k+1;
+	} else {
+	  assert(false);
+	}
+
+	// Color structure after gluon split
+	// split_gluon also simplifies, so no polynomial factor in Qls
+	Col_amp Ca2= colorFunctions.split_gluon( Ca1, g_old, q_old, qbar_old );
+
+	// The map should be the dict (containing the map of old non-involved partons)
+	std::map<int, int> map;
+	for ( size_t ii = 0; ii < bBasis.size(); ii++ ){
+		if ( ii  != m ) {// exclude splitting gluon
+			int parton = static_cast<int>( dict.at(ii) );
+			map[ii+1] = parton+1;// Parton numbers one unit higher in ColorFull
+		}
+	}
+
+	map[q_old] = q_new;
+	map[qbar_old] = qbar_new;
+
+	assert( map.size() == aBasis.size() );
+
+	// Color structure when partons have ColorFull default names
+	Col_amp Ca3= colorFunctions.rename_partons( Ca2, map ); // does normal ordering as well
+
+	// Check if the new color structure has a component for basis vector i in ABasis
+	// Loop over Col_strs in Col_amp after split
+	for ( uint Csi=0; Csi < Ca3.size(); Csi++ ){
+		if( Ca3.at(Csi).cs == ABasis.at(i).at(0).cs ){// If col_strs are the same, note that they must be normal ordered
+			return colorFunctions.double_num( Ca3.at(Csi).Poly ); // Return Polynomial coefficient in front of Col_str
+		};
+	}
+
+	// If no component corresponding to vector i is found
+	return 0.;
 
 }
 
 bool TraceBasis::colourConnected(const cPDVector& sub,
 				 const vector<PDT::Colour>& basisId,
 				 const pair<int,bool>& first,
 				 const pair<int,bool>& second, 
 				 size_t tensor) const {
 
   // get the basis
   map<vector<PDT::Colour>,Trace_basis>::const_iterator bit =
     theBasisMap.find(basisId);
   assert(bit != theBasisMap.end());
   const Trace_basis& basis = bit->second;
 
   // translate process to basis ids
   map<cPDVector,map<size_t,size_t> >::const_iterator trans
     = indexMap().find(sub);
   assert(trans != indexMap().end());
 
   int idColoured = first.second ? second.first : first.first;
   idColoured = trans->second.find(idColoured)->second;
   ++idColoured;
   int idAntiColoured = first.second ? first.first : second.first;
   idAntiColoured = trans->second.find(idAntiColoured)->second;
   ++idAntiColoured;
 
   const Col_str& cs = basis.cb.at(tensor).at(0);
 
   return cs.left_neighbor(idAntiColoured,idColoured);
 
 }
 
+map<size_t,size_t> TraceBasis::indexChange(const vector<PDT::Colour>& basis,
+					   const size_t dim,
+					   const map<size_t,size_t>& indPerm) const {
+  // Change the map to indices starting at 1 (colorfull numbering of legs) from
+  // starting at 0 (Herwig numbering of legs).
+  map<int,int> iPerm;
+  for ( map<size_t,size_t>::const_iterator it = indPerm.begin();
+	it != indPerm.end(); it++ ) {
+    iPerm[(it->first) + 1] = (it->second) + 1;
+  }
+
+  // Get the basis
+  map<vector<PDT::Colour>,Trace_basis>::const_iterator bit =
+    theBasisMap.find(basis);
+
+  assert(bit != theBasisMap.end());
+
+  const Trace_basis& Basis = bit->second;
+
+  
+  // Naive way: loop over every basis vector and rename the partons,
+  //            then loop over the basis vectors to see which basis vector it became.
+  //            This is sufficient for the current application, as it will
+  //            only be used on the hard subprocess, which will never have
+  //            a very large colour basis.
+  map<size_t,size_t> indexMap;
+  Col_amp Cai, Cai_re;
+  Col_amp Caj;
+  for ( size_t i = 0; i < dim; i++ ) {
+    // Get the basis vector and change the leg numbering
+    Cai = Basis.at(i);
+    Cai_re = colorFunctions.rename_partons( Cai, iPerm );
+    for ( size_t j = 0; j < dim; j++ ) {
+      Caj = Basis.at(j);
+      if ( Cai_re.at(0).cs == Caj.at(0).cs )
+        indexMap[i] = j;
+    }
+  }
+  // Check that the map was filled (every vector should have been
+  // changed into a new vector)
+  assert( indexMap.size() == dim );
+
+  return indexMap;
+}
+
 // If needed, insert default implementations of virtual function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void TraceBasis::persistentOutput(PersistentOStream &) const {}
 
 void TraceBasis::persistentInput(PersistentIStream & , int) {}
 
 
 // *** Attention *** The following static variable is needed for the type
 // description system in ThePEG. Please check that the template arguments
 // are correct (the class and its base class), and that the constructor
 // arguments are correct (the class name and the name of the dynamically
 // loadable library where the class implementation can be found).
 DescribeClass<TraceBasis,Herwig::ColourBasis>
   describeTraceBasis("ColorFull::TraceBasis", 
 		     "HwColorFull.so");
 
 void TraceBasis::Init() {
 
   static ClassDocumentation<TraceBasis> documentation
     ("TraceBasis implements the trace colour basis.",
      "The colour algebra has been performed using ColorFull \\cite{Sjodahl:2014opa}",
      "%\\cite{Sjodahl:2014opa}\n"
      "\\bibitem{Sjodahl:2014opa}\n"
      "M.~Sjodahl,\n"
      "``ColorFull -- a C++ library for calculations in SU(Nc)color space,''\n"
      "arXiv:1412.3967 [hep-ph].\n"
      "%%CITATION = ARXIV:1412.3967;%%");
 
 }
 
diff --git a/MatrixElement/Matchbox/ColorFull/TraceBasis.h b/MatrixElement/Matchbox/ColorFull/TraceBasis.h
--- a/MatrixElement/Matchbox/ColorFull/TraceBasis.h
+++ b/MatrixElement/Matchbox/ColorFull/TraceBasis.h
@@ -1,179 +1,215 @@
 // -*- C++ -*-
 //
 // TraceBasis.h is a part of ColorFull
 // Copyright (C) 2010-2011 Simon Platzer & Malin Sjodahl
 //
 // ColorFull is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 #ifndef COLORFULL_TraceBasis_H
 #define COLORFULL_TraceBasis_H
 //
 // This is the declaration of the TraceBasis class.
 //
 
 #include "Herwig/MatrixElement/Matchbox/Utility/ColourBasis.h"
 #include "Trace_basis.h"
 
 namespace ColorFull {
 
 using namespace ThePEG;
 using namespace Herwig;
 
 /**
  * TraceBasis implements the trace colour basis.
  *
  * @see \ref TraceBasisInterfaces "The interfaces"
  * defined for TraceBasis.
  */
 class TraceBasis: public Herwig::ColourBasis {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   TraceBasis();
 
   /**
    * The destructor.
    */
   virtual ~TraceBasis();
   //@}
 
 public:
 
   /**
    * Clear this colour basis
    */
   virtual void clear();
 
   /**
    * Return a map of basis tensor indices to vectors identifying a
    * certain ordering corresponding to the given colour structure. May
    * not be supported by all colour basis implementations.
    */
   virtual map<size_t,vector<vector<size_t> > > basisList(const vector<PDT::Colour>&) const;
 
   /**
    * Prepare the basis for the normal ordered legs and return the
    * dimensionality of the basis.
    */
   virtual size_t prepareBasis(const vector<PDT::Colour>&);
 
   /**
    * Gather any implementation dependend details when reading a basis
    */
   virtual void readBasisDetails(const vector<PDT::Colour>&);
 
   /**
    * Return the scalar product of basis tensors labelled a and b in
    * the basis used for the given normal ordered legs.
    */
   virtual double scalarProduct(size_t a, size_t b,
 			       const vector<PDT::Colour>& abBasis) const;
 
   /**
+   * Return true, if this colour basis supports gluon splittings.
+   */
+  virtual bool canSplitGluons() const {
+    return false;
+  }
+
+  /**
    * Return the matrix element of a colour charge
    * <c_{n+1,a}|T_i|c_{n,b}> between basis tensors a and b, with
    * respect to aBasis and bBasis
    */
   virtual double tMatrixElement(size_t i, size_t a, size_t b,
 				const vector<PDT::Colour>& aBasis,
-				const vector<PDT::Colour>& bBasis) const;
+				const vector<PDT::Colour>& bBasis,
+				size_t k, size_t l,
+				const map<size_t,size_t>& dict) const;
+
+  /**
+   * Return the matrix element of a quark splitting matrix
+   * <c_{n+1,a}|T_i|c_{n,b}> between basis tensors a and b, with
+   * respect to aBasis and bBasis. Here
+   * m is splitting gluon,
+   * i is the new vector number in the new large aBasis,
+   * j is the old vector number in the old small bBasis,
+   * k is the number of the new q,
+   * l is the number of the new qbar,
+   * and dict contains the map from old to new numbers, of the partons not participating.
+   * All parton numbers are given in Herwig conventions.
+   */
+  virtual double sMatrixElement(size_t i, size_t a, size_t b,
+				const vector<PDT::Colour>& aBasis,
+				const vector<PDT::Colour>& bBasis,
+				size_t k, size_t l,
+				const map<size_t,size_t>& dict) const;
 
   /**
    * Return true, if the colour basis is capable of assigning colour
    * flows.
    */
   virtual bool haveColourFlows() const { return true; }
 
   /**
    * Return true, if a large-N colour connection exists for the
    * given external legs and basis tensor.
    */
   virtual bool colourConnected(const cPDVector&,
 			       const vector<PDT::Colour>&,
 			       const pair<int,bool>&, 
 			       const pair<int,bool>&, 
 			       size_t) const;
 
+  /**
+   * Returns a map of how the order of the vectors of a colour basis are 
+   * changed when the indices are changed.
+   */
+  virtual map<size_t,size_t> indexChange(const vector<PDT::Colour>& basis,
+					 const size_t dim,
+					 const map<size_t,size_t>& legPerm) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 private:
 
   /**
    * The color functions object to be used
    */
   mutable Col_functions colorFunctions;
 
   /**
    * Map legs to known basis vectors.
    */
   mutable map<vector<PDT::Colour>,Trace_basis> theBasisMap;
 
   /**
    * Memorize scalar product intermediate results.
    */
   mutable map<string,Polynomial> theScalarProducts;
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   TraceBasis & operator=(const TraceBasis &) = delete;
 
 };
 
 }
 
 #endif /* COLORFULL_TraceBasis_H */
diff --git a/MatrixElement/Matchbox/ColorFull/Trace_basis.cc b/MatrixElement/Matchbox/ColorFull/Trace_basis.cc
--- a/MatrixElement/Matchbox/ColorFull/Trace_basis.cc
+++ b/MatrixElement/Matchbox/ColorFull/Trace_basis.cc
@@ -1,255 +1,257 @@
 // -*- C++ -*-
 /*
  * Trace_basis.cc
  * Contains the definitions of the class Trace_basis, related types and operators
  * Created on: Aug 9, 2012
  * Author: Malin Sjodahl
  */
 
 #include "Trace_basis.h"
 #include <cassert>
 #include <iostream>
 
 
 namespace ColorFull {
 
 
 void Trace_basis::create_basis(int n_quark, int n_gluon){
 
 	// Create the basis with an upper bound for n_loop to
 	// keep all basis vectors
 	// Maximal number of "loops"
 	int n_l=n_gluon/2; // Integer division
 	create_basis( n_quark, n_gluon, n_l);
 }
 
 
 void Trace_basis::create_basis(int n_quark, int n_gluon, int n_loop){
 
 	// Setting basis variables
 	nq=n_quark;
 	ng=n_gluon;
 
 	// If only to finite "loop" the maximal number of qls change
 	max_ql=std::max(nq,1)+n_loop;
 
 	// Remove a potentially already calculated basis
 	cb.clear();
 	// The Col_amp containing the basis
 	Col_amp Ca_basis;
 
 	// Create the basis using the old function for a maximal number of loops
 	Ca_basis=create_trace_basis(nq, ng, n_loop);
 
 	// Sort the resulting Col_amp into the Col_basis cb
 	for ( uint i=0; i < Ca_basis.ca.size(); i++ ){
 		// A Col_amp to contain a basis vector
 		Col_amp Ca_vec;
 		Ca_vec.ca.push_back(Ca_basis.ca.at(i));
 		cb.push_back(Ca_vec);
 	}
 }
 
 
 Col_amp Trace_basis::create_trace_basis( int n_quark, int n_g, int n_loop ) const {
 
 	// To contain the resulting basis
 	Col_amp Basis;
 
 	// First connect all q and qbars in all n_quark! ways
 	// This gives a basis for the case of n_quark quarks and n_quarkbar anti-quarks
 	if( n_quark != 0)  Basis= connect_quarks( n_quark );
 
 	// If there were no quarks
 	if( n_quark==0 ){
 		// There has to be at least two gluons
 		if( n_g <= 1 ) {
 			std::cerr << "Trace_basis::create_trace_basis: For 0 quarks there is no basis with " << n_g << " gluons" << std::endl;
 			assert( 0 );
 		}
 		// If 2 or more gluons, build from the 2-gluon basis
 		else if( n_g>=2 ){
 			Col_str Cs_OnlyState("[(1,2)]");
 			Col_amp Ca_tmp;
 			Ca_tmp.ca.push_back(Cs_OnlyState);
 
 			Basis= Ca_tmp;
 			// For 2 gluons, the work is done
 			if( n_g==2 ) return Basis;
 			//cout << Basis;
 		}
 	}
 
 	// Then, add the gluons one at the time
 	// If there are only gluons the generation should start from gluon 3,
 	// otherwise from 2*n_quark+1;
 	for( int g_new=std::max(3, 2*n_quark+1); g_new <= 2*n_quark+ n_g; g_new++){
 		// If only gluons start from the 2-gluon state, so add gluon 3
-		Basis=add_one_gluon(Basis, n_quark ,n_g, g_new, n_loop);
+		Basis=add_one_gluon(Basis, n_quark, g_new, n_loop);
 		}
 
 	// Remove basis vectors with too many Quark_lines
 	uint max_Ql=std::max(1, n_quark)+n_loop;
 	for(int i=Basis.size()-1; i>-1; i--){
 		if (Basis.ca.at(i).size() > max_Ql ) Basis.erase(i);
 	}
 
 	// Normal order the Col_str's
 	Basis.normal_order();
 
 	return Basis;
 
 }
 
 
 Col_amp Trace_basis::connect_quarks( int n_quark ) const{
 
 	Col_amp Basis;
 
 	// If n_quark=1, there is only one state
 	if( n_quark==1 )	{
 		Col_str Cs_tmp("[{1,2}]");
-		Basis=Basis+Cs_tmp;
+		Basis+=Cs_tmp;
 	}
 	else{ // For more than one q qbar pair, build up states iteratively
 		// Start from the state with one less q qbar state
 		Col_amp Old_bas=connect_quarks( n_quark-1 );
 
 		// Loop over old basis vectors
 		for (uint old_v = 0; old_v < Old_bas.ca.size(); old_v++) {
 
 			// Some, 1*(n_quark-1)!, new states are obtained by just adding q_new qbar_new to the old states
 			// Construct the new Ql with i.e. {q_new, qbar_new}
 			Quark_line Ql_new;
 			Ql_new.open = true;
 			Ql_new.ql.push_back(2 * n_quark - 1);
 			Ql_new.ql.push_back(2 * n_quark);
 			Col_str New_state;
 			New_state.cs.push_back(Ql_new);
 			New_state.append( Old_bas.ca.at(old_v).cs );
-			Basis=Basis+New_state;
+			Basis+= New_state;
 		}
 
 		// The other (n_quark-1)*(n_quark-1)! states are obtained by combining the new qbar with any old quark
 		// Loop over old basis states
 		for (uint old_v = 0; old_v < Old_bas.ca.size(); old_v++) {
 			// Loop over old qbar indices
 			for (int qbar_old = 2; qbar_old < 2 * n_quark; qbar_old += 2) {
 				// To contain the new basis vector
 				Col_str New_state = Old_bas.ca.at(old_v);
 
 				// Replace the index qbar_old with 2*nq
 				New_state.replace(qbar_old, 2 * n_quark);
 
 				// Create the Quark_line {q_new, qbar_old}
 				Quark_line Ql_new;
 				Ql_new.open = true;
 				Ql_new.ql.push_back(2 * n_quark - 1);
 				Ql_new.ql.push_back(qbar_old);
 
 				// Add the Col_str from  {q_new, qbar_old} to the new basis vector
 				New_state.cs.push_back(Ql_new);
 
 				// Add the new basis tensor to the basis
-				Basis = Basis + New_state;
+				Basis += New_state;
 			}
 		}
 	}
 
 	return Basis;
 }
 
 
-Col_amp Trace_basis::add_one_gluon( const Col_str & Cs, int g_new, int ) const {
+Col_amp Trace_basis::add_one_gluon( const Col_str & Cs, int g_new ) const {
+
+	//(void) n_loop;
 
 	// For storing the new basis
 	Col_amp New_tensors;
 
 	// Add the new gluon in all possible ways to the old Color structure
 	// Loop over the Quark_lines
 	for (uint ql = 0; ql < Cs.cs.size(); ql++) {
 
 		// The old Quark_line, before insertion of the new gluon index
 		Quark_line Old_Ql = Cs.cs.at(ql);
 		Col_str New_tensor = Cs;
 
 		// Loop over (potential) insertion places in the Quark_lines, starting from the end
 		for (int j = Old_Ql.ql.size(); j > 0; j--) {
 
 			// Special treatment of last place, insert here only if the ring is open
 			// (the gluon index cannot take the place of the a quark index)
 			if (Old_Ql.open && j == static_cast<int>(Old_Ql.ql.size()) ) j--;
 
 			Quark_line New_Ql = Old_Ql;
 			quark_line::iterator it = New_Ql.ql.begin() + j;
 			New_Ql.ql.insert(it, g_new);
 
 			// Replace the old Col_str with the new and add to the new basis states
 			New_tensor.cs.at(ql) = New_Ql;
-			New_tensors = New_tensors + New_tensor;
+			New_tensors += New_tensor;
 		}
 
 	}
 	return New_tensors;
 }
 
 
-Col_amp Trace_basis::add_one_gluon(const Col_amp & Old_basis, int n_q, int, int g_new, int n_loop) const{
+Col_amp Trace_basis::add_one_gluon(const Col_amp & Old_basis, int n_q, int g_new, int n_loop) const{
 
 	// For storing the new basis
 	Col_amp New_bas;
 
 	// Add the new gluon to each of the previous color tensors
 	for (uint t = 0; t < Old_basis.ca.size(); t++) {
-		New_bas = New_bas + add_one_gluon(Old_basis.ca.at(t), g_new, n_loop);
+		New_bas = New_bas + add_one_gluon(Old_basis.ca.at(t), g_new);
 	}
 
 	// Create new states with 2-rings formed from taking the new gluon and any old gluon
 	// these states can be created by taking the ng-2 basis but use the indices
 	// 1...i_ex-1, i_ex+1 ng-1
 	// for the gluons, that is exclude one index (to be combined with the index ng in a 2-ring)
 	// First, create the ng-2 basis here, must have at least 4 gluons
 	// Do this only is not tree-level mode, i.e. n_loop>0
 	if ( n_loop>0 && (( n_q>0 && g_new-2*n_q>=2 ) or (n_q==0 && g_new >= 4) )) {
 		Col_amp Bas_n_g_minus_2 = create_trace_basis(n_q, g_new-n_q*2-2, n_loop);
 
 		// Loop over indices to group with the new gluon index
 		for (int g_ex = 2 * n_q + 1; (g_ex <= g_new - 1 ); g_ex++) {
 
 			// Create the 2-ring with g_ex and g_new
 			Quark_line Ql2_ring;
 			Ql2_ring.open = false;
 			Ql2_ring.append(g_ex);
 			Ql2_ring.append(g_new);
 
 			// Loop over Col_str's=basis vectors
 			for (uint bv = 0; bv < Bas_n_g_minus_2.ca.size(); bv++) {
 
 				Col_str Cs_new; // To contain the new basis vector
 				Cs_new = Bas_n_g_minus_2.ca.at(bv);
 
 				// Loop over the Quark_lines in the basis vectors
 				for (uint ql = 0; ql < Bas_n_g_minus_2.ca.at(bv).cs.size(); ql++) {
 					// Loop over positions in the quark_line
 					for (uint pos = 0; pos < Bas_n_g_minus_2.ca.at(bv).cs.at(ql).ql.size(); pos++)
 
 						// Jump over index g_ex by increasing the index g_ex, and all indices above with 1
 						if (Bas_n_g_minus_2.ca.at(bv).cs.at(ql).ql.at(pos)
 								>= g_ex) {
 							// Change the index if >= g_ex
 							Cs_new.cs.at(ql).ql.at(pos)++;
 						}
 				}
 				Cs_new.cs.push_back(Ql2_ring);
-				New_bas = New_bas + Cs_new;
+				New_bas += Cs_new;
 			}
 		}
 	}
 	return New_bas;
 }
 
 
 
 }// end namespace ColorFull {
 
 
diff --git a/MatrixElement/Matchbox/ColorFull/Trace_basis.h b/MatrixElement/Matchbox/ColorFull/Trace_basis.h
--- a/MatrixElement/Matchbox/ColorFull/Trace_basis.h
+++ b/MatrixElement/Matchbox/ColorFull/Trace_basis.h
@@ -1,92 +1,91 @@
 // -*- C++ -*-
 /*
  * Trace_basis.h
  * Contains the declarations of the class Trace_basis, related types and operators
  * Created on: Aug 9, 2012
  * Author: Malin Sjodahl
  */
 
 #ifndef COLORFULL_Trace_basis_h
 #define COLORFULL_Trace_basis_h
 
 #include "Trace_type_basis.h"
 
 namespace ColorFull {
 
 
 /// In a trace basis the basis vectors are closed or open quark-lines
 /// or products of close and open quark-lines.
 class Trace_basis:public Trace_type_basis {
 public:
 
 	/// Default constructor.
 	Trace_basis():Trace_type_basis(){
 		initialize();
 	}
 
 	/// Constructor for creating a trace basis for n_quark qqbar-pairs
 	/// and n_gluon gluons.
-	/// (Note: For electroweak interactions more color structures may
-	/// be needed.)
 	Trace_basis( int n_quark, int n_gluon ){
 		initialize();
 		create_basis( n_quark, n_gluon );
 	}
 
 	/// Constructor for creating a trace basis for n_quark qqbar-pairs
-	/// and ng gluons, keeping only those color structures that
-	/// can appear to order n_loop in QCD.
+	/// and n_gluon gluons, keeping only those color structures that
+	/// can appear to order n_loop in pure QCD.
 	/// (Note: For electroweak interactions more color structures may
 	/// be needed.)
 	Trace_basis( int n_quark, int n_gluon, int n_loop ){
 		initialize();
 		create_basis( n_quark, n_gluon, n_loop );
 	}
 
-	/// Little helper function, called by all constructors.
-	void initialize(){
-		nq=0;
-		ng=0;
-		tree_level_gluon_basis = false;
-		orthogonal_basis = false;
-		trace_basis = true;
-	}
 
 	/******************** Functions for basis creation **********************/
 
 	/// Creates a trace basis with basis vectors saved in the cb member.
 	/// Keeps all possible basis vectors, i.e., the basis is valid to any order
 	/// in perturbation theory.
 	void create_basis( int n_q, int n_g );
 
 	/// Creates a trace basis with basis vectors saved in the cb member.
 	/// Keeps only basis vectors needed up to n_loop in pure QCD.
 	void create_basis( int n_q, int n_g, int n_loop );
 
 
 private:
 
 	/******************** Internal function for basis creation **********************/
 
+	/// Little helper function, called by all constructors.
+	void initialize(){
+		nq=0;
+		ng=0;
+		tree_level_gluon_basis = false;
+		orthogonal_basis = false;
+		trace_basis = true;
+	}
+
 	/// Function for creating a basis with n_q=n_qbar
 	/// quarks and ng gluons to order n_loop,
 	/// i.e. each Col_str is a product of at most
 	/// max(1+nq)+n_loop Quark_lines.
 	Col_amp create_trace_basis( int n_q, int n_g, int n_loop ) const;
 
 	/// Connect the n_q quarks in all n_q! ways.
 	/// This function is used when creating a basis.
 	Col_amp connect_quarks( int n_quark ) const;
 
 	/// Compute the new basis states coming from
 	/// one old vector when one gluon, g_new, is added.
-	Col_amp add_one_gluon( const Col_str & Cs, int g_new, int n_loop ) const;
+	Col_amp add_one_gluon( const Col_str & Cs, int g_new ) const;
 
 	/// Compute the basis if one gluon is added to the old basis Old_basis.
 	/// If n_loop==0, only tree level states are constructed.
-	Col_amp add_one_gluon( const Col_amp & Old_basis, int n_q, int n_g, int g_new, int n_loop ) const;
+	Col_amp add_one_gluon( const Col_amp & Old_basis, int n_q, int g_new, int n_loop ) const;
 
 };
 
 } /* namespace ColorFull */
 #endif /* COLORFULL_Trace_basis_h */
diff --git a/MatrixElement/Matchbox/ColorFull/Trace_type_basis.cc b/MatrixElement/Matchbox/ColorFull/Trace_type_basis.cc
--- a/MatrixElement/Matchbox/ColorFull/Trace_type_basis.cc
+++ b/MatrixElement/Matchbox/ColorFull/Trace_type_basis.cc
@@ -1,692 +1,692 @@
 // -*- C++ -*-
 /*
  * Trace_type_basis.cc
  * Contains definition of the class Trace_basis and associated types and operators.
  * Created on: Aug 9, 2012
  * Author: Malin Sjödahl
  */
 
 #include "Trace_type_basis.h"
 #include <cassert>
 #include <iostream>
 
 
 namespace ColorFull {
 
 
 Poly_vec Trace_type_basis::decompose( const Col_amp & Ca ) {
 
 	Col_amp Ca_copy=Ca;
 	Ca_copy.simplify();
 
 	// To contain the decomposed vector
 	Poly_vec Decv;
 	Polynomial Zero;
-	Zero=Zero*0;
+	Zero*=0;
 	if(cb.size()==0){
 		std::cerr << "Trace_type_basis::decompose: The basis vector cb is empty consider using create_basis or read in basis." << std::endl;
 		assert( 0 );
 	}
 	else if(Ca_copy.size()>0 ){
 		if(Ca_copy.at(0).n_quark() != nq)
 		{
 			std::cerr << "Trace_type_basis::decompose: The number of quarks in the argument Col_amp, " <<  Ca
 					<< ", does not fit the number of quarks in the basis "
 					<< nq << "."<< std::endl;}
 		if(Ca_copy.at(0).n_gluon() != ng )
 		{
 			std::cerr << "Trace_type_basis::decompose: The number of gluons in the argument Col_amp, " << Ca
 					<< ", does not fit the number of gluons in the basis "
 					<< ng << "."<< std::endl;
 		}
 	}
 
 	// Initially set all components of the vectors to 0
 	for (uint m2 = 0; m2 < cb.size(); m2++){
-		Decv.push_back(Zero);
+		Decv.append(Zero);
 	}
 
 	// Loop over Cs in Ca and check which basis vector they equal
 	for (uint m1 = 0; m1 < Ca_copy.ca.size(); m1++) {
 
 		for ( uint m2 = 0; m2 < cb.size(); m2++ ) {
 			bool found=false;
 
 			// For a trace type basis it is enough to compare to see if the basis vector
 			// is equal to the Col_str in the Ca.
 			if (Ca_copy.ca.at(m1).cs == cb.at(m2).at(0).cs) {
 				found=true;
-				Decv.at(m2)=Decv.at(m2)+Ca_copy.ca.at(m1).Poly;
+				Decv.at(m2) += Ca_copy.ca.at(m1).Poly;
 				Decv.at(m2).simplify();
 			}
 
 			if(found) break; // The tensor is ONE of the tensors in the Basis
 		}
 	}
 
 	return Decv;
 }
 
 std::pair<int, int>  Trace_type_basis::new_vector_numbers( const Col_str & Cs, int emitter ) {
 
 	// Number of new gluon
 	int new_g=Cs.n_gluon()+2*Cs.n_quark()+1;
 
 	// First check that basis is not empty
 	if( cb.empty() ){
 		std::cerr << "Trace_type_basis::new_vector_numbers: The basis has no vectors, "
 					<< "consider using create_basis or read_in_basis." << std::endl;
 		assert( 0 );
 	}
 	// Then check that number of quarks is the same as for the Cs
 	if( nq != Cs.n_quark() ){
 		std::cerr << "Trace_type_basis::new_vector_numbers: The number of quarks in the (new) basis, " << nq << " is not the same "
 					<< "as the number of quarks in Cs, " << Cs.n_quark() << ", in Cs."<< std::endl;
 		assert( 0 );
 	}
 	// Then check that number of gluons is one more than for the Cs
 	if( ng != Cs.n_gluon()+1 ){
 		std::cerr << "Trace_type_basis::new_vector_numbers: The number of gluons in the (new) basis, " << ng
 					<< ", is not one plus the number of gluons in Cs << "
 					<< Cs.n_gluon()<< std::endl;
 		assert( 0 );
 	}
 
 	// To contain the numbers of the new non-zero vectors
 	int plus_comp=-1;
 	int minus_comp=-1;
 
 	// The vector after emission
 	Col_amp Ca=Col_fun.emit_gluon(Cs, emitter, new_g);
 	Poly_vec vec=decompose( Ca );
 
 	// Loop over vector entries to identify the non-zero ones
 	for ( uint veci= 0; veci < cb.size(); veci++) {
 		if( Col_fun. double_num(vec.at(veci))!=0 ){
 			if(Col_fun.double_num(vec.at(veci)) > 0){plus_comp=veci;}
 			if(Col_fun.double_num(vec.at(veci)) < 0){minus_comp=veci;}
 		}
 	}
 
 	std::pair<int, int> res= std::make_pair(plus_comp,minus_comp);
 
 	return res;
 }
 
 
 std::pair<int, int> Trace_type_basis::new_vector_numbers( int old_num, int emitter, int n_loop ) const{
 
 	int n_g_old=ng-1;
 
 	if( !(nq==0 or nq==1 or nq==2) or n_loop!=0 ){
 		std::cerr << "Trace_type_basis:new_vector_numbers(int, int, int): Function only intended for special case of 0-2 q qbar pair at tree level. For the general case use the general version." << std::endl;
 		assert( 0 );
 	}
 
 	// Find the place of the parton
 	std::pair<int,int> parton_place=find_parton( emitter, old_num, nq, n_g_old, n_loop);
 
 	// If the q or qbar is radiating, there is only one term
 	if(parton_place.second==0 && nq>=1)// If the q is radiating
 		return std::make_pair(new_vector_number(old_num, std::make_pair(parton_place.first,parton_place.second+1),  n_loop),-1);
 
 	else if(parton_place.second==n_g_old+1 && nq==1)
 		return std::make_pair(-1,new_vector_number(old_num, parton_place, n_loop));
 
 	// If the emitter is a g there are two different terms
 	std::pair<int,int> first_insertion_place, second_insertion_place;
 	if( nq==0 && parton_place.second!=0) {
 		first_insertion_place=std::make_pair(parton_place.first, parton_place.second + 1);
 		second_insertion_place=std::make_pair(parton_place.first, parton_place.second );
 	}
 	// Special case that the emitter is standing first
 	else if(nq==0 && parton_place.second==0){
 		first_insertion_place=std::make_pair(0,  1);
 		second_insertion_place=std::make_pair(0, n_g_old );
 	}
 	else if(nq==1){ // special cases already excluded
 		first_insertion_place=std::make_pair(parton_place.first, parton_place.second+1);
 		second_insertion_place=std::make_pair(parton_place.first, parton_place.second);
 	}
 	else if(nq==2){ // special case of quark already excluded
 
 		// If the emitter is an anti-quark
 		if(emitter==2 or emitter==4){
 			return std::make_pair(-1,new_vector_number(old_num, parton_place, n_loop));
 
 		}
 
 		// Emitter is a gluon, and is thus not standing in the ends
 		first_insertion_place=std::make_pair(parton_place.first, parton_place.second+1);
 		second_insertion_place=std::make_pair(parton_place.first, parton_place.second);
 	}
 
 	int first_tens = new_vector_number(old_num, first_insertion_place, n_loop);
 	int second_tens = new_vector_number(old_num, second_insertion_place, n_loop);
 
 	return std::make_pair( first_tens, second_tens );
 }
 
 
 
 int Trace_type_basis::new_vector_number( int old_num, std::pair<int,int> place, int n_loop) const{
 
 	int n_g_old=ng-1;
 
 	std::cout.flush();
 	if( !( nq==0 or nq==1 or nq==2 ) ){
-		std::cerr << "Trace_type_basis::new_vector_number: Function only intended for special case of 1 quark line or 2 open quark lines." << std::endl;
+		std::cerr << "Trace_type_basis::new_vector_number: Function only intended for special case of 1 or 2 open quark-lines." << std::endl;
 		std::cerr.flush();
 		assert( 0 );
 	}
 	if( nq==0 and !tree_level_gluon_basis ){
 		std::cerr << "Trace_type_basis:new_vector_number: For 0 qqbar-pairs this function is only available for Tree_level_gluon_basis." << std::endl;
 		assert( 0 );
 	}
 	if( nq>0 and !trace_basis ){
 		std::cerr << "Trace_type_basis:new_vector_number: The basis type should be Trace_basis for processes with quarks, not Tree_level_gluon_basis." << std::endl;
 		assert( 0 );
 	}
 
 	if(place.second == 0 && nq>0 ){
 		std::cerr << "Trace_type_basis::new_vector_number: Cannot insert gluon at place 0, reserved for quark." << std::endl;
 		std::cerr.flush();
 		assert( 0 );
 	} else if(place.second==n_g_old+2 && nq==1){
 		std::cerr << "Trace_type_basis::new_vector_number: Cannot insert gluon at place n_g_old+2, reserved for qbar." << std::endl;
 		std::cerr.flush();
 		assert( 0 );}
 	else if(nq==2 && (0 > place.second or place.second > n_g_old+1+1) ){
 		std::cerr << "Trace_type_basis::new_vector_number: Cannot insert gluon outside range 1...n_g_old." << std::endl;
 		std::cerr.flush();
 		assert( 0 );
 	}
 	else if( 0 > place.second or place.second > n_g_old+1+nq){
 		std::cerr << "Trace_type_basis::new_vector_number: Cannot insert gluon outside range 1...n_g_old ." << std::endl;
 		std::cerr.flush();
 		assert( 0 );
 	}
 	// If asked to insert a gluon at place 0, it should be inserted beyond the last place instead
 	if( nq==0 && place.second==0 ){
 		place.second=n_g_old;
 	}
 
 	// In the gluons only case we need to keep track of the next position relative to gluon 2
 	int place2=0;
 
 	int fnext=old_num; // To contain the remaining part of tensor number
 	// If there are 2 quarks, there is an effective scalar place in {1,g1...gm,2}{3,gm+1...4}
 	// obtained by crossing 2}{3 out. This place is given by
 	// (place in the first ql) if it is in the first ql
 	// (number of gluons in first ql) + place in second if it's in the second ql
 
 	// If nq=2 the color structure is of type {q1, g1....gm,q2}{q3,gm+1...gn,q4}
 	// This is almost as in the case of only one Ql {q1, g1....gm,gm+1...gn,q4}
 	// with a breakpoint "q2}{q3" inserted or q4}{q3.
 	// To find the tensor number, first locate the breakpoint.
 	// This can be done by noting that there are 2*2*n_g_old! options for each breakpoints,
 	// where the factor 2*2 comes from the options for the quarks
 	// we thus have
 	int break_after=0;
 	int fsplit=0; // Contribution from where the ql is split
 	int fq1=0; // Contribution from first quark
 	if (nq == 2) {
 
 		// To contain the number of gluon in the first ql
 		// First the number of gluons in 2nd ql
 		// For each gluon in 2nd ql there was
 		// 2 (from nq)*2 (from n_qbar)*factorial(n_g_old) (from the gluons)
 		// tensors with lower numbers from other breaks
 		// Note that for all other splitting the factor from the first q is relevant
 		break_after = old_num /( 2*2*Col_fun.factorial(n_g_old) ) ;
 
 
 		fnext= old_num % (2*2*Col_fun.factorial(n_g_old));
 		// The factor from the split
 		fsplit=old_num-fnext;
 		break_after=n_g_old-break_after;
 
 		// Check if the first quark is 1 or 3
 		// The factor from the first quark
 		fq1=(fnext/( 2*Col_fun.factorial(n_g_old) ))*2*Col_fun.factorial(n_g_old);
 		// Special case of 2 quark lines of equal length, then there is no option for q1 (it is 1)
 		if( break_after==n_g_old-break_after ) fq1=0; // 1 is first, no factor from first quark
 		fnext= fnext % (2*Col_fun.factorial(n_g_old));
 
 		// First treat the special case when the ql's switch place
 		// This can happen when
 		// 1) The 2nd ql gets longer than the first such as
 		// 		emission from 6 in {1,5,2}{3,6,4} -> {3,6,7,4}{1,5,2}
 		// 2) The 2nd is one shorter than the first but has the q=1 standing first
 		// 		{3,5,6,2}{1,7,4} ->{1,8,7,4}{3,5,6,2}
 		if( ((break_after==n_g_old-break_after) && place.first==1) or ((break_after==n_g_old+1-break_after) && fq1>0 && place.first==1)) {
 
 			// Locate all partons in old ql
 			std::vector< std::pair<int, std::pair<int,int> > > parton_and_place;
 			for( int p=1; p<=n_g_old+2*nq; p++ ){
 				std::pair<int,int> p_place=find_parton(p, old_num, nq, n_g_old, n_loop);
 				make_pair(p,p_place);
 				// note that parton p stands at place p-1
 				parton_and_place.push_back( make_pair(p,p_place) ) ;
 			}
 
 			// To contain new tensor number
 			int new_num=0;
 
 			// First calculate the number from the split
 			// After the split the number of gluons in the qls are
 			// break_after in the 2nd ql
 			// This is true for both special cases of form
 			// {1,5,2}{3,6,4} -> {3,6,7,4}{1,5,2}
 			// 	{3,5,6,2}{1,7,4} ->{1,8,7,4}{3,5,6,2}
 			new_num=(break_after)*2*2*Col_fun.factorial(n_g_old+1);
 
 			// Then calculate the number from the first quark
 			// There is a factor 2 from the anti-quark and a factor (n_g_old+1)! from the gluons
 			// if the first factor is 3, which it is in swapings of form
 			// {1,5,2}{3,6,4} -> {3,6,7,4}{1,5,2}
 			if( (break_after==n_g_old-break_after) && place.first==1 )	new_num=new_num+2*Col_fun.factorial(n_g_old+1);
 			// In cases of form {3,5,6,2}{1,7,4} ->{1,8,7,4}{3,5,6,2}
 			// the factor from the first quark is 0, and
 
 
 			// For the anti-quark qbar=2, check if it stands in first or 2nd ql
 			// If it stands in first ql, there is no contribution to the tensor numbers
 			// otherwise there is a contribution from all orders of gluons in 2nd ql
 			if( parton_and_place.at(2-1).second.first==0) new_num+=Col_fun.factorial(break_after);
 
 			// The 2nd anti-quark and 2nd quark gives no contribution
 
 			// Then calculate the contribution to the new tensor number from the gluons
 			// Loop over gluons
 			for( int p=5; p<=n_g_old+2*nq; p++ ){
 
 				// The NEW scalar place of the gluon
 				int p_place=parton_and_place.at(p-1).second.second; // contribution from pos in ql
 				// If a gluon was standing in the first ql it is afterwards standing in the 2nd
 				// All gluons in the new first (old 2nd ql) are therefore standing in front
 				// they are n_g_old-break_after +1 (the +1 is added below)
 				if(parton_and_place.at(p-1).second.first==0) p_place+=(n_g_old-break_after);
 				// If the new gluon was inserted before the parton, then the p_place should be increased with one
 				// This happens when the parton stands in the new 2nd ql= old first ql  (always)
 				// or when the gluon is in the new first ql, but after the emitter
 				if( parton_and_place.at(p-1).second.first==0 or place.second <=parton_and_place.at(p-1).second.second ) p_place++;// ?? is this right
 
 				// See how many smaller stand to the right
 				int smaller_right_of_p=0;
 				// Check all gluons with smaller number than p to see how many stand to the right
 				for( int ps=5; ps<p; ps++ ){
 					int ps_place=parton_and_place.at(ps-1).second.second; // Contribution from pos in ql
 					if(parton_and_place.at(ps-1).second.first==0) ps_place+=(n_g_old-break_after); // From first ql
 					if( parton_and_place.at(ps-1).second.first==0 or place.second <=parton_and_place.at(ps-1).second.second ) ps_place++; // From new g
 					// If the smaller parton ps stand to the right of the parton p
 					if( ps_place>p_place ) smaller_right_of_p++;
 				}
 
 				// Increase the new tensor number for partons to the right
 				if( smaller_right_of_p>0 ){
 					// If the gluon stands in the first ql (former 2nd), there is also a factor of 2 from the
 					// choice of anti-quarks
 					// All smaller_right_of_p ways of replacing p with a smaller number contributes a factor
 					// Col_fun.factorial(gluons to the right), and there are smaller_right_of_p options
 					if(parton_and_place.at(p-1).second.first==1) new_num+=2*smaller_right_of_p*Col_fun.factorial(n_g_old+1-p_place);
 					else new_num+=smaller_right_of_p*Col_fun.factorial(n_g_old+1-p_place);
 				}
 
 			} // End of loop over gluons
 
 			// Add contribution from the new gluon. The gluon number is larger than every other gluon number,
 			// so all gluons standing to the right are smaller
 			// In the new first ql the new gluon is at place place.second
 			// and there are in total n_g_old-break_after+1 gluons, so the total number of gluons to the right is
 			// break_after+(n_g_old-break_after+1) -place.second
 			int n_right_new=(n_g_old+1)-place.second;
 			// The overall contribution also has a factor 2 from the qbar choice
 			// The factor 2 is from the qbar, Col_fun.factorial(n_right_new) from ordering gluons
 			new_num+=2*n_right_new*Col_fun.factorial(n_right_new);
 
 			return new_num;
 		} // End of hard case
 	}
 
 
 	if ( nq==0 ) place2=find_parton(2, old_num, nq, n_g_old, n_loop).second;
 	// Initially we had q=1, g1,....gn, qbar=2
 	// After the insertion at place place we have q=1, g1, ...g(place-1), g_new, g(place), ...gn, qbar=2
 	// The number of the new vector can be seen as a sum of 3 factors:
 	// f1 = the contribution from q=1, g1, ...g(place-1)
 	// fnew= the contribution from the newly inserted gluon
 	// f2= the contribution from g(place), ...gn, qbar=2 (this contribution is the same as before the insertion)
 	// Of these contributions fnew is easiest to calculate it is simply:
 	int fnew=0;
 	// If one ql
 	if( nq==1 ) fnew=(n_g_old - place.second + 1)*Col_fun.factorial(n_g_old - place.second + 1);
 	// Special case of place after last gluon
 	else if( nq==0 && place.second == n_g_old+1 ) fnew=0;
 	// If one closed ql and the parton is to the right of 2
 	else if( nq==0 && place.second > place2 && place.second < n_g_old+1) fnew=(n_g_old - place.second )*Col_fun.factorial(n_g_old - place.second );
 	// If the parton is before 2
 	else if( nq==0 && place2 >= place.second ) fnew=(n_g_old - place.second )*(Col_fun.factorial(n_g_old - place.second )/2); //Rel order 2 3 fixed
 
 	// The factor f1 is trickier to obtain. Its initial value (before emission) is
 	// sum_{i=1}^(place-1) n_sri (n_p-i)!
 	// where n_sri denotes the number of smaller partons standing to the rigt at place i
 	// these factors are not known, but can be calculated.
 	// Once these factors are known the final value of f1 can also be obtained from
 	// sum_{i=1}^(place-1) n_sri (n_p-i+1)!
 	// where the extra 1 in the factorial is present as after the emission there is
 	// one more parton standing to the right.
 
 	int f1new=0; // To contain the new f1
 	int f1old=0; // To contain the old f1
 
 	int scalar_place=0; // The scalar place
 	if( place.first!=0 )  scalar_place=break_after;
 	scalar_place+=place.second;
 
 	if( nq==2 ) {
 		fnew=(n_g_old + 1- scalar_place )*Col_fun.factorial(n_g_old + 1- scalar_place );
 
 		// If g inserted in first ql, there is an extra factor of 2 from interchanging quarks
 		if( place.first==0 ) fnew*=2;
 
 	} // end of if( nq==2 )
 
 	// The last relevant parton for calculating the contribution to f1
 	int last_rel=scalar_place-1;
 
 	for (int i=1; i<=last_rel; i++){
 		//cout << "i " << i << endl;
 		// number of partons to the right
 		int n_r=n_g_old-i;
 		if( nq==0 ) n_r--;
 
 		// nsri is the number of smaller partons to the right
 		int nsri=0;
 		if (nq==1 ) {
 			// Note integer division, how many times do we find the factorial
 			nsri=fnext/(Col_fun.factorial(n_r));
 			// The contribution to the old f1
 			f1old+=nsri*Col_fun.factorial(n_r);
 			// The next effective f, to use for finding next nsri
 			fnext=fnext%(Col_fun.factorial(n_r));
 			// The contribution to the new f1
 			f1new+=nsri*(Col_fun.factorial(n_r+1));
 		}
 		else if (nq==2) {
 			int q_part=1;
 			// Keeps track of a possible multiplicative factor from first qbar option
 			if ( i <= break_after) q_part=nq;
 
 			// Note integer division, how many times do we find the factorial
 			nsri=fnext/(q_part*Col_fun.factorial(n_r));
 			// The contribution to the old f1
 			f1old+=nsri*q_part*Col_fun.factorial(n_r);
 			// The next effective f, to use for finding next nsri
 			fnext=fnext%(q_part*Col_fun.factorial(n_r));
 			// The contribution to the new f1
 			f1new+=nsri*(q_part*Col_fun.factorial(n_r+1));
 
 			// Take care of factor from first qbar "when we reach it"
 			// if( i == break_after && place.second!=break_after+1 && break_after=n_g_old-break_after) {
 			if( i == break_after ) {
 				// Note integer division, how many times do we find the factorial
 				nsri=fnext/(Col_fun.factorial(n_r));
 				int f1old_before_qbar=f1old;
 				// The contribution to the old f1
 				f1old+=nsri*Col_fun.factorial(n_r);
 				// The next effective f, to use for finding next nsri
 				fnext=fnext%(Col_fun.factorial(n_r));
 				// if the gluon is inserted just before the qbar the factor from
 				// the qbar should be taken care of in the f2 instead
 				// (f1old still has to be recalculated as it is used for finding f2 which is unchanged)
 				// If the g is NOT inserted just before the qbar
 				// i.e. if it is either inserted in 2nd ql or at other place than break_after+1
 				if ( !(scalar_place == break_after+1) or place.first ==1){
 					// The contribution to the new f1 from the anti-quark
 					//f1new+=nsri*(factorial(n_r+1));
 					// There are (n_r+1)! options to have 2 before 4
 					// and we should only have a contribution if 4 is before 2
 					f1new+=nsri*(Col_fun.factorial(n_r+1));
 				}
 				else { // If the gluon is inserted just before the qbar
 					// The factor should be accounted for in fnew instead
 					// If the second qbar was 4, this should be compensated for in fnew
 					if( f1old_before_qbar!=f1old && place.first ==0){
 
 						// The factor is the number of ways of ordering the gluons in 2nd ql
 						// The q and qbar are fixed and do not contribute
 						// There is no factor if no gluons to the right ??
 						// There are n_r gluons in the second ql (also after emission)
 						fnew=fnew+Col_fun.factorial(n_r);
 					}
 				}
 			}
 
 		} // end if (nq==2)
 
 		// If i is after the place of 2 we have the standard case
 		else if(nq==0 && i >= place2) {
 			nsri=fnext/(Col_fun.factorial(n_r));
 			f1old+=nsri*Col_fun.factorial(n_r);
 			fnext=fnext%(Col_fun.factorial(n_r));
 			f1new+=nsri*(Col_fun.factorial(n_r+1));
 		}
 		// If i is before the place of 2 ordering of 2 and 3 irrelevant
 		else if(nq==0 &&  i < place2) {
 
 			nsri=fnext/(Col_fun.factorial(n_r)/2);
 			f1old+=nsri*(Col_fun.factorial(n_r)/2);
 			fnext=fnext%(Col_fun.factorial(n_r)/2);
 			f1new+=nsri*(Col_fun.factorial(n_r+1)/2);
 		}
 	}
 
 	// Once f1 is known then f2 is simply,
 	int f2=0;
 	if( nq==2 ) {
 		// For 2 qqbar pairs we have to take care of factor from split
 		f2=old_num-f1old-fsplit-fq1;
 	}
 	else f2=old_num-f1old;
 
 	// and the contribution from f2 is the same as before (irrespectively of position relative 2)
 
 	// In the case of 2 quarks, if there was a contribution to the tensor number from the split
 	// this has to be added back
 
 	// The contribution was (n_g_old-break_after)*(2*factorial(n_g_old))
 	// The special case of ql swapping should already have been taken care of
 	if( nq==2 ) {
 
 		// Calculating new factor from the split
 		int fsplitnew=0;
 
 		// New factor from split after insertion in first ql
 		if(place.first==0) {
 			// The length of 2nd ql is then still (n_g_old-break_after)
 			// and for each break there are 2*factorial(n_g_old+1) options
 			// The lengths of first and 2nd ql are never equal as 1st was at least as long as 2nd
 			// -> factor 2 from option of first q
 			fsplitnew=(n_g_old-break_after)*2*2*Col_fun.factorial(n_g_old+1);
 		}
 
 		// If the insertion was in the second ql (of new length n_g_old-break_after+1)
 		if(place.first==1) {
 			// The length of the 2nd ql is now (n_g_old+1-break_after)
 			// all gluon orders matter, and the qbar matters
 			// Also the factor fomr the split, coming from all "lower splits"
 			// has a factor 2 as the q matters for the lower splits
 			fsplitnew=(n_g_old+1-break_after)*2*2*Col_fun.factorial(n_g_old+1); // 1*2*2!
 
 		}
 
 		int fq1new=fq1*(n_g_old+1);
 
 		// If after emission the 2nd ql has the same length as the first
 		if(place.first==1 && break_after==n_g_old+1-break_after){
 			fq1new=fq1new/2; // How can this be right?? There should be no factor from first quark then
 		}
 
 		f1new=fsplitnew+fq1new+f1new;
 
 	} // End of nq==2
 
 	return f1new+fnew+f2;
 }
 
 
 std::pair<int,int> Trace_type_basis::find_parton( int parton, int vec_num, int n_quark, int n_gluon, int n_loop ) const{
 	if( !(n_quark==1 or n_quark==0 or n_quark==2) or n_loop >0 ){
 		std::cerr << "Trace_type_basis:find_parton: Function only intended for special case of 0-2 qqbar pairs, and a tree level bases." << std::endl;
 		assert( 0 );
 	}
 	if( n_quark==0 and !tree_level_gluon_basis ){
 		std::cerr << "Trace_type_basis:find_parton: For 0 qqbar-pairs this function is only available for Tree_level_gluon_basis." << std::endl;
 		assert( 0 );
 	}
 	if( n_quark>0 and !trace_basis ){
 		std::cerr << "Trace_type_basis:find_parton: The basis type should be Trace_basis for processes with quarks, not Tree_level_gluon_basis." << std::endl;
 		assert( 0 );
 	}
 
 	if( parton==1 && n_quark == 1) return std::make_pair( 0, 0 ); // q=1 or g=1 has position 0 if one ql
 	if( parton==1 && n_quark == 0) return std::make_pair( 0, 0 ); // q=1 or g=1 has position 0 if one ql
 	if( parton==2 && n_quark==1 ) return std::make_pair( 0, n_gluon+1 ); // qbar has last pos
 
 	// If n_quark=2 the color structure is of type {q1, g1....gm,q2}{q3,gm+1...gn,q4}
 	// This is almost as in the case of only one Ql {q1, g1....gm,gm+1...gn,q4}
 	// with a breakpoint "q2}{q3" inserted or q4}{q3.
 	// To find the tensor number, first locate the breakpoint.
 	// This can be done by noting that there are 2*n_gluon! options for each breakpoints,
 	// where the factor 2 comes from the 2 options for the first anti-quark
 	// we thus have
 	int break_after=n_gluon;
 	if (n_quark == 2) {
 		// There are n_quark!n_quark!n_gluon! assignments for each break
 		break_after = break_after-(vec_num) / (2*2*Col_fun.factorial(n_gluon));
 		vec_num= vec_num -(n_gluon-break_after)*(2*2*Col_fun.factorial(n_gluon));
 
 		// Check if first parton is 1 or 3, there are 2 options for each from the qbar being 2 or 4
 		bool first3=false;
 		if (  ( vec_num / ( 2*Col_fun.factorial(n_gluon)) ) ) first3=true;
 
 		vec_num= vec_num % (2*Col_fun.factorial(n_gluon));
 
 		// Special cases of asked for quark
 		if(parton == 1){
 			if(!first3) return std::make_pair(0,0);
 			else return std::make_pair(1,0);
 		}
 		if(parton == 3){
 			if(first3) return std::make_pair(0,0);
 			else return std::make_pair(1,0);
 		}
 	}
 
 	// The number of partons gluons with lower parton number than the parton
 	// (and possibly standing to the right, hence -1)
 	int lower=parton-2-n_quark;
 	if ( n_quark==2 ) lower=parton -2*n_quark-1; // quarks don't count
 
 	// To contain the number of gluons standing to the right of the parton under consideration
 	// and being smaller than 2, noting to the right is smaller than 2, hence 0
 	// needed for special case of gluons only
 	int lower2=0;
 
 	// Number of partons to the right, when checking the various positions
 	int n_r=0;
 	// For quark lines(s) all gluons except the one under consideration matter
 	if ( n_quark>0 ) n_r=n_gluon-1;
 	// For a gluon line we have to subtract 1 extra as we start read at place 1 anyway
 	else if ( n_quark==0 ) n_r=n_gluon-2;
 
 	// Was the gluon 2 found or not, needed for special case of gluons only
 	bool found_2=false;
 
 	// The resulting quark_line number (can change only in case 2 q qbar pairs)
 	int ql_num=0;
 
 	// Loop over possible places of the gluon, start with checking place 1
 	// n_l_r contains the number of partons lower than the parton at the position under consideration
 	int n_l_r=0; // To make compiler not warn
 	int looped_over=0;
 	while(true){
 		if( n_quark==1 ) {
 			n_l_r=vec_num/Col_fun.factorial(n_r); // The result of integer division
 			vec_num=vec_num%Col_fun.factorial(n_r); // The rest after integer division
 		}
 
 		if( n_quark==2 ) {
 
 			// If both qbars to right extra factor 2!
 			if( break_after > looped_over) {
 
 				n_l_r=vec_num/(Col_fun.factorial(n_r)*2); // The result of integer division
 				vec_num=vec_num%(Col_fun.factorial(n_r)*2); // The rest after integer division
 			}
 			else{
 				// Check if it is time to compensate for first qbar and second q
 				if ( break_after==looped_over ){
 
 					// If we have already looped over all gluons
 					if(n_r==-1) n_r=0;
 					// Special cases if asked for first qbar = 2 or 4
 					if( parton==2){
 						// All gluons which are not looped over are to right
 						if (vec_num/(Col_fun.factorial(n_r+1))==0) return std::make_pair(0,break_after+1);
 						else return std::make_pair(1,n_gluon-break_after+1);
 					}
 					if( parton==4){
 						if (vec_num/(Col_fun.factorial(n_r+1))==1) return std::make_pair(0,break_after+1);
 						else return std::make_pair(1,n_gluon-break_after+1);
 					}
 
 					vec_num=vec_num%(Col_fun.factorial(n_r+1)); // compensated for first qbar
 
 
 					// After looking at first qbar the ql_num should be 1
 					ql_num=1;
 				}
 
 				// Otherwise the situation is as for gluons only
 				n_l_r=vec_num/(Col_fun.factorial(n_r)); // The result of integer division
 				vec_num=vec_num%Col_fun.factorial(n_r); // The rest after integer division
 			}
 		}
 		else if (n_quark==0){
 			if( found_2 ){
 				n_l_r=vec_num/Col_fun.factorial(n_r);
 				vec_num=vec_num%Col_fun.factorial(n_r);
 			}
 			else{
 				// First check if 2 was at the position
 				n_l_r=vec_num/(Col_fun.factorial(n_r)); // If 2 was at the place, then all orders matter
 				// If 2 was found
 				if( n_l_r==lower2 ) {
 					found_2=true;
 					vec_num=vec_num%(Col_fun.factorial(n_r));				}
 				else{ // Recalculate knowing that we did not find 2
 					n_l_r=vec_num/(Col_fun.factorial(n_r)/2); // There is only one relative order of gluon 2 and 3
 					vec_num=vec_num%(Col_fun.factorial(n_r)/2); // The rest after integer division
 				}
 			}
 		}
 		if( n_l_r==lower ) break; // Number smaller to right = number smaller than parton to right
 		if( n_l_r < lower ) lower--;
 		n_r--;
 		looped_over++; // needed to compare with break in 2q case
 	}
 
 	// and then the number in the quark_line
 	int pos_num=n_gluon-n_r; // n_quark==1 case
 	if( n_quark==0) pos_num=n_gluon-n_r-1;
 	else if( n_quark==2 && ql_num==0) pos_num=n_gluon-n_r;
 	else if(n_quark==2 && ql_num==1) pos_num=n_gluon-break_after-n_r;
 
 	return std::make_pair( ql_num, pos_num );
 }
 
 
 
 } // end namespace ColorFull
diff --git a/MatrixElement/Matchbox/ColorFull/Trace_type_basis.h b/MatrixElement/Matchbox/ColorFull/Trace_type_basis.h
--- a/MatrixElement/Matchbox/ColorFull/Trace_type_basis.h
+++ b/MatrixElement/Matchbox/ColorFull/Trace_type_basis.h
@@ -1,104 +1,103 @@
 // -*- C++ -*-
 /*
  *  Trace_type_basis.h
  *	Contains the declarations of the class Trace_type_basis, related types and operators.
  *  Created on: Aug 9, 2012
  *  Author: Malin Sjödahl
  */
 
 #ifndef COLORFULL_Trace_type_basis_h
 #define COLORFULL_Trace_type_basis_h
 
 #include "Col_basis.h"
 
 
 namespace ColorFull {
 
 /// Trace_type_basis is used for the common features of
 /// Trace_basis and Tree_level_gluon_basis which both inherit
 /// from Trace_type_basis.
 class Trace_type_basis:public Col_basis{
 
 public:
 
 	/// Default constructor.
 	Trace_type_basis():Col_basis(){
 		// The maximal number of quark_lines is
 		// nq+n_g/2 for a Trace_basis and 1 for a Tree_level_gluon basis,
 		// but at this time nq and n_g are not known.
 		max_ql=0;
 	}
 
 	/// A function for decomposing the color amplitude ca in the basis,
 	/// returning the result as a Polynomial.
 	Poly_vec decompose( const Col_amp & Ca );
 
 
 	/// Function for finding the new vector numbers in the new basis
 	/// (this trace basis)
 	/// after radiating a new gluon from the parton emitter.
 	/// The old color structure is Cs, and after emission a linear combination
 	/// of new basis vectors is obtained.
-	/// For emission from a quark or anti-quark there is only one resulting color
+	/// For emission from a quark or an anti-quark there is only one resulting color
 	/// structure, and -1 is returned in the place of the absent color structure.
 	/// The second vector, where the new gluon is inserted before the emitter,
 	/// comes with a minus sign in the new total amplitude.
 	std::pair<int, int>  new_vector_numbers( const Col_str & Cs, int emitter ) ;
 
 
-	/// This function is intended for tree level processes with at most 2 qqbar-pairs.
+	/// This function is intended for tree-level processes with at most 2 qqbar-pairs.
 	/// It finds the new vector numbers in the basis for n_p+1 partons
-	/// after radiating a new parton from the parton emitter.
-	/// This function doesn't actually use the cb, but only calculates the
+	/// after radiating a new gluon from the parton emitter.
+	/// This function does not actually use the cb, but only calculates
 	/// the basis vector number, which makes it much quicker than the general version.
 	/// The old vector has number old_num, and there were, before emission,
 	/// nq quarks (+ nq anti-quarks) and n_g-1 gluons, i.e. n_p=2 nq+ n_g-1.
 	/// For emission from q or qbar there is only one resulting color structure,
 	/// and -1 is returned in the place of the absent color structure.
 	/// The second vector, where the new gluon is inserted before the emitter
 	/// comes with a minus sign in the new total amplitude.
 	/// The function has been explicitly tested against its sister function
 	/// for initial states with 2 qqbar-pairs and up to 5 gluons,
 	/// 1qqbar-pair and up to 7 gluons and 0 qqbar-pairs and up to 8 gluons.
 	std::pair<int, int>  new_vector_numbers( int old_num, int emitter, int n_loop ) const;
 
 
-
 protected:
 
 	/// The maximal number of quark-lines allowed in the basis.
 	/// This is used for constructing bases that only are valid
 	/// up to a certain order in QCD, such that unused information
 	/// need not be carried around.
 	int max_ql;
 
 	/// Function for finding the new vector number in the basis with n_p+1 partons (this basis)
 	/// after inserting a new gluon with larger parton number at the place place.
 	/// This function is only intended for the special cases of
 	/// 0 qqbar-pairs and Tree_level_gluon_basis
 	/// or Trace_basis and 1-2 qqbar-pairs at tree level, i.e. n_loop must be 0.
 	/// This function doesn't actually use the cb, but only calculates the
 	/// the basis vector number using find_parton.
 	/// The old vector has number old_num, and there were, before emission
 	/// nq quarks (+ nq anti-quarks) and n_g-1 gluons, i.e. n_p=2 nq + n_g-1.
 	/// The function has been explicitly tested for initial states with 2qqbar-pairs and up to 5 gluons,
 	/// 1qqbar-pair and up to 7 gluons, 0 qqbar-pairs and up to 8 gluons.
 	int new_vector_number( int old_num, std::pair<int,int> place, int n_loop ) const;
 
 	/// This function is only intended for special case of:
 	/// 0 qqbar-pairs and Tree_level_gluon_basis
 	/// or Trace_basis and 1-2 qqbar-pairs at tree level, i.e. n_loop must be 0.
 	/// It locates the parton parton in the normal ordered basis,
 	/// given the number of the vector vec_num, and the number of quarks and gluons in the basis.
 	/// The function has been explicitly tested for Trace_basis with 1 qqbar-pair and up to 8 gluons
 	/// and 2 qqbar-pairs and up to 7 gluons, and for Tree_level_gluon_bases with up to 9 gluons.
 	/// The arguments n_quark and n_gluon has to be provided as it may be desirable to
 	/// use the function with a different number of quarks and gluons than in the basis itself.
 	std::pair<int,int> find_parton( int parton, int vec_num, int n_quark, int n_gluon, int n_loop ) const;
 
 };
 
 }
 
 #endif /* COLBASIS_H_ */
 
diff --git a/MatrixElement/Matchbox/ColorFull/Tree_level_gluon_basis.cc b/MatrixElement/Matchbox/ColorFull/Tree_level_gluon_basis.cc
--- a/MatrixElement/Matchbox/ColorFull/Tree_level_gluon_basis.cc
+++ b/MatrixElement/Matchbox/ColorFull/Tree_level_gluon_basis.cc
@@ -1,285 +1,285 @@
 // -*- C++ -*-
 /*
  * Tree_level_gluon_basis.h
  * Contains definition of the class Tree_level_gluon_basis and associated types and operators.
  * Created on: Aug 9, 2012
  * Author: Malin Sjodahl
  */
 
 #include "Tree_level_gluon_basis.h"
 #include "parameters.h"
 #include <cassert>
 #include <fstream>
 #include <iostream>
 
 
 namespace ColorFull {
 
 
 void Tree_level_gluon_basis::create_basis( int n_gluon ) {
 
 	// Setting basis variable
 	ng=n_gluon;
 
 	// Remove a potentially already calculated basis
 	cb.clear();
 	// The Col_amp containing the basis
 	Col_amp Ca_basis;
 
 	// Create the basis using the old function for a maximal number of loops
 	Ca_basis = create_trace_basis(ng);
 
 	// Sort the resulting Col_amp into the Col_basis cb
 	for ( uint i = 0; i < Ca_basis.ca.size(); i++ ) {
 		// A Col_amp to contain a basis vector
 		Col_amp Ca_vec;
 		Ca_vec.ca.push_back(Ca_basis.ca.at(i));
 		cb.push_back(Ca_vec);
 	}
 }
 
 
 void Tree_level_gluon_basis::read_in_Col_basis( std::string filename ){
 
 
 	// First read in basis as normally
 
 	// Read in file
 	std::ifstream fin(filename.c_str());
 
 	// Check that file exists
 	if( !fin ){
 		std::cerr << "Tree_level_gluon_basis::read_in_Col_basis: The file "
 				<< filename << " could not be opened." << std::endl;
 		assert( 0 );
 	}
 
 	// Erase current information
 	cb.clear();
 
 	// Copy info from file to string
 	std::string str((std::istreambuf_iterator<char>(fin)), std::istreambuf_iterator<char>());
 
 	Col_basis_of_str( str );
 
 	// Then check that it's really a tree level gluon basis
 	// Check that length of each Col_amp is 2
 	for( uint bv=0; bv < cb.size(); bv++ ){
 		if( cb.at(bv).size()!=2 ){
 			std::cerr << "Tree_level_gluon_basis::read_in_Col_basis: The basis read in from file " << filename <<
 					" has basis vectors with length > 2, and is thus not a tree level gluon basis."
 					<< std::endl;
 			assert( 0 );
 		}
 
 		// Check that the first term is the conjugate of the second
 		// Check col_str exactly
 		Col_str Cs_conj=cb.at(bv).at(1) ;
 		Cs_conj.conjugate();
 		Cs_conj.simplify();
 		if( cb.at(bv).at(0).cs !=  Cs_conj.cs ){
 			std::cerr << "Tree_level_gluon_basis::read_in_Col_basis: The basis read in from file " << filename
 					<< " has basis vector " << bv << " with non self-conjugate color structure "
 					<< cb.at(bv)
 					<<". The col_str " <<  cb.at(bv).at(0).cs << " is not the same as " << Cs_conj.cs << std::endl;
 			assert( 0 );
 		}
 		// Check Polynomial numerically
 		if( std::abs(  Col_fun. cnum_num(cb.at(bv).at(0).Poly - (pow(-1.0, ng))* Cs_conj.Poly) ) > accuracy ){
 			std::cerr << "Tree_level_gluon_basis::read_in_Col_basis: The basis read in from file " << filename
 					<< " has basis vector " << bv << " which is not real due to multiplying Polynomial."
 					<< std::endl;
 			assert( 0 );
 		}
 
 		// Then, remove implicit part
 		cb.at(bv).erase(1);
 	}
 }
 
 
 void Tree_level_gluon_basis::write_out_Col_basis( ) const{
 
 	write_out_Col_basis( basis_file_name() );
 
 }
 
 
 void Tree_level_gluon_basis::read_in_Col_basis( ) {
 
 	read_in_Col_basis( basis_file_name() );
 
 }
 
 
 void Tree_level_gluon_basis::write_out_Col_basis( std::string filename ) const{
 
 	if(  (cb.size()==0 ) ) {
 		std::cout << "Tree_level_gluon_basis::write_out_Col_basis(string): There are no basis vectors in this basis, consider using create_basis or read_in_basis." << std::endl;
 		std::cout.flush();
 		return ;
 	}
 
 	std::ofstream outfile(filename.c_str());
 
 	if ( !outfile )
 	std::cerr << "Tree_level_gluon_basis::write_out_Col_basis: Cannot write out basis as the file \""
 		<< filename.c_str() << "\" could not be opened. (Does the directory exist? Consider creating the directory.)" << std::endl;
 
 
 	int sign=pow(-1,cb.at(0).n_gluon());
 	for (uint m = 0; m < cb.size(); m++) {
 		outfile << m << "      "<< cb.at(m);
 		if(sign==1 ) outfile << " + ";
 		else outfile << " - ";
 		Col_amp Ca_conj=cb.at(m);
 		Ca_conj.conjugate();
 		Ca_conj.normal_order();
 		outfile << Ca_conj << std::endl;
 	}
 	outfile.flush();
 }
 
 
-void Tree_level_gluon_basis::write_out_Col_basis_to_cout() const{
+std::ostream&  Tree_level_gluon_basis::write_out_Col_basis_to_stream( std::ostream&  out ) const{
 
 	if(  (cb.size()==0 ) ) {
 		std::cout << "Tree_level_gluon_basis::write_out_Col_basis(): There are no basis vectors in this basis, consider using create_basis." << std::endl;
 		std::cout.flush();
-		return ;
 	}
 
 	int sign=pow(-1,cb.at(0).n_gluon());
 	for (uint m = 0; m < cb.size(); m++) {
 		std::cout << m << "      "<< cb.at(m);
 		if(sign==1 ) std::cout << " + ";
 		else std::cout << " - ";
 		Col_amp Ca_conj=cb.at(m);
 		Ca_conj.conjugate();
 		Ca_conj.normal_order();
-		std::cout << Ca_conj << std::endl;
+		out << Ca_conj << std::endl;
 	}
+	return out;
 }
 
 
 Polynomial Tree_level_gluon_basis::ij_entry( const int i, const int j ) const{
 
 	// Loop over basis vectors in Basis
 	Polynomial ijEntry;
 	uint Ng=cb.at(i).n_gluon();
 
 	// The sign of the interference, (-1)^Ng
 	int sign=(Ng % 2 ? -1:1);
 
 	Col_amp Cbi_conj=cb.at(i);
 	Cbi_conj.conjugate();
 	ijEntry=2*Col_fun.scalar_product( cb.at(i), cb.at(j) )
 			+sign*2*Col_fun.scalar_product( cb.at(j), Cbi_conj );
 	ijEntry.simplify();
 	return ijEntry;
 }
 
 
 Col_amp Tree_level_gluon_basis::create_trace_basis( int n_g ) const {
 
 	// To contain the resulting basis
 	Col_amp Basis;
 
 	// There has to be at least two gluons
 	if (n_g <= 1) {
 		std::cerr
 				<< "Tree_level_gluon_basis::create_trace_basis: For 0 quarks there is no basis with only "
 				<< n_g << " gluons" << std::endl;
 		assert( 0 );
 	}
 
 	// If 2 or more gluons, build from the 2-gluon basis
 	else if (n_g >= 2) {
 		Col_str Cs_OnlyState("[(1,2)]");
 		Col_amp Ca_tmp;
 		Ca_tmp.ca.push_back(Cs_OnlyState);
 
 		Basis = Ca_tmp;
 		// For 2 gluons, the work is done
 		if (n_g == 2)
 			return Basis;
 	}
 
 	// Then, add the gluons one at the time
 	// As there are only gluons the generation should start from gluon 3,
 	// otherwise from 2*n_q+1;
 	for (int g_new = 3; g_new <= n_g; g_new++) {
 		// If only gluons start from the 2-gluon state, so add gluon 3
-		Basis = add_one_gluon(Basis, n_g, g_new);
+		Basis = add_one_gluon(Basis, g_new);
 	}
 
 	// Normal order the Col_str's
 	Basis.normal_order();
 	return Basis;
 
 }
 
 
 Col_amp Tree_level_gluon_basis::add_one_gluon( const Col_str & Cs, int g_new ) const {
 
 	// For storing the new basis
 	Col_amp New_tensors;
 
 	// Add the new gluon in all possible ways to the old Color structure
 	// Loop over the Quark_lines
 	for (uint ql = 0; ql < Cs.cs.size(); ql++) {
 		// The old Quark_line, before insertion of the new gluon index
 		Quark_line Old_Ql = Cs.cs.at(ql);
 		Col_str New_tensor = Cs;
 
 		// Special case of insertion of a gluon in a 2-ring in a gluons only basis
 		// in this case only "half" the basis states for rings with >= 3 gluons are
 		// generated. The rest are obtained by taking the indices in anti-cyclic order
 		// i.e. by complex conjugating
 		if ((Old_Ql.ql.size() == 2 && Cs.gluons_only())) {
 			// Insert the new gluon after the existing gluons
 			Quark_line New_Ql = Old_Ql;
 			New_Ql.ql.push_back(g_new);
 			// Replace the old Col_str with the new and add to the new basis states
 			New_tensor.cs.at(ql) = New_Ql;
 			New_tensors = New_tensors + New_tensor;
 		} else { // ordinary case
 
 			// Loop over (potential) insertion places in the Quark_lines, starting from the end
 			for (int j = Old_Ql.ql.size(); j > 0; j--) {
 
 				// Special treatment of last place, insert here only if the ring is open
 				// (the gluon index cannot take the place of the a quark index)
 				if (Old_Ql.open && j == static_cast<int>(Old_Ql.ql.size()))
 					j--;
 
 				Quark_line New_Ql = Old_Ql;
 				quark_line::iterator it = New_Ql.ql.begin() + j;
 				New_Ql.ql.insert(it, g_new);
 
 				// Replace the old Col_str with the new and add to the new basis states
 				New_tensor.cs.at(ql) = New_Ql;
 				New_tensors = New_tensors + New_tensor;
 			}
 		}
 	}
 
 	return New_tensors;
 }
 
 
-Col_amp Tree_level_gluon_basis::add_one_gluon(const Col_amp & Old_basis, int, int g_new) const {
+Col_amp Tree_level_gluon_basis::add_one_gluon(const Col_amp & Old_basis, int g_new) const {
 
 	// For storing the new basis
 	Col_amp New_bas;
 
 	// Add the new gluon to each of the previous color tensors
 	for (uint t = 0; t < Old_basis.ca.size(); t++) {
 		New_bas = New_bas + add_one_gluon(Old_basis.ca.at(t), g_new);
 	}
 
 	return New_bas;
 }
 
 } // end namespace ColorFull
 
diff --git a/MatrixElement/Matchbox/ColorFull/Tree_level_gluon_basis.h b/MatrixElement/Matchbox/ColorFull/Tree_level_gluon_basis.h
--- a/MatrixElement/Matchbox/ColorFull/Tree_level_gluon_basis.h
+++ b/MatrixElement/Matchbox/ColorFull/Tree_level_gluon_basis.h
@@ -1,116 +1,116 @@
 // -*- C++ -*-
 /*
  *  Trace_basis.h
  *	Contains the declarations of the class Tree_level_gluon_basis, related types and operators
  *  Created on: Aug 9, 2012
  *  Author: Malin Sjodahl
  */
 
 #ifndef COLORFULL_Tree_level_gluon_basis_h
 #define COLORFULL_Tree_level_gluon_basis_h
 
 #include "Trace_type_basis.h"
 
 namespace ColorFull {
 
 
 /// This class is for containing tree level gluon bases,
 /// i.e. bases of form Tr(t^a t^b....t^z) +/- Tr(t^z .... t^b t^a),
 /// where the sign is given by (-1)^n_g.
 /// Technically only one of the quark-lines are carried
 /// around in the cb member, the other is implicit.
 /// This speeds up calculations.
 class Tree_level_gluon_basis:public Trace_type_basis {
 public:
 
 	/// Default constructor.
 	Tree_level_gluon_basis():Trace_type_basis(){
 		initialize();
 	}
 
-	/// Constructor for creating a tree level gluon basis for n_g gluons.
+	/// Constructor for creating a tree level gluon basis with n_g gluons.
 	Tree_level_gluon_basis( int n_g ):Trace_type_basis(){
 		initialize();
 		create_basis( n_g );
 	}
 
-	/// Little helper function, called by constructors.
-	void initialize(){
-		tree_level_gluon_basis = true;
-		max_ql=1;
-	}
-
 	/******************** Basis creation **********************/
 	// Special functions are needed as half the color structure is implicit
 
 	/// Creates a basis with basis vectors saved in the cb member.
 	/// Each basis vector is a sum of two traces,
 	/// of form Tr(t^a t^b....t^z) +/- Tr(t^z .... t^b t^a).
 	/// The charge conjugated trace
 	/// is implicit, and only one trace is actually
 	/// carried around.
 	void create_basis( int n_g );
 
 	/******************** Basis reading and writing **********************/
 
 	/// Function for reading in the basis from a file.
 	/// The file should contain the whole basis,
 	/// including the charge conjugated part.
 	void read_in_Col_basis( std::string filename );
 
 	/// Function reading in the basis from default name
 	/// (see basis_file_name in the Col_basis class).
 	/// The full basis, including the charge conjugated
-	/// part is written out. (This is to simplify
+	/// part should be contained in the file. (This is to simplify
 	/// comparison with other programs, such as ColorMath.)
 	void read_in_Col_basis( );
 
 	/// Function for writing out the basis to default name,
 	/// (see basis_file_name in the Col_basis class).
 	/// The full basis, including the charge conjugated
 	/// part is written out. (This is to simplify
 	/// comparison with other programs, such as ColorMath.)
 	void write_out_Col_basis( ) const;
 
 	/// Function for writing out the basis to filename,
 	/// (see basis_file_name in the Col_basis class).
 	/// The full basis, including the charge conjugated
 	/// part is written out. (This is to simplify
 	/// comparison with other programs, such as ColorMath.)
 	void write_out_Col_basis( std::string filename ) const;
 
-	/// Function for writing out the basis to cout.
-	/// As the charge conjugated quark_line is implicit,
-	/// a special function is needed for the Tree_level_gluon_basis case.
-	void write_out_Col_basis_to_cout() const;
 
 protected:
 
+	/// Function for writing out the basis in a human readable
+	/// format to an ostream.
+	virtual std::ostream&  write_out_Col_basis_to_stream( std::ostream&  out ) const;
+
 
 private:
 
+	/// Little helper function, called by constructors.
+	void initialize(){
+		tree_level_gluon_basis = true;
+		max_ql=1;
+	}
+
 	/// Calculate element ij in scalar product matrix
 	/// using the implicit presence of a charge conjugated Col_str.
 	Polynomial ij_entry( const int i, const int j ) const;
 
 	/******************** Basis creation **********************/
 
 	/// Function for creating a basis with n_g gluons.
 	Col_amp create_trace_basis( int n_g ) const;
 
 	/// Computes the new basis states coming from one old Col_str
 	/// when one gluon, g_new, is added.
 	/// g_new is the number of the new gluon.
 	Col_amp add_one_gluon( const Col_str & Cs, int g_new ) const;
 
 	/// Compute the basis if one gluon is added to the old basis Old_basis.
 	/// (For a Trace_type_basis, the basis is can be contained in a
 	/// Col_amp, and this is the case for Old_basis).
 	/// g_new is the number of the new gluon.
 	/// Used by create_basis.
-	Col_amp add_one_gluon( const Col_amp & Old_basis, int n_g, int g_new ) const;
+	Col_amp add_one_gluon( const Col_amp & Old_basis, int g_new ) const;
 
 };
 
 } /* namespace ColorFull */
 #endif /* COLORFULL_Tree_level_gluon_basis_h */
diff --git a/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.cc
@@ -1,392 +1,325 @@
 // -*- C++ -*-
 //
 // FFMassiveInvertedTildeKinematics.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 FFMassiveInvertedTildeKinematics class.
 //
 
 #include "FFMassiveInvertedTildeKinematics.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Repository/EventGenerator.h"
 
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 #include "Herwig/MatrixElement/Matchbox/Phasespace/RandomHelpers.h"
 
 using namespace Herwig;
 
-FFMassiveInvertedTildeKinematics::FFMassiveInvertedTildeKinematics() 
-  : theFullJacobian(true) {}
+FFMassiveInvertedTildeKinematics::FFMassiveInvertedTildeKinematics() {}
 
 FFMassiveInvertedTildeKinematics::~FFMassiveInvertedTildeKinematics() {}
 
 IBPtr FFMassiveInvertedTildeKinematics::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FFMassiveInvertedTildeKinematics::fullclone() const {
   return new_ptr(*this);
 }
 
+// Matches Stephen Webster's thesis
 bool FFMassiveInvertedTildeKinematics::doMap(const double * r) {
 
-  // todo - SW: Sort out all of the notation in the matchbox
-  // kinematics to match the manual, before manual release. 
   if ( ptMax() < ptCut() ) {
     jacobian(0.0);
     return false;
   }
 
   Lorentz5Momentum emitter = bornEmitterMomentum();
   Lorentz5Momentum spectator = bornSpectatorMomentum();
 
   double mapping = 1.0;
   vector<double> values(6);
   pair<Energy,double> ptz = generatePtZ(mapping, r, &values);
   if ( mapping == 0.0 ) {
     jacobian(0.0);
     return false;
   }
 
-  // pt and zPrime = qi.nk / (qi+qj).nk are the generated variables
   Energy pt = ptz.first;
   Energy2 pt2 = sqr(pt);
-  double zPrime = ptz.second;
-  
+  double z = ptz.second;
+
+  // masses
+  double mui2 = sqr( realEmitterData()->hardProcessMass() / lastScale() );
+  double muj2 = sqr( realEmissionData()->hardProcessMass() / lastScale() );
+  double muk2 = sqr( realSpectatorData()->hardProcessMass() / lastScale() );
+  double Muij2 = sqr( bornEmitterData()->hardProcessMass() / lastScale() );
+  double Muk2 = sqr( bornSpectatorData()->hardProcessMass() / lastScale() );
 
   // Define the scale
   Energy2 Qijk = sqr(lastScale());
 
   // Most of the required values have been calculated in ptzAllowed
   double y = values[0];
-  double z = values[1];
-  double A = values[2];
-  double xk = values[3];
-  double xij = values[4];
-  double suijk = values[5];
-  double suijk2 = sqr(suijk);
-  
-  // masses
-  double mui2 = sqr( realEmitterData()->hardProcessMass() / lastScale() );
-  double mu2  = sqr( realEmissionData()->hardProcessMass() / lastScale() );
-  //double muj2 = sqr( realSpectatorData()->hardProcessMass() / lastScale() );
-  double Mui2 = sqr( bornEmitterData()->hardProcessMass() / lastScale() );
-  double Muj2 = sqr( bornSpectatorData()->hardProcessMass() / lastScale() );
+  double zi = values[1];
+  double xk = values[2];
+  double xij = values[3];
+  double QijN2 = values[4];
+  double sijkN = values[5];
+  double sijkN2 = sqr(sijkN);
 
+  // Construct reference momenta nk, nij
+  Lorentz5Momentum nij = ( sijkN2 / (sijkN2-Muij2*Muk2) )
+    * (emitter - (Muij2/sijkN)*spectator);
+  Lorentz5Momentum nk = ( sijkN2 / (sijkN2-Muij2*Muk2) )
+    * (spectator - (Muk2/sijkN)*emitter);
 
-  // Construct reference momenta nk, nij, nt
-  Lorentz5Momentum nij = ( suijk2 / (suijk2-Mui2*Muj2) )
-    * (emitter - (Mui2/suijk)*spectator);
-  Lorentz5Momentum nk = ( suijk2 / (suijk2-Mui2*Muj2) )
-    * (spectator - (Muj2/suijk)*emitter);
-
-  // Following notation in notes, qt = sqrt(wt)*nt
+  // Construct qt
   double phi = 2.*Constants::pi*r[2];
-  Lorentz5Momentum qt = getKt(nij,nk,pt,phi);
+  Lorentz5Momentum qt = getKt(emitter,spectator,pt,phi);
 
   // Construct qij, qk, qi and qj
-  Lorentz5Momentum qij = xij*nij + (Mui2/(xij*suijk))*nk;
-  Lorentz5Momentum spe = xk*nk + (Muj2/(xk*suijk))*nij;
+  Lorentz5Momentum qij = xij*nij + (Muij2/(xij*sijkN))*nk;
+  Lorentz5Momentum spe = xk*nk + (Muk2/(xk*sijkN))*nij;
 
-  Lorentz5Momentum em = zPrime*qij
-    + ((pt2/Qijk + mui2 - zPrime*zPrime*Mui2)/(xij*suijk*zPrime))*nk + qt;
-  Lorentz5Momentum emm = (1.-zPrime)*qij
-    + ((pt2/Qijk + mu2 - sqr(1.-zPrime)*Mui2)/(xij*suijk*(1.-zPrime)))*nk - qt;
+  Lorentz5Momentum em = z*qij
+    + ((pt2/Qijk + mui2 - z*z*Muij2)/(xij*sijkN*z))*nk + qt;
+  Lorentz5Momentum emm = (1.-z)*qij
+    + ((pt2/Qijk + muj2 - sqr(1.-z)*Muij2)/(xij*sijkN*(1.-z)))*nk - qt;
 
   em.setMass(realEmitterData()->hardProcessMass());
   em.rescaleEnergy();
   emm.setMass(realEmissionData()->hardProcessMass());
   emm.rescaleEnergy();
   spe.setMass(realSpectatorData()->hardProcessMass());
   spe.rescaleEnergy();
 
   // book
   realEmitterMomentum() = em;
   realEmissionMomentum() = emm;
   realSpectatorMomentum() = spe;
+
+  // Calculate the jacobian
+  double bar = 1.-mui2-muj2-muk2;
   
-  // Compute and store the jacobian
-  // The jacobian here corresponds to dpt2 / sqr(lastscale) NOT dpt2 / pt2.
-  // This jacobian is the one-particle phase space
-  
-  // jac s.t.: dy dz = jac* dpt2/sqr(lastScale()) dz
-  double jac = 0.0;
-
-  // SW - Change in notation here that needs to be fixed (j<->nothing<->k)
-  Energy2 mi2 = sqr(realEmitterData()->hardProcessMass());
-  Energy2 mj2 = sqr(realEmissionData()->hardProcessMass());
-  Energy2 mk2 = sqr(realSpectatorData()->hardProcessMass());
-  Energy2 mij2 = sqr(bornEmitterData()->hardProcessMass());
-  Energy2 sbar = Qijk - mi2 - mj2 -mk2;
-
-  if ( theFullJacobian && bornSpectatorData()->hardProcessMass() != ZERO ) {
-
-    Energy2 sijk = Qijk*suijk;
-
-    double lambdaK = 1. + (mk2/sijk);
-    double lambdaIJ = 1. + (mij2/sijk);
-    
-    // Compute dy/dzPrime and pt2* dy/dpt2
-    double dyBydzPrime = (1./sbar) *
-      ( -pt2*(1.-2.*zPrime)/sqr(zPrime*(1.-zPrime))
-	- mi2/sqr(zPrime) + mj2/sqr(1.-zPrime) );
-    InvEnergy2 dyBydpt2 = 1./(sbar*zPrime*(1.-zPrime));
-
-    // Compute dA/dzPrime and dA/dpt2
-    double dABydzPrime = (sbar/sijk) * dyBydzPrime;
-    InvEnergy2 dABydpt2 = (sbar/sijk) * dyBydpt2;
-
-    // Compute dxk/dzPrime, dxk/dpt2, dxij/dzPrime and dxij/dpt2
-    double factor = (0.5/lambdaK) *
-      (-1. 
-       - (1./sqrt( sqr(lambdaK + (mk2/sijk)*lambdaIJ - A)
-		 - 4.*lambdaK*lambdaIJ*mk2/sijk))
-       * (lambdaK + (mk2/sijk)*lambdaIJ - A) );
-    
-    double dxkBydzPrime = factor * dABydzPrime;
-    InvEnergy2 dxkBydpt2 = factor * dABydpt2;
-
-    double dxijBydzPrime = (mk2/sijk) * (1./sqr(xk)) * dxkBydzPrime;
-    InvEnergy2 dxijBydpt2 = (mk2/sijk) * (1./sqr(xk)) * dxkBydpt2;
-
-    Energy2 dqiDotqkBydzPrime = xij*xk*0.5*sijk
-      + zPrime*dxijBydzPrime*xk*0.5*sijk + zPrime*xij*dxkBydzPrime*0.5*sijk
-      + 0.5*(mk2/sijk)*(pt2 + mi2)
-      * (-1./(xk*xij*sqr(zPrime)) - dxkBydzPrime/(zPrime*xij*sqr(xk))
-	 - dxijBydzPrime/(zPrime*xk*sqr(xij)));
-
-    double dqiDotqkBydpt2 =  dxijBydpt2*zPrime*xk*0.5*sijk
-      + zPrime*xij*dxkBydpt2*0.5*sijk
-      + (0.5*mk2/sijk) * (1./(zPrime*xk*xij))
-      * (1. + (pt2+mi2)*(-dxkBydpt2/xk - dxijBydpt2/xij) );
-
-    
-    // Compute dzBydzPrime and dzBydpt2
-    Energy2 qiDotqk = (zPrime*xij*xk*sijk*0.5)
-      + (mk2/ ( 2.*xk*xij*sijk*zPrime))*(pt2 + mi2);
-
-    double dzBydzPrime = (1./sbar)
-      * ( 2.*qiDotqk*dyBydzPrime/sqr(1.-y) + (1./(1.-y))*2.*dqiDotqkBydzPrime );
-    InvEnergy2 dzBydpt2 = (1./sbar)
-      * ( 2.*qiDotqk*dyBydpt2/sqr(1.-y) + (1./(1.-y))*2.*dqiDotqkBydpt2 );
-
-    // Compute the jacobian    
-    jac = Qijk * abs(dzBydpt2*dyBydzPrime - dzBydzPrime*dyBydpt2);
-
-  }
-
-  // This is correct in the massless spectator case.
-  else {
-    jac = Qijk / (sbar*zPrime*(1.-zPrime));
-  }
+  // mapFactor defined as dy dz = mapFactor * dpt2/sqr(lastScale()) dz
+  double mapFactor = 0.0;
+  mapFactor = y*(sqr(lastScale()) / (pt2 + sqr(1.-z)*mui2*Qijk + sqr(z)*muj2*Qijk))
+      * abs(1. - 2.*Muk2*QijN2 / (bar*(1.-y)*xij*xk*sijkN));
   
   // Mapping includes only the variable changes/jacobians
-  mapping *= jac;
-  jacobian( (sqr(sbar)/rootOfKallen(Qijk,mij2,mk2)) * mapping*(1.-y)/(16.*sqr(Constants::pi)) / sHat() );
+  mapping *= mapFactor;
+  jacobian( (Qijk*sqr(bar)/rootOfKallen(1.,Muij2,Muk2)) * mapping
+            * (1.-y)/(16.*sqr(Constants::pi)) / sHat() );
   
   // Store the parameters
   subtractionParameters().resize(3);
   subtractionParameters()[0] = y;
-  subtractionParameters()[1] = z;
-  subtractionParameters()[2] = zPrime;
-   
+  subtractionParameters()[1] = zi;
+  subtractionParameters()[2] = z;
+  
   return true;
-
 }
 
 
 Energy FFMassiveInvertedTildeKinematics::lastPt() const {
   
   Energy scale = (bornEmitterMomentum()+bornSpectatorMomentum()).m();
   // masses
   double mui2 = sqr( realEmitterData()->hardProcessMass() / scale );
-  double mu2  = sqr( realEmissionData()->hardProcessMass() / scale );
-  double muj2 = sqr( realSpectatorData()->hardProcessMass() / scale );
+  double muj2  = sqr( realEmissionData()->hardProcessMass() / scale );
+  double muk2 = sqr( realSpectatorData()->hardProcessMass() / scale );
   
   double y = subtractionParameters()[0];
-  double zPrime = subtractionParameters()[2];
+  double z = subtractionParameters()[2];
   
-  Energy ret = scale * sqrt( y * (1.-mui2-mu2-muj2) * zPrime*(1.-zPrime) - sqr(1.-zPrime)*mui2 - sqr(zPrime)*mu2 );
+  Energy ret = scale * sqrt( y * (1.-mui2-muj2-muk2) * z*(1.-z) - sqr(1.-z)*mui2 - sqr(z)*muj2 );
 
   return ret;
 }
 
 double FFMassiveInvertedTildeKinematics::lastZ() const {
   return subtractionParameters()[2];
 }    
 
 Energy FFMassiveInvertedTildeKinematics::ptMax() const {
   
   Energy scale = (bornEmitterMomentum()+bornSpectatorMomentum()).m();
   // masses
   double mui2 = sqr( realEmitterData()->hardProcessMass() / scale );
-  double mu2  = sqr( realEmissionData()->hardProcessMass() / scale );
-  double muj2 = sqr( realSpectatorData()->hardProcessMass() / scale );
+  double muj2  = sqr( realEmissionData()->hardProcessMass() / scale );
+  double muk2 = sqr( realSpectatorData()->hardProcessMass() / scale );
   
-  Energy ptmax = rootOfKallen( mui2, mu2, sqr(1.-sqrt(muj2)) ) /
-    ( 2.-2.*sqrt(muj2) ) * scale;
+  Energy ptmax = rootOfKallen( mui2, muj2, sqr(1.-sqrt(muk2)) ) /
+    ( 2.-2.*sqrt(muk2) ) * scale;
   
   return ptmax > 0.*GeV ? ptmax : 0.*GeV;
 }
 
 // NOTE: bounds calculated at this step may be too loose
-// These apply to zPrime, which is stored in lastZ()
 pair<double,double> FFMassiveInvertedTildeKinematics::zBounds(Energy pt, Energy hardPt) const {
 
   hardPt = hardPt == ZERO ? ptMax() : min(hardPt,ptMax());
   if(pt>hardPt) return make_pair(0.5,0.5);
   
   Energy scale = (bornEmitterMomentum()+bornSpectatorMomentum()).m();
   // masses
   double mui2 = sqr( realEmitterData()->hardProcessMass() / scale );
-  double mu2  = sqr( realEmissionData()->hardProcessMass() / scale );
-  double muj2 = sqr( realSpectatorData()->hardProcessMass() / scale );
+  double muj2  = sqr( realEmissionData()->hardProcessMass() / scale );
+  double muk2 = sqr( realSpectatorData()->hardProcessMass() / scale );
   
-  double zp = ( 1.+mui2-mu2+muj2-2.*sqrt(muj2) +
-    rootOfKallen(mui2,mu2,sqr(1-sqrt(muj2))) *
+  double zp = ( 1.+mui2-muj2+muk2-2.*sqrt(muk2) +
+    rootOfKallen(mui2,muj2,sqr(1.-sqrt(muk2))) *
     sqrt( 1.-sqr(pt/hardPt) ) ) /
-    ( 2.*sqr(1.-sqrt(muj2)) );
-  double zm = ( 1.+mui2-mu2+muj2-2.*sqrt(muj2) -
-    rootOfKallen(mui2,mu2,sqr(1-sqrt(muj2))) *
+    ( 2.*sqr(1.-sqrt(muk2)) );
+  double zm = ( 1.+mui2-muj2+muk2-2.*sqrt(muk2) -
+    rootOfKallen(mui2,muj2,sqr(1.-sqrt(muk2))) *
     sqrt( 1.-sqr(pt/hardPt) ) ) /
-    ( 2.*sqr(1.-sqrt(muj2)) );
+    ( 2.*sqr(1.-sqrt(muk2)) );
     
   return make_pair(zm,zp);
 }
 
+// Matches Stephen Webster's thesis
 bool FFMassiveInvertedTildeKinematics::ptzAllowed(pair<Energy,double> ptz, vector<double>* values) const {
 
   Energy pt = ptz.first;
   Energy2 pt2 = sqr(pt);
-  double zPrime = ptz.second;
+  double z = ptz.second;
 
   // masses
   double mui2 = sqr( realEmitterData()->hardProcessMass() / lastScale() );
-  double mu2  = sqr( realEmissionData()->hardProcessMass() / lastScale() );
-  double muj2 = sqr( realSpectatorData()->hardProcessMass() / lastScale() );
-  double Mui2 = sqr( bornEmitterData()->hardProcessMass() / lastScale() );
-  double Muj2 = sqr( bornSpectatorData()->hardProcessMass() / lastScale() );
+  double muj2  = sqr( realEmissionData()->hardProcessMass() / lastScale() );
+  double muk2 = sqr( realSpectatorData()->hardProcessMass() / lastScale() );
+  double Muij2 = sqr( bornEmitterData()->hardProcessMass() / lastScale() );
+  double Muk2 = sqr( bornSpectatorData()->hardProcessMass() / lastScale() );
   
   // Calculate the scales that we need
   Energy2 Qijk = sqr(lastScale());
-  double suijk = 0.5*( 1. - Mui2 - Muj2 + sqrt( sqr(1.-Mui2-Muj2) - 4.*Mui2*Muj2 ) );
-  double bar = 1.-mui2-mu2-muj2;
+  double QijN2 = (pt2/Qijk + (1.-z)*mui2 + z*muj2) / z / (1.-z);
+  double sijkN = 0.5*( 1. - Muij2 - Muk2 + sqrt( sqr(1.-Muij2-Muk2) - 4.*Muij2*Muk2 ) );
+  double bar = 1.-mui2-muj2-muk2;
 
-  double y = ( pt2/Qijk + sqr(1.-zPrime)*mui2 + zPrime*zPrime*mu2 ) /
-      (zPrime*(1.-zPrime)*bar);
-
-  // Calculate A:=xij*w
-  double A = (1./(suijk*zPrime*(1.-zPrime))) * ( pt2/Qijk + zPrime*mu2 + (1.-zPrime)*mui2 - zPrime*(1.-zPrime)*Mui2 );
+  double y = ( pt2/Qijk + sqr(1.-z)*mui2 + z*z*muj2 ) /
+      (z*(1.-z)*bar);
 
   // Calculate the scaling factors, xk and xij
-  double lambdaK = 1. + (Muj2/suijk);
-  double lambdaIJ = 1. + (Mui2/suijk);
-  double xk = (1./(2.*lambdaK)) * ( (lambdaK + (Muj2/suijk)*lambdaIJ - A) + sqrt( sqr(lambdaK + (Muj2/suijk)*lambdaIJ - A) - 4.*lambdaK*lambdaIJ*Muj2/suijk) );
-  double xij = 1. - ( (Muj2/suijk) * (1.-xk) / xk );
+  double lambdaK = 1. + (Muk2/sijkN);
+  double lambdaIJ = 1. + (Muij2/sijkN);
+  double fac1 = lambdaIJ*lambdaK + (muk2 - QijN2)/sijkN;
+  double xk =
+    ( fac1 + sqrt( sqr(fac1) - 4.*lambdaIJ*lambdaK*muk2/sijkN ) )
+    / 2. / lambdaK ;
+  double xij = 1. - muk2*(1.-xk) / xk / sijkN;
 
-  // Calculate z
-  double z = ( (zPrime*xij*xk*suijk/2.) + (Muj2/ ( 2.*xk*xij*suijk*zPrime))*(pt2/Qijk + mui2) ) /
-    ( (xij*xk*suijk/2.) + (Muj2/(2.*xk*xij))*(Mui2/suijk + A) );
+  // Calculate zi
+  double zi =
+    ( z*xij*xk*sijkN + muk2*(pt2/Qijk + mui2) / (z*xij*xk*sijkN) )
+    / (1.-y) / bar;
+  
+  // Limits on zi
+  double facA = (2.*mui2+bar*y)/2./(mui2 + muj2 + bar*y);
+  double facB =
+    sqrt( (sqr(2.*muk2 + bar*(1.-y)) - 4.*muk2) *
+          (sqr(bar)*sqr(y) - 4.*mui2*muj2))
+    / bar / (1.-y) / (bar*y + 2.*mui2);
+  double zim = facA * (1. - facB);
+  double zip = facA * (1. + facB);
   
   // check (y,z) phase space boundary
-  // TODO: is y boundary necessary?
-  double ym = 2.*sqrt(mui2)*sqrt(mu2)/bar;
-  double yp = 1. - 2.*sqrt(muj2)*(1.-sqrt(muj2))/bar;
-  // These limits apply to z, not zPrime
-  double zm = ( (2.*mui2+bar*y)*(1.-y) - sqrt(y*y-ym*ym)*sqrt(sqr(2.*muj2+bar-bar*y)-4.*muj2) ) /
-    ( 2.*(1.-y)*(mui2+mu2+bar*y) );
-  double zp = ( (2.*mui2+bar*y)*(1.-y) + sqrt(y*y-ym*ym)*sqrt(sqr(2.*muj2+bar-bar*y)-4.*muj2) ) /
-    ( 2.*(1.-y)*(mui2+mu2+bar*y) );
-  
-  if ( y<ym || y>yp || z<zm || z>zp ) return false;
+  double ym = 2.*sqrt(mui2)*sqrt(muj2)/bar;
+  double yp = 1. - 2.*sqrt(muk2)*(1.-sqrt(muk2))/bar;
+
+  if ( y<ym || y>yp || zi<zim || zi>zip ) return false;
 
   assert( (*values).size() == 6);
   (*values)[0] = y;
-  (*values)[1] = z;
-  (*values)[2] = A;
-  (*values)[3] = xk;
-  (*values)[4] = xij;
-  (*values)[5] = suijk;
-      
+  (*values)[1] = zi;
+  (*values)[2] = xk;
+  (*values)[3] = xij;
+  (*values)[4] = QijN2;
+  (*values)[5] = sijkN;
+
   return true;
 }
 
 
-// This is used to generate pt and zPrime
+// This is used to generate pt and z
 pair<Energy,double> FFMassiveInvertedTildeKinematics::generatePtZ(double& jac, const double * r, vector<double> * values) const {
 
   double kappaMin = 
     ptCut() != ZERO ?
     sqr(ptCut()/ptMax()) :
     sqr(0.1*GeV/GeV);
 
   double kappa;
 
   using namespace RandomHelpers;
 
   if ( ptCut() > ZERO ) {
     pair<double,double> kw =
       generate(inverse(0.,kappaMin,1.),r[0]);
     kappa = kw.first;
     jac *= kw.second;
   } else {
     pair<double,double> kw =
       generate((piecewise(),
 		flat(1e-4,kappaMin),
 		match(inverse(0.,kappaMin,1.))),r[0]);
     kappa = kw.first;
     jac *= kw.second;
   }
 
   Energy pt = sqrt(kappa)*ptMax();
 
   pair<double,double> zLims = zBounds(pt);
 
   pair<double,double> zw =
     generate(inverse(0.,zLims.first,zLims.second)+
 	     inverse(1.,zLims.first,zLims.second),r[1]);
 
   double z = zw.first;
   jac *= zw.second;
 
   jac *= sqr(ptMax()/lastScale());
   
   if( !ptzAllowed(make_pair(pt,z), values )) jac = 0.;
 
   return make_pair(pt,z);
 
 }
 
 // If needed, insert default implementations of virtual function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FFMassiveInvertedTildeKinematics::persistentOutput(PersistentOStream &) const {
 }
 
 void FFMassiveInvertedTildeKinematics::persistentInput(PersistentIStream &, int) {  
 }
 
 void FFMassiveInvertedTildeKinematics::Init() {
 
   static ClassDocumentation<FFMassiveInvertedTildeKinematics> documentation
     ("FFMassiveInvertedTildeKinematics inverts the final-final tilde "
      "kinematics involving a massive particle.");
 }
 
 // *** Attention *** The following static variable is needed for the type
 // description system in ThePEG. Please check that the template arguments
 // are correct (the class and its base class), and that the constructor
 // arguments are correct (the class name and the name of the dynamically
 // loadable library where the class implementation can be found).
 DescribeClass<FFMassiveInvertedTildeKinematics,InvertedTildeKinematics>
 describeHerwigFFMassiveInvertedTildeKinematics("Herwig::FFMassiveInvertedTildeKinematics", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.cc
@@ -1,229 +1,232 @@
 // -*- C++ -*-
 //
 // FFMassiveTildeKinematics.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 FFMassiveTildeKinematics class.
 //
 
 #include "FFMassiveTildeKinematics.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 FFMassiveTildeKinematics::FFMassiveTildeKinematics() {}
 
 FFMassiveTildeKinematics::~FFMassiveTildeKinematics() {}
 
 IBPtr FFMassiveTildeKinematics::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FFMassiveTildeKinematics::fullclone() const {
   return new_ptr(*this);
 }
 
+// Matches Stephen Webster's thesis
 bool FFMassiveTildeKinematics::doMap() {
 
   Lorentz5Momentum emitter = realEmitterMomentum();
   Lorentz5Momentum emission = realEmissionMomentum();
   Lorentz5Momentum spectator = realSpectatorMomentum();
 
   // Compute y
   double y = emission*emitter / (emission*emitter + emission*spectator + emitter*spectator);
 
   // Calculate the scale
   Lorentz5Momentum pTot = emitter+emission+spectator;
   Energy scale = pTot.m();
 
   // masses
   double mui2 = sqr( realEmitterData()->hardProcessMass() / scale );
-  double mu2  = sqr( realEmissionData()->hardProcessMass() / scale );
-  double muj2 = sqr( realSpectatorData()->hardProcessMass() / scale );
-  double Mui2 = sqr( bornEmitterData()->hardProcessMass() / scale );
-  double Muj2 = sqr( bornSpectatorData()->hardProcessMass() / scale );
+  double muj2  = sqr( realEmissionData()->hardProcessMass() / scale );
+  double muk2 = sqr( realSpectatorData()->hardProcessMass() / scale );
+  double Muij2 = sqr( bornEmitterData()->hardProcessMass() / scale );
+  double Muk2 = sqr( bornSpectatorData()->hardProcessMass() / scale );
  
   // Calculate the invariants
   Energy2 Qijk = sqr(scale);
-  double suijk = 0.5*( 1. - Mui2 - Muj2 + sqrt( sqr(1.-Mui2-Muj2) - 4.*Mui2*Muj2 ) );
-  double bar = 1. - mui2 - mu2 - muj2;
+  double sijkN = 0.5*( 1. - Muij2 - Muk2 + sqrt( sqr(1.-Muij2-Muk2) - 4.*Muij2*Muk2 ) );
+  double bar = 1. - mui2 - muj2 - muk2;
+  
+  // Calculate Qij2
+  double QijN2 = sqr(emitter + emission)/Qijk;
+  
+  // Calculate the scale factors, xk and xij
+  double lambdaK = 1. + (Muk2/sijkN);
+  double lambdaIJ = 1. + (Muij2/sijkN);
+  double fac1 = lambdaIJ*lambdaK + (muk2 - QijN2)/sijkN;
+  double xk =
+    ( fac1 + sqrt( sqr(fac1) - 4.*lambdaIJ*lambdaK*muk2/sijkN ) )
+    / 2. / lambdaK ;
+  double xij = 1. - muk2*(1.-xk) / xk / sijkN;
+  
+  // Calculate z = qi.nk / (qi+qj).nk from qi.qk and y
+  double l = Muk2 / (2.*xk*xij*sijkN);
+  double a = (xij*xk*sijkN/2.) - l*(bar*y + mui2 + muj2);
+  double b = (-emitter*spectator)/Qijk + l*(bar*y + 2.*mui2);
+  double z = -b/a;
 
-  // Calculate A (as in notes)
-  double A = (y*bar - Mui2 + mui2 + mu2)/suijk;
+  // Calculate zi
+  double zi = emitter*spectator / ((emitter + emission)*spectator);
 
-  // Calculate the scale factors, xk and xij
-  double lambdaK = 1. + (Muj2/suijk);
-  double lambdaIJ = 1. + (Mui2/suijk);
-  double xk = (1./(2.*lambdaK)) * ( (lambdaK + (Muj2/suijk)*lambdaIJ - A) + sqrt( sqr(lambdaK + (Muj2/suijk)*lambdaIJ - A) - 4.*lambdaK*lambdaIJ*Muj2/suijk) );
-  double xij = 1. - ( (Muj2/suijk) * (1.-xk) / xk );
-
-  // Calculate zPrime = qi.nk / (qi+qj).nk from qi.qk and y
-  double l = Muj2 / (2.*xk*xij*suijk);
-  double a = (xij*xk*suijk/2.) - l*(bar*y + mui2 + mu2);
-  double b = (-emitter*spectator)/Qijk + l*(bar*y + 2.*mui2);
-  double zPrime = -b/a;
-
-
-  // Store z as well
-  double z = emitter*spectator / ((emitter + emission)*spectator);
-
+  // Store the variables
   subtractionParameters().resize(3);
   subtractionParameters()[0] = y;
-  subtractionParameters()[1] = z;
-  subtractionParameters()[2] = zPrime;
+  subtractionParameters()[1] = zi;
+  subtractionParameters()[2] = z;
   
   // Calculate nij and nk from qi, q, qj
-  double B = (Mui2/(xij*suijk) + A/xij) / xk;
-  double den = (xij/B - Muj2/(xk*suijk));
-
-  Lorentz5Momentum nij = (1./den)*( (emitter+emission)/B - spectator);
-  Lorentz5Momentum nk = (1./xk)*(spectator - Muj2*nij/(xk*suijk));
-
+  double L = QijN2/xij/xk/sijkN;
+  Lorentz5Momentum nij = (emitter + emission - L*spectator)/(xij - L*Muk2/xk/sijkN);
+  Lorentz5Momentum nk = (1./xk)*(spectator - Muk2*nij/(xk*sijkN));
+    
   // Calculate the born momenta from nij and nk
-  bornSpectatorMomentum() = nk + (Muj2/suijk)*nij;
+  bornSpectatorMomentum() = nk + (Muk2/sijkN)*nij;
   bornEmitterMomentum() = pTot - bornSpectatorMomentum();
 
   bornEmitterMomentum().setMass( bornEmitterData()->hardProcessMass() );
   bornEmitterMomentum().rescaleEnergy();
   bornSpectatorMomentum().setMass( bornSpectatorData()->hardProcessMass() );
   bornSpectatorMomentum().rescaleEnergy();
   
   return true;
 
 }
 
 Energy FFMassiveTildeKinematics::lastPt() const {
   
   Energy scale = (bornEmitterMomentum()+bornSpectatorMomentum()).m();
   
   double y = subtractionParameters()[0];
-  double zPrime = subtractionParameters()[2];
+  double z = subtractionParameters()[2];
   
   // masses
   double mui2 = sqr( realEmitterData()->hardProcessMass() / scale );
-  double mu2  = sqr( realEmissionData()->hardProcessMass() / scale );
-  double muj2 = sqr( realSpectatorData()->hardProcessMass() / scale );
+  double muj2  = sqr( realEmissionData()->hardProcessMass() / scale );
+  double muk2 = sqr( realSpectatorData()->hardProcessMass() / scale );
 
-  Energy ret = scale * sqrt( y * (1.-mui2-mu2-muj2) * zPrime*(1.-zPrime) - sqr(1.-zPrime)*mui2 - sqr(zPrime)*mu2 );
-
+  Energy ret = scale * sqrt( y * (1.-mui2-muj2-muk2) * z*(1.-z) - sqr(1.-z)*mui2 - sqr(z)*muj2 );
+  
   return ret;
+  
 }
 
-
+// Matches Stephen Webster's thesis
 Energy FFMassiveTildeKinematics::lastPt(Lorentz5Momentum emitter,
 					Lorentz5Momentum emission,
 					Lorentz5Momentum spectator)const {
 
 
   // Compute y
   double y = emission*emitter / (emission*emitter 
 			       + emission*spectator 
 			       + emitter*spectator);
 
   // Calculate the scale
   Lorentz5Momentum pTot = emitter+emission+spectator;
   Energy scale = pTot.m();
 
   // masses
   double mui2 = sqr( emitter.mass() / scale );
-  double mu2  = sqr( emission.mass() / scale );
-  double muj2 = sqr( spectator.mass() / scale );
+  double muj2  = sqr( emission.mass() / scale );
+  double muk2 = sqr( spectator.mass() / scale );
    // TODO: here we assume a gluon
   bool isgluon= emitter.mass()==emission.mass();
-  double Mui2 = sqr(( isgluon?ZERO:max(emission.mass(),emitter.mass()) )/ scale );
-  double Muj2 = sqr( spectator.mass() / scale );
+  double Muij2 = sqr(( isgluon?ZERO:max(emission.mass(),emitter.mass()) )/ scale );
+  double Muk2 = sqr( spectator.mass() / scale );
  
   // Calculate the invariants
   Energy2 Qijk = sqr(scale);
-  double suijk = 0.5*( 1. - Mui2 - Muj2 + sqrt( sqr(1.-Mui2-Muj2) - 4.*Mui2*Muj2 ) );
-  double bar = 1. - mui2 - mu2 - muj2;
+  double sijkN = 0.5*( 1. - Muij2 - Muk2 + sqrt( sqr(1.-Muij2-Muk2) - 4.*Muij2*Muk2 ) );
+  double bar = 1. - mui2 - muj2 - muk2;
+  
+  // Calculate Qij2
+  double QijN2 = sqr(emitter + emission)/Qijk;
+  
+  // Calculate the scale factors, xk and xij
+  double lambdaK = 1. + (Muk2/sijkN);
+  double lambdaIJ = 1. + (Muij2/sijkN);
+  double fac1 = lambdaIJ*lambdaK + (muk2 - QijN2)/sijkN;
+  double xk =
+    ( fac1 + sqrt( sqr(fac1) - 4.*lambdaIJ*lambdaK*muk2/sijkN ) )
+    / 2. / lambdaK ;
+  double xij = 1. - muk2*(1.-xk) / xk / sijkN;
+  
+  // Calculate z = qi.nk / (qi+qj).nk from qi.qk and y
+  double l = Muk2 / (2.*xk*xij*sijkN);
+  double a = (xij*xk*sijkN/2.) - l*(bar*y + mui2 + muj2);
+  double b = (-emitter*spectator)/Qijk + l*(bar*y + 2.*mui2);
+  double z = -b/a;
 
-  // Calculate A (as in notes)
-  double A = (y*bar - Mui2 + mui2 + mu2)/suijk;
-
-  // Calculate the scale factors, xk and xij
-  double lambdaK = 1. + (Muj2/suijk);
-  double lambdaIJ = 1. + (Mui2/suijk);
-  double xk = (1./(2.*lambdaK)) * ( (lambdaK + (Muj2/suijk)*lambdaIJ - A) + sqrt( sqr(lambdaK + (Muj2/suijk)*lambdaIJ - A) - 4.*lambdaK*lambdaIJ*Muj2/suijk) );
-  double xij = 1. - ( (Muj2/suijk) * (1.-xk) / xk );
-
-  // Calculate zPrime = qi.nk / (qi+qj).nk from qi.qk and y
-  double l = Muj2 / (2.*xk*xij*suijk);
-  double a = (xij*xk*suijk/2.) - l*(bar*y + mui2 + mu2);
-  double b = (-emitter*spectator)/Qijk + l*(bar*y + 2.*mui2);
-  double zPrime = -b/a;
-
-
-
-  Energy ret = scale * sqrt( y * (1.-mui2-mu2-muj2) * zPrime*(1.-zPrime) - sqr(1.-zPrime)*mui2 - sqr(zPrime)*mu2 );
-
+  Energy ret = scale * sqrt( z*(1.-z)*QijN2 - (1.-z)*mui2 - z*muj2 );
+    
   return ret;
-
-
+  
 }
 
 
   // NOTE: bounds calculated at this step may be too loose
 pair<double,double> FFMassiveTildeKinematics::zBounds(Energy pt, Energy hardPt) const {
   
   if(pt>hardPt) return make_pair(0.5,0.5);
   
   Energy scale = (bornEmitterMomentum()+bornSpectatorMomentum()).m();
     // masses
   double mui2 = sqr( realEmitterData()->hardProcessMass() / scale );
-  double mu2  = sqr( realEmissionData()->hardProcessMass() / scale );
-  double muj2 = sqr( realSpectatorData()->hardProcessMass() / scale );
+  double muj2  = sqr( realEmissionData()->hardProcessMass() / scale );
+  double muk2 = sqr( realSpectatorData()->hardProcessMass() / scale );
   
-  double zp = ( 1.+mui2-mu2+muj2-2.*sqrt(muj2) +
-               rootOfKallen(mui2,mu2,sqr(1-sqrt(muj2))) *
+  double zp = ( 1.+mui2-muj2+muk2-2.*sqrt(muk2) +
+               rootOfKallen(mui2,muj2,sqr(1.-sqrt(muk2))) *
                sqrt( 1.-sqr(pt/hardPt) ) ) /
-  ( 2.*sqr(1.-sqrt(muj2)) );
-  double zm = ( 1.+mui2-mu2+muj2-2.*sqrt(muj2) -
-               rootOfKallen(mui2,mu2,sqr(1-sqrt(muj2))) *
+  ( 2.*sqr(1.-sqrt(muk2)) );
+  double zm = ( 1.+mui2-muj2+muk2-2.*sqrt(muk2) -
+               rootOfKallen(mui2,muj2,sqr(1.-sqrt(muk2))) *
                sqrt( 1.-sqr(pt/hardPt) ) ) /
-  ( 2.*sqr(1.-sqrt(muj2)) );
+  ( 2.*sqr(1.-sqrt(muk2)) );
   
   return make_pair(zm,zp);
 }
 
 
 
 double FFMassiveTildeKinematics::lastZ() const {
   return subtractionParameters()[2];
 }
 
 
 // If needed, insert default implementations of virtual function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FFMassiveTildeKinematics::persistentOutput(PersistentOStream &) const {
 }
 
 void FFMassiveTildeKinematics::persistentInput(PersistentIStream &, int) {
 }
 
 void FFMassiveTildeKinematics::Init() {
 
   static ClassDocumentation<FFMassiveTildeKinematics> documentation
     ("FFMassiveTildeKinematics implements the 'tilde' kinematics for "
      "a final-final subtraction dipole involving a massive particle.");
 
 }
 
 // *** Attention *** The following static variable is needed for the type
 // description system in ThePEG. Please check that the template arguments
 // are correct (the class and its base class), and that the constructor
 // arguments are correct (the class name and the name of the dynamically
 // loadable library where the class implementation can be found).
 DescribeClass<FFMassiveTildeKinematics,TildeKinematics>
 describeHerwigFFMassiveTildeKinematics("Herwig::FFMassiveTildeKinematics", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.cc
@@ -1,166 +1,165 @@
 // -*- C++ -*-
 //
 // IFMassiveInvertedTildeKinematics.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 IFMassiveInvertedTildeKinematics class.
 //
 
 #include "IFMassiveInvertedTildeKinematics.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/Repository/EventGenerator.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 IFMassiveInvertedTildeKinematics::IFMassiveInvertedTildeKinematics() {}
 
 IFMassiveInvertedTildeKinematics::~IFMassiveInvertedTildeKinematics() {}
 
 IBPtr IFMassiveInvertedTildeKinematics::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr IFMassiveInvertedTildeKinematics::fullclone() const {
   return new_ptr(*this);
 }
 
 bool IFMassiveInvertedTildeKinematics::doMap(const double * r) { 
   if ( ptMax() < ptCut() ) {
     jacobian(0.0);
     return false;
   }
 
   // Compute dipole scale
   Lorentz5Momentum emitter = bornEmitterMomentum();
   Lorentz5Momentum spectator = bornSpectatorMomentum();
   Energy2 scale = 2.*(spectator*emitter);
 
   // Generate pt and z
   double mapping = 1.0;
   pair<Energy,double> ptz = generatePtZ(mapping,r);
   if ( mapping == 0.0 ){
     jacobian(0.0);
     return false;
   }
 
   Energy pt = ptz.first;
   double z = ptz.second;
  
     // Compute x and u
     double ratio = sqr(pt)/scale;
     double muk2 = sqr(bornSpectatorData()->hardProcessMass())/scale;
     double rho = 1. - 4.*ratio*(1.-muk2)*z*(1.-z)/sqr(1.-z+ratio);
 
     double x = 0.5*((1.-z+ratio)/(ratio*(1.-muk2))) * (1. - sqrt(rho));
     double u = x*ratio / (1.-z);
       
     // Following Catani-Seymour paper
     double muk2CS = x*muk2;
     double up = (1.-x) /
       ( 1.-x + muk2CS );
       
     if ( x < emitterX() || x > 1. ||
 	 u < 0. || u > up ) {
       jacobian(0.0);
       return false;
     }
    
 
     // Store x and u
     subtractionParameters().resize(2);
     subtractionParameters()[0] = x;
     subtractionParameters()[1] = u;
     
-    // The jacobian here is the single particle phasespace
-    // saj*(1./x^2)*dx*du
+    // jac = sajk*(1./x^2)*dx*du
     // Note - lastScale() is not equal to scale!!!!!!!
-    double jac = abs( (1.+x*(muk2-1.))*(-u*(1.-u)/sqr(x)) - (1.+u*(muk2-1.))*((1.-2.*u)*(1.-x)/x - 2.*u*muk2) );
-    mapping /= x*x*jac;
+    double jac = u/x/(u + x - 2.*u*x*(1.-muk2))*scale/sqr(pt);
+    mapping *= jac;
     jacobian( mapping*(sqr(lastScale())/sHat()) / (16.*sqr(Constants::pi)) );
 
     // Compute the new momenta
     double phi = 2.*Constants::pi*r[2];
     Lorentz5Momentum kt = getKt(emitter,spectator,pt,phi,true);
     
     realEmitterMomentum() = (1./x)*emitter;
     realEmissionMomentum() = ((1.-x)*(1.-u)/x - 2.*u*muk2)*emitter + u*spectator + kt;
     realSpectatorMomentum() = ((1.-x)*u/x + 2.*u*muk2)*emitter + (1.-u)*spectator - kt;
 
     realEmitterMomentum().setMass(ZERO);
     realEmitterMomentum().rescaleEnergy();
     realEmissionMomentum().setMass(ZERO);
     realEmissionMomentum().rescaleEnergy();
     realSpectatorMomentum().setMass(bornSpectatorData()->hardProcessMass());
     realSpectatorMomentum().rescaleEnergy();
     return true;
     
   }
 
 Energy IFMassiveInvertedTildeKinematics::lastPt() const {
     Energy2 scale = 2.*(bornEmitterMomentum()*bornSpectatorMomentum());
     double muk2 = sqr(bornSpectatorData()->hardProcessMass())/scale;
     double x = subtractionParameters()[0];
     double u = subtractionParameters()[1];
     return sqrt(scale * ( u*(1.-u)*(1.-x)/x - u*u*muk2 ));
 }
 
 double IFMassiveInvertedTildeKinematics::lastZ() const {
     Energy2 scale = 2.*(bornEmitterMomentum()*bornSpectatorMomentum());
     double muk2 = sqr(bornSpectatorData()->hardProcessMass())/scale;
     double x = subtractionParameters()[0];
     double u = subtractionParameters()[1];  
     return u + x + u*x*(muk2-1.);
 }
 
 Energy IFMassiveInvertedTildeKinematics::ptMax() const {
     double xe = emitterX();
     Energy2 scale = 2.*(bornEmitterMomentum()*bornSpectatorMomentum());
     Energy2 A = scale*(1.-xe)/xe;
     Energy2 mk2 = sqr(bornSpectatorData()->hardProcessMass());
     return 0.5*A/sqrt(mk2+A);
 }
 
 pair<double,double> IFMassiveInvertedTildeKinematics::zBounds(Energy pt, Energy hardPt) const {
   hardPt = hardPt == ZERO ? ptMax() : min(hardPt,ptMax());
   if(pt>hardPt) return make_pair(0.5,0.5);
   double s = sqrt(1.-sqr(pt/hardPt));
   double xe = emitterX();
   return make_pair(0.5*(1.+xe-(1.-xe)*s),0.5*(1.+xe+(1.-xe)*s));
 }
 
 
 
 // If needed, insert default implementations of virtual function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void IFMassiveInvertedTildeKinematics::persistentOutput(PersistentOStream &) const {
 }
 
 void IFMassiveInvertedTildeKinematics::persistentInput(PersistentIStream &, int) {
 }
 
 void IFMassiveInvertedTildeKinematics::Init() {
 
   static ClassDocumentation<IFMassiveInvertedTildeKinematics> documentation
     ("IFMassiveInvertedTildeKinematics inverts the initial-final tilde "
      "kinematics involving a massive particle.");
 
 }
 
 // *** Attention *** The following static variable is needed for the type
 // description system in ThePEG. Please check that the template arguments
 // are correct (the class and its base class), and that the constructor
 // arguments are correct (the class name and the name of the dynamically
 // loadable library where the class implementation can be found).
 DescribeClass<IFMassiveInvertedTildeKinematics,InvertedTildeKinematics>
 describeHerwigIFMassiveInvertedTildeKinematics("Herwig::IFMassiveInvertedTildeKinematics", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Utility/ColourBasis.cc b/MatrixElement/Matchbox/Utility/ColourBasis.cc
--- a/MatrixElement/Matchbox/Utility/ColourBasis.cc
+++ b/MatrixElement/Matchbox/Utility/ColourBasis.cc
@@ -1,1311 +1,1338 @@
 // -*- C++ -*-
 //
 // ColourBasis.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 ColourBasis class.
 //
 
 #include "ColourBasis.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Parameter.h"
 #include "ThePEG/Interface/Switch.h"
 #include "ThePEG/EventRecord/Particle.h"
 #include "ThePEG/Handlers/SamplerBase.h"
 #include "ThePEG/Repository/UseRandom.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 #include <boost/numeric/ublas/io.hpp>
 #include <boost/numeric/ublas/matrix_proxy.hpp>
 #include <iterator>
 using std::ostream_iterator;
 
 #include "DiagramDrawer.h"
 
 using namespace Herwig;
 
 using boost::numeric::ublas::trans;
 
 // default gcc on SLC6 confuses this with std::conj, 
 // use explicit namespacing in the code instead
 //
 // using boost::numeric::ublas::conj;
 
 using boost::numeric::ublas::row;
 using boost::numeric::ublas::column;
 using boost::numeric::ublas::prod;
 
 Ptr<MatchboxFactory>::tptr ColourBasis::factory() const {
   return MatchboxFactory::currentFactory();
 }
 
 ColourBasis::ColourBasis() 
   : theLargeN(false), didRead(false), didWrite(false), theSearchPath("") {}
 
 ColourBasis::~ColourBasis() {
   for ( map<Ptr<Tree2toNDiagram>::tcptr,vector<ColourLines*> >::iterator cl =
 	  theColourLineMap.begin(); cl != theColourLineMap.end(); ++cl ) {
     for ( vector<ColourLines*>::iterator c = cl->second.begin();
 	  c != cl->second.end(); ++c ) {
       if ( *c )
 	delete *c;
     }
   }
   theColourLineMap.clear();
 }
 
 void ColourBasis::clear() {
   theLargeN = false;
   theNormalOrderedLegs.clear();
   theIndexMap.clear();
+  theEmissionMaps.clear();
+  theCharges.clear();
   theScalarProducts.clear();
-  theCharges.clear();
-  theChargeNonZeros.clear();
   theCorrelators.clear();
   theFlowMap.clear();
   theColourLineMap.clear();
   theOrderingStringIdentifiers.clear();
   theOrderingIdentifiers.clear();
   didRead = false;
   didWrite = false;
   tmp.clear();
 }
 
 // If needed, insert default implementations of virtual function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 bool ColourBasis::colourConnected(const cPDVector& sub,
 				  const vector<PDT::Colour>& basis,
 				  const pair<int,bool>& i, 
 				  const pair<int,bool>& j, 
 				  size_t a) const {
 
   // translate process to basis ids
   map<cPDVector,map<size_t,size_t> >::const_iterator trans
     = indexMap().find(sub);
   assert(trans != indexMap().end());
 
   int idColoured = i.second ? j.first : i.first;
   idColoured = trans->second.find(idColoured)->second;
   int idAntiColoured = i.second ? i.first : j.first;
   idAntiColoured = trans->second.find(idAntiColoured)->second;
 
   return colourConnected(basis,idColoured,idAntiColoured,a);
 
 }
 
 const string& ColourBasis::orderingString(const cPDVector& sub, 
 					  const map<size_t,size_t>& colourToAmplitude,
 					  size_t tensorId) {
 
   map<size_t,string>& tensors = theOrderingStringIdentifiers[sub];
   if ( !tensors.empty() ) {
     assert(tensors.find(tensorId) != tensors.end());
     return tensors[tensorId];
   }
 
   const set<vector<size_t> >& xordering = ordering(sub,colourToAmplitude,tensorId);
 
   ostringstream os;
   os << "[";
   for ( set<vector<size_t> >::const_iterator t = xordering.begin();
 	t != xordering.end(); ++t ) {
     os << "[";
     for ( vector<size_t>::const_iterator s = t->begin();
 	  s != t->end(); ++s ) {
       os << *s << (s != --t->end() ? "," : "");
     }
     os << "]" << (t != --xordering.end() ? "," : "");
   }
   os << "]";
 
   tensors[tensorId] = os.str();
   return tensors[tensorId];
 
 }
 
 const set<vector<size_t> >& ColourBasis::ordering(const cPDVector& sub, 
 						  const map<size_t,size_t>& colourToAmplitude,
 						  size_t tensorId, size_t shift) {
 
   map<size_t,set<vector<size_t> > >& tensors = theOrderingIdentifiers[sub];
   if ( !tensors.empty() ) {
     assert(tensors.find(tensorId) != tensors.end());
     return tensors[tensorId];
   }
 
   const vector<PDT::Colour>& basisId = normalOrderedLegs(sub);
 
   map<size_t,vector<vector<size_t> > > labels = basisList(basisId);
 
   for ( map<size_t,vector<vector<size_t> > >::const_iterator t =
 	  labels.begin(); t != labels.end(); ++t ) {
     set<vector<size_t> > xordering;
     for ( vector<vector<size_t> >::const_iterator s = t->second.begin();
 	  s != t->second.end(); ++s ) {
       vector<size_t> crossed;
       for ( vector<size_t>::const_iterator l = s->begin();
 	    l != s->end(); ++l ) {
 	map<size_t,size_t>::const_iterator trans = 
 	  colourToAmplitude.find(*l);
 	assert(trans != colourToAmplitude.end());
 	crossed.push_back(trans->second + shift);
       }
       xordering.insert(crossed);
     }
     tensors[t->first] = xordering;
   }
 
   assert(tensors.find(tensorId) != tensors.end());
   return tensors[tensorId];
 
 }
 
 vector<PDT::Colour> ColourBasis::normalOrderMap(const cPDVector& sub) {
 
   vector<PDT::Colour> allLegs = projectColour(sub);
   vector<PDT::Colour> legs = normalOrder(allLegs);
 
     // if no coloured legs.
   if(legs.empty())return legs;
   
   if ( allLegs[0] == PDT::Colour3 )
     allLegs[0] = PDT::Colour3bar;
   else if ( allLegs[0] == PDT::Colour3bar )
     allLegs[0] = PDT::Colour3;
   if ( allLegs[1] == PDT::Colour3 )
     allLegs[1] = PDT::Colour3bar;
   else if ( allLegs[1] == PDT::Colour3bar )
     allLegs[1] = PDT::Colour3;
 
   if ( theIndexMap.find(sub) == theIndexMap.end() ) {
     map<size_t,size_t> trans;
     vector<PDT::Colour> checkLegs = legs;
     size_t n = checkLegs.size();
     for ( size_t i = 0; i < allLegs.size(); ++i ) {
       size_t j = 0;
       while ( checkLegs[j] != allLegs[i] ) {
 	++j; if ( j == n ) break;
       }
       if ( j == n ) continue;
       trans[i] = j;
       checkLegs[j] = PDT::ColourUndefined;
     }  
 
     theIndexMap[sub] = trans;
 
   }
 
   return legs;
 
 }
 
 const vector<PDT::Colour>& ColourBasis::normalOrderedLegs(const cPDVector& sub) const {
   static vector<PDT::Colour> empty;
   map<cPDVector,vector<PDT::Colour> >::const_iterator n =
     theNormalOrderedLegs.find(sub);
   if ( n != theNormalOrderedLegs.end() )
     return n->second;
   return empty;
 }
 
+const std::tuple<vector<PDT::Colour>,vector<PDT::Colour>,
+		 size_t,size_t,size_t,map<size_t,size_t> >& 
+ColourBasis::normalOrderEmissionMap(const cPDVector& subFrom,
+				    const cPDVector& subTo,
+				    size_t ij, size_t i, size_t j,
+				    const map<size_t,size_t>& emissionMap) {
+
+  auto key = std::make_tuple(subFrom,subTo,ij,i,j,emissionMap);
+
+  auto em = theEmissionMaps.find(key);
+  if ( em != theEmissionMaps.end() )
+    return em->second;
+
+  auto transFrom = indexMap().find(subFrom);
+  auto transTo = indexMap().find(subTo);
+  const vector<PDT::Colour>& lFrom = normalOrderedLegs(subFrom);
+  const vector<PDT::Colour>& lTo = normalOrderedLegs(subTo);
+
+  assert(transFrom != theIndexMap.end() &&
+	 transTo != theIndexMap.end());
+
+  map<size_t,size_t> res;
+
+  size_t cij, ci, cj;
+  auto tFromIt = transFrom->second.find(ij);
+  assert(tFromIt != transFrom->second.end());
+  cij = tFromIt->second;
+
+  auto tToIt = transTo->second.find(i);
+  assert(tToIt != transTo->second.end());
+  ci = tToIt->second;
+  tToIt = transTo->second.find(j);
+  assert(tToIt != transTo->second.end());
+  cj = tToIt->second;
+
+  for ( auto fromBasisIt = transFrom->second.begin();
+	fromBasisIt != transFrom->second.end(); ++fromBasisIt ) {
+    if ( fromBasisIt->first == ij )
+      continue;
+    auto toProcessIndexIt = emissionMap.find(fromBasisIt->first);
+    assert(toProcessIndexIt != emissionMap.end());
+    auto toBasisIndexIt = transTo->second.find(toProcessIndexIt->second);
+    assert(toBasisIndexIt != transTo->second.end());
+    res[fromBasisIt->second] = toBasisIndexIt->second;
+  }
+
+  return theEmissionMaps[key] = std::make_tuple(lFrom,lTo,cij,ci,cj,res);
+
+}
+
+const pair<compressed_matrix<double>,vector<pair<size_t,size_t> > >&
+ColourBasis::charge(const cPDVector& subFrom,
+		    const cPDVector& subTo,
+		    size_t ij, size_t i, size_t j,
+		    const map<size_t,size_t>& emissionMap) {
+
+  auto bKey = normalOrderEmissionMap(subFrom,subTo,ij,i,j,emissionMap);
+
+  auto it = theCharges.find(bKey);
+
+  if ( it != theCharges.end() )
+    return it->second;
+
+  size_t dimFrom = prepare(subFrom,false);
+  size_t dimTo = prepare(subTo,false);
+
+  compressed_matrix<double> tm(dimTo,dimFrom);
+  vector<pair<size_t,size_t> > nonZero;
+
+  const vector<PDT::Colour>& basisFrom = std::get<0>(bKey);
+  const vector<PDT::Colour>& basisTo = std::get<1>(bKey);
+  size_t cij = std::get<2>(bKey);
+  size_t ci = std::get<3>(bKey);
+  size_t cj = std::get<4>(bKey);
+  const map<size_t,size_t>& dict = std::get<5>(bKey);
+
+  for ( size_t bFrom = 0; bFrom < dimFrom; ++bFrom )
+    for ( size_t aTo = 0; aTo < dimTo; ++aTo ) {
+      tm(aTo,bFrom) =
+	tMatrixElement(cij,aTo,bFrom,basisTo,basisFrom,ci,cj,dict);
+      if ( tm(aTo,bFrom) != 0. )
+	nonZero.push_back(make_pair(aTo,bFrom));
+    }
+
+  return theCharges[bKey] = make_pair(tm,nonZero);
+
+}
+
 size_t ColourBasis::prepare(const cPDVector& sub,
 			    bool noCorrelations) {
 
   vector<PDT::Colour> legs = normalOrderMap(sub);
 
   bool doPrepare = false;
 
   if ( theNormalOrderedLegs.find(sub) == theNormalOrderedLegs.end() )
     theNormalOrderedLegs[sub] = legs;
   
     //if no coloured legs.
   if(legs.empty()){
     auto sp = symmetric_matrix<double,upper>(1,1);
     sp(0,0)=1.;
     theScalarProducts.insert({ legs , sp });
     return 0;
   }
   
   if ( theScalarProducts.find(legs) == theScalarProducts.end() )
     doPrepare = true;
 
   if ( doPrepare )
     doPrepare = !readBasis(legs);
 
   size_t dim = doPrepare ? prepareBasis(legs) : theScalarProducts[legs].size1();
 
-  if ( theCharges.find(legs) != theCharges.end() )
+  if ( theCorrelators.find(legs) != theCorrelators.end() )
     return dim;
 
   if ( !doPrepare && noCorrelations )
     return dim;
 
   symmetric_matrix<double,upper>& sp = 
     theScalarProducts.insert(make_pair(legs,symmetric_matrix<double,upper>(dim,dim))).first->second;
   
   for ( size_t a = 0; a < dim; ++a )
     for ( size_t b = a; b < dim; ++b )
       sp(a,b) = scalarProduct(a,b,legs);
 
   if ( noCorrelations )
     return dim;
 
   vector<PDT::Colour> legsPlus = legs;
   legsPlus.push_back(PDT::Colour8);
   legsPlus = normalOrder(legsPlus);
 
   bool doPreparePlus = theScalarProducts.find(legsPlus) == theScalarProducts.end();
-
   size_t dimPlus = doPreparePlus ? prepareBasis(legsPlus) : theScalarProducts[legsPlus].size1();
 
   symmetric_matrix<double,upper>& spPlus = 
     doPreparePlus ?
     theScalarProducts.insert(make_pair(legsPlus,symmetric_matrix<double,upper>(dimPlus,dimPlus))).first->second :
     theScalarProducts[legsPlus];
 
   if ( doPreparePlus ) {
     for ( size_t a = 0; a < dimPlus; ++a )
       for ( size_t b = a; b < dimPlus; ++b )
 	spPlus(a,b) = scalarProduct(a,b,legsPlus);
   }
 
-  typedef map<size_t,compressed_matrix<double> > cMap;
-  cMap& cm = theCharges.insert(make_pair(legs,cMap())).first->second;
-
-  typedef map<size_t,vector<pair<size_t,size_t> > > ccMap;
-  ccMap& ccm = theChargeNonZeros.insert(make_pair(legs,ccMap())).first->second;
+  map<size_t,compressed_matrix<double> > cm;
+  map<size_t,vector<pair<size_t,size_t> > > ccm;
 
   tmp.resize(dimPlus,dim);
   for ( size_t i = 0; i < legs.size(); ++i ) {
     size_t nonZero = 0;
     vector<pair<size_t,size_t> > nonZeros;
+    map<size_t,size_t> standardMap;
+    for ( size_t j = 0; j < legs.size(); ++j )
+      if ( j != i )
+	standardMap[j] = j;
     for ( size_t a = 0; a < dimPlus; ++a )
       for ( size_t b = 0; b < dim; ++b ) {
-	tmp(a,b) = tMatrixElement(i,a,b,legsPlus,legs);
+	tmp(a,b) = tMatrixElement(i,a,b,legsPlus,legs,i,legs.size(),standardMap);
 	if ( tmp(a,b) != 0. ) {
 	  ++nonZero;
 	  nonZeros.push_back(make_pair(a,b));
 	}
       }
     ccm.insert(make_pair(i,nonZeros));
     compressed_matrix<double>& tm = 
       cm.insert(make_pair(i,compressed_matrix<double>(dimPlus,dim,nonZero))).first->second;
     for ( size_t a = 0; a < dimPlus; ++a )
       for ( size_t b = 0; b < dim; ++b ) {
 	if ( tmp(a,b) != 0. )
 	  tm(a,b) = tmp(a,b);
       }
   }
 
   map<pair<size_t,size_t>,symmetric_matrix<double,upper> >& xm = theCorrelators[legs];
   for ( size_t i = 0; i < legs.size(); ++i )
     for ( size_t j = i+1; j < legs.size(); ++j ) {
       symmetric_matrix<double,upper>& mm =
 	xm.insert(make_pair(make_pair(i,j),symmetric_matrix<double,upper>(dim,dim))).first->second;
       chargeProduct(cm[i],ccm[i],spPlus,cm[j],ccm[j],mm);
     }
 
   return dim;
 
 }
 
 void ColourBasis::chargeProduct(const compressed_matrix<double>& ti,
 				const vector<pair<size_t,size_t> >& tiNonZero,
 				const symmetric_matrix<double,upper>& X,
 				const compressed_matrix<double>& tj,
 				const vector<pair<size_t,size_t> >& tjNonZero,
 				symmetric_matrix<double,upper>& result) const {
   for ( size_t i = 0; i < result.size1(); ++i )
     for ( size_t j = i; j < result.size1(); ++j )
       result(i,j) = 0.;
   for ( vector<pair<size_t,size_t> >::const_iterator i = tiNonZero.begin();
 	i != tiNonZero.end(); ++i )
     for ( vector<pair<size_t,size_t> >::const_iterator j = tjNonZero.begin();
 	  j != tjNonZero.end(); ++j ) {
       if ( j->second < i->second )
 	continue;
       result(i->second,j->second) += 
 	ti(i->first,i->second)*tj(j->first,j->second)*X(i->first,j->first);
     }
 }
 
 void ColourBasis::chargeProductAdd(const compressed_matrix<double>& ti,
 				   const vector<pair<size_t,size_t> >& tiNonZero,
 				   const matrix<Complex>& X,
 				   const compressed_matrix<double>& tj,
 				   const vector<pair<size_t,size_t> >& tjNonZero,
 				   matrix<Complex>& result,
 				   double factor) const {
   for ( vector<pair<size_t,size_t> >::const_iterator i = tiNonZero.begin();
 	i != tiNonZero.end(); ++i )
     for ( vector<pair<size_t,size_t> >::const_iterator j = tjNonZero.begin();
 	  j != tjNonZero.end(); ++j ) {
       result(i->first,j->first) += factor*
 	ti(i->first,i->second)*tj(j->first,j->second)*X(i->second,j->second);
     }
 }
 
 string ColourBasis::cfstring(const list<list<pair<int,bool> > >& flow) {
   ostringstream out("");
   for ( list<list<pair<int,bool> > >::const_iterator line =
 	  flow.begin(); line != flow.end(); ++line ) {
     for ( list<pair<int,bool> >::const_iterator node = 
 	    line->begin(); node != line->end(); ++node ) {
       out << (node->second ? "-" : "") << (node->first+1) << " ";
     }
     if ( line != --(flow.end()) )
       out << ", ";
   }
   return out.str();
 }
 
 vector<string> ColourBasis::makeFlows(Ptr<Tree2toNDiagram>::tcptr diag,
 				      size_t dim) const {
 
   vector<string> res(dim);
 
    //if no coloured legs.
   if(dim==0)return res;
 
   list<list<list<pair<int,bool> > > > fdata =
     colourFlows(diag);
 
   cPDVector ext;
   tcPDVector dext = diag->external();
   copy(dext.begin(),dext.end(),back_inserter(ext));
 
   vector<PDT::Colour> colouredLegs =
     normalOrder(projectColour(ext));
 
   for ( list<list<list<pair<int,bool> > > >::const_iterator flow =
 	  fdata.begin(); flow != fdata.end(); ++flow ) {
     for ( size_t i = 0; i < dim; ++i ) {
       bool matches = true;
       for ( list<list<pair<int,bool> > >::const_iterator line =
 	      flow->begin(); line != flow->end(); ++line ) {
 	pair<int,bool> front(diag->externalId(line->front().first),line->front().second);
 	if ( front.first < 2  )
 	  front.second = !front.second;
 	pair<int,bool> back(diag->externalId(line->back().first),line->back().second);
 	if ( back.first < 2 )
 	  back.second = !back.second;
 	if ( !colourConnected(ext,colouredLegs,front,back,i) ) {
 	  matches = false;
 	  break;
 	}
       }
       if ( matches ) {
 	assert(res[i] == "" && 
 	       "only support colour bases with unique mapping to large-N colour flows");
 	res[i] = cfstring(*flow);
       }
     }
   }
 
   bool gotone = false;
   for ( vector<string>::const_iterator f = res.begin();
 	f != res.end(); ++f ) {
     if ( *f != "" ) {
       gotone = true;
       break;
     }
   }
   if ( !gotone ) {
     generator()->log() << "warning no color flow found for diagram\n";
     DiagramDrawer::drawDiag(generator()->log(),*diag);
   }
 
   return res;
   
 }
 
 size_t ColourBasis::prepare(const MEBase::DiagramVector& diags,
 			    bool noCorrelations) {
 
   size_t dim = 0;
 
   for ( MEBase::DiagramVector::const_iterator d = diags.begin();
 	d != diags.end(); ++d ) {
     Ptr<Tree2toNDiagram>::tcptr dd = dynamic_ptr_cast<Ptr<Tree2toNDiagram>::ptr>(*d);
     assert(dd);
     dim = prepare(dd->partons(),noCorrelations);
     if ( !haveColourFlows() || theFlowMap.find(dd) != theFlowMap.end() )
       continue;
     theFlowMap[dd] = makeFlows(dd,dim);
   }
 
   return dim;
 
 }
 
 bool matchEnd(int a, pair<int,bool> b,
 	      Ptr<Tree2toNDiagram>::tcptr diag) {
 
   if ( a != b.first )
     return false;
 
   if ( b.first != diag->nSpace()-1 ) {
     return
       !b.second ? 
       diag->allPartons()[b.first]->hasColour() :
       diag->allPartons()[b.first]->hasAntiColour();
   } else {
     return
       !b.second ? 
       diag->allPartons()[b.first]->hasAntiColour() :
       diag->allPartons()[b.first]->hasColour();
   }
 
   return false;
 
 }
 
 bool findPath(pair<int,bool> a, pair<int,bool> b,
 	      Ptr<Tree2toNDiagram>::tcptr diag,
 	      list<pair<int,bool> >& path,
 	      bool backward) {
 
   assert(a.first==0 ? !backward : true);
 
   if ( path.empty() )
     path.push_back(a);
 
   if ( !backward ) {
 
     if ( diag->children(a.first).first == -1 )
       return matchEnd(a.first,b,diag);
 
     pair<int,int> children = diag->children(a.first);
 
     bool cc = (children.first == diag->nSpace()-1);
     if ( diag->allPartons()[children.first]->coloured() )
       if ( !cc ? 
 	   (!a.second ?
 	    diag->allPartons()[children.first]->hasColour() :
 	    diag->allPartons()[children.first]->hasAntiColour()) :
 	   (!a.second ?
 	    diag->allPartons()[children.first]->hasAntiColour() :
 	    diag->allPartons()[children.first]->hasColour())  ) {
 	pair<int,bool> next(children.first,a.second);
 	path.push_back(next);
 	if ( !findPath(next,b,diag,path,false) ) {
 	  path.pop_back();
 	} else return true;
       }
 
     cc = (children.second == diag->nSpace()-1);
     if ( diag->allPartons()[children.second]->coloured() )
       if ( !cc ? 
 	   (!a.second ?
 	    diag->allPartons()[children.second]->hasColour() :
 	    diag->allPartons()[children.second]->hasAntiColour()) :
 	   (!a.second ?
 	    diag->allPartons()[children.second]->hasAntiColour() :
 	    diag->allPartons()[children.second]->hasColour())  ) {
 	pair<int,bool> next(children.second,a.second);
 	path.push_back(next);
 	if ( !findPath(next,b,diag,path,false) ) {
 	  path.pop_back();
 	} else return true;
       }
 
     if ( path.size() == 1 )
       path.pop_back();
     return false;
 
   } else {
 
     int parent = diag->parent(a.first);
     pair<int,int> neighbours = diag->children(parent);
     int neighbour = a.first == neighbours.first ? neighbours.second : neighbours.first;
 
     if ( matchEnd(parent,b,diag) ) {
       path.push_back(b);
       return true;
     }
 
     if ( matchEnd(neighbour,b,diag) ) {
       path.push_back(b);
       return true;
     }
 
     if ( diag->allPartons()[neighbour]->coloured() ) 
       if ( a.second ?
 	   diag->allPartons()[neighbour]->hasColour() :
 	   diag->allPartons()[neighbour]->hasAntiColour() ) {
 	pair<int,bool> next(neighbour,!a.second);
 	path.push_back(next);
 	if ( !findPath(next,b,diag,path,false) ) {
 	  path.pop_back();
 	} else return true;
       }
 
     if ( parent == 0 ) {
       if ( path.size() == 1 )
 	path.pop_back();
       return false;
     }
 
     if ( diag->allPartons()[parent]->coloured() ) 
       if ( !a.second ?
 	   diag->allPartons()[parent]->hasColour() :
 	   diag->allPartons()[parent]->hasAntiColour() ) {
 	pair<int,bool> next(parent,a.second);
 	path.push_back(next);
 	if ( !findPath(next,b,diag,path,true) ) {
 	  path.pop_back();
 	} else return true;
       }
 
     if ( path.size() == 1 )
       path.pop_back();
     return false;
 
   }
 
   return false;
 
 }
 
 
 list<pair<int,bool> > ColourBasis::colouredPath(pair<int,bool> a, pair<int,bool> b,
 						Ptr<Tree2toNDiagram>::tcptr diag) {
 
   list<pair<int,bool> > res;
 
   if ( a.first == b.first )
     return res;
 
   bool aIn = (a.first < 2);
   bool bIn = (b.first < 2);
 
   if ( (aIn && bIn) || (!aIn && !bIn) )
     if ( (a.second && b.second) ||
 	 (!a.second && !b.second) )
       return res;
 
   if ( (aIn && !bIn) || (!aIn && bIn) )
     if ( (!a.second && b.second) ||
 	 (a.second && !b.second) )
       return res;
 
   if ( a.first > b.first )
     swap(a,b);
 
   a.first = diag->diagramId(a.first);
   b.first = diag->diagramId(b.first);
 
   if ( a.first == diag->nSpace()-1 )
     a.second = !a.second;
 
   if ( b.first == diag->nSpace()-1 )
     b.second = !b.second;
 
   if ( !findPath(a,b,diag,res,a.first != 0) )
     return res;
 
   if ( b.first == diag->nSpace()-1 ) {
     res.back().second = !res.back().second;
   }
 
   if ( a.first == diag->nSpace()-1 ) {
     res.front().second = !res.front().second;
   }
 
   return res;
 
 }
 
 list<list<list<pair<int,bool> > > >
 ColourBasis::colourFlows(Ptr<Tree2toNDiagram>::tcptr diag) {
 
   vector<pair<int,bool> > connectSource;
   vector<pair<int,bool> > connectSink;
   for ( size_t i = 0; i != diag->partons().size(); ++i ) {
     if ( i < 2 && diag->partons()[i]->hasAntiColour() )
       connectSource.push_back(make_pair(i,true));
     if ( i < 2 && diag->partons()[i]->hasColour() )
       connectSink.push_back(make_pair(i,false));
     if ( i > 1 && diag->partons()[i]->hasColour() )
       connectSource.push_back(make_pair(i,false));
     if ( i > 1 && diag->partons()[i]->hasAntiColour() )
       connectSink.push_back(make_pair(i,true));
   }
 
   assert(connectSource.size() == connectSink.size());
 
   list<list<list<pair<int,bool> > > > ret;
 
   do {
 
     vector<pair<int,bool> >::iterator source =
       connectSource.begin();
     vector<pair<int,bool> >::iterator sink =
       connectSink.begin();
     list<list<pair<int,bool> > > res;
     for ( ; source != connectSource.end(); ++source, ++sink ) {
       if ( source->first == sink->first ) {
 	res.clear();
 	break;
       }
       list<pair<int,bool> > line =
 	colouredPath(*source,*sink,diag);
       if ( line.empty() ) {
 	res.clear();
 	break;
       }
       res.push_back(line);
     }
 
     if ( !res.empty() ) {
 
       // check, if all dressed properly
       vector<pair<int,int> > dressed((*diag).allPartons().size(),make_pair(0,0));
       for ( size_t p = 0; p < diag->allPartons().size(); ++p ) {
 	if ( diag->allPartons()[p]->hasColour() &&
 	     !diag->allPartons()[p]->hasAntiColour() )
 	  dressed[p].first = 1;
 	if ( diag->allPartons()[p]->hasAntiColour() &&
 	     !diag->allPartons()[p]->hasColour() )
 	  dressed[p].second = 1;
 	if ( diag->allPartons()[p]->hasAntiColour() &&
 	     diag->allPartons()[p]->hasColour() ) {
 	  dressed[p].first = 1; dressed[p].second = 1;
 	}
       }
       for ( list<list<pair<int,bool> > >::const_iterator l = res.begin();
 	    l != res.end(); ++l ) {
 	for ( list<pair<int,bool> >::const_iterator n = l->begin();
 	      n != l->end(); ++n ) {
 	  if ( !(n->second) )
 	    dressed[n->first].first -= 1;
 	  else
 	    dressed[n->first].second -= 1;
 	}
       }
       for ( vector<pair<int,int> >::const_iterator d = dressed.begin();
 	    d != dressed.end(); ++d ) {
 	if ( d->first != 0 || d->second != 0 ) {
 	  res.clear();
 	  break;
 	}
       }
 
       if ( !res.empty() )
 	ret.push_back(res);
 
     }
 
   } while ( std::next_permutation(connectSink.begin(),connectSink.end()) );
 
   return ret;
 
 }
 
 void ColourBasis::updateColourLines(Ptr<Tree2toNDiagram>::tcptr dd) {
   map<Ptr<Tree2toNDiagram>::tcptr,vector<string> >::const_iterator cl =
     theFlowMap.find(dd);
   assert(cl != theFlowMap.end());
   vector<ColourLines*> clines(cl->second.size());
   for ( size_t k = 0; k < cl->second.size(); ++k ) {
     if ( cl->second[k] == "" ) {
       clines[k] = 0;
       continue;
     }
     clines[k] = new ColourLines(cl->second[k]);
   }
   theColourLineMap[cl->first] = clines;
 }
 
 map<Ptr<Tree2toNDiagram>::tcptr,vector<ColourLines*> >&
 ColourBasis::colourLineMap() {
   
   if ( !theColourLineMap.empty() )
     return theColourLineMap;
 
   for ( map<Ptr<Tree2toNDiagram>::tcptr,vector<string> >::const_iterator cl =
 	  theFlowMap.begin(); cl != theFlowMap.end(); ++cl ) {
     vector<ColourLines*> clines(cl->second.size());
     for ( size_t k = 0; k < cl->second.size(); ++k ) {
       if ( cl->second[k] == "" ) {
 	clines[k] = 0;
 	continue;
       }
       clines[k] = new ColourLines(cl->second[k]);
     }
     theColourLineMap[cl->first] = clines;
   }
 
   return theColourLineMap;
 
 }
 
 Selector<const ColourLines *> ColourBasis::colourGeometries(tcDiagPtr diag,
 							    const map<vector<int>,CVector>& amps) {
   Ptr<Tree2toNDiagram>::tcptr dd = 
     dynamic_ptr_cast<Ptr<Tree2toNDiagram>::tcptr>(diag);
   assert(dd && theFlowMap.find(dd) != theFlowMap.end());
   map<Ptr<Tree2toNDiagram>::tcptr,vector<ColourLines*> >::const_iterator colit =
     colourLineMap().find(dd);
   if ( colit == colourLineMap().end() ) {
     updateColourLines(dd);
     colit = colourLineMap().find(dd);
   }
   const vector<ColourLines*>& cl = colit->second;
 
   Selector<const ColourLines *> sel;
   size_t dim = amps.begin()->second.size();
   
     // special treatment if no coloured legs.
     // as in e.g. MEee2gZ2ll.cc
   if (cl.empty()){
     static ColourLines ctST(" ");
     sel.insert(1.,&ctST);
     return sel;
   }
   
   assert(dim == cl.size());
   double w = 0.;
   for ( size_t i = 0; i < dim; ++i ) {
     if ( !cl[i] )
       continue;
     w = 0.;
     for ( map<vector<int>,CVector>::const_iterator a = amps.begin();
 	  a != amps.end(); ++a )
       w += real(conj((a->second)(i))*((a->second)(i)));
     if ( w > 0. )
       sel.insert(w,cl[i]);
   }
   assert(!sel.empty());
   return sel;
 }
 
 size_t ColourBasis::tensorIdFromFlow(tcDiagPtr diag, const ColourLines * flow) {
 
  Ptr<Tree2toNDiagram>::tcptr dd = 
     dynamic_ptr_cast<Ptr<Tree2toNDiagram>::tcptr>(diag);
   assert(dd && theFlowMap.find(dd) != theFlowMap.end());
   map<Ptr<Tree2toNDiagram>::tcptr,vector<ColourLines*> >::const_iterator colit =
     colourLineMap().find(dd);
   if ( colit == colourLineMap().end() ) {
     updateColourLines(dd);
     colit = colourLineMap().find(dd);
   }
 
   const vector<ColourLines*>& cl = colit->second;
 
   size_t res = 0;
   for ( ; res < cl.size(); ++res ) {
     if ( flow == cl[res] )
       break;
   }
 
   assert(res < cl.size());
 
   return res;
 
 }
 
 const symmetric_matrix<double,upper>& ColourBasis::scalarProducts(const cPDVector& sub) const {
 
   map<cPDVector,vector<PDT::Colour> >::const_iterator lit =
     theNormalOrderedLegs.find(sub);
   assert(lit != theNormalOrderedLegs.end());
 
   ScalarProductMap::const_iterator spit =
     theScalarProducts.find(lit->second);
   assert(spit != theScalarProducts.end());
 
   return spit->second;
 
 }
 
-const compressed_matrix<double>& ColourBasis::charge(const cPDVector& sub, size_t iIn) const {
-
-  map<cPDVector,vector<PDT::Colour> >::const_iterator lit =
-    theNormalOrderedLegs.find(sub);
-  assert(lit != theNormalOrderedLegs.end());
-
-  ChargeMap::const_iterator ct =
-    theCharges.find(lit->second);
-  assert(ct != theCharges.end());
-
-  map<cPDVector,map<size_t,size_t> >::const_iterator trans
-    = theIndexMap.find(sub);
-  assert(trans != theIndexMap.end());
-  size_t i = trans->second.find(iIn)->second;
-
-  map<size_t,compressed_matrix<double> >::const_iterator cit
-    = ct->second.find(i);
-  assert(cit != ct->second.end());
-
-  return cit->second;
-
-}
-
-const vector<pair<size_t,size_t> >& ColourBasis::chargeNonZero(const cPDVector& sub, size_t iIn) const {
-
-  map<cPDVector,vector<PDT::Colour> >::const_iterator lit =
-    theNormalOrderedLegs.find(sub);
-  assert(lit != theNormalOrderedLegs.end());
-
-  ChargeNonZeroMap::const_iterator ct =
-    theChargeNonZeros.find(lit->second);
-  assert(ct != theChargeNonZeros.end());
-
-  map<cPDVector,map<size_t,size_t> >::const_iterator trans
-    = theIndexMap.find(sub);
-  assert(trans != theIndexMap.end());
-  size_t i = trans->second.find(iIn)->second;
-
-  map<size_t,vector<pair<size_t,size_t> > >::const_iterator cit
-    = ct->second.find(i);
-  assert(cit != ct->second.end());
-
-  return cit->second;
-
-}
-
 const symmetric_matrix<double,upper>& ColourBasis::correlator(const cPDVector& sub,
 							      const pair<size_t,size_t>& ijIn) const {
 
   map<cPDVector,vector<PDT::Colour> >::const_iterator lit =
     theNormalOrderedLegs.find(sub);
   assert(lit != theNormalOrderedLegs.end());
 
   CorrelatorMap::const_iterator cit =
     theCorrelators.find(lit->second);
   assert(cit != theCorrelators.end());
 
   map<cPDVector,map<size_t,size_t> >::const_iterator trans
     = theIndexMap.find(sub);
   assert(trans != theIndexMap.end());
   pair<size_t,size_t> ij(trans->second.find(ijIn.first)->second,
 			 trans->second.find(ijIn.second)->second);
   if ( ij.first > ij.second )
     swap(ij.first,ij.second);
 
   map<pair<size_t,size_t>,symmetric_matrix<double,upper> >::const_iterator cijit
     = cit->second.find(ij);
   assert(cijit != cit->second.end());
 
   return cijit->second;
 
 }
 
 double ColourBasis::me2(const cPDVector& sub, 
 			const map<vector<int>,CVector>& amps) const {
 
   const symmetric_matrix<double,upper>& sp = scalarProducts(sub);
 
   double res = 0.;
 
   for ( map<vector<int>,CVector>::const_iterator a = amps.begin();
 	a != amps.end(); ++a ) {
     res += real(inner_prod(boost::numeric::ublas::conj(a->second),prod(sp,a->second)));
   }
 
   return res;
 
 }
 
 double ColourBasis::interference(const cPDVector& sub, 
 				 const map<vector<int>,CVector>& amps1,
 				 const map<vector<int>,CVector>& amps2) const {
 
   const symmetric_matrix<double,upper>& sp = scalarProducts(sub);
 
   double res = 0.;
 
   map<vector<int>,CVector>::const_iterator a = amps1.begin();
   map<vector<int>,CVector>::const_iterator b = amps2.begin();
   for ( ; a != amps1.end(); ++a, ++b ) {
     assert(a->first == b->first);
     res += 2.*real(inner_prod(boost::numeric::ublas::conj(a->second),prod(sp,b->second)));
   }
 
   assert(!std::isnan(res));
 
   return res;
 
 }
 
 double ColourBasis::colourCorrelatedME2(const pair<size_t,size_t>& ij,
 					const cPDVector& sub, 
 					const map<vector<int>,CVector>& amps) const {
 
   const symmetric_matrix<double,upper>& cij = correlator(sub,ij);
 
   double res = 0.;
 
   for ( map<vector<int>,CVector>::const_iterator a = amps.begin();
 	a != amps.end(); ++a ) {
     res += real(inner_prod(boost::numeric::ublas::conj(a->second),prod(cij,a->second)));
   }
 
   return res;
 
 }
 
 Complex ColourBasis::interference(const cPDVector& sub, 
 				  const CVector& left,
 				  const CVector& right) const {
 
   const symmetric_matrix<double,upper>& sp = scalarProducts(sub);
   return inner_prod(boost::numeric::ublas::conj(left),prod(sp,right));
 
 }
 
 Complex ColourBasis::colourCorrelatedInterference(const pair<size_t,size_t>& ij,
 						  const cPDVector& sub, 
 						  const CVector& left,
 						  const CVector& right) const {
 
   const symmetric_matrix<double,upper>& cij = correlator(sub,ij);
   return inner_prod(boost::numeric::ublas::conj(left),prod(cij,right));
 
 }
 
 double ColourBasis::me2(const cPDVector& sub, 
 			const matrix<Complex>& amp) const {
 
   const symmetric_matrix<double,upper>& sp = scalarProducts(sub);
 
   double tr = 0;
 
   size_t n = amp.size1();
 
   for ( size_t i = 0; i < n; ++i ) {
     tr += real(inner_prod(row(sp,i),column(amp,i)));
   }
 
   return tr;
 
 }
 
 double ColourBasis::colourCorrelatedME2(const pair<size_t,size_t>& ij,
 					const cPDVector& sub, 
 					const matrix<Complex>& amp) const {
 
   const symmetric_matrix<double,upper>& cij = correlator(sub,ij);
 
   double tr = 0;
 
   size_t n = amp.size1();
 
   for ( size_t i = 0; i < n; ++i ) {
     tr += real(inner_prod(row(cij,i),column(amp,i)));
   }
 
   return tr;
 
 }
 
 struct pickColour {
   PDT::Colour operator()(tcPDPtr p) const {
     return p->iColour();
   }
 };
 
 vector<PDT::Colour> ColourBasis::projectColour(const cPDVector& sub) const {
   vector<PDT::Colour> res(sub.size());
   transform(sub.begin(),sub.end(),res.begin(),pickColour());
   return res;
 }
 
 vector<PDT::Colour> ColourBasis::normalOrder(const vector<PDT::Colour>& legs) const {
     //if no coloured legs.
   if (legs.empty())return legs;
   vector<PDT::Colour> crosslegs = legs;
   if ( crosslegs[0] == PDT::Colour3 )
     crosslegs[0] = PDT::Colour3bar;
   else if ( crosslegs[0] == PDT::Colour3bar )
     crosslegs[0] = PDT::Colour3;
   if ( crosslegs[1] == PDT::Colour3 )
     crosslegs[1] = PDT::Colour3bar;
   else if ( crosslegs[1] == PDT::Colour3bar )
     crosslegs[1] = PDT::Colour3;
   int n3 = count_if(crosslegs.begin(),crosslegs.end(),matchRep(PDT::Colour3));
   int n8 = count_if(crosslegs.begin(),crosslegs.end(),matchRep(PDT::Colour8));
   vector<PDT::Colour> ordered(2*n3+n8,PDT::Colour8);
   int i = 0;
   while ( i < 2*n3 ) {
     ordered[i] = PDT::Colour3;
     ordered[i+1] = PDT::Colour3bar;
     i+=2;
   }
   return ordered;
 }
 
 string ColourBasis::file(const vector<PDT::Colour>& sub) const {
 
   string res = name() + "-";
 
   for ( vector<PDT::Colour>::const_iterator lit = sub.begin();
 	lit != sub.end(); ++lit ) {
     if ( *lit == PDT::Colour3 )
       res += "3";
     if ( *lit == PDT::Colour3bar )
       res += "3bar";
     if ( *lit == PDT::Colour8 )
       res += "8";
   }
 
   if ( largeN() )
     res += "largeN";
 
   return res;
 
 }
 
 void ColourBasis::writeBasis(const string& prefix) const {
 
   if ( didWrite )
     return;
 
   set<vector<PDT::Colour> > legs;
   for ( map<cPDVector,vector<PDT::Colour> >::const_iterator lit
 	  = theNormalOrderedLegs.begin(); lit != theNormalOrderedLegs.end(); ++lit ) {
     legs.insert(lit->second);
   }
 
   string searchPath = theSearchPath;
 
   if ( searchPath != "" )
     if ( *(--searchPath.end()) != '/' )
       searchPath += "/";
 
   for ( set<vector<PDT::Colour> >::const_iterator known = legs.begin();
 	known != legs.end(); ++known ) {
     string fname = searchPath + prefix + file(*known) + ".cdat";
     if ( !( SamplerBase::runLevel() == SamplerBase::ReadMode ||
             SamplerBase::runLevel() == SamplerBase::BuildMode ) ) {
       ifstream check(fname.c_str());
       if ( check ) continue;
     }
     ofstream out(fname.c_str());
     if ( !out )
       throw Exception() << "ColourBasis: Failed to open "
 			<< fname << " for storing colour basis information."
 			<< Exception::runerror;
     out << setprecision(18);
     const symmetric_matrix<double,upper>& sp = 
       theScalarProducts.find(*known)->second;
     write(sp,out);
-    if ( theCharges.find(*known) != theCharges.end() ) {
-      out << "#charges\n";
-      const map<size_t,compressed_matrix<double> >& tm =
-	theCharges.find(*known)->second;
-      const map<size_t,vector<pair<size_t,size_t> > >& tc =
-	theChargeNonZeros.find(*known)->second;
-      map<size_t,vector<pair<size_t,size_t> > >::const_iterator kc =
-	tc.begin();
-      for ( map<size_t,compressed_matrix<double> >::const_iterator k = tm.begin();
-	    k != tm.end(); ++k, ++kc ) {
-	out << k->first << "\n";
-	write(k->second,out,kc->second);
-      }
+    if ( theCorrelators.find(*known) != theCorrelators.end() ) {
+      out << "#correlators\n";
       const map<pair<size_t,size_t>,symmetric_matrix<double,upper> >& cm =
 	theCorrelators.find(*known)->second;
       for ( map<pair<size_t,size_t>,symmetric_matrix<double,upper> >::const_iterator k =
 	      cm.begin(); k != cm.end(); ++k ) {
 	out << k->first.first << "\n" << k->first.second << "\n";
 	write(k->second,out);
       }
     } else {
-      out << "#nocharges\n";
+      out << "#nocorrelators\n";
     }
     out << flush;
   }
 
   didWrite = true;
 
 }
 
 bool ColourBasis::readBasis(const vector<PDT::Colour>& legs) {
 
   string searchPath = theSearchPath;
 
   if ( searchPath != "" )
     if ( *(--searchPath.end()) != '/' )
       searchPath += "/";
 
   string fname = searchPath + file(legs) + ".cdat";
   ifstream in(fname.c_str());
   if ( !in )
     return false;
   read(theScalarProducts[legs],in);
   string tag; in >> tag;
-  if ( tag != "#nocharges" ) {
-    for ( size_t k = 0; k < legs.size(); ++k ) {
-      size_t i; in >> i;
-      read(theCharges[legs][i],in,theChargeNonZeros[legs][i]);
-    }
+  if ( tag == "#correlators" ) {
     for ( size_t k = 0; k < legs.size()*(legs.size()-1)/2; ++k ) {
       size_t i,j; in >> i >> j;
       read(theCorrelators[legs][make_pair(i,j)],in);
     }
   }
 
   readBasisDetails(legs);
 
   return true;
 
 }
 
 void ColourBasis::readBasis() {
 
   if ( didRead )
     return;
 
   string searchPath = theSearchPath;
 
   if ( searchPath != "" )
     if ( *(--searchPath.end()) != '/' )
       searchPath += "/";
 
   set<vector<PDT::Colour> > legs;
   for ( map<cPDVector,vector<PDT::Colour> >::const_iterator lit
 	  = theNormalOrderedLegs.begin(); lit != theNormalOrderedLegs.end(); ++lit )
     legs.insert(lit->second);
 
   for ( set<vector<PDT::Colour> >::const_iterator known = legs.begin();
 	known != legs.end(); ++known ) {
     if ( theScalarProducts.find(*known) != theScalarProducts.end() )
       continue;
     //if no coloured legs.
     if(known->empty()){
       auto sp = symmetric_matrix<double,upper>(1,1);
       sp(0,0)=1.;
       theScalarProducts.insert({ *known , sp });
       continue;
     }
      
     string fname = searchPath + file(*known) + ".cdat";
     if ( !readBasis(*known) )
       throw Exception() << "ColourBasis: Failed to open "
 			<< fname << " for reading colour basis information."
 			<< Exception::runerror;
   }
 
   didRead = true;
 
 }
 
 void ColourBasis::write(const symmetric_matrix<double,upper>& m, ostream& os) const {
   os << m.size1() << "\n";
   for ( size_t i = 0; i < m.size1(); ++i )
     for ( size_t j = i; j < m.size1(); ++j )
       os << m(i,j) << "\n";
   os << flush;
 }
 
 void ColourBasis::read(symmetric_matrix<double,upper>& m, istream& is) {
   size_t s; is >> s;
   m.resize(s);
   for ( size_t i = 0; i < m.size1(); ++i )
     for ( size_t j = i; j < m.size1(); ++j )
       is >> m(i,j);
 }
 
 void ColourBasis::write(const compressed_matrix<double>& m, ostream& os,
 			const vector<pair<size_t,size_t> >& nonZeros) const {
   os << nonZeros.size() << "\n"
      << m.size1() << "\n"
      << m.size2() << "\n";
   for ( vector<pair<size_t,size_t> >::const_iterator nz = nonZeros.begin();
 	nz != nonZeros.end(); ++nz )
     os << nz->first << "\n" << nz->second << "\n"
        << m(nz->first,nz->second) << "\n";
   os << flush;
 }
 
 void ColourBasis::read(compressed_matrix<double>& m, istream& is,
 		       vector<pair<size_t,size_t> >& nonZeros) {
   size_t nonZero, size1, size2; 
   is >> nonZero >> size1 >> size2;
   nonZeros.resize(nonZero);
   m = compressed_matrix<double>(size1,size2,nonZero);
   for ( size_t k = 0; k < nonZero; ++k ) {
     size_t i,j; double val;
     is >> i >> j >> val;
     nonZeros[k] = make_pair(i,j);
     m(i,j) = val;
   }
 }
 
 void ColourBasis::doinit() {
   HandlerBase::doinit();
   if ( theSearchPath.empty() && factory() )
     theSearchPath = factory()->runStorage();
   readBasis();
 }
 
 void ColourBasis::dofinish() {
   HandlerBase::dofinish();
   writeBasis();
 }
 
 void ColourBasis::doinitrun() {
   HandlerBase::doinitrun();
   if ( theSearchPath.empty() && factory() )
     theSearchPath = factory()->runStorage();
   readBasis();
 }
 
 void ColourBasis::persistentOutput(PersistentOStream & os) const {
   os << theLargeN << theNormalOrderedLegs
      << theIndexMap << theFlowMap << theOrderingStringIdentifiers 
      << theOrderingIdentifiers << theSearchPath;
   writeBasis();
 }
 
 void ColourBasis::persistentInput(PersistentIStream & is, int) {
   is >> theLargeN >> theNormalOrderedLegs
      >> theIndexMap >> theFlowMap >> theOrderingStringIdentifiers
      >> theOrderingIdentifiers >> theSearchPath;
 }
 
 
 // *** Attention *** The following static variable is needed for the type
 // description system in ThePEG. Please check that the template arguments
 // are correct (the class and its base class), and that the constructor
 // arguments are correct (the class name and the name of the dynamically
 // loadable library where the class implementation can be found).
 DescribeAbstractClass<ColourBasis,HandlerBase>
 describeColourBasis("Herwig::ColourBasis", "Herwig.so");
 
 void ColourBasis::Init() {
 
   static ClassDocumentation<ColourBasis> documentation
     ("ColourBasis is an interface to a colour basis "
      "implementation.");
 
   static Switch<ColourBasis,bool> interfaceLargeN
     ("LargeN",
      "Switch on or off large-N evaluation.",
      &ColourBasis::theLargeN, false, false, false);
   static SwitchOption interfaceLargeNYes
     (interfaceLargeN,
      "Yes",
      "Work in N=infinity",
      true);
   static SwitchOption interfaceLargeNNo
     (interfaceLargeN,
      "No",
      "Work in N=3",
      false);
 
 }
 
diff --git a/MatrixElement/Matchbox/Utility/ColourBasis.h b/MatrixElement/Matchbox/Utility/ColourBasis.h
--- a/MatrixElement/Matchbox/Utility/ColourBasis.h
+++ b/MatrixElement/Matchbox/Utility/ColourBasis.h
@@ -1,566 +1,602 @@
 // -*- C++ -*-
 //
 // ColourBasis.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_ColourBasis_H
 #define HERWIG_ColourBasis_H
 //
 // This is the declaration of the ColourBasis class.
 //
 
 #include "ThePEG/Handlers/HandlerBase.h"
 
 #include "ThePEG/MatrixElement/Tree2toNDiagram.h"
 #include "ThePEG/MatrixElement/MEBase.h"
 
 #include "Herwig/MatrixElement/Matchbox/Utility/MatchboxXComb.h"
 #include "Herwig/MatrixElement/Matchbox/MatchboxFactory.fh"
 
 #include <iterator>
+#include <tuple>
 
 namespace Herwig {
 
 using std::iterator_traits;
 using std::distance;
 
 using namespace ThePEG;
 
 using boost::numeric::ublas::matrix;
 using boost::numeric::ublas::symmetric_matrix;
 using boost::numeric::ublas::compressed_matrix;
 using boost::numeric::ublas::upper;
 
 /**
  * \ingroup Matchbox
  * \author Simon Platzer
  *
  * \brief ColourBasis is an interface to a colour basis
  * implementation.
  *
  */
 class ColourBasis: public HandlerBase {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   ColourBasis();
 
   /**
    * The destructor.
    */
   virtual ~ColourBasis();
   //@}
 
 public:
 
   /**
    * Return the factory which produced this matrix element
    */
   Ptr<MatchboxFactory>::tptr factory() const;
 
   /**
    * Clone this colour basis.
    */
   Ptr<ColourBasis>::ptr cloneMe() const {
     return dynamic_ptr_cast<Ptr<ColourBasis>::ptr>(clone());
   }
 
   /**
    * Clear this colour basis
    */
   virtual void clear();
 
   /**
    * Prepare for the given sub process and return the basis
    * dimensionality.
    */
   size_t prepare(const cPDVector&, bool);
 
   /**
    * Prepare for the given diagrams.
    */
   size_t prepare(const MEBase::DiagramVector&, bool);
 
   /**
    * Return the index map.
    */
   const map<cPDVector,map<size_t,size_t> >& indexMap() const { return theIndexMap; }
 
   /**
    * Return a map of basis tensor indices to vectors identifying a
    * certain ordering corresponding to the given colour structure. May
    * not be supported by all colour basis implementations.
    */
   virtual map<size_t,vector<vector<size_t> > > basisList(const vector<PDT::Colour>&) const {
     return map<size_t,vector<vector<size_t> > >();
   }
 
   /**
    * Given a physical subprocess, a colour to amplitude label map and
    * a basis tensor index, return an identifier of the ordering
    * coresponding to the given colour structure. This will only return
    * sensible results for colour bases which implement the basisList
    * query.
    */
   const string& orderingString(const cPDVector& sub, 
 			       const map<size_t,size_t>& colourToAmplitude,
 			       size_t tensorId);
 
   /**
    * Given a physical subprocess, a colour to amplitude label map and
    * a basis tensor index, return an identifier of the ordering
    * coresponding to the given colour structure. This will only return
    * sensible results for colour bases which implement the basisList
    * query.
    */
   const set<vector<size_t> >& ordering(const cPDVector& sub, 
 				       const map<size_t,size_t>& colourToAmplitude,
 				       size_t tensorId, size_t shift = 0);
 
   /**
    * For the given subprocess and amplitude vectors
    * calculate the amplitude squared.
    */
   double me2(const cPDVector&, const map<vector<int>,CVector>&) const;
  
   /**
    * For the given subprocess and amplitude vectors
    * calculate the interference.
    */
   double interference(const cPDVector&, 
 		      const map<vector<int>,CVector>&,
 		      const map<vector<int>,CVector>&) const;
 
   /**
    * For the given subprocess and amplitude vector
    * calculate the colour correlated amplitude.
    */
   double colourCorrelatedME2(const pair<size_t,size_t>&,
 			     const cPDVector&, 
 			     const map<vector<int>,CVector>&) const;
 
   /**
    * For the given subprocess and amplitude vector
    * calculate the amplitude squared.
    */
   Complex interference(const cPDVector&, 
 		       const CVector&, const CVector&) const;
 
   /**
    * For the given subprocess and amplitude vector
    * calculate the colour correlated amplitude.
    */
   Complex colourCorrelatedInterference(const pair<size_t,size_t>&,
 				       const cPDVector&, 
 				       const CVector&, const CVector&) const;
 
   /**
    * For the given subprocess and amplitude given as amp amp^\dagger
    * calculate the amplitude squared.
    */
   double me2(const cPDVector&, const matrix<Complex>&) const;
 
   /**
    * For the given subprocess and amplitude given as amp amp^\dagger
    * calculate the colour correlated amplitude.
    */
   double colourCorrelatedME2(const pair<size_t,size_t>&,
 			     const cPDVector&, 
 			     const matrix<Complex>&) const;
 
   /**
    * Return the scalar product matrix for the given process.
    */
   const symmetric_matrix<double,upper>& scalarProducts(const cPDVector&) const;
 
   /**
-   * Return the matrix representation of a colour charge.
-   */
-  const compressed_matrix<double>& charge(const cPDVector&, size_t) const;
-
-  /**
-   * Return the non-vanishing elements of a colour charge.
-   */
-  const vector<pair<size_t,size_t> >& chargeNonZero(const cPDVector&, size_t) const;
-
-  /**
    * Return the correlator matrix for the given process.
    */
   const symmetric_matrix<double,upper>& correlator(const cPDVector&,
 						   const pair<size_t,size_t>&) const;
 
   /**
    * Return true, if the colour basis is capable of assigning colour
    * flows.
    */
   virtual bool haveColourFlows() const { return false; }
 
   /**
    * Return a Selector with possible colour geometries for the selected
    * diagram weighted by their relative probabilities.
    */
   Selector<const ColourLines *> colourGeometries(tcDiagPtr diag,
 						 const map<vector<int>,CVector>& amps);
 
   /**
    * Return the colour tensor used for the selected colour flow
    */
   size_t tensorIdFromFlow(tcDiagPtr diag, const ColourLines * cl);
 
   /**
    * Match colour representation.
    */
   struct matchRep {
     PDT::Colour m;
     matchRep(PDT::Colour n)
       : m(n) {}
     bool operator()(PDT::Colour c) const {
       return c == m;
     }
   };
 
   /**
    * Return true, if this basis is running in large-N mode
    */
   virtual bool largeN() const { return theLargeN; }
 
   /**
    * Switch to large n
    */
   void doLargeN(bool yes = true) { theLargeN = yes; }
 
   /**
    * Convert particle data to colour information
    */
   vector<PDT::Colour> projectColour(const cPDVector&) const;
 
   /**
    * Perform a normal ordering of the external legs. This default
    * implementation assumes normal ordered legs as 3 3bar ... 3 3bar 8 ... 8
    * while removing all non-coloured particles.
    */
   virtual vector<PDT::Colour> normalOrder(const vector<PDT::Colour>&) const;
 
   /**
    * Determine the mapping of process to colour indices and return the
    * normal ordered vector of colour indices
    */
   vector<PDT::Colour> normalOrderMap(const cPDVector& sub);
 
   /**
    * Get the normal ordered legs
    */
   const vector<PDT::Colour>& normalOrderedLegs(const cPDVector& sub) const;
 
   /**
+   * Generate the emission/splitting map for basis labels from sub-process
+   * information; we consider the splitting of leg ij from subprocess subFrom
+   * with the legs not participating in the splitting relabelled according to
+   * emissionMap.
+   */
+  const std::tuple<vector<PDT::Colour>,vector<PDT::Colour>,
+		   size_t,size_t,size_t,map<size_t,size_t> >& 
+  normalOrderEmissionMap(const cPDVector& subFrom,
+			 const cPDVector& subTo,
+			 size_t ij, size_t i, size_t j,
+			 const map<size_t,size_t>& emissionMap);
+
+  /**
+   * Return the colour charge matrix representation for the given splitting ij
+   * -> i,j with other legs relabbeled as indicated by the dictionary map.
+   */
+  const pair<compressed_matrix<double>,vector<pair<size_t,size_t> > >&
+  charge(const cPDVector& subFrom,
+	 const cPDVector& subTo,
+	 size_t ij, size_t i, size_t j,
+	 const map<size_t,size_t>& emissionMap);
+
+  /**
    * Convert the legs to a string.
    */
   string file(const vector<PDT::Colour>&) const;
 
   /**
    * Calculate T_i^\dagger X T_j
    */
   void chargeProduct(const compressed_matrix<double>& ti,
 		     const vector<pair<size_t,size_t> >& tiNonZero,
 		     const symmetric_matrix<double,upper>& X,
 		     const compressed_matrix<double>& tj,
 		     const vector<pair<size_t,size_t> >& tjNonZero,
 		     symmetric_matrix<double,upper>& result) const;
 
   /**
    * Calculate T_i X T_j^\dagger
    */
   void chargeProductAdd(const compressed_matrix<double>& ti,
 			const vector<pair<size_t,size_t> >& tiNonZero,
 			const matrix<Complex>& X,
 			const compressed_matrix<double>& tj,
 			const vector<pair<size_t,size_t> >& tjNonZero,
 			matrix<Complex>& result,
 			double factor = 1.) const;
 
 public:
 
   /**
    * Find a coloured path from a to b within the given diagram.
    */
   static list<pair<int,bool> > colouredPath(pair<int,bool> a, pair<int,bool> b,
 					    Ptr<Tree2toNDiagram>::tcptr);
 
   /**
    * Get all colour flows for the given diagram.
    */
   static list<list<list<pair<int,bool> > > > colourFlows(Ptr<Tree2toNDiagram>::tcptr);
 
   /**
    * Convert a flow to a string representation appropriate for
    * ColourLines
    */
   static string cfstring(const list<list<pair<int,bool> > >&);
 
+  /**
+   * Returns a map of how the order of the vectors of a colour basis are 
+   * changed when the indices are changed.
+   */
+  virtual map<size_t,size_t> indexChange(const vector<PDT::Colour>&,
+					 const size_t,
+					 const map<size_t,size_t>&) const {
+    map<size_t,size_t> aMap;
+    return aMap;
+  }
+
+
 protected:
 
   /**
    * Prepare the basis for the normal ordered legs and return the
    * dimensionality of the basis.
    */
   virtual size_t prepareBasis(const vector<PDT::Colour>&) = 0;
 
   /**
    * Return the scalar product of basis tensors labelled a and b in
    * the basis used for the given normal ordered legs.
    */
   virtual double scalarProduct(size_t a, size_t b,
 			       const vector<PDT::Colour>& abBasis) const = 0;
 
   /**
-   * Return the matrix element of a colour charge
-   * <c_{n+1,a}|T_i|c_{n,b}> between basis tensors a and b, with
-   * respect to aBasis and bBasis
+   * Return the matrix element of a colour charge or quark splitting
+   * <c_{n+1,a}|T_i|c_{n,b}> between basis tensors a and b, with respect to
+   * aBasis and bBasis; k and l index the splitting product's labels, and dict
+   * encodes how legs not participating in the splitting are relabeled to the
+   * larger basis.
    */
   virtual double tMatrixElement(size_t i, size_t a, size_t b,
 				const vector<PDT::Colour>& aBasis,
-				const vector<PDT::Colour>& bBasis) const = 0;
+				const vector<PDT::Colour>& bBasis,
+				size_t k, size_t l,
+				const map<size_t,size_t>& dict) const = 0;
 
   /**
    * Return true, if a large-N colour connection exists for the
    * given external legs and basis tensor.
    */
   virtual bool colourConnected(const cPDVector&,
 			       const vector<PDT::Colour>&,
 			       const pair<int,bool>&, 
 			       const pair<int,bool>&, 
 			       size_t) const;
 
   /**
    * Return true, if a large-N colour connection exists for the
    * given external legs and basis tensor.
    */
   virtual bool colourConnected(const vector<PDT::Colour>&,
 			       int, int, size_t) const {
     return false;
   }
 
   /**
    * Match up colour flows for given diagram to basis tensors.
    */
   vector<string> makeFlows(Ptr<Tree2toNDiagram>::tcptr, size_t) const;
 
   /**
    * Return the colour line map.
    */
   map<Ptr<Tree2toNDiagram>::tcptr,vector<ColourLines*> >&
   colourLineMap();
 
   /**
    * Update the colour line map for a given diagram.
    */
   void updateColourLines(Ptr<Tree2toNDiagram>::tcptr);
 
+  
 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();
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 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();
 
   /**
    * Finalize this object. Called in the run phase just after a
    * run has ended. Used eg. to write out statistics.
    */
   virtual void dofinish();
   //@}
 
 private:
 
   typedef map<vector<PDT::Colour>,symmetric_matrix<double,upper> >
   ScalarProductMap;
 
-  typedef map<vector<PDT::Colour>,map<size_t,compressed_matrix<double> > > ChargeMap;
-  typedef map<vector<PDT::Colour>,map<size_t,vector<pair<size_t,size_t > > > > ChargeNonZeroMap;
+  typedef map<vector<PDT::Colour>,map<pair<size_t,size_t>,symmetric_matrix<double,upper> > >
+  CorrelatorMap;
 
-  typedef map<vector<PDT::Colour>,map<pair<size_t,size_t>,symmetric_matrix<double,upper> > > CorrelatorMap;
+  typedef map<std::tuple<vector<PDT::Colour>,vector<PDT::Colour>,
+			 size_t,size_t,size_t,map<size_t,size_t> >,
+	      pair<compressed_matrix<double>,vector<pair<size_t,size_t> > > > TSMap;
 
   /**
    * True, if this basis is running in large-N mode
    */
   bool theLargeN;
 
   /**
    * Map external legs to normal ordered versions
    */
   map<cPDVector,vector<PDT::Colour> > theNormalOrderedLegs;
 
   /**
    * Index mappings to normal order from given leg assignments,
    * indexed by the original leg assignment.
    */
   map<cPDVector,map<size_t,size_t> > theIndexMap;
 
   /**
+   * Translations of emission maps
+   */
+  map<std::tuple<cPDVector,cPDVector,
+		 size_t,size_t,size_t,map<size_t,size_t> >,
+      std::tuple<vector<PDT::Colour>,vector<PDT::Colour>,
+		 size_t,size_t,size_t,map<size_t,size_t> > >
+  theEmissionMaps;
+
+  /**
    * The scalar product matrix S_n = <c_{n,a}|c_{n,b}> , indexed
    * by normal ordered leg assignments.
    */
   ScalarProductMap theScalarProducts;
 
   /**
-   * The colour charge matrices <c_{n+1,a}|T_i|c_{n,b}> indexed by
-   * the `n' normal ordered legs and the index i.
-   */
-  ChargeMap theCharges;
-
-  /**
-   * The nonzero elements of the charge matrices.
-   */
-  ChargeNonZeroMap theChargeNonZeros;
-
-  /**
    * The correlator matrices T_i\cdot T_j -> T_i^\dagger S_{n+1} T_j
    * with T_i = <c_{n+1,a}|T_i|c_{n,b}> indexed by the `n' basis
    * normal ordered legs and indices i,j
    */
   CorrelatorMap theCorrelators;
 
   /**
+   * Colour charge or quark splitting matrix representations
+   */
+  TSMap theCharges;
+
+  /**
    * Map diagrams to colour flows indexed by basis tensor.
    */
   map<Ptr<Tree2toNDiagram>::tcptr,vector<string> > theFlowMap;
 
   /**
    * Map diagrams to colour line objects.
    */
   map<Ptr<Tree2toNDiagram>::tcptr,vector<ColourLines*> > theColourLineMap;
 
   /**
    * Store ordering identifiers
    */
   map<cPDVector,map<size_t,string> > theOrderingStringIdentifiers;
 
   /**
    * Store ordering identifiers
    */
   map<cPDVector,map<size_t,set<vector<size_t> > > > theOrderingIdentifiers;
 
   /**
    * Write out yet unknown basis computations.
    */
   void writeBasis(const string& prefix = "") const;
 
   /**
    * Read in the basis computation which are supposed to be known.
    */
   void readBasis();
 
   /**
    * Read in the basis computation which are supposed to be known.
    */
   bool readBasis(const vector<PDT::Colour>&);
 
   /**
    * Gather any implementation dependend details when reading a basis
    */
   virtual void readBasisDetails(const vector<PDT::Colour>&) {}
 
   /**
    * Write out symmetric matrices.
    */
   void write(const symmetric_matrix<double,upper>&, ostream&) const;
 
   /**
    * Read in symmetric matrices.
    */
   void read(symmetric_matrix<double,upper>&, istream&);
 
   /**
    * Write out compressed matrices.
    */
   void write(const compressed_matrix<double>&, ostream&,
 	     const vector<pair<size_t,size_t> >&) const;
 
   /**
    * Read in compressed matrices.
    */
   void read(compressed_matrix<double>&, istream&,
 	    vector<pair<size_t,size_t> >&);
 
   /**
    * True, if an attempt to read in basis information has been
    * completed.
    */
   bool didRead;
 
   /**
    * True, if an attempt to write out basis information has been
    * completed.
    */
   mutable bool didWrite;
 
   /**
    * Temporary storage.
    */
   matrix<double> tmp;
 
   /**
    * The search path
    */
   string theSearchPath;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   ColourBasis & operator=(const ColourBasis &) = delete;
 
 };
 
 }
 
 #endif /* HERWIG_ColourBasis_H */
diff --git a/MatrixElement/Matchbox/Utility/DensityOperator.cc b/MatrixElement/Matchbox/Utility/DensityOperator.cc
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Matchbox/Utility/DensityOperator.cc
@@ -0,0 +1,479 @@
+// -*- C++ -*-
+//
+// DensityOperator.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
+// Copyright (C) 2002-2007 The Herwig Collaboration
+//
+// Herwig is licenced under version 2 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 DensityOperator class.
+//
+
+#include "DensityOperator.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+
+#include "Herwig/MatrixElement/Matchbox/Utility/MatchboxXCombData.h"
+#include "Herwig/MatrixElement/Matchbox/Base/MatchboxMEBase.h"
+
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+
+using namespace Herwig;
+
+
+DensityOperator::DensityOperator() : Nc(3.0), TR(0.5) { }
+
+DensityOperator::~DensityOperator() {}
+
+void DensityOperator::clear() {
+	theCorrelatorMap.clear();
+}
+
+// Prepare density operator if not done before
+void DensityOperator::prepare(const cPDVector& mePartonData) {
+
+	// Take parton data and create key of type 33bar888 to use as key for basis
+	vector<PDT::Colour> mePartonDataColoured = theColourBasis->normalOrderMap(mePartonData);
+
+	if( theDensityOperatorMap.count( mePartonDataColoured ) == 0 ){
+		// Get basis dimension
+		size_t dim = theColourBasis->prepare( mePartonData, false );
+		// Allocate space for density matrix
+		theDensityOperatorMap.insert(make_pair(mePartonDataColoured,matrix<Complex> (dim,dim)));
+	}
+}
+
+// Fill the density matrix for the first time
+void DensityOperator::fill(const Ptr<MatchboxXComb>::ptr MBXCombPtr,
+				 const cPDVector& partons,
+				 const vector<Lorentz5Momentum>& momenta){
+
+	// Map from helicity structure to amplitude vector in the color basis
+	const map<vector<int>,CVector>& amplitudeMap = MBXCombPtr->lastAmplitudes();
+	const cPDVector& mePartonData = MBXCombPtr->mePartonData();
+	// Get the dimension of the basis for the indexChange method
+	size_t dim = theColourBasis->prepare(mePartonData,false);
+	// Normal order partons according to ColourBasis
+	const vector<PDT::Colour> mePartonDataColoured = theColourBasis->normalOrderMap(mePartonData);
+
+	// Get the colour basis to colour basis map for this hard subprocess
+	map<cPDVector,map<size_t,size_t> >::iterator cb2cbit = theColourBasisToColourBasisMap.find(mePartonData);
+	// Fill the map with this hard subprocess if it doesn't have it yet
+	if ( cb2cbit == theColourBasisToColourBasisMap.end() ) {
+		// Get the index map for the partons as they are ordered in the MatchboxXComb
+		// object
+		const map<size_t,size_t>& mbIndexMap = theColourBasis->indexMap().at(mePartonData);
+		
+		// Get the index map for the partons as they are ordered
+		// in the shower.
+		// Use prepare, as it might not have been done for this order of the partons
+		theColourBasis->prepare(partons,false);
+		const map<size_t,size_t>& showerIndexMap = theColourBasis->indexMap().at(partons);
+		
+		// ensure the maps are of the same size
+		assert( mbIndexMap.size() == showerIndexMap.size() );
+
+		// Loop over both sets of partons to determine how the order between them
+		// differs, then translate the index to the colour basis and put the
+		// key-value pair into the map
+		map<size_t,size_t> cb2cbMap;
+
+		// Get the momenta for comparison
+		const vector<Lorentz5Momentum>& meMomenta = MBXCombPtr->matchboxME()->lastMEMomenta();
+		// Make sure there's the same number of momenta in both vectors
+		assert( momenta.size() == meMomenta.size() );
+		bool done;
+		// Boost the momenta to the same frame
+		const vector<Lorentz5Momentum> momentaCM = boostToRestFrame(momenta);
+		for ( size_t i = 0; i < momentaCM.size(); i++ ) {
+		  // The cb2cb map is intended to translate how the indices
+		  // are different in the colour basis due to the different 
+		  // orderings of the partons, so it should only bother
+		  // with coloured particles.
+                 if ( partons[i]->coloured() ) {
+			done = false;
+			for ( size_t j = 0; j < meMomenta.size(); j++ ) {
+	if ( !done ) {
+		if ( compareMomentum(momentaCM[i],meMomenta[j]) ) {
+				cb2cbMap[mbIndexMap.at(i)] = showerIndexMap.at(j);
+				done = true;
+		}
+	}	
+			}
+		 }
+		}
+
+		// Make sure all momenta have been identified
+		assert( cb2cbMap.size() == mePartonDataColoured.size() );
+
+		// Add the map to the cache
+		theColourBasisToColourBasisMap[mePartonData] = cb2cbMap;
+
+		// Get the iterator
+		cb2cbit = theColourBasisToColourBasisMap.find(mePartonData);
+	}
+
+	// With the cb2cb index map we can create the basis vector index map
+	const map<size_t,size_t> vectorMap = theColourBasis->indexChange(mePartonDataColoured,
+									 dim,cb2cbit->second);
+	
+	// Prepare density operator (allocate) for set of particles
+	prepare(mePartonData);
+
+	// Check that density operator (place holder for) exist in density operator map
+	map<vector<PDT::Colour>,matrix<Complex> >::iterator dOit = theDensityOperatorMap.find(mePartonDataColoured);
+	assert(dOit != theDensityOperatorMap.end());
+
+	// Initialize the density operator
+	matrix<Complex>& densOp = dOit->second;
+	for(unsigned int i = 0; i < (amplitudeMap.begin()->second).size(); i++){
+		for(unsigned int j = 0; j < (amplitudeMap.begin()->second).size(); j++){
+			densOp (i,j) = 0;
+		}
+	}
+
+	// Fill the density operator, ok to sum over helicities since the density operator
+	// exist at the probability level
+	CVector amplitude;
+	for ( map<vector<int>,CVector>::const_iterator itHel = amplitudeMap.begin();
+	itHel != amplitudeMap.end(); itHel++ ) {
+		amplitude = itHel->second;
+		for ( unsigned int i = 0; i < amplitude.size(); i++ ) {
+			for ( unsigned int j = 0; j < amplitude.size(); j++ ) {
+	// vectorMap is used such that densOp is filled according to the
+	// basis order defined by the input cPDVector partons.
+	densOp (vectorMap.at(i),vectorMap.at(j)) += amplitude(i)*std::conj(amplitude(j));
+			}
+		}
+	}
+	
+	// Colour conservation check
+	colourConservation(mePartonData);
+}
+
+// Update density matrix after emitting or splitting a gluon
+// The emissionsMap argument contains the relation of the indices in the smaller (before)
+// and larger basis (after). the first 3-tuple contains the indices
+// (emitter before, emitter after, emitted parton)
+// The map contains the old and new indices of all other partons (not involved)
+void DensityOperator::evolve(const map<pair<size_t,size_t>,Complex>& Vijk, 
+					 const cPDVector& before,
+					 const cPDVector& after,
+					 const map<std::tuple<size_t,size_t,size_t>,map<size_t,size_t> >& emissionsMap,
+					 const bool splitAGluon,
+					 const bool initialGluonSplitting) {
+
+	size_t dimBefore = theColourBasis->prepare( before, false );
+	size_t dimAfter = theColourBasis->prepare( after, false );
+
+	vector<PDT::Colour> beforeColoured = theColourBasis->normalOrderMap(before);
+	vector<PDT::Colour> afterColoured = theColourBasis->normalOrderMap(after);
+
+	const map<vector<PDT::Colour>,matrix<Complex> >::iterator dOit = theDensityOperatorMap.find(beforeColoured);
+	assert(dOit != theDensityOperatorMap.end());
+
+	const matrix<Complex>& densOpBefore = dOit->second;
+
+	prepare(after);
+	matrix<Complex>& densOpAfter = theDensityOperatorMap[afterColoured];
+	for(size_t i = 0; i < densOpAfter.size1(); i++){
+		for(size_t j = 0; j < densOpAfter.size2(); j++){
+			densOpAfter(i,j) = 0;
+		}
+	}
+
+	compressed_matrix<double> Tij;
+	matrix<Complex> TijMn (dimAfter,dimBefore);
+	compressed_matrix<double> Tk;
+	matrix<Complex> TijMnTkdagger (dimAfter,dimAfter);
+	Complex V;
+	// Compensate for sign from updated density matrix
+	// TODO Check signs again
+	double sign = -1.0;
+	if ( splitAGluon )
+		sign = 1.0;
+	// Loop over emitter legs ij and recoil legs k and add the contribution,
+	// for Vijk is assumed to contain the factor 4*pi*\alpha_s/pi.pj
+	typedef map<std::tuple<size_t,size_t,size_t>,map<size_t,size_t> > dictMap;
+	int ij,k;
+	
+	// Loop over emitters
+	for(dictMap::const_iterator ijit = emissionsMap.begin();
+			ijit != emissionsMap.end(); ijit++) {
+		// get first element in 3-tuple, i.e., emitter before
+		ij = std::get<0>(ijit->first);
+		assert(before[ij]->coloured());
+		// Get rectangular matrices T_{ij} or S_{ij} taking us from the
+		// smaller to the larger basis depending on
+		// the involved particles before and after, the emitter index before ij,
+		// the emitter after and the emitted parton index
+		int i=std::get<1>(ijit->first); // emitter after
+		int j=std::get<2>(ijit->first);// emitted parton
+		Tij = theColourBasis->charge(before,after,
+				 ij,i,j,ijit->second).first;
+		TijMn = prodSparseDense(Tij,densOpBefore);
+
+		// Loop over spectators
+		for(dictMap::const_iterator kit = emissionsMap.begin();
+	kit != emissionsMap.end(); kit++) {
+			k = std::get<0>(kit->first);
+			assert(before[k]->coloured());
+			// Standard case of gluon radiation
+			if ( ijit != kit || splitAGluon || initialGluonSplitting ) {
+	int k_after=std::get<1>(kit->first); // For color structure k now has role of emitter
+	int k_emission= std::get<2>(kit->first); // Emitted parton index
+	Tk = theColourBasis->charge(before,after,
+						k, k_after, k_emission, kit->second).first;
+	TijMnTkdagger = prodDenseSparse(TijMn,Tk);
+	// sign == -1.0 if it isn't a gluon splitting into a qqbar pair
+	V = sign*(1.0/colourNorm(before[ij]))*
+		Vijk.at(make_pair(ij,k));
+	densOpAfter += V*TijMnTkdagger;
+			}
+		}
+	}
+	// Check that the density operator does not vanish
+	assert( theColourBasis->me2(after,densOpAfter) != 0.0 );
+	colourConservation(after);
+}
+
+// The 3-tuple contains (emitter index, spectator index, emission pid)
+double DensityOperator::colourMatrixElementCorrection(const std::tuple<size_t,size_t,long>& ikemission,
+									const cPDVector& particles) {
+	const int i = std::get<0>(ikemission);
+	const int k = std::get<1>(ikemission);
+	const long emissionID = std::get<2>(ikemission);
+
+
+	// Get the density operator
+	// normal order particles as in ColourBasis
+	vector<PDT::Colour> particlesColoured = theColourBasis->normalOrderMap(particles);
+	// ... and find corresponding density operator
+	const map<vector<PDT::Colour>,matrix<Complex> >::iterator particlesit = theDensityOperatorMap.find(particlesColoured);
+	assert(particlesit != theDensityOperatorMap.end());
+	const matrix<Complex>& densOp = particlesit->second;
+
+	double Ti2 = colourNorm(particles[i]);
+
+	// Emitter-spectator pair
+	const pair<size_t,size_t> ik = make_pair(i,k);
+	// Create key for color matrix element correction map
+	pair<vector<PDT::Colour>,pair<size_t,size_t> > particlesAndLegs = make_pair(particlesColoured,ik);
+
+	// Result
+	double res = 0;
+
+	// Check if it has already been calculated
+	// TODO: move this check earlier (we only need particlesColoured to check if it has been
+	//			 calculated).
+	// Check for color matrix element associated with key, and calculate if not done
+	const map<pair<vector<PDT::Colour>,pair<size_t,size_t> >,double >::const_iterator corrit = theCorrelatorMap.find(particlesAndLegs);
+	if ( corrit == theCorrelatorMap.end() ) {
+		double corrME2 = theColourBasis->colourCorrelatedME2(ik,particles,densOp);
+		double me2 = theColourBasis->me2(particles,densOp);
+		res = -(1/Ti2)*corrME2/me2;
+
+		if ( particles[i]->id() == ParticleID::g )
+			res *= 2.;
+		
+		theCorrelatorMap.insert(make_pair(particlesAndLegs,res));
+
+	} else {
+		res = corrit->second;
+	}
+
+	return res;
+}
+
+double DensityOperator::colourNorm(const cPDPtr particle) {
+	if ( particle->id() == ParticleID::g ) {
+		return Nc; //is 3.0 for Nc = 3, TR = 1/2
+	} else if ( particle->iColour() == PDT::Colour3 || particle->iColour() == PDT::Colour3bar ) {
+	  return TR*(Nc*Nc-1.)/Nc; // is 4.0/3.0 for Nc = 3, TR = 1/2
+	} else {
+		throw Exception() << "Colour matrix element corrections only work "
+					<< "on quark and gluon legs.	"
+					<< Exception::runerror;
+	}
+}
+
+void DensityOperator::colourConservation(const cPDVector& particles) {
+	// To contain (emitter, spectator, emission pid)
+	std::tuple<size_t,size_t,long> ikemission;
+	// Normal order particles as defined in ColourBasis
+	const vector<PDT::Colour> particlesColoured = theColourBasis->normalOrderMap(particles);
+	vector<double> sum(particlesColoured.size(),0.0);
+	size_t iterm = 0;
+
+	// To compensate for the CMEC having a 1/(1+\delta(i is gluon)) factor
+	// in the splitting kernel
+	double gluonFactor = 1.0;
+	// Loop over "emitters" to check color conservation for
+	for ( size_t i = 0; i < particles.size(); i++ ) {
+		if ( particles[i]->coloured() ) {
+			for ( size_t k = 0; k < particles.size(); k++ ) {
+	if ( particles[k]->coloured() && i != k ) {
+		ikemission = std::make_tuple(i,k,ParticleID::g);
+		if ( particles[i]->id() != ParticleID::g ) {
+			gluonFactor = 1.0;
+		} else {
+			gluonFactor = 1./2.;
+		}
+		sum[iterm] += gluonFactor*colourMatrixElementCorrection(ikemission,particles);
+	}
+			}
+			iterm++;
+		}
+	}
+	for ( size_t i = 0; i < sum.size(); i++ )
+		assert( std::abs(sum[i]-1.0) < pow(10.0,-10.0));
+}
+
+matrix<Complex> DensityOperator::prodSparseDense(const compressed_matrix<double>& Tij,
+						 const matrix<Complex>& Mn){
+	// Dimension before emission
+	size_t dimBefore = Tij.size2();
+	// Dimension after emission
+	size_t dimAfter = Tij.size1();
+
+	//Check matrix dimensions
+	assert( dimBefore == Mn.size1() );
+
+	// Allocate memory for the matrix
+	matrix<Complex> TijMn (dimAfter,dimBefore,0);
+	// Use iterators for the compressed matrix to iterate only over the non-zero
+	// elements.
+	size_t ii;
+	size_t jj;
+	for ( compressed_matrix<double>::const_iterator1 it1 = Tij.begin1();
+	it1 != Tij.end1(); it1++ ) {
+		for ( compressed_matrix<double>::const_iterator2 it2 = it1.begin();
+		it2 != it1.end(); it2++ ) {
+			ii = it2.index1();
+			jj = it2.index2();
+			for ( size_t kk = 0; kk < dimBefore; kk++ ) {
+	// *it2 is Tij(ii,jj)
+	TijMn(ii,kk) += (*it2)*Mn(jj,kk);
+			}
+		}
+	}
+	return TijMn;
+}
+
+matrix<Complex> DensityOperator::prodDenseSparse(const matrix<Complex>& TijMn,
+						 const compressed_matrix<double>& Tk){
+	// The compressed matrix comes from the charge method, do not transpose yet
+	// Dimension after emission
+	size_t dimAfter = Tk.size1();//Since this method returns TijMn*Tk^\dagger
+
+	//Check matrix dimensions
+	assert( TijMn.size2() == Tk.size2() );
+
+	// Allocate memory for the matrix
+	matrix<Complex> TijMnTkdagger (dimAfter,dimAfter,0);
+	size_t jj;
+	size_t kk;
+	for ( compressed_matrix<double>::const_iterator1 it1 = Tk.begin1();
+	it1 != Tk.end1(); it1++ ) {
+		for ( compressed_matrix<double>::const_iterator2 it2 = it1.begin();
+		it2 != it1.end(); it2++ ) {
+			jj = it2.index2();//transposing Tk jj is index2(), not index1()
+			kk = it2.index1();//transposing Tk
+			for ( size_t ii = 0; ii < dimAfter; ii++ ) {
+	// *it2 is Tk(kk,jj) = trans(Tk)(jj,kk)
+	TijMnTkdagger(ii,kk) += TijMn(ii,jj)*(*it2);
+			}
+		}
+	}
+	return TijMnTkdagger;
+}
+
+vector<Lorentz5Momentum> DensityOperator::boostToRestFrame(const vector<Lorentz5Momentum>& momenta) {
+	// We need 2 initial particles
+	assert(momenta.size() >= 2);
+	// The boosted vectors
+	vector<Lorentz5Momentum> vboosted = momenta;
+
+	// The boost should be to the rest frame of the initial particles
+	Boost b = (momenta[0] + momenta[1]).findBoostToCM();
+
+	// Boost all of the vectors
+	for ( size_t i = 0; i < momenta.size(); i++ ) {
+		vboosted[i].boost(b);
+	}
+		
+	return vboosted;
+}
+
+bool DensityOperator::compareMomentum(const Lorentz5Momentum& p, const Lorentz5Momentum& q) {
+	bool equal = true;
+	// Compares two momentum vectors p and q, if they are close enough (defined by the
+	// double eps below) it returns true. This is sufficient to distinguish particles
+	// in the matrix element as we are not interested in the matrix element for extremely
+	// collinear radiation (better described by the parton shower).
+
+	// Create the difference of the two vectors
+	const Lorentz5Momentum l = p - q;
+	// A relevant size that is guaranteed to be larger than 0
+	const Energy2 e2 = p.t()*p.t();
+	// Size of the difference that would be considered equal
+	const double eps = pow(10.,-15.);
+
+	if ( l.x()*l.x()/e2 > eps )
+		equal = false;
+	if ( l.y()*l.y()/e2 > eps )
+		equal = false;
+	if ( l.z()*l.z()/e2 > eps )
+		equal = false;
+	if ( l.t()*l.t()/e2 > eps )
+		equal = false;
+	
+	return equal;
+}
+
+
+
+
+IBPtr DensityOperator::clone() const {
+	return new_ptr(*this);
+}
+
+IBPtr DensityOperator::fullclone() const {
+	return new_ptr(*this);
+}
+
+
+// If needed, insert default implementations of virtual function defined
+// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
+
+
+void DensityOperator::persistentOutput(PersistentOStream &) const {
+	// *** ATTENTION *** os << ; // Add all member variable which should be written persistently here.
+}
+
+void DensityOperator::persistentInput(PersistentIStream &, int) {
+	// *** ATTENTION *** is >> ; // Add all member variable which should be read persistently here.
+}
+
+
+// *** Attention *** The following static variable is needed for the type
+// description system in ThePEG. Please check that the template arguments
+// are correct (the class and its base class), and that the constructor
+// arguments are correct (the class name and the name of the dynamically
+// loadable library where the class implementation can be found).
+DescribeClass<DensityOperator,HandlerBase>
+describeHerwigDensityOperator("Herwig::DensityOperator", "DensityOperator.so");
+
+void DensityOperator::Init() {
+
+	static ClassDocumentation<DensityOperator> documentation
+	        ("There is no documentation for the DensityOperator class");
+
+}
+
diff --git a/MatrixElement/Matchbox/Utility/DensityOperator.h b/MatrixElement/Matchbox/Utility/DensityOperator.h
new file mode 100644
--- /dev/null
+++ b/MatrixElement/Matchbox/Utility/DensityOperator.h
@@ -0,0 +1,248 @@
+// -*- C++ -*-
+//
+// DensityOperator.h is a part of Herwig - A multi-purpose Monte Carlo event generator
+// Copyright (C) 2002-2007 The Herwig Collaboration
+//
+// Herwig is licenced under version 2 of the GPL, see COPYING for details.
+// Please respect the MCnet academic guidelines, see GUIDELINES for details.
+//
+#ifndef Herwig_DensityOperator_H
+#define Herwig_DensityOperator_H
+//
+// This is the declaration of the DensityOperator class.
+//
+
+#include "ThePEG/Handlers/HandlerBase.h"
+
+#include "Herwig/MatrixElement/Matchbox/Utility/ColourBasis.h"
+
+#include <tuple>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+typedef boost::numeric::ublas::vector<Complex> CVector;
+
+
+
+/**
+ * Here is the documentation of the DensityOperator class.
+ *
+ * @see \ref DensityOperatorInterfaces "The interfaces"
+ * defined for DensityOperator.
+ */
+class DensityOperator: public HandlerBase {
+
+public:
+
+  /** @name Standard constructors and destructors. */
+  //@{
+  /**
+   * The default constructor.
+   */
+  DensityOperator();
+
+  /**
+   * The destructor.
+   */
+  virtual ~DensityOperator();
+  //@}
+
+public:
+  
+  /**
+   * Clears theDensityOperatorMap.
+   */
+  void clear();
+
+  /**
+   * Prepare for the given sub process.
+   */
+  void prepare(const cPDVector&);
+
+  /**
+   * Fill the density operator for the given hard subprocess, summing over all
+   * helicity configurations.
+   */
+  void fill(const Ptr<MatchboxXComb>::ptr,
+	    const cPDVector&, const vector<Lorentz5Momentum>& momenta);
+  
+  /**
+   * Evolve the density operator, by 
+   * M_{n+1} = -\sum_{i,k}{-4*pi*alpha_s/Ti2*V_{ij,k} T_{i,n}M_nT_{k,n}^\dag},
+   * see arXiv:1206.0180 eq. (5), note that the pi*pj factor is assumed to be
+   * included in V_{ij,k}.
+   */
+  void evolve(const map<pair<size_t,size_t>,Complex>& Vijk, 
+	      const cPDVector& before, 
+	      const cPDVector& after,
+	      const map<std::tuple<size_t,size_t,size_t>,map<size_t,size_t> >& emissionsMap,
+	      const bool splitAGluon,
+	      const bool initialGluonSplitting);
+  
+  /**
+   * Calculate the colour matrix element correction.
+   * -(1+delta(i,gluon))/Ti^2 Tr(Sn+1 Ti Mn Tk^dagger)/Tr(Sn Mn)
+   * where the bracket in front compensates for the gluon symmetry factor,
+   * Ti^2 is C_f or C_a, Sn+1 is the matrix of scalar products, and
+   * Ti is the radiation matrix.
+   * The first arg contains (emitter index, spectator index, emission pid)
+   *
+   */
+  double colourMatrixElementCorrection(const std::tuple<size_t,size_t,long>& ikemission,
+				       const cPDVector& particles);
+
+  /**
+   * Checking colour conservation for the colour matrix element corrections.
+   */
+  void colourConservation(const cPDVector& particles);
+
+  /**
+   * Get the colour basis.
+   */
+  Ptr<ColourBasis>::tptr colourBasis() { return theColourBasis; }
+  
+  /**
+   * Get the colour basis.
+   */
+  const Ptr<ColourBasis>::tptr colourBasis() const { return theColourBasis; }
+  
+  /**
+   * Set the colour basis.
+   */
+  void colourBasis(Ptr<ColourBasis>::ptr ptr) { theColourBasis = ptr; }
+  
+  /**
+   * Get the correlator map.
+   */
+  const map<pair<vector<PDT::Colour>,pair<size_t,size_t> >,double>& correlatorMap() const {
+    return theCorrelatorMap;
+  }
+
+  /** @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;
+  //@}
+
+
+// If needed, insert declarations of virtual function defined in the
+// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
+
+
+private:
+
+  /**
+  * Number of colours used in colourNorm.
+  */
+  double Nc;
+
+  /**
+   * QCD vertex normalization.
+   */
+  double TR;
+
+  /**
+   * Normalization of colour charges \mathbf{T}_{ij}^2.
+   */
+  double colourNorm(const cPDPtr particle);
+
+  /**
+   * Fast evaluation of Tij*Mn, where a Tij is the matrix from ColourBasis::charge,
+   * which is a sparse matrix, and Mn is the density operator, a dense matrix.
+   *
+   */
+  matrix<Complex> prodSparseDense(const compressed_matrix<double>&,
+				  const matrix<Complex>&);
+  /**
+   * Fast evaluation of TijMn*Tkdagger, where a TijMn is the result from the method
+   * prodSparseDense, a dense matrix, and Tkdagger is the transponse conjugate of
+   * the matrix from ColourBasis::charge, a sparse matrix.
+   *
+   */
+  matrix<Complex> prodDenseSparse(const matrix<Complex>&,
+				  const compressed_matrix<double>&);
+
+  /**
+   * Boosts a vector of momenta to the rest frame of the initial pair
+   * of particles (the first 2 elements of the argument vector). Returns
+   * the boosted vectors
+   */
+  vector<Lorentz5Momentum> boostToRestFrame(const vector<Lorentz5Momentum>& momenta);
+
+  /**
+   * Boosts a vector of momenta to the rest frame of the initial pair
+   */
+  bool compareMomentum(const Lorentz5Momentum& p, const Lorentz5Momentum& q);
+  
+  /**
+   * Mapping of colour structures to density operator matrices.
+   *
+   */
+  map<vector<PDT::Colour>,matrix<Complex> > theDensityOperatorMap;
+  
+  /**
+   * Mapping of colour structures and legs to colour correlators. 
+   */
+  map<pair<vector<PDT::Colour>,pair<size_t,size_t> >,double> theCorrelatorMap;
+
+  /**
+   * A map from the hard subprocess particles to a map of amplitude colour
+   * basis order to the normal ordered colour basis. 
+   */
+  map<cPDVector, map<size_t,size_t> > theColourBasisToColourBasisMap;
+  
+  /**
+   * Colour basis used.
+   */
+  Ptr<ColourBasis>::ptr theColourBasis;
+
+  /**
+   * The assignment operator is private and must never be called.
+   * In fact, it should not even be implemented.
+   */
+  DensityOperator & operator=(const DensityOperator &);
+
+};
+
+}
+
+#endif /* Herwig_DensityOperator_H */
diff --git a/MatrixElement/Matchbox/Utility/Makefile.am b/MatrixElement/Matchbox/Utility/Makefile.am
--- a/MatrixElement/Matchbox/Utility/Makefile.am
+++ b/MatrixElement/Matchbox/Utility/Makefile.am
@@ -1,33 +1,35 @@
 noinst_LTLIBRARIES = libHwMatchboxUtility.la
 
 libHwMatchboxUtility_la_SOURCES = \
 AmplitudeCache.h \
 AmplitudeCache.tcc \
 ColourBasis.cc \
 ColourBasis.h \
+DensityOperator.cc \
+DensityOperator.h \
 DiagramDrawer.cc \
 DiagramDrawer.h \
 MatchboxScaleChoice.cc \
 MatchboxScaleChoice.h \
 ProcessData.h \
 ProcessData.fh \
 ProcessData.cc \
 SimpleColourBasis.cc \
 SimpleColourBasis.h \
 SimpleColourBasis2.cc \
 SimpleColourBasis2.h \
 SpinCorrelationTensor.h \
 SpinorHelicity.h \
 SU2Helper.cc \
 SU2Helper.h \
 Tree2toNGenerator.cc \
 Tree2toNGenerator.h \
 MatchboxXComb.h \
 MatchboxXComb.cc \
 MatchboxXCombGroup.h \
 MatchboxXCombGroup.cc \
 MatchboxXCombData.h \
 MatchboxXCombData.cc \
 LastMatchboxXCombInfo.h \
 MatchboxFactoryMatcher.h \
 MatchboxFactoryMatcher.cc
diff --git a/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc b/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc
--- a/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc
+++ b/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc
@@ -1,396 +1,410 @@
 // -*- C++ -*-
 //
 // SimpleColourBasis.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.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the SimpleColourBasis class.
 //
 
 #include "SimpleColourBasis.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/EventRecord/Particle.h"
 #include "ThePEG/Repository/UseRandom.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/StandardModel/StandardModelBase.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 SimpleColourBasis::SimpleColourBasis() {}
 
 SimpleColourBasis::~SimpleColourBasis() {}
 
 IBPtr SimpleColourBasis::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr SimpleColourBasis::fullclone() const {
   return new_ptr(*this);
 }
 
 size_t SimpleColourBasis::prepareBasis(const vector<PDT::Colour>& basis) {
 
   if ( id33bar.empty() )
     makeIds();
 
   if ( basis == id88 || basis == id33bar || basis == id33bar8 )
     return 1;
 
   if ( basis == id888 || basis == id33bar88 || basis == id33bar33bar )
     return 2;
 
   if ( basis == id8888 )
     return 6;
 
   throw Exception() << "SimpleColourBasis::prepareBasis(): Cannot handle colour configuration" << Exception::runerror;
 
   return 0;
 
 }
 
 double SimpleColourBasis::scalarProduct(size_t a, size_t b,
 					const vector<PDT::Colour>& abBasis) const {
 
   if ( id33bar.empty() )
     makeIds();
 
   double Nc = SM().Nc();
   double Nc2 = sqr(Nc);
   double Nc3 = Nc*Nc2;
   double Nc4 = sqr(Nc2);
   double Nc6 = Nc2*Nc4;
 
   if ( a > b )
     swap(a,b);
 
   if ( !largeN() ) {
 
     if ( abBasis == id88 ) {
       return ( Nc2 - 1. )/4.;
     }
 
     if ( abBasis == id33bar ) {
       return Nc;
     }
 
     if ( abBasis == id888 ) {
       if ( a == b )
 	return ( Nc4 - 3.*Nc2 + 2. )/(8.*Nc);
       return -( Nc2 - 1. )/(4.*Nc);
     }
 
     if ( abBasis == id33bar8 ) {
       return ( Nc2 - 1. )/2.;
     }
 
     if ( abBasis == id8888 ) {
       if ( a == b )
 	return ( Nc6 - 4.*Nc4 + 6.*Nc2 - 3. )/(16.*Nc2);
       if ( ( a == 0 && b == 1 ) ||
 	   ( a == 2 && b == 3 ) ||
 	   ( a == 4 && b == 5 ) )
 	return ( Nc4 + 2.*Nc2 - 3. )/(16.*Nc2);
       return -( Nc2 - 4. + 3./Nc2 )/16.;
     }
 
     if ( abBasis == id33bar88 ) {
       if ( a == b )
 	return ( Nc4 - 2.*Nc2 + 1 )/(4.*Nc);
       return -( Nc2 - 1. )/(4.*Nc);
     }
 
     if ( abBasis == id33bar33bar ) {
       if ( a == b )
 	return Nc2;
       return Nc;
     }
 
   } else {
 
     if ( a != b )
       return 0.;
 
     if ( abBasis == id88 ) {
       return Nc2/4.;
     }
 
     if ( abBasis == id33bar ) {
       return Nc;
     }
 
     if ( abBasis == id888 ) {
       return Nc3/8.;
     }
 
     if ( abBasis == id33bar8 ) {
       return Nc2/2.;
     }
 
     if ( abBasis == id8888 ) {
       return Nc4/16.;
     }
 
     if ( abBasis == id33bar88 ) {
       return Nc3/4.;
     }
 
     if ( abBasis == id33bar33bar ) {
       return Nc2;
     }
 
   }
 
   throw Exception() << "SimpleColourBasis::scalarProduct(): Cannot handle colour configuration" << Exception::runerror;
 
 }
 
 double SimpleColourBasis::tMatrixElement(size_t i, size_t a, 
 					 size_t b,
 					 const vector<PDT::Colour>&,
-					 const vector<PDT::Colour>& bBasis) const {
+					 const vector<PDT::Colour>& bBasis,
+					 size_t k, size_t l,
+					 const map<size_t,size_t>& dict) const {
+  // Check indices k and l
+  assert( k == i );
+  assert( l == bBasis.size() );
+  // Check that dict is the standardMap
+  assert( dict.size()+1 == bBasis.size() );
+  map<size_t,size_t>::const_iterator tmp;
+  for ( size_t ii = 0; ii < bBasis.size(); ii++ )
+    if ( ii != i ) {
+      tmp = dict.find(ii);
+      assert( tmp != dict.end() ); 
+      assert( tmp->second == ii );
+    }
 
   if ( id33bar.empty() )
     makeIds();
 
   if ( bBasis == id88 ) {
     if ( i == 0 )
       return a == 0 ? -1. : 1.;
     else
       return a == 0 ? 1. : -1.;
   }
 
   if ( bBasis == id33bar ) {
     return i == 0 ? 1. : -1.;
   }
 
   if ( bBasis == id888 ) {
     if ( i == 0 ) {
       if ( a == 3 && b == 0 )
 	return 1.;
       if ( a == 0 && b == 0 )
 	return -1.;
       if ( a == 1 && b == 1 )
 	return 1.;
       if ( a == 2 && b == 1 )
 	return -1.;
     }
     if ( i == 1 ) {
       if ( a == 4 && b == 0 )
 	return 1.;
       if ( a == 3 && b == 0 )
 	return -1.;
       if ( a == 2 && b == 1 )
 	return 1.;
       if ( a == 5 && b == 1 )
 	return -1.;
     }
     if ( i == 2 ) {
       if ( a == 0 && b == 0 )
 	return 1.;
       if ( a == 4 && b == 0 )
 	return -1.;
       if ( a == 5 && b == 1 )
 	return 1.;
       if ( a == 1 && b == 1 )
 	return -1.;
     }
     return 0.;
   }
 
   if ( bBasis == id33bar8 ) {
     if ( i == 0 )
       return a == 1 ? 1. : 0.;
     if ( i == 1 )
       return a == 0 ? -1. : 0.;
     if ( i == 2 )
       return a == 0 ? 1. : -1.;
   }
 
   throw Exception() << "SimpleColourBasis::tMatrixElement(): Cannot handle colour configuration" << Exception::runerror;
 
   return 0.;
 
 }
 
 bool SimpleColourBasis::colourConnected(const cPDVector& sub,
 					const vector<PDT::Colour>& basis,
 					const pair<int,bool>& i, 
 					const pair<int,bool>& j, 
 					size_t a) const {
 
   if ( id33bar.empty() )
     makeIds();
 
   // translate process to basis ids
   map<cPDVector,map<size_t,size_t> >::const_iterator trans
     = indexMap().find(sub);
   assert(trans != indexMap().end());
 
   int idColoured = i.second ? j.first : i.first;
   idColoured = trans->second.find(idColoured)->second;
   int idAntiColoured = i.second ? i.first : j.first;
   idAntiColoured = trans->second.find(idAntiColoured)->second;
 
   if ( basis == id88 ) {
     return
       ( idColoured == 0 && idAntiColoured == 1 ) ||
       ( idColoured == 1 && idAntiColoured == 0 );
   }
 
   if ( basis == id33bar ) {
     return
       idColoured == 0 && idAntiColoured == 1;
   }
 
   if ( basis == id888 ) {
     if ( a == 0 )
       return
 	( idColoured == 0 && idAntiColoured == 1 ) ||
 	( idColoured == 1 && idAntiColoured == 2 ) ||
 	( idColoured == 2 && idAntiColoured == 0 );
     if ( a == 1 )
       return
 	( idColoured == 0 && idAntiColoured == 2 ) ||
 	( idColoured == 2 && idAntiColoured == 1 ) ||
 	( idColoured == 1 && idAntiColoured == 0 );
   }
 
   if ( basis == id33bar8 ) {
     return
       ( idColoured == 0 && idAntiColoured == 2 ) ||
       ( idColoured == 2 && idAntiColoured == 1 );
   }
 
   if ( basis == id8888 ) {
     if ( a == 0 )
       return
 	( idColoured == 0 && idAntiColoured == 1 ) ||
 	( idColoured == 1 && idAntiColoured == 2 ) ||
 	( idColoured == 2 && idAntiColoured == 3 ) ||
 	( idColoured == 3 && idAntiColoured == 0 );
     if ( a == 1 )
       return
 	( idColoured == 0 && idAntiColoured == 3 ) ||
 	( idColoured == 3 && idAntiColoured == 2 ) ||
 	( idColoured == 2 && idAntiColoured == 1 ) ||
 	( idColoured == 1 && idAntiColoured == 0 );
     if ( a == 2 )
       return
 	( idColoured == 0 && idAntiColoured == 2 ) ||
 	( idColoured == 2 && idAntiColoured == 1 ) ||
 	( idColoured == 1 && idAntiColoured == 3 ) ||
 	( idColoured == 3 && idAntiColoured == 0 );
     if ( a == 3 )
       return
 	( idColoured == 0 && idAntiColoured == 3 ) ||
 	( idColoured == 3 && idAntiColoured == 1 ) ||
 	( idColoured == 1 && idAntiColoured == 2 ) ||
 	( idColoured == 2 && idAntiColoured == 0 );
     if ( a == 4 )
       return
 	( idColoured == 0 && idAntiColoured == 1 ) ||
 	( idColoured == 1 && idAntiColoured == 3 ) ||
 	( idColoured == 3 && idAntiColoured == 2 ) ||
 	( idColoured == 2 && idAntiColoured == 0 );
     if ( a == 5 )
       return
 	( idColoured == 0 && idAntiColoured == 2 ) ||
 	( idColoured == 2 && idAntiColoured == 3 ) ||
 	( idColoured == 3 && idAntiColoured == 1 ) ||
 	( idColoured == 1 && idAntiColoured == 0 );
   }
 
   if ( basis == id33bar88 ) {
     if ( a == 0 )
       return
 	( idColoured == 0 && idAntiColoured == 2 ) ||
 	( idColoured == 2 && idAntiColoured == 3 ) ||
 	( idColoured == 3 && idAntiColoured == 1 );
     if ( a == 1 )
       return
 	( idColoured == 0 && idAntiColoured == 3 ) ||
 	( idColoured == 3 && idAntiColoured == 2 ) ||
 	( idColoured == 2 && idAntiColoured == 1 );
   }
 
   if ( basis == id33bar33bar ) {
     if ( a == 0 )
       return
 	( idColoured == 0 && idAntiColoured == 1 ) ||
 	( idColoured == 2 && idAntiColoured == 3 );
     if ( a == 1 )
       return
 	( idColoured == 0 && idAntiColoured == 3 ) ||
 	( idColoured == 2 && idAntiColoured == 1 );
   }
 
   return false;
 
 }
 
 // If needed, insert default implementations of virtual function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 void SimpleColourBasis::makeIds() const {
 
   id88.push_back(PDT::Colour8);
   id88.push_back(PDT::Colour8);
 
   id33bar.push_back(PDT::Colour3);
   id33bar.push_back(PDT::Colour3bar);
 
   id888.push_back(PDT::Colour8);
   id888.push_back(PDT::Colour8);
   id888.push_back(PDT::Colour8);
 
   id33bar8.push_back(PDT::Colour3);
   id33bar8.push_back(PDT::Colour3bar);
   id33bar8.push_back(PDT::Colour8);
 
   id8888.push_back(PDT::Colour8);
   id8888.push_back(PDT::Colour8);
   id8888.push_back(PDT::Colour8);
   id8888.push_back(PDT::Colour8);
 
   id33bar88.push_back(PDT::Colour3);
   id33bar88.push_back(PDT::Colour3bar);
   id33bar88.push_back(PDT::Colour8);
   id33bar88.push_back(PDT::Colour8);
 
   id33bar33bar.push_back(PDT::Colour3);
   id33bar33bar.push_back(PDT::Colour3bar);
   id33bar33bar.push_back(PDT::Colour3);
   id33bar33bar.push_back(PDT::Colour3bar);
 
 }
 
 void SimpleColourBasis::persistentOutput(PersistentOStream &) const {}
 
 void SimpleColourBasis::persistentInput(PersistentIStream &, int) {}
 
 
 // *** Attention *** The following static variable is needed for the type
 // description system in ThePEG. Please check that the template arguments
 // are correct (the class and its base class), and that the constructor
 // arguments are correct (the class name and the name of the dynamically
 // loadable library where the class implementation can be found).
 DescribeClass<SimpleColourBasis,ColourBasis>
   describeHerwigSimpleColourBasis("Herwig::SimpleColourBasis", "Herwig.so");
 
 void SimpleColourBasis::Init() {
 
   static ClassDocumentation<SimpleColourBasis> documentation
     ("SimpleColourBasis implements the colour algebra needed for "
      "electroweak boson and electroweak boson + jet production at NLO. It mainly "
      "serves as an example for the general ColourBasis interface.");
 
 }
 
diff --git a/MatrixElement/Matchbox/Utility/SimpleColourBasis.h b/MatrixElement/Matchbox/Utility/SimpleColourBasis.h
--- a/MatrixElement/Matchbox/Utility/SimpleColourBasis.h
+++ b/MatrixElement/Matchbox/Utility/SimpleColourBasis.h
@@ -1,189 +1,209 @@
 // -*- C++ -*-
 //
 // SimpleColourBasis.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_SimpleColourBasis_H
 #define Herwig_SimpleColourBasis_H
 //
 // This is the declaration of the SimpleColourBasis class.
 //
 
 #include "Herwig/MatrixElement/Matchbox/Utility/ColourBasis.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup Matchbox
  * \author Simon Platzer
  *
  * \brief SimpleColourBasis implements the colour algebra needed for
  * electroweak boson and electroweak boson + jet production at NLO. It
  * mainly serves as an example for the general ColourBasis interface.
  *
  */
 class SimpleColourBasis: public ColourBasis {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   SimpleColourBasis();
 
   /**
    * The destructor.
    */
   virtual ~SimpleColourBasis();
   //@}
 
 public:
 
   /**
    * Prepare the basis for the normal ordered legs and return the
    * dimensionality of the basis.
    */
   virtual size_t prepareBasis(const vector<PDT::Colour>&);
 
   /**
    * Return the scalar product of basis tensors labelled a and b in
    * the basis used for the given normal ordered legs.
    */
   virtual double scalarProduct(size_t a, size_t b,
 			       const vector<PDT::Colour>& abBasis) const;
 
   /**
    * Return the matrix element of a colour charge
    * <c_{n+1,a}|T_i|c_{n,b}> between basis tensors a and b, with
    * respect to aBasis and bBasis
    */
   virtual double tMatrixElement(size_t i, size_t a, size_t b,
 				const vector<PDT::Colour>& aBasis,
-				const vector<PDT::Colour>& bBasis) const;
+				const vector<PDT::Colour>& bBasis,
+				size_t k, size_t l,
+				const map<size_t,size_t>& dict
+				) const;
+
+  virtual double sMatrixElement(size_t, size_t, size_t,
+				const vector<PDT::Colour>&,
+				const vector<PDT::Colour>&,
+				size_t, size_t,
+				const map<size_t,size_t>&
+				) const {
+    assert( 0 == 1 );
+    return 0;
+  }
+
+  /**
+   * Return true, if this colour basis supports gluon splittings.
+   */
+  virtual bool canSplitGluons() const {
+    return false;
+  }
 
   /**
    * Return true, if a large-N colour connection exists for the
    * given external legs and basis tensor.
    */
   virtual bool colourConnected(const cPDVector&,
 			       const vector<PDT::Colour>&,
 			       const pair<int,bool>&, 
 			       const pair<int,bool>&, 
 			       size_t) const;
 
   /**
    * Return true, if the colour basis is capable of assigning colour
    * flows.
    */
   virtual bool haveColourFlows() const { return true; }
 
   /**
    * Create ids for bases
    */
   void makeIds() 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * id for 88
    */
   mutable vector<PDT::Colour> id88;
 
   /**
    * id for 33bar
    */
   mutable vector<PDT::Colour> id33bar;
 
   /**
    * id for 888
    */
   mutable vector<PDT::Colour> id888;
 
   /**
    * id for 33bar8
    */
   mutable vector<PDT::Colour> id33bar8;
 
   /**
    * id for 8888
    */
   mutable vector<PDT::Colour> id8888;
 
   /**
    * id for 33bar88
    */
   mutable vector<PDT::Colour> id33bar88;
 
   /**
    * id for 33bar33bar
    */
   mutable vector<PDT::Colour> id33bar33bar;
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   SimpleColourBasis & operator=(const SimpleColourBasis &) = delete;
 
 };
 
 }
 
 #endif /* Herwig_SimpleColourBasis_H */
diff --git a/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc b/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc
--- a/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc
+++ b/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc
@@ -1,2864 +1,2878 @@
 // -*- C++ -*-
 //
 // SimpleColourBasis2.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.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the SimpleColourBasis2 class.
 //
 
 #include "SimpleColourBasis2.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/EventRecord/Particle.h"
 #include "ThePEG/Repository/UseRandom.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/Utilities/DescribeClass.h"
 #include "ThePEG/StandardModel/StandardModelBase.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 SimpleColourBasis2::SimpleColourBasis2() {}
 
 SimpleColourBasis2::~SimpleColourBasis2() {}
 
 IBPtr SimpleColourBasis2::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr SimpleColourBasis2::fullclone() const {
   return new_ptr(*this);
 }
 
 size_t SimpleColourBasis2::prepareBasis(const vector<PDT::Colour>& basis) {
 
   if ( id33bar.empty() )
     makeIds();
 
   if ( basis == id88 ) {
     return 1;
   }
 
   if ( basis == id33bar ) {
     return 1;
   }
 
   if ( basis == id888 ) {
     return 2;
   }
 
   if ( basis == id33bar8 ) {
     return 1;
   }
 
   if ( basis == id8888 ) {
     return 9;
   }
 
   if ( basis == id33bar88 ) {
     return 3;
   }
 
   if ( basis == id33bar33bar ) {
     return 2;
   }
 
   if ( basis == id88888 ) {
     return 44;
   }
 
   if ( basis == id33bar888 ) {
     return 11;
   }
 
   if ( basis == id33bar33bar8 ) {
     return 4;
   }
 
   throw Exception() << "SimpleColourBasis2::prepareBasis(): Cannot handle colour configuration" << Exception::runerror;
 
   return 0;
 
 }
 
 double SimpleColourBasis2::scalarProduct(size_t a, size_t b,
 					const vector<PDT::Colour>& basis) const {
 
   if ( id33bar.empty() )
     makeIds();
 
   double Nc = SM().Nc();
   double Nc2 = sqr(Nc);
   double Nc3 = Nc*Nc2;
   double Nc4 = sqr(Nc2);
   double Nc5 = Nc*Nc4;
   double Nc6 = Nc2*Nc4;
   double Nc8 = Nc2*Nc6;
 
   if ( a > b )
     swap(a,b);
 
   if ( !largeN() ) {
 
     if ( basis == id88 ) {
       if( a == 0 && b == 0  )
 	return (-1 + Nc2)/4.;
     }
 
     if ( basis == id33bar ) {
       if( a == 0 && b == 0  )
 	return Nc;
     }
 
     if ( basis == id888 ) {
       if( ( a == 0 && b == 0 ) ||
 	  ( a == 1 && b == 1 )  )
 	return (2 - 3*Nc2 + Nc4)/(8.*Nc);
       if( ( a == 0 ) && ( b == 1 )  )
 	return -(-1 + Nc2)/(4.*Nc);
     }
 
     if ( basis == id33bar8 ) {
       if( a == 0 && b == 0  )
 	return (-1 + Nc2)/2.;
     }
 
     if ( basis == id8888 ) {
       if( ( a == 0 && b == 0 ) ||
 	  ( a == 1 && b == 1 ) ||
 	  ( a == 2 && b == 2 )  )
 	return sqr(-1 + Nc2)/16.;
       if( ( a == 0 && b == 1 ) ||
 	  ( a == 0 && b == 2 ) ||
 	  ( a == 1 && b == 2 )  )
 	return (-1 + Nc2)/16.;
       if( ( a == 0 && b == 3 ) ||
 	  ( a == 0 && b == 5 ) ||
 	  ( a == 0 && b == 7 ) ||
 	  ( a == 0 && b == 8 ) ||
 	  ( a == 1 && b == 4 ) ||
 	  ( a == 1 && b == 5 ) ||
 	  ( a == 1 && b == 6 ) ||
 	  ( a == 1 && b == 7 ) ||
 	  ( a == 2 && b == 3 ) ||
 	  ( a == 2 && b == 4 ) ||
 	  ( a == 2 && b == 6 ) ||
 	  ( a == 2 && b == 8 )  )
 	return sqr(-1 + Nc2)/(16.*Nc);
       if( ( a == 0 && b == 4 ) ||
 	  ( a == 0 && b == 6 ) ||
 	  ( a == 1 && b == 3 ) ||
 	  ( a == 1 && b == 8 ) ||
 	  ( a == 2 && b == 5 ) ||
 	  ( a == 2 && b == 7 )  )
 	return -(-1 + Nc2)/(16.*Nc);
       if( ( a == 3 && b == 3 ) ||
 	  ( a == 4 && b == 4 ) ||
 	  ( a == 5 && b == 5 ) ||
 	  ( a == 6 && b == 6 ) ||
 	  ( a == 7 && b == 7 ) ||
 	  ( a == 8 && b == 8 )  )
 	return (-3 + 6*Nc2 - 4*Nc4 + Nc6)/(16.*Nc2);
       if( ( a == 3 && b == 4 ) ||
 	  ( a == 3 && b == 5 ) ||
 	  ( a == 3 && b == 6 ) ||
 	  ( a == 3 && b == 7 ) ||
 	  ( a == 4 && b == 5 ) ||
 	  ( a == 4 && b == 7 ) ||
 	  ( a == 4 && b == 8 ) ||
 	  ( a == 5 && b == 6 ) ||
 	  ( a == 5 && b == 8 ) ||
 	  ( a == 6 && b == 7 ) ||
 	  ( a == 6 && b == 8 ) ||
 	  ( a == 7 && b == 8 )  )
 	return (4 - 3/Nc2 - Nc2)/16.;
       if( ( a == 3 && b == 8 ) ||
 	  ( a == 4 && b == 6 ) ||
 	  ( a == 5 && b == 7 )  )
 	return (-3 + 2*Nc2 + Nc4)/(16.*Nc2);
     }
 
     if ( basis == id33bar88 ) {
       if( a == 0 && b == 0  )
 	return (Nc*(-1 + Nc2))/4.;
       if( ( a == 0 && b == 1 ) ||
 	  ( a == 0 && b == 2 )  )
 	return (-1 + Nc2)/4.;
       if( ( a == 1 && b == 1 ) ||
 	  ( a == 2 && b == 2 )  )
 	return sqr(-1 + Nc2)/(4.*Nc);
       if( a == 1 && b == 2  )
 	return -(-1 + Nc2)/(4.*Nc);
     }
 
     if ( basis == id33bar33bar ) {
       if( ( a == 0 && b == 0 ) ||
 	  ( a == 1 && b == 1 )  )
 	return Nc2;
       if( a == 0 && b == 1  )
 	return Nc;
     }
 
     if ( basis == id88888 ) {
       if( ( a == 0 && b == 0 ) ||
 	  ( a == 1 && b == 1 ) ||
 	  ( a == 2 && b == 2 ) ||
 	  ( a == 3 && b == 3 ) ||
 	  ( a == 4 && b == 4 ) ||
 	  ( a == 5 && b == 5 ) ||
 	  ( a == 6 && b == 6 ) ||
 	  ( a == 7 && b == 7 ) ||
 	  ( a == 8 && b == 8 ) ||
 	  ( a == 9 && b == 9 ) ||
 	  ( a == 10 && b == 10 ) ||
 	  ( a == 11 && b == 11 ) ||
 	  ( a == 12 && b == 12 ) ||
 	  ( a == 13 && b == 13 ) ||
 	  ( a == 14 && b == 14 ) ||
 	  ( a == 15 && b == 15 ) ||
 	  ( a == 16 && b == 16 ) ||
 	  ( a == 17 && b == 17 ) ||
 	  ( a == 18 && b == 18 ) ||
 	  ( a == 19 && b == 19 )  )
 	return ((-2 + Nc2)*sqr(-1 + Nc2))/(32.*Nc);
       if( ( a == 0 && b == 1 ) ||
 	  ( a == 0 && b == 2 ) ||
 	  ( a == 0 && b == 7 ) ||
 	  ( a == 0 && b == 10 ) ||
 	  ( a == 0 && b == 12 ) ||
 	  ( a == 0 && b == 13 ) ||
 	  ( a == 1 && b == 2 ) ||
 	  ( a == 1 && b == 4 ) ||
 	  ( a == 1 && b == 11 ) ||
 	  ( a == 1 && b == 14 ) ||
 	  ( a == 1 && b == 15 ) ||
 	  ( a == 2 && b == 5 ) ||
 	  ( a == 2 && b == 8 ) ||
 	  ( a == 2 && b == 16 ) ||
 	  ( a == 2 && b == 17 ) ||
 	  ( a == 3 && b == 4 ) ||
 	  ( a == 3 && b == 5 ) ||
 	  ( a == 3 && b == 6 ) ||
 	  ( a == 3 && b == 9 ) ||
 	  ( a == 3 && b == 14 ) ||
 	  ( a == 3 && b == 16 ) ||
 	  ( a == 4 && b == 5 ) ||
 	  ( a == 4 && b == 11 ) ||
 	  ( a == 4 && b == 12 ) ||
 	  ( a == 4 && b == 18 ) ||
 	  ( a == 5 && b == 8 ) ||
 	  ( a == 5 && b == 13 ) ||
 	  ( a == 5 && b == 19 ) ||
 	  ( a == 6 && b == 7 ) ||
 	  ( a == 6 && b == 8 ) ||
 	  ( a == 6 && b == 9 ) ||
 	  ( a == 6 && b == 12 ) ||
 	  ( a == 6 && b == 17 ) ||
 	  ( a == 7 && b == 8 ) ||
 	  ( a == 7 && b == 10 ) ||
 	  ( a == 7 && b == 14 ) ||
 	  ( a == 7 && b == 19 ) ||
 	  ( a == 8 && b == 15 ) ||
 	  ( a == 8 && b == 18 ) ||
 	  ( a == 9 && b == 10 ) ||
 	  ( a == 9 && b == 11 ) ||
 	  ( a == 9 && b == 13 ) ||
 	  ( a == 9 && b == 15 ) ||
 	  ( a == 10 && b == 11 ) ||
 	  ( a == 10 && b == 16 ) ||
 	  ( a == 10 && b == 18 ) ||
 	  ( a == 11 && b == 17 ) ||
 	  ( a == 11 && b == 19 ) ||
 	  ( a == 12 && b == 13 ) ||
 	  ( a == 12 && b == 17 ) ||
 	  ( a == 12 && b == 18 ) ||
 	  ( a == 13 && b == 15 ) ||
 	  ( a == 13 && b == 19 ) ||
 	  ( a == 14 && b == 15 ) ||
 	  ( a == 14 && b == 16 ) ||
 	  ( a == 14 && b == 19 ) ||
 	  ( a == 15 && b == 18 ) ||
 	  ( a == 16 && b == 17 ) ||
 	  ( a == 16 && b == 18 ) ||
 	  ( a == 17 && b == 19 )  )
 	return (2 - 3*Nc2 + Nc4)/(32.*Nc);
       if( ( a == 0 && b == 3 ) ||
 	  ( a == 1 && b == 6 ) ||
 	  ( a == 2 && b == 9 ) ||
 	  ( a == 4 && b == 7 ) ||
 	  ( a == 5 && b == 10 ) ||
 	  ( a == 8 && b == 11 ) ||
 	  ( a == 12 && b == 14 ) ||
 	  ( a == 13 && b == 16 ) ||
 	  ( a == 15 && b == 17 ) ||
 	  ( a == 18 && b == 19 )  )
 	return -sqr(-1 + Nc2)/(16.*Nc);
       if( ( a == 0 && b == 4 ) ||
 	  ( a == 0 && b == 5 ) ||
 	  ( a == 0 && b == 6 ) ||
 	  ( a == 0 && b == 9 ) ||
 	  ( a == 0 && b == 14 ) ||
 	  ( a == 0 && b == 16 ) ||
 	  ( a == 1 && b == 3 ) ||
 	  ( a == 1 && b == 7 ) ||
 	  ( a == 1 && b == 8 ) ||
 	  ( a == 1 && b == 9 ) ||
 	  ( a == 1 && b == 12 ) ||
 	  ( a == 1 && b == 17 ) ||
 	  ( a == 2 && b == 3 ) ||
 	  ( a == 2 && b == 6 ) ||
 	  ( a == 2 && b == 10 ) ||
 	  ( a == 2 && b == 11 ) ||
 	  ( a == 2 && b == 13 ) ||
 	  ( a == 2 && b == 15 ) ||
 	  ( a == 3 && b == 7 ) ||
 	  ( a == 3 && b == 10 ) ||
 	  ( a == 3 && b == 12 ) ||
 	  ( a == 3 && b == 13 ) ||
 	  ( a == 4 && b == 6 ) ||
 	  ( a == 4 && b == 8 ) ||
 	  ( a == 4 && b == 10 ) ||
 	  ( a == 4 && b == 14 ) ||
 	  ( a == 4 && b == 19 ) ||
 	  ( a == 5 && b == 7 ) ||
 	  ( a == 5 && b == 9 ) ||
 	  ( a == 5 && b == 11 ) ||
 	  ( a == 5 && b == 16 ) ||
 	  ( a == 5 && b == 18 ) ||
 	  ( a == 6 && b == 11 ) ||
 	  ( a == 6 && b == 14 ) ||
 	  ( a == 6 && b == 15 ) ||
 	  ( a == 7 && b == 11 ) ||
 	  ( a == 7 && b == 12 ) ||
 	  ( a == 7 && b == 18 ) ||
 	  ( a == 8 && b == 9 ) ||
 	  ( a == 8 && b == 10 ) ||
 	  ( a == 8 && b == 17 ) ||
 	  ( a == 8 && b == 19 ) ||
 	  ( a == 9 && b == 16 ) ||
 	  ( a == 9 && b == 17 ) ||
 	  ( a == 10 && b == 13 ) ||
 	  ( a == 10 && b == 19 ) ||
 	  ( a == 11 && b == 15 ) ||
 	  ( a == 11 && b == 18 ) ||
 	  ( a == 12 && b == 15 ) ||
 	  ( a == 12 && b == 16 ) ||
 	  ( a == 12 && b == 19 ) ||
 	  ( a == 13 && b == 14 ) ||
 	  ( a == 13 && b == 17 ) ||
 	  ( a == 13 && b == 18 ) ||
 	  ( a == 14 && b == 17 ) ||
 	  ( a == 14 && b == 18 ) ||
 	  ( a == 15 && b == 16 ) ||
 	  ( a == 15 && b == 19 ) ||
 	  ( a == 16 && b == 19 ) ||
 	  ( a == 17 && b == 18 )  )
 	return -(-1 + Nc2)/(16.*Nc);
       if( ( a == 0 && b == 8 ) ||
 	  ( a == 0 && b == 11 ) ||
 	  ( a == 0 && b == 15 ) ||
 	  ( a == 0 && b == 17 ) ||
 	  ( a == 0 && b == 18 ) ||
 	  ( a == 0 && b == 19 ) ||
 	  ( a == 1 && b == 5 ) ||
 	  ( a == 1 && b == 10 ) ||
 	  ( a == 1 && b == 13 ) ||
 	  ( a == 1 && b == 16 ) ||
 	  ( a == 1 && b == 18 ) ||
 	  ( a == 1 && b == 19 ) ||
 	  ( a == 2 && b == 4 ) ||
 	  ( a == 2 && b == 7 ) ||
 	  ( a == 2 && b == 12 ) ||
 	  ( a == 2 && b == 14 ) ||
 	  ( a == 2 && b == 18 ) ||
 	  ( a == 2 && b == 19 ) ||
 	  ( a == 3 && b == 8 ) ||
 	  ( a == 3 && b == 11 ) ||
 	  ( a == 3 && b == 15 ) ||
 	  ( a == 3 && b == 17 ) ||
 	  ( a == 3 && b == 18 ) ||
 	  ( a == 3 && b == 19 ) ||
 	  ( a == 4 && b == 9 ) ||
 	  ( a == 4 && b == 13 ) ||
 	  ( a == 4 && b == 15 ) ||
 	  ( a == 4 && b == 16 ) ||
 	  ( a == 4 && b == 17 ) ||
 	  ( a == 5 && b == 6 ) ||
 	  ( a == 5 && b == 12 ) ||
 	  ( a == 5 && b == 14 ) ||
 	  ( a == 5 && b == 15 ) ||
 	  ( a == 5 && b == 17 ) ||
 	  ( a == 6 && b == 10 ) ||
 	  ( a == 6 && b == 13 ) ||
 	  ( a == 6 && b == 16 ) ||
 	  ( a == 6 && b == 18 ) ||
 	  ( a == 6 && b == 19 ) ||
 	  ( a == 7 && b == 9 ) ||
 	  ( a == 7 && b == 13 ) ||
 	  ( a == 7 && b == 15 ) ||
 	  ( a == 7 && b == 16 ) ||
 	  ( a == 7 && b == 17 ) ||
 	  ( a == 8 && b == 12 ) ||
 	  ( a == 8 && b == 13 ) ||
 	  ( a == 8 && b == 14 ) ||
 	  ( a == 8 && b == 16 ) ||
 	  ( a == 9 && b == 12 ) ||
 	  ( a == 9 && b == 14 ) ||
 	  ( a == 9 && b == 18 ) ||
 	  ( a == 9 && b == 19 ) ||
 	  ( a == 10 && b == 12 ) ||
 	  ( a == 10 && b == 14 ) ||
 	  ( a == 10 && b == 15 ) ||
 	  ( a == 10 && b == 17 ) ||
 	  ( a == 11 && b == 12 ) ||
 	  ( a == 11 && b == 13 ) ||
 	  ( a == 11 && b == 14 ) ||
 	  ( a == 11 && b == 16 )  )
 	return 0;
       if( ( a == 0 && b == 20 ) ||
 	  ( a == 0 && b == 21 ) ||
 	  ( a == 0 && b == 23 ) ||
 	  ( a == 0 && b == 25 ) ||
 	  ( a == 0 && b == 36 ) ||
 	  ( a == 0 && b == 42 ) ||
 	  ( a == 1 && b == 21 ) ||
 	  ( a == 1 && b == 22 ) ||
 	  ( a == 1 && b == 23 ) ||
 	  ( a == 1 && b == 24 ) ||
 	  ( a == 1 && b == 30 ) ||
 	  ( a == 1 && b == 40 ) ||
 	  ( a == 2 && b == 20 ) ||
 	  ( a == 2 && b == 22 ) ||
 	  ( a == 2 && b == 24 ) ||
 	  ( a == 2 && b == 25 ) ||
 	  ( a == 2 && b == 28 ) ||
 	  ( a == 2 && b == 34 ) ||
 	  ( a == 3 && b == 26 ) ||
 	  ( a == 3 && b == 27 ) ||
 	  ( a == 3 && b == 29 ) ||
 	  ( a == 3 && b == 31 ) ||
 	  ( a == 3 && b == 37 ) ||
 	  ( a == 3 && b == 43 ) ||
 	  ( a == 4 && b == 24 ) ||
 	  ( a == 4 && b == 27 ) ||
 	  ( a == 4 && b == 28 ) ||
 	  ( a == 4 && b == 29 ) ||
 	  ( a == 4 && b == 30 ) ||
 	  ( a == 4 && b == 38 ) ||
 	  ( a == 5 && b == 22 ) ||
 	  ( a == 5 && b == 26 ) ||
 	  ( a == 5 && b == 28 ) ||
 	  ( a == 5 && b == 30 ) ||
 	  ( a == 5 && b == 31 ) ||
 	  ( a == 5 && b == 32 ) ||
 	  ( a == 6 && b == 31 ) ||
 	  ( a == 6 && b == 32 ) ||
 	  ( a == 6 && b == 33 ) ||
 	  ( a == 6 && b == 35 ) ||
 	  ( a == 6 && b == 37 ) ||
 	  ( a == 6 && b == 41 ) ||
 	  ( a == 7 && b == 25 ) ||
 	  ( a == 7 && b == 33 ) ||
 	  ( a == 7 && b == 34 ) ||
 	  ( a == 7 && b == 35 ) ||
 	  ( a == 7 && b == 36 ) ||
 	  ( a == 7 && b == 39 ) ||
 	  ( a == 8 && b == 20 ) ||
 	  ( a == 8 && b == 26 ) ||
 	  ( a == 8 && b == 32 ) ||
 	  ( a == 8 && b == 34 ) ||
 	  ( a == 8 && b == 36 ) ||
 	  ( a == 8 && b == 37 ) ||
 	  ( a == 9 && b == 29 ) ||
 	  ( a == 9 && b == 35 ) ||
 	  ( a == 9 && b == 38 ) ||
 	  ( a == 9 && b == 39 ) ||
 	  ( a == 9 && b == 41 ) ||
 	  ( a == 9 && b == 43 ) ||
 	  ( a == 10 && b == 23 ) ||
 	  ( a == 10 && b == 33 ) ||
 	  ( a == 10 && b == 39 ) ||
 	  ( a == 10 && b == 40 ) ||
 	  ( a == 10 && b == 41 ) ||
 	  ( a == 10 && b == 42 ) ||
 	  ( a == 11 && b == 21 ) ||
 	  ( a == 11 && b == 27 ) ||
 	  ( a == 11 && b == 38 ) ||
 	  ( a == 11 && b == 40 ) ||
 	  ( a == 11 && b == 42 ) ||
 	  ( a == 11 && b == 43 ) ||
 	  ( a == 12 && b == 20 ) ||
 	  ( a == 12 && b == 28 ) ||
 	  ( a == 12 && b == 32 ) ||
 	  ( a == 12 && b == 38 ) ||
 	  ( a == 12 && b == 41 ) ||
 	  ( a == 12 && b == 42 ) ||
 	  ( a == 13 && b == 21 ) ||
 	  ( a == 13 && b == 30 ) ||
 	  ( a == 13 && b == 32 ) ||
 	  ( a == 13 && b == 35 ) ||
 	  ( a == 13 && b == 36 ) ||
 	  ( a == 13 && b == 38 ) ||
 	  ( a == 14 && b == 22 ) ||
 	  ( a == 14 && b == 26 ) ||
 	  ( a == 14 && b == 34 ) ||
 	  ( a == 14 && b == 39 ) ||
 	  ( a == 14 && b == 40 ) ||
 	  ( a == 14 && b == 43 ) ||
 	  ( a == 15 && b == 23 ) ||
 	  ( a == 15 && b == 26 ) ||
 	  ( a == 15 && b == 29 ) ||
 	  ( a == 15 && b == 30 ) ||
 	  ( a == 15 && b == 36 ) ||
 	  ( a == 15 && b == 39 ) ||
 	  ( a == 16 && b == 24 ) ||
 	  ( a == 16 && b == 27 ) ||
 	  ( a == 16 && b == 33 ) ||
 	  ( a == 16 && b == 34 ) ||
 	  ( a == 16 && b == 37 ) ||
 	  ( a == 16 && b == 40 ) ||
 	  ( a == 17 && b == 25 ) ||
 	  ( a == 17 && b == 27 ) ||
 	  ( a == 17 && b == 28 ) ||
 	  ( a == 17 && b == 31 ) ||
 	  ( a == 17 && b == 33 ) ||
 	  ( a == 17 && b == 42 ) ||
 	  ( a == 18 && b == 20 ) ||
 	  ( a == 18 && b == 23 ) ||
 	  ( a == 18 && b == 24 ) ||
 	  ( a == 18 && b == 29 ) ||
 	  ( a == 18 && b == 37 ) ||
 	  ( a == 18 && b == 41 ) ||
 	  ( a == 19 && b == 21 ) ||
 	  ( a == 19 && b == 22 ) ||
 	  ( a == 19 && b == 25 ) ||
 	  ( a == 19 && b == 31 ) ||
 	  ( a == 19 && b == 35 ) ||
 	  ( a == 19 && b == 43 )  )
 	return ((-2 + Nc2)*sqr(-1 + Nc2))/(32.*Nc2);
       if( ( a == 0 && b == 22 ) ||
 	  ( a == 0 && b == 24 ) ||
 	  ( a == 0 && b == 32 ) ||
 	  ( a == 0 && b == 33 ) ||
 	  ( a == 0 && b == 38 ) ||
 	  ( a == 0 && b == 39 ) ||
 	  ( a == 1 && b == 20 ) ||
 	  ( a == 1 && b == 25 ) ||
 	  ( a == 1 && b == 26 ) ||
 	  ( a == 1 && b == 27 ) ||
 	  ( a == 1 && b == 38 ) ||
 	  ( a == 1 && b == 39 ) ||
 	  ( a == 2 && b == 21 ) ||
 	  ( a == 2 && b == 23 ) ||
 	  ( a == 2 && b == 26 ) ||
 	  ( a == 2 && b == 27 ) ||
 	  ( a == 2 && b == 32 ) ||
 	  ( a == 2 && b == 33 ) ||
 	  ( a == 3 && b == 28 ) ||
 	  ( a == 3 && b == 30 ) ||
 	  ( a == 3 && b == 34 ) ||
 	  ( a == 3 && b == 35 ) ||
 	  ( a == 3 && b == 40 ) ||
 	  ( a == 3 && b == 41 ) ||
 	  ( a == 4 && b == 20 ) ||
 	  ( a == 4 && b == 21 ) ||
 	  ( a == 4 && b == 26 ) ||
 	  ( a == 4 && b == 31 ) ||
 	  ( a == 4 && b == 40 ) ||
 	  ( a == 4 && b == 41 ) ||
 	  ( a == 5 && b == 20 ) ||
 	  ( a == 5 && b == 21 ) ||
 	  ( a == 5 && b == 27 ) ||
 	  ( a == 5 && b == 29 ) ||
 	  ( a == 5 && b == 34 ) ||
 	  ( a == 5 && b == 35 ) ||
 	  ( a == 6 && b == 28 ) ||
 	  ( a == 6 && b == 29 ) ||
 	  ( a == 6 && b == 34 ) ||
 	  ( a == 6 && b == 36 ) ||
 	  ( a == 6 && b == 42 ) ||
 	  ( a == 6 && b == 43 ) ||
 	  ( a == 7 && b == 22 ) ||
 	  ( a == 7 && b == 23 ) ||
 	  ( a == 7 && b == 32 ) ||
 	  ( a == 7 && b == 37 ) ||
 	  ( a == 7 && b == 42 ) ||
 	  ( a == 7 && b == 43 ) ||
 	  ( a == 8 && b == 22 ) ||
 	  ( a == 8 && b == 23 ) ||
 	  ( a == 8 && b == 28 ) ||
 	  ( a == 8 && b == 29 ) ||
 	  ( a == 8 && b == 33 ) ||
 	  ( a == 8 && b == 35 ) ||
 	  ( a == 9 && b == 30 ) ||
 	  ( a == 9 && b == 31 ) ||
 	  ( a == 9 && b == 36 ) ||
 	  ( a == 9 && b == 37 ) ||
 	  ( a == 9 && b == 40 ) ||
 	  ( a == 9 && b == 42 ) ||
 	  ( a == 10 && b == 24 ) ||
 	  ( a == 10 && b == 25 ) ||
 	  ( a == 10 && b == 36 ) ||
 	  ( a == 10 && b == 37 ) ||
 	  ( a == 10 && b == 38 ) ||
 	  ( a == 10 && b == 43 ) ||
 	  ( a == 11 && b == 24 ) ||
 	  ( a == 11 && b == 25 ) ||
 	  ( a == 11 && b == 30 ) ||
 	  ( a == 11 && b == 31 ) ||
 	  ( a == 11 && b == 39 ) ||
 	  ( a == 11 && b == 41 ) ||
 	  ( a == 12 && b == 21 ) ||
 	  ( a == 12 && b == 24 ) ||
 	  ( a == 12 && b == 29 ) ||
 	  ( a == 12 && b == 31 ) ||
 	  ( a == 12 && b == 33 ) ||
 	  ( a == 12 && b == 36 ) ||
 	  ( a == 13 && b == 20 ) ||
 	  ( a == 13 && b == 22 ) ||
 	  ( a == 13 && b == 29 ) ||
 	  ( a == 13 && b == 31 ) ||
 	  ( a == 13 && b == 39 ) ||
 	  ( a == 13 && b == 42 ) ||
 	  ( a == 14 && b == 23 ) ||
 	  ( a == 14 && b == 25 ) ||
 	  ( a == 14 && b == 27 ) ||
 	  ( a == 14 && b == 30 ) ||
 	  ( a == 14 && b == 35 ) ||
 	  ( a == 14 && b == 37 ) ||
 	  ( a == 15 && b == 20 ) ||
 	  ( a == 15 && b == 22 ) ||
 	  ( a == 15 && b == 35 ) ||
 	  ( a == 15 && b == 37 ) ||
 	  ( a == 15 && b == 38 ) ||
 	  ( a == 15 && b == 40 ) ||
 	  ( a == 16 && b == 23 ) ||
 	  ( a == 16 && b == 25 ) ||
 	  ( a == 16 && b == 26 ) ||
 	  ( a == 16 && b == 28 ) ||
 	  ( a == 16 && b == 41 ) ||
 	  ( a == 16 && b == 43 ) ||
 	  ( a == 17 && b == 21 ) ||
 	  ( a == 17 && b == 24 ) ||
 	  ( a == 17 && b == 32 ) ||
 	  ( a == 17 && b == 34 ) ||
 	  ( a == 17 && b == 41 ) ||
 	  ( a == 17 && b == 43 ) ||
 	  ( a == 18 && b == 26 ) ||
 	  ( a == 18 && b == 28 ) ||
 	  ( a == 18 && b == 33 ) ||
 	  ( a == 18 && b == 36 ) ||
 	  ( a == 18 && b == 38 ) ||
 	  ( a == 18 && b == 40 ) ||
 	  ( a == 19 && b == 27 ) ||
 	  ( a == 19 && b == 30 ) ||
 	  ( a == 19 && b == 32 ) ||
 	  ( a == 19 && b == 34 ) ||
 	  ( a == 19 && b == 39 ) ||
 	  ( a == 19 && b == 42 )  )
 	return -(2 - 3*Nc2 + Nc4)/(32.*Nc2);
       if( ( a == 0 && b == 26 ) ||
 	  ( a == 0 && b == 27 ) ||
 	  ( a == 0 && b == 29 ) ||
 	  ( a == 0 && b == 31 ) ||
 	  ( a == 0 && b == 37 ) ||
 	  ( a == 0 && b == 43 ) ||
 	  ( a == 1 && b == 31 ) ||
 	  ( a == 1 && b == 32 ) ||
 	  ( a == 1 && b == 33 ) ||
 	  ( a == 1 && b == 35 ) ||
 	  ( a == 1 && b == 37 ) ||
 	  ( a == 1 && b == 41 ) ||
 	  ( a == 2 && b == 29 ) ||
 	  ( a == 2 && b == 35 ) ||
 	  ( a == 2 && b == 38 ) ||
 	  ( a == 2 && b == 39 ) ||
 	  ( a == 2 && b == 41 ) ||
 	  ( a == 2 && b == 43 ) ||
 	  ( a == 3 && b == 20 ) ||
 	  ( a == 3 && b == 21 ) ||
 	  ( a == 3 && b == 23 ) ||
 	  ( a == 3 && b == 25 ) ||
 	  ( a == 3 && b == 36 ) ||
 	  ( a == 3 && b == 42 ) ||
 	  ( a == 4 && b == 25 ) ||
 	  ( a == 4 && b == 33 ) ||
 	  ( a == 4 && b == 34 ) ||
 	  ( a == 4 && b == 35 ) ||
 	  ( a == 4 && b == 36 ) ||
 	  ( a == 4 && b == 39 ) ||
 	  ( a == 5 && b == 23 ) ||
 	  ( a == 5 && b == 33 ) ||
 	  ( a == 5 && b == 39 ) ||
 	  ( a == 5 && b == 40 ) ||
 	  ( a == 5 && b == 41 ) ||
 	  ( a == 5 && b == 42 ) ||
 	  ( a == 6 && b == 21 ) ||
 	  ( a == 6 && b == 22 ) ||
 	  ( a == 6 && b == 23 ) ||
 	  ( a == 6 && b == 24 ) ||
 	  ( a == 6 && b == 30 ) ||
 	  ( a == 6 && b == 40 ) ||
 	  ( a == 7 && b == 24 ) ||
 	  ( a == 7 && b == 27 ) ||
 	  ( a == 7 && b == 28 ) ||
 	  ( a == 7 && b == 29 ) ||
 	  ( a == 7 && b == 30 ) ||
 	  ( a == 7 && b == 38 ) ||
 	  ( a == 8 && b == 21 ) ||
 	  ( a == 8 && b == 27 ) ||
 	  ( a == 8 && b == 38 ) ||
 	  ( a == 8 && b == 40 ) ||
 	  ( a == 8 && b == 42 ) ||
 	  ( a == 8 && b == 43 ) ||
 	  ( a == 9 && b == 20 ) ||
 	  ( a == 9 && b == 22 ) ||
 	  ( a == 9 && b == 24 ) ||
 	  ( a == 9 && b == 25 ) ||
 	  ( a == 9 && b == 28 ) ||
 	  ( a == 9 && b == 34 ) ||
 	  ( a == 10 && b == 22 ) ||
 	  ( a == 10 && b == 26 ) ||
 	  ( a == 10 && b == 28 ) ||
 	  ( a == 10 && b == 30 ) ||
 	  ( a == 10 && b == 31 ) ||
 	  ( a == 10 && b == 32 ) ||
 	  ( a == 11 && b == 20 ) ||
 	  ( a == 11 && b == 26 ) ||
 	  ( a == 11 && b == 32 ) ||
 	  ( a == 11 && b == 34 ) ||
 	  ( a == 11 && b == 36 ) ||
 	  ( a == 11 && b == 37 ) ||
 	  ( a == 12 && b == 22 ) ||
 	  ( a == 12 && b == 26 ) ||
 	  ( a == 12 && b == 34 ) ||
 	  ( a == 12 && b == 39 ) ||
 	  ( a == 12 && b == 40 ) ||
 	  ( a == 12 && b == 43 ) ||
 	  ( a == 13 && b == 24 ) ||
 	  ( a == 13 && b == 27 ) ||
 	  ( a == 13 && b == 33 ) ||
 	  ( a == 13 && b == 34 ) ||
 	  ( a == 13 && b == 37 ) ||
 	  ( a == 13 && b == 40 ) ||
 	  ( a == 14 && b == 20 ) ||
 	  ( a == 14 && b == 28 ) ||
 	  ( a == 14 && b == 32 ) ||
 	  ( a == 14 && b == 38 ) ||
 	  ( a == 14 && b == 41 ) ||
 	  ( a == 14 && b == 42 ) ||
 	  ( a == 15 && b == 25 ) ||
 	  ( a == 15 && b == 27 ) ||
 	  ( a == 15 && b == 28 ) ||
 	  ( a == 15 && b == 31 ) ||
 	  ( a == 15 && b == 33 ) ||
 	  ( a == 15 && b == 42 ) ||
 	  ( a == 16 && b == 21 ) ||
 	  ( a == 16 && b == 30 ) ||
 	  ( a == 16 && b == 32 ) ||
 	  ( a == 16 && b == 35 ) ||
 	  ( a == 16 && b == 36 ) ||
 	  ( a == 16 && b == 38 ) ||
 	  ( a == 17 && b == 23 ) ||
 	  ( a == 17 && b == 26 ) ||
 	  ( a == 17 && b == 29 ) ||
 	  ( a == 17 && b == 30 ) ||
 	  ( a == 17 && b == 36 ) ||
 	  ( a == 17 && b == 39 ) ||
 	  ( a == 18 && b == 21 ) ||
 	  ( a == 18 && b == 22 ) ||
 	  ( a == 18 && b == 25 ) ||
 	  ( a == 18 && b == 31 ) ||
 	  ( a == 18 && b == 35 ) ||
 	  ( a == 18 && b == 43 ) ||
 	  ( a == 19 && b == 20 ) ||
 	  ( a == 19 && b == 23 ) ||
 	  ( a == 19 && b == 24 ) ||
 	  ( a == 19 && b == 29 ) ||
 	  ( a == 19 && b == 37 ) ||
 	  ( a == 19 && b == 41 )  )
 	return -sqr(-1 + Nc2)/(16.*Nc2);
       if( ( a == 0 && b == 28 ) ||
 	  ( a == 0 && b == 30 ) ||
 	  ( a == 0 && b == 34 ) ||
 	  ( a == 0 && b == 35 ) ||
 	  ( a == 0 && b == 40 ) ||
 	  ( a == 0 && b == 41 ) ||
 	  ( a == 1 && b == 28 ) ||
 	  ( a == 1 && b == 29 ) ||
 	  ( a == 1 && b == 34 ) ||
 	  ( a == 1 && b == 36 ) ||
 	  ( a == 1 && b == 42 ) ||
 	  ( a == 1 && b == 43 ) ||
 	  ( a == 2 && b == 30 ) ||
 	  ( a == 2 && b == 31 ) ||
 	  ( a == 2 && b == 36 ) ||
 	  ( a == 2 && b == 37 ) ||
 	  ( a == 2 && b == 40 ) ||
 	  ( a == 2 && b == 42 ) ||
 	  ( a == 3 && b == 22 ) ||
 	  ( a == 3 && b == 24 ) ||
 	  ( a == 3 && b == 32 ) ||
 	  ( a == 3 && b == 33 ) ||
 	  ( a == 3 && b == 38 ) ||
 	  ( a == 3 && b == 39 ) ||
 	  ( a == 4 && b == 22 ) ||
 	  ( a == 4 && b == 23 ) ||
 	  ( a == 4 && b == 32 ) ||
 	  ( a == 4 && b == 37 ) ||
 	  ( a == 4 && b == 42 ) ||
 	  ( a == 4 && b == 43 ) ||
 	  ( a == 5 && b == 24 ) ||
 	  ( a == 5 && b == 25 ) ||
 	  ( a == 5 && b == 36 ) ||
 	  ( a == 5 && b == 37 ) ||
 	  ( a == 5 && b == 38 ) ||
 	  ( a == 5 && b == 43 ) ||
 	  ( a == 6 && b == 20 ) ||
 	  ( a == 6 && b == 25 ) ||
 	  ( a == 6 && b == 26 ) ||
 	  ( a == 6 && b == 27 ) ||
 	  ( a == 6 && b == 38 ) ||
 	  ( a == 6 && b == 39 ) ||
 	  ( a == 7 && b == 20 ) ||
 	  ( a == 7 && b == 21 ) ||
 	  ( a == 7 && b == 26 ) ||
 	  ( a == 7 && b == 31 ) ||
 	  ( a == 7 && b == 40 ) ||
 	  ( a == 7 && b == 41 ) ||
 	  ( a == 8 && b == 24 ) ||
 	  ( a == 8 && b == 25 ) ||
 	  ( a == 8 && b == 30 ) ||
 	  ( a == 8 && b == 31 ) ||
 	  ( a == 8 && b == 39 ) ||
 	  ( a == 8 && b == 41 ) ||
 	  ( a == 9 && b == 21 ) ||
 	  ( a == 9 && b == 23 ) ||
 	  ( a == 9 && b == 26 ) ||
 	  ( a == 9 && b == 27 ) ||
 	  ( a == 9 && b == 32 ) ||
 	  ( a == 9 && b == 33 ) ||
 	  ( a == 10 && b == 20 ) ||
 	  ( a == 10 && b == 21 ) ||
 	  ( a == 10 && b == 27 ) ||
 	  ( a == 10 && b == 29 ) ||
 	  ( a == 10 && b == 34 ) ||
 	  ( a == 10 && b == 35 ) ||
 	  ( a == 11 && b == 22 ) ||
 	  ( a == 11 && b == 23 ) ||
 	  ( a == 11 && b == 28 ) ||
 	  ( a == 11 && b == 29 ) ||
 	  ( a == 11 && b == 33 ) ||
 	  ( a == 11 && b == 35 ) ||
 	  ( a == 12 && b == 23 ) ||
 	  ( a == 12 && b == 25 ) ||
 	  ( a == 12 && b == 27 ) ||
 	  ( a == 12 && b == 30 ) ||
 	  ( a == 12 && b == 35 ) ||
 	  ( a == 12 && b == 37 ) ||
 	  ( a == 13 && b == 23 ) ||
 	  ( a == 13 && b == 25 ) ||
 	  ( a == 13 && b == 26 ) ||
 	  ( a == 13 && b == 28 ) ||
 	  ( a == 13 && b == 41 ) ||
 	  ( a == 13 && b == 43 ) ||
 	  ( a == 14 && b == 21 ) ||
 	  ( a == 14 && b == 24 ) ||
 	  ( a == 14 && b == 29 ) ||
 	  ( a == 14 && b == 31 ) ||
 	  ( a == 14 && b == 33 ) ||
 	  ( a == 14 && b == 36 ) ||
 	  ( a == 15 && b == 21 ) ||
 	  ( a == 15 && b == 24 ) ||
 	  ( a == 15 && b == 32 ) ||
 	  ( a == 15 && b == 34 ) ||
 	  ( a == 15 && b == 41 ) ||
 	  ( a == 15 && b == 43 ) ||
 	  ( a == 16 && b == 20 ) ||
 	  ( a == 16 && b == 22 ) ||
 	  ( a == 16 && b == 29 ) ||
 	  ( a == 16 && b == 31 ) ||
 	  ( a == 16 && b == 39 ) ||
 	  ( a == 16 && b == 42 ) ||
 	  ( a == 17 && b == 20 ) ||
 	  ( a == 17 && b == 22 ) ||
 	  ( a == 17 && b == 35 ) ||
 	  ( a == 17 && b == 37 ) ||
 	  ( a == 17 && b == 38 ) ||
 	  ( a == 17 && b == 40 ) ||
 	  ( a == 18 && b == 27 ) ||
 	  ( a == 18 && b == 30 ) ||
 	  ( a == 18 && b == 32 ) ||
 	  ( a == 18 && b == 34 ) ||
 	  ( a == 18 && b == 39 ) ||
 	  ( a == 18 && b == 42 ) ||
 	  ( a == 19 && b == 26 ) ||
 	  ( a == 19 && b == 28 ) ||
 	  ( a == 19 && b == 33 ) ||
 	  ( a == 19 && b == 36 ) ||
 	  ( a == 19 && b == 38 ) ||
 	  ( a == 19 && b == 40 )  )
 	return (1 - 1/Nc2)/16.;
       if( ( a == 20 && b == 20 ) ||
 	  ( a == 21 && b == 21 ) ||
 	  ( a == 22 && b == 22 ) ||
 	  ( a == 23 && b == 23 ) ||
 	  ( a == 24 && b == 24 ) ||
 	  ( a == 25 && b == 25 ) ||
 	  ( a == 26 && b == 26 ) ||
 	  ( a == 27 && b == 27 ) ||
 	  ( a == 28 && b == 28 ) ||
 	  ( a == 29 && b == 29 ) ||
 	  ( a == 30 && b == 30 ) ||
 	  ( a == 31 && b == 31 ) ||
 	  ( a == 32 && b == 32 ) ||
 	  ( a == 33 && b == 33 ) ||
 	  ( a == 34 && b == 34 ) ||
 	  ( a == 35 && b == 35 ) ||
 	  ( a == 36 && b == 36 ) ||
 	  ( a == 37 && b == 37 ) ||
 	  ( a == 38 && b == 38 ) ||
 	  ( a == 39 && b == 39 ) ||
 	  ( a == 40 && b == 40 ) ||
 	  ( a == 41 && b == 41 ) ||
 	  ( a == 42 && b == 42 ) ||
 	  ( a == 43 && b == 43 )  )
 	return (4 - 10*Nc2 + 10*Nc4 - 5*Nc6 + Nc8)/(32.*Nc3);
       if( ( a == 20 && b == 21 ) ||
 	  ( a == 20 && b == 22 ) ||
 	  ( a == 20 && b == 26 ) ||
 	  ( a == 20 && b == 29 ) ||
 	  ( a == 20 && b == 38 ) ||
 	  ( a == 21 && b == 24 ) ||
 	  ( a == 21 && b == 27 ) ||
 	  ( a == 21 && b == 31 ) ||
 	  ( a == 21 && b == 32 ) ||
 	  ( a == 22 && b == 23 ) ||
 	  ( a == 22 && b == 32 ) ||
 	  ( a == 22 && b == 35 ) ||
 	  ( a == 22 && b == 39 ) ||
 	  ( a == 23 && b == 25 ) ||
 	  ( a == 23 && b == 26 ) ||
 	  ( a == 23 && b == 33 ) ||
 	  ( a == 23 && b == 37 ) ||
 	  ( a == 24 && b == 25 ) ||
 	  ( a == 24 && b == 33 ) ||
 	  ( a == 24 && b == 38 ) ||
 	  ( a == 24 && b == 41 ) ||
 	  ( a == 25 && b == 27 ) ||
 	  ( a == 25 && b == 39 ) ||
 	  ( a == 25 && b == 43 ) ||
 	  ( a == 26 && b == 27 ) ||
 	  ( a == 26 && b == 28 ) ||
 	  ( a == 26 && b == 40 ) ||
 	  ( a == 27 && b == 30 ) ||
 	  ( a == 27 && b == 34 ) ||
 	  ( a == 28 && b == 29 ) ||
 	  ( a == 28 && b == 33 ) ||
 	  ( a == 28 && b == 34 ) ||
 	  ( a == 28 && b == 41 ) ||
 	  ( a == 29 && b == 31 ) ||
 	  ( a == 29 && b == 35 ) ||
 	  ( a == 29 && b == 36 ) ||
 	  ( a == 30 && b == 31 ) ||
 	  ( a == 30 && b == 35 ) ||
 	  ( a == 30 && b == 39 ) ||
 	  ( a == 30 && b == 40 ) ||
 	  ( a == 31 && b == 41 ) ||
 	  ( a == 31 && b == 42 ) ||
 	  ( a == 32 && b == 33 ) ||
 	  ( a == 32 && b == 34 ) ||
 	  ( a == 32 && b == 42 ) ||
 	  ( a == 33 && b == 36 ) ||
 	  ( a == 34 && b == 35 ) ||
 	  ( a == 34 && b == 43 ) ||
 	  ( a == 35 && b == 37 ) ||
 	  ( a == 36 && b == 37 ) ||
 	  ( a == 36 && b == 38 ) ||
 	  ( a == 36 && b == 42 ) ||
 	  ( a == 37 && b == 40 ) ||
 	  ( a == 37 && b == 43 ) ||
 	  ( a == 38 && b == 39 ) ||
 	  ( a == 38 && b == 40 ) ||
 	  ( a == 39 && b == 42 ) ||
 	  ( a == 40 && b == 41 ) ||
 	  ( a == 41 && b == 43 ) ||
 	  ( a == 42 && b == 43 )  )
 	return -(-4 + 7*Nc2 - 4*Nc4 + Nc6)/(32.*Nc3);
       if( ( a == 20 && b == 23 ) ||
 	  ( a == 20 && b == 24 ) ||
 	  ( a == 20 && b == 28 ) ||
 	  ( a == 20 && b == 32 ) ||
 	  ( a == 20 && b == 36 ) ||
 	  ( a == 21 && b == 22 ) ||
 	  ( a == 21 && b == 25 ) ||
 	  ( a == 21 && b == 30 ) ||
 	  ( a == 21 && b == 38 ) ||
 	  ( a == 21 && b == 42 ) ||
 	  ( a == 22 && b == 25 ) ||
 	  ( a == 22 && b == 26 ) ||
 	  ( a == 22 && b == 30 ) ||
 	  ( a == 22 && b == 34 ) ||
 	  ( a == 23 && b == 24 ) ||
 	  ( a == 23 && b == 36 ) ||
 	  ( a == 23 && b == 39 ) ||
 	  ( a == 23 && b == 40 ) ||
 	  ( a == 24 && b == 27 ) ||
 	  ( a == 24 && b == 28 ) ||
 	  ( a == 24 && b == 40 ) ||
 	  ( a == 25 && b == 33 ) ||
 	  ( a == 25 && b == 34 ) ||
 	  ( a == 25 && b == 42 ) ||
 	  ( a == 26 && b == 29 ) ||
 	  ( a == 26 && b == 30 ) ||
 	  ( a == 26 && b == 34 ) ||
 	  ( a == 26 && b == 37 ) ||
 	  ( a == 27 && b == 28 ) ||
 	  ( a == 27 && b == 31 ) ||
 	  ( a == 27 && b == 40 ) ||
 	  ( a == 27 && b == 43 ) ||
 	  ( a == 28 && b == 31 ) ||
 	  ( a == 28 && b == 32 ) ||
 	  ( a == 29 && b == 30 ) ||
 	  ( a == 29 && b == 37 ) ||
 	  ( a == 29 && b == 38 ) ||
 	  ( a == 29 && b == 41 ) ||
 	  ( a == 30 && b == 38 ) ||
 	  ( a == 31 && b == 32 ) ||
 	  ( a == 31 && b == 35 ) ||
 	  ( a == 31 && b == 43 ) ||
 	  ( a == 32 && b == 35 ) ||
 	  ( a == 32 && b == 36 ) ||
 	  ( a == 33 && b == 34 ) ||
 	  ( a == 33 && b == 37 ) ||
 	  ( a == 33 && b == 41 ) ||
 	  ( a == 33 && b == 42 ) ||
 	  ( a == 34 && b == 37 ) ||
 	  ( a == 35 && b == 36 ) ||
 	  ( a == 35 && b == 39 ) ||
 	  ( a == 35 && b == 43 ) ||
 	  ( a == 36 && b == 39 ) ||
 	  ( a == 37 && b == 41 ) ||
 	  ( a == 38 && b == 41 ) ||
 	  ( a == 38 && b == 42 ) ||
 	  ( a == 39 && b == 40 ) ||
 	  ( a == 39 && b == 43 ) ||
 	  ( a == 40 && b == 43 ) ||
 	  ( a == 41 && b == 42 )  )
 	return (2 - 3*Nc2 + Nc4)/(16.*Nc3);
       if( ( a == 20 && b == 25 ) ||
 	  ( a == 20 && b == 34 ) ||
 	  ( a == 20 && b == 37 ) ||
 	  ( a == 20 && b == 41 ) ||
 	  ( a == 20 && b == 42 ) ||
 	  ( a == 21 && b == 23 ) ||
 	  ( a == 21 && b == 35 ) ||
 	  ( a == 21 && b == 36 ) ||
 	  ( a == 21 && b == 40 ) ||
 	  ( a == 21 && b == 43 ) ||
 	  ( a == 22 && b == 24 ) ||
 	  ( a == 22 && b == 28 ) ||
 	  ( a == 22 && b == 31 ) ||
 	  ( a == 22 && b == 40 ) ||
 	  ( a == 22 && b == 43 ) ||
 	  ( a == 23 && b == 29 ) ||
 	  ( a == 23 && b == 30 ) ||
 	  ( a == 23 && b == 41 ) ||
 	  ( a == 23 && b == 42 ) ||
 	  ( a == 24 && b == 29 ) ||
 	  ( a == 24 && b == 30 ) ||
 	  ( a == 24 && b == 34 ) ||
 	  ( a == 24 && b == 37 ) ||
 	  ( a == 25 && b == 28 ) ||
 	  ( a == 25 && b == 31 ) ||
 	  ( a == 25 && b == 35 ) ||
 	  ( a == 25 && b == 36 ) ||
 	  ( a == 26 && b == 31 ) ||
 	  ( a == 26 && b == 32 ) ||
 	  ( a == 26 && b == 36 ) ||
 	  ( a == 26 && b == 39 ) ||
 	  ( a == 26 && b == 43 ) ||
 	  ( a == 27 && b == 29 ) ||
 	  ( a == 27 && b == 33 ) ||
 	  ( a == 27 && b == 37 ) ||
 	  ( a == 27 && b == 38 ) ||
 	  ( a == 27 && b == 42 ) ||
 	  ( a == 28 && b == 30 ) ||
 	  ( a == 28 && b == 38 ) ||
 	  ( a == 28 && b == 42 ) ||
 	  ( a == 29 && b == 39 ) ||
 	  ( a == 29 && b == 43 ) ||
 	  ( a == 30 && b == 32 ) ||
 	  ( a == 30 && b == 36 ) ||
 	  ( a == 31 && b == 33 ) ||
 	  ( a == 31 && b == 37 ) ||
 	  ( a == 32 && b == 37 ) ||
 	  ( a == 32 && b == 38 ) ||
 	  ( a == 32 && b == 41 ) ||
 	  ( a == 33 && b == 35 ) ||
 	  ( a == 33 && b == 39 ) ||
 	  ( a == 33 && b == 40 ) ||
 	  ( a == 34 && b == 36 ) ||
 	  ( a == 34 && b == 39 ) ||
 	  ( a == 34 && b == 40 ) ||
 	  ( a == 35 && b == 38 ) ||
 	  ( a == 35 && b == 41 ) ||
 	  ( a == 38 && b == 43 ) ||
 	  ( a == 39 && b == 41 ) ||
 	  ( a == 40 && b == 42 )  )
 	return (4 - 3*Nc2 - 2*Nc4 + Nc6)/(32.*Nc3);
       if( ( a == 20 && b == 27 ) ||
 	  ( a == 20 && b == 31 ) ||
 	  ( a == 20 && b == 35 ) ||
 	  ( a == 20 && b == 39 ) ||
 	  ( a == 20 && b == 40 ) ||
 	  ( a == 21 && b == 26 ) ||
 	  ( a == 21 && b == 29 ) ||
 	  ( a == 21 && b == 33 ) ||
 	  ( a == 21 && b == 34 ) ||
 	  ( a == 21 && b == 41 ) ||
 	  ( a == 22 && b == 29 ) ||
 	  ( a == 22 && b == 33 ) ||
 	  ( a == 22 && b == 37 ) ||
 	  ( a == 22 && b == 38 ) ||
 	  ( a == 22 && b == 42 ) ||
 	  ( a == 23 && b == 27 ) ||
 	  ( a == 23 && b == 28 ) ||
 	  ( a == 23 && b == 32 ) ||
 	  ( a == 23 && b == 35 ) ||
 	  ( a == 23 && b == 43 ) ||
 	  ( a == 24 && b == 31 ) ||
 	  ( a == 24 && b == 32 ) ||
 	  ( a == 24 && b == 36 ) ||
 	  ( a == 24 && b == 39 ) ||
 	  ( a == 24 && b == 43 ) ||
 	  ( a == 25 && b == 26 ) ||
 	  ( a == 25 && b == 30 ) ||
 	  ( a == 25 && b == 37 ) ||
 	  ( a == 25 && b == 38 ) ||
 	  ( a == 25 && b == 41 ) ||
 	  ( a == 26 && b == 33 ) ||
 	  ( a == 26 && b == 38 ) ||
 	  ( a == 26 && b == 41 ) ||
 	  ( a == 27 && b == 32 ) ||
 	  ( a == 27 && b == 35 ) ||
 	  ( a == 27 && b == 39 ) ||
 	  ( a == 28 && b == 35 ) ||
 	  ( a == 28 && b == 36 ) ||
 	  ( a == 28 && b == 40 ) ||
 	  ( a == 28 && b == 43 ) ||
 	  ( a == 29 && b == 33 ) ||
 	  ( a == 29 && b == 34 ) ||
 	  ( a == 29 && b == 42 ) ||
 	  ( a == 30 && b == 34 ) ||
 	  ( a == 30 && b == 37 ) ||
 	  ( a == 30 && b == 41 ) ||
 	  ( a == 30 && b == 42 ) ||
 	  ( a == 31 && b == 36 ) ||
 	  ( a == 31 && b == 39 ) ||
 	  ( a == 31 && b == 40 ) ||
 	  ( a == 32 && b == 39 ) ||
 	  ( a == 32 && b == 43 ) ||
 	  ( a == 33 && b == 38 ) ||
 	  ( a == 34 && b == 41 ) ||
 	  ( a == 34 && b == 42 ) ||
 	  ( a == 35 && b == 40 ) ||
 	  ( a == 36 && b == 40 ) ||
 	  ( a == 36 && b == 43 ) ||
 	  ( a == 37 && b == 38 ) ||
 	  ( a == 37 && b == 42 )  )
 	return -(-1 + Nc2)/(8.*Nc3);
       if( ( a == 20 && b == 30 ) ||
 	  ( a == 20 && b == 33 ) ||
 	  ( a == 21 && b == 28 ) ||
 	  ( a == 21 && b == 39 ) ||
 	  ( a == 22 && b == 27 ) ||
 	  ( a == 22 && b == 36 ) ||
 	  ( a == 23 && b == 34 ) ||
 	  ( a == 23 && b == 38 ) ||
 	  ( a == 24 && b == 26 ) ||
 	  ( a == 24 && b == 42 ) ||
 	  ( a == 25 && b == 32 ) ||
 	  ( a == 25 && b == 40 ) ||
 	  ( a == 26 && b == 35 ) ||
 	  ( a == 27 && b == 41 ) ||
 	  ( a == 28 && b == 37 ) ||
 	  ( a == 29 && b == 32 ) ||
 	  ( a == 29 && b == 40 ) ||
 	  ( a == 30 && b == 43 ) ||
 	  ( a == 31 && b == 34 ) ||
 	  ( a == 31 && b == 38 ) ||
 	  ( a == 33 && b == 43 ) ||
 	  ( a == 35 && b == 42 ) ||
 	  ( a == 36 && b == 41 ) ||
 	  ( a == 37 && b == 39 )  )
 	return (4 - 5*Nc2 + Nc4)/(32.*Nc3);
       if( ( a == 20 && b == 43 ) ||
 	  ( a == 21 && b == 37 ) ||
 	  ( a == 22 && b == 41 ) ||
 	  ( a == 23 && b == 31 ) ||
 	  ( a == 24 && b == 35 ) ||
 	  ( a == 25 && b == 29 ) ||
 	  ( a == 26 && b == 42 ) ||
 	  ( a == 27 && b == 36 ) ||
 	  ( a == 28 && b == 39 ) ||
 	  ( a == 30 && b == 33 ) ||
 	  ( a == 32 && b == 40 ) ||
 	  ( a == 34 && b == 38 )  )
 	return -(-1 + Nc4)/(8.*Nc3);
     }
 
     if ( basis == id33bar888 ) {
       if( ( a == 0 && b == 0 ) ||
 	  ( a == 1 && b == 1 )  )
 	return (2 - 3*Nc2 + Nc4)/8.;
       if( a == 0 && b == 1  )
 	return (1 - Nc2)/4.;
       if( ( a == 0 && b == 2 ) ||
 	  ( a == 0 && b == 3 ) ||
 	  ( a == 0 && b == 4 ) ||
 	  ( a == 1 && b == 2 ) ||
 	  ( a == 1 && b == 3 ) ||
 	  ( a == 1 && b == 4 )  )
 	return 0;
       if( ( a == 0 && b == 5 ) ||
 	  ( a == 0 && b == 8 ) ||
 	  ( a == 0 && b == 9 ) ||
 	  ( a == 1 && b == 6 ) ||
 	  ( a == 1 && b == 7 ) ||
 	  ( a == 1 && b == 10 )  )
 	return (2 - 3*Nc2 + Nc4)/(8.*Nc);
       if( ( a == 0 && b == 6 ) ||
 	  ( a == 0 && b == 7 ) ||
 	  ( a == 0 && b == 10 ) ||
 	  ( a == 1 && b == 5 ) ||
 	  ( a == 1 && b == 8 ) ||
 	  ( a == 1 && b == 9 )  )
 	return -(-1 + Nc2)/(4.*Nc);
       if( ( a == 2 && b == 2 ) ||
 	  ( a == 3 && b == 3 ) ||
 	  ( a == 4 && b == 4 )  )
 	return sqr(-1 + Nc2)/8.;
       if( ( a == 2 && b == 3 ) ||
 	  ( a == 2 && b == 4 ) ||
 	  ( a == 3 && b == 4 )  )
 	return (-1 + Nc2)/8.;
       if( ( a == 2 && b == 5 ) ||
 	  ( a == 2 && b == 6 ) ||
 	  ( a == 2 && b == 8 ) ||
 	  ( a == 2 && b == 10 ) ||
 	  ( a == 3 && b == 6 ) ||
 	  ( a == 3 && b == 7 ) ||
 	  ( a == 3 && b == 8 ) ||
 	  ( a == 3 && b == 9 ) ||
 	  ( a == 4 && b == 5 ) ||
 	  ( a == 4 && b == 7 ) ||
 	  ( a == 4 && b == 9 ) ||
 	  ( a == 4 && b == 10 )  )
 	return sqr(-1 + Nc2)/(8.*Nc);
       if( ( a == 2 && b == 7 ) ||
 	  ( a == 2 && b == 9 ) ||
 	  ( a == 3 && b == 5 ) ||
 	  ( a == 3 && b == 10 ) ||
 	  ( a == 4 && b == 6 ) ||
 	  ( a == 4 && b == 8 )  )
 	return -(-1 + Nc2)/(8.*Nc);
       if( ( a == 5 && b == 5 ) ||
 	  ( a == 6 && b == 6 ) ||
 	  ( a == 7 && b == 7 ) ||
 	  ( a == 8 && b == 8 ) ||
 	  ( a == 9 && b == 9 ) ||
 	  ( a == 10 && b == 10 )  )
 	return pow(-1 + Nc2,3.)/(8.*Nc2);
       if( ( a == 5 && b == 6 ) ||
 	  ( a == 5 && b == 7 ) ||
 	  ( a == 6 && b == 9 ) ||
 	  ( a == 7 && b == 8 ) ||
 	  ( a == 8 && b == 10 ) ||
 	  ( a == 9 && b == 10 )  )
 	return -sqr(-1 + Nc2)/(8.*Nc2);
       if( ( a == 5 && b == 8 ) ||
 	  ( a == 5 && b == 9 ) ||
 	  ( a == 6 && b == 7 ) ||
 	  ( a == 6 && b == 10 ) ||
 	  ( a == 7 && b == 10 ) ||
 	  ( a == 8 && b == 9 )  )
 	return 0.125 - 1/(8.*Nc2);
       if( ( a == 5 && b == 10 ) ||
 	  ( a == 6 && b == 8 ) ||
 	  ( a == 7 && b == 9 )  )
 	return (-1 + Nc4)/(8.*Nc2);
     }
 
     if ( basis == id33bar33bar8 ) {
       if( ( a == 0 && b == 0 ) ||
 	  ( a == 1 && b == 1 ) ||
 	  ( a == 2 && b == 2 ) ||
 	  ( a == 3 && b == 3 )  )
 	return (Nc*(-1 + Nc2))/2.;
       if( ( a == 0 && b == 1 ) ||
 	  ( a == 0 && b == 3 ) ||
 	  ( a == 1 && b == 2 ) ||
 	  ( a == 2 && b == 3 )  )
 	return (-1 + Nc2)/2.;
       if( ( a == 0 && b == 2 ) ||
 	  ( a == 1 && b == 3 )  )
 	return 0;
     }
 
   } else {
 
     if ( a != b )
       return 0.;
 
     if ( basis == id88 ) {
       return Nc2/4.;
     }
 
     if ( basis == id33bar ) {
       return Nc;
     }
 
     if ( basis == id888 ) {
       return Nc3/8.;
     }
 
     if ( basis == id33bar8 ) {
       return Nc2/2.;
     }
 
     if ( basis == id8888 ) {
       return Nc4/16.;
     }
 
     if ( basis == id33bar88 ) {
       return Nc3/4.;
     }
 
     if ( basis == id33bar33bar ) {
       return Nc2;
     }
 
     if ( basis == id88888 ) {
       return Nc5/32.;
     }
 
     if ( basis == id33bar888 ) {
       return Nc4/8.;
     }
 
     if ( basis == id33bar33bar8 ) {
       return Nc3/2.;
     }
 
   }
 
   throw Exception() << "SimpleColourBasis2::scalarProduct(): Cannot handle colour configuration" << Exception::runerror;
 
 }
 
 double SimpleColourBasis2::tMatrixElement(size_t i, size_t a, 
 					 size_t b,
 					 const vector<PDT::Colour>&,
-					 const vector<PDT::Colour>& basis) const {
+					 const vector<PDT::Colour>& basis,
+					 size_t k, size_t l,
+					 const map<size_t,size_t>& dict) const {
+  // Check indices k and l
+  assert( k == i );
+  assert( l == basis.size() );
+  // Check that dict is the standardMap
+  assert( dict.size()+1 == basis.size() );
+  map<size_t,size_t>::const_iterator tmp;
+  for ( size_t ii = 0; ii < basis.size(); ii++ )
+    if ( ii != i ) {
+      tmp = dict.find(ii);
+      assert( tmp != dict.end() ); 
+      assert( tmp->second == ii );
+    }
 
   if ( id33bar.empty() )
     makeIds();
 
   if ( basis == id88 ) {
     if(i == 0 && a == 0 && b == 0) return -1;
     if(i == 0 && a == 1 && b == 0) return 1;
     if(i == 1 && a == 0 && b == 0) return 1;
     if(i == 1 && a == 1 && b == 0) return -1;
     return 0.;
   }
 
   if ( basis == id33bar ) {
     if(i == 0 && a == 0 && b == 0) return 1;
     if(i == 1 && a == 0 && b == 0) return -1;
     return 0.;
   }
 
   if ( basis == id888 ) {
     if(i == 0 && a == 3 && b == 0) return -1;
     if(i == 0 && a == 5 && b == 1) return -1;
     if(i == 0 && a == 7 && b == 0) return 1;
     if(i == 0 && a == 8 && b == 1) return 1;
     if(i == 1 && a == 4 && b == 0) return 1;
     if(i == 1 && a == 5 && b == 1) return 1;
     if(i == 1 && a == 6 && b == 1) return -1;
     if(i == 1 && a == 7 && b == 0) return -1;
     if(i == 2 && a == 3 && b == 0) return 1;
     if(i == 2 && a == 4 && b == 0) return -1;
     if(i == 2 && a == 6 && b == 1) return 1;
     if(i == 2 && a == 8 && b == 1) return -1;
     return 0.;
   }
 
   if ( basis == id33bar8 ) {
     if(i == 0 && a == 2 && b == 0) return 1;
     if(i == 1 && a == 1 && b == 0) return -1;
     if(i == 2 && a == 1 && b == 0) return 1;
     if(i == 2 && a == 2 && b == 0) return -1;
     return 0.;
   }
 
   if ( basis == id8888 ) {
     if(i == 0 && a == 2 && b == 2) return -1;
     if(i == 0 && a == 5 && b == 1) return -1;
     if(i == 0 && a == 8 && b == 0) return -1;
     if(i == 0 && a == 9 && b == 2) return 1;
     if(i == 0 && a == 10 && b == 1) return 1;
     if(i == 0 && a == 11 && b == 0) return 1;
     if(i == 0 && a == 20 && b == 3) return -1;
     if(i == 0 && a == 22 && b == 4) return -1;
     if(i == 0 && a == 26 && b == 5) return -1;
     if(i == 0 && a == 28 && b == 6) return -1;
     if(i == 0 && a == 32 && b == 7) return -1;
     if(i == 0 && a == 34 && b == 8) return -1;
     if(i == 0 && a == 38 && b == 3) return 1;
     if(i == 0 && a == 39 && b == 4) return 1;
     if(i == 0 && a == 40 && b == 5) return 1;
     if(i == 0 && a == 41 && b == 6) return 1;
     if(i == 0 && a == 42 && b == 7) return 1;
     if(i == 0 && a == 43 && b == 8) return 1;
     if(i == 1 && a == 2 && b == 2) return 1;
     if(i == 1 && a == 9 && b == 2) return -1;
     if(i == 1 && a == 13 && b == 0) return -1;
     if(i == 1 && a == 15 && b == 1) return -1;
     if(i == 1 && a == 16 && b == 0) return 1;
     if(i == 1 && a == 17 && b == 1) return 1;
     if(i == 1 && a == 24 && b == 3) return 1;
     if(i == 1 && a == 25 && b == 4) return 1;
     if(i == 1 && a == 27 && b == 5) return 1;
     if(i == 1 && a == 28 && b == 6) return 1;
     if(i == 1 && a == 29 && b == 6) return -1;
     if(i == 1 && a == 30 && b == 5) return -1;
     if(i == 1 && a == 33 && b == 7) return 1;
     if(i == 1 && a == 34 && b == 8) return 1;
     if(i == 1 && a == 35 && b == 8) return -1;
     if(i == 1 && a == 36 && b == 7) return -1;
     if(i == 1 && a == 38 && b == 3) return -1;
     if(i == 1 && a == 39 && b == 4) return -1;
     if(i == 2 && a == 5 && b == 1) return 1;
     if(i == 2 && a == 10 && b == 1) return -1;
     if(i == 2 && a == 13 && b == 0) return 1;
     if(i == 2 && a == 16 && b == 0) return -1;
     if(i == 2 && a == 18 && b == 2) return -1;
     if(i == 2 && a == 19 && b == 2) return 1;
     if(i == 2 && a == 21 && b == 3) return 1;
     if(i == 2 && a == 22 && b == 4) return 1;
     if(i == 2 && a == 23 && b == 4) return -1;
     if(i == 2 && a == 24 && b == 3) return -1;
     if(i == 2 && a == 30 && b == 5) return 1;
     if(i == 2 && a == 31 && b == 6) return 1;
     if(i == 2 && a == 32 && b == 7) return 1;
     if(i == 2 && a == 33 && b == 7) return -1;
     if(i == 2 && a == 35 && b == 8) return 1;
     if(i == 2 && a == 37 && b == 8) return -1;
     if(i == 2 && a == 40 && b == 5) return -1;
     if(i == 2 && a == 41 && b == 6) return -1;
     if(i == 3 && a == 8 && b == 0) return 1;
     if(i == 3 && a == 11 && b == 0) return -1;
     if(i == 3 && a == 15 && b == 1) return 1;
     if(i == 3 && a == 17 && b == 1) return -1;
     if(i == 3 && a == 18 && b == 2) return 1;
     if(i == 3 && a == 19 && b == 2) return -1;
     if(i == 3 && a == 20 && b == 3) return 1;
     if(i == 3 && a == 21 && b == 3) return -1;
     if(i == 3 && a == 23 && b == 4) return 1;
     if(i == 3 && a == 25 && b == 4) return -1;
     if(i == 3 && a == 26 && b == 5) return 1;
     if(i == 3 && a == 27 && b == 5) return -1;
     if(i == 3 && a == 29 && b == 6) return 1;
     if(i == 3 && a == 31 && b == 6) return -1;
     if(i == 3 && a == 36 && b == 7) return 1;
     if(i == 3 && a == 37 && b == 8) return 1;
     if(i == 3 && a == 42 && b == 7) return -1;
     if(i == 3 && a == 43 && b == 8) return -1;
     return 0.;
   }
 
   if ( basis == id33bar88 ) {
     if(i == 0 && a == 4 && b == 0) return 1;
     if(i == 0 && a == 9 && b == 1) return 1;
     if(i == 0 && a == 10 && b == 2) return 1;
     if(i == 1 && a == 4 && b == 0) return -1;
     if(i == 1 && a == 5 && b == 1) return -1;
     if(i == 1 && a == 7 && b == 2) return -1;
     if(i == 2 && a == 0 && b == 0) return -1;
     if(i == 2 && a == 1 && b == 0) return 1;
     if(i == 2 && a == 6 && b == 1) return 1;
     if(i == 2 && a == 7 && b == 2) return 1;
     if(i == 2 && a == 8 && b == 2) return -1;
     if(i == 2 && a == 9 && b == 1) return -1;
     if(i == 3 && a == 0 && b == 0) return 1;
     if(i == 3 && a == 1 && b == 0) return -1;
     if(i == 3 && a == 5 && b == 1) return 1;
     if(i == 3 && a == 6 && b == 1) return -1;
     if(i == 3 && a == 8 && b == 2) return 1;
     if(i == 3 && a == 10 && b == 2) return -1;
     return 0.;
   }
 
   if ( basis == id33bar33bar ) {
     if(i == 0 && a == 0 && b == 0) return 1;
     if(i == 0 && a == 1 && b == 1) return 1;
     if(i == 1 && a == 1 && b == 1) return -1;
     if(i == 1 && a == 2 && b == 0) return -1;
     if(i == 2 && a == 2 && b == 0) return 1;
     if(i == 2 && a == 3 && b == 1) return 1;
     if(i == 3 && a == 0 && b == 0) return -1;
     if(i == 3 && a == 3 && b == 1) return -1;
     return 0.;
   }
 
   throw Exception() << "SimpleColourBasis2::tMatrixElement(): Cannot handle colour configuration" << Exception::runerror;
 
   return 0.;
 
 }
 
 bool SimpleColourBasis2::colourConnected(const cPDVector& sub,
 					const vector<PDT::Colour>& basis,
 					const pair<int,bool>& i, 
 					const pair<int,bool>& j, 
 					size_t a) const {
 
   if ( id33bar.empty() )
     makeIds();
 
   // translate process to basis ids
   map<cPDVector,map<size_t,size_t> >::const_iterator trans
     = indexMap().find(sub);
   assert(trans != indexMap().end());
 
   int idColoured = i.second ? j.first : i.first;
   idColoured = trans->second.find(idColoured)->second;
   int idAntiColoured = i.second ? i.first : j.first;
   idAntiColoured = trans->second.find(idAntiColoured)->second;
 
   if ( basis == id88 ) {
     return
       a == 0 &&
       ((idColoured == 0 && idAntiColoured == 1) ||
        (idColoured == 1 && idAntiColoured == 0));
   }
 
   if ( basis == id33bar ) {
     return
       a == 0 &&
       (idColoured == 0 && idAntiColoured == 1);
   }
 
   if ( basis == id888 ) {
     return
       (a == 0 &&
        ((idColoured == 0 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 0))) ||
       (a == 1 &&
        ((idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 0)));
   }
 
   if ( basis == id33bar8 ) {
     return
       a == 0 &&
       ((idColoured == 0 && idAntiColoured == 2) ||
        (idColoured == 2 && idAntiColoured == 1));
   }
 
   if ( basis == id8888 ) {
     return
       (a == 0 &&
        ((idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 0) ||
 	(idColoured == 1 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 1))) ||
       (a == 1 &&
        ((idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 0) ||
 	(idColoured == 1 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 1))) ||
       (a == 2 &&
        ((idColoured == 0 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 0) ||
 	(idColoured == 2 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 2))) ||
       (a == 3 &&
        ((idColoured == 0 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 0))) ||
       (a == 4 &&
        ((idColoured == 0 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 0))) ||
       (a == 5 &&
        ((idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 0))) ||
       (a == 6 &&
        ((idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 0))) ||
       (a == 7 &&
        ((idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 0))) ||
       (a == 8 &&
        ((idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 0)));
   }
 
   if ( basis == id33bar88 ) {
     return
       (a == 0 &&
        ((idColoured == 2 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 2) ||
 	(idColoured == 0 && idAntiColoured == 1))) ||
       (a == 1 &&
        ((idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 3 && idAntiColoured == 1) ||
 	(idColoured == 2 && idAntiColoured == 3))) ||
       (a == 2 &&
        ((idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 2 && idAntiColoured == 1) ||
 	(idColoured == 3 && idAntiColoured == 2)));
   }
 
   if ( basis == id33bar33bar ) {
     return
       (a == 0 &&
        ((idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 2 && idAntiColoured == 1))) ||
       (a == 1 &&
        ((idColoured == 0 && idAntiColoured == 1) ||
 	(idColoured == 2 && idAntiColoured == 3)));
   }
 
   if ( basis == id88888 ) {
     return
       (a == 0 &&
        ((idColoured == 3 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 3) ||
 	(idColoured == 0 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 0))) ||
       (a == 1 &&
        ((idColoured == 2 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 2) ||
 	(idColoured == 0 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 0))) ||
       (a == 2 &&
        ((idColoured == 2 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 2) ||
 	(idColoured == 0 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 0))) ||
       (a == 3 &&
        ((idColoured == 3 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 3) ||
 	(idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 0))) ||
       (a == 4 &&
        ((idColoured == 1 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 1) ||
 	(idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 0))) ||
       (a == 5 &&
        ((idColoured == 1 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 1) ||
 	(idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 0))) ||
       (a == 6 &&
        ((idColoured == 2 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 2) ||
 	(idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 0))) ||
       (a == 7 &&
        ((idColoured == 1 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 1) ||
 	(idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 0))) ||
       (a == 8 &&
        ((idColoured == 1 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 1) ||
 	(idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 0))) ||
       (a == 9 &&
        ((idColoured == 2 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 2) ||
 	(idColoured == 0 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 0))) ||
       (a == 10 &&
        ((idColoured == 1 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 1) ||
 	(idColoured == 0 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 0))) ||
       (a == 11 &&
        ((idColoured == 1 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 1) ||
 	(idColoured == 0 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 0))) ||
       (a == 12 &&
        ((idColoured == 0 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 0) ||
 	(idColoured == 1 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 1))) ||
       (a == 13 &&
        ((idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 0) ||
 	(idColoured == 1 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 1))) ||
       (a == 14 &&
        ((idColoured == 0 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 0) ||
 	(idColoured == 1 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 1))) ||
       (a == 15 &&
        ((idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 0) ||
 	(idColoured == 1 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 1))) ||
       (a == 16 &&
        ((idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 0) ||
 	(idColoured == 1 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 1))) ||
       (a == 17 &&
        ((idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 0) ||
 	(idColoured == 1 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 1))) ||
       (a == 18 &&
        ((idColoured == 0 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 0) ||
 	(idColoured == 2 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 2))) ||
       (a == 19 &&
        ((idColoured == 0 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 0) ||
 	(idColoured == 2 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 2))) ||
       (a == 20 &&
        ((idColoured == 0 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 0))) ||
       (a == 21 &&
        ((idColoured == 0 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 0))) ||
       (a == 22 &&
        ((idColoured == 0 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 0))) ||
       (a == 23 &&
        ((idColoured == 0 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 0))) ||
       (a == 24 &&
        ((idColoured == 0 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 0))) ||
       (a == 25 &&
        ((idColoured == 0 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 0))) ||
       (a == 26 &&
        ((idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 0))) ||
       (a == 27 &&
        ((idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 0))) ||
       (a == 28 &&
        ((idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 0))) ||
       (a == 29 &&
        ((idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 0))) ||
       (a == 30 &&
        ((idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 0))) ||
       (a == 31 &&
        ((idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 0))) ||
       (a == 32 &&
        ((idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 0))) ||
       (a == 33 &&
        ((idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 0))) ||
       (a == 34 &&
        ((idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 0))) ||
       (a == 35 &&
        ((idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 0))) ||
       (a == 36 &&
        ((idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 0))) ||
       (a == 37 &&
        ((idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 0))) ||
       (a == 38 &&
        ((idColoured == 0 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 0))) ||
       (a == 39 &&
        ((idColoured == 0 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 0))) ||
       (a == 40 &&
        ((idColoured == 0 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 0))) ||
       (a == 41 &&
        ((idColoured == 0 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 0))) ||
       (a == 42 &&
        ((idColoured == 0 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 0))) ||
       (a == 43 &&
        ((idColoured == 0 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 1) ||
 	(idColoured == 1 && idAntiColoured == 0)));
   }
 
   if ( basis == id33bar888 ) {
     return
       (a == 0 &&
        ((idColoured == 2 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 2) ||
 	(idColoured == 0 && idAntiColoured == 1))) ||
       (a == 1 &&
        ((idColoured == 2 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 2) ||
 	(idColoured == 0 && idAntiColoured == 1))) ||
       (a == 2 &&
        ((idColoured == 3 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 3) ||
 	(idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 1))) ||
       (a == 3 &&
        ((idColoured == 2 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 2) ||
 	(idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 1))) ||
       (a == 4 &&
        ((idColoured == 2 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 2) ||
 	(idColoured == 0 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 1))) ||
       (a == 5 &&
        ((idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 4 && idAntiColoured == 1) ||
 	(idColoured == 2 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 4))) ||
       (a == 6 &&
        ((idColoured == 0 && idAntiColoured == 2) ||
 	(idColoured == 3 && idAntiColoured == 1) ||
 	(idColoured == 2 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 3))) ||
       (a == 7 &&
        ((idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 4 && idAntiColoured == 1) ||
 	(idColoured == 3 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 4))) ||
       (a == 8 &&
        ((idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 2 && idAntiColoured == 1) ||
 	(idColoured == 3 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 2))) ||
       (a == 9 &&
        ((idColoured == 0 && idAntiColoured == 4) ||
 	(idColoured == 3 && idAntiColoured == 1) ||
 	(idColoured == 4 && idAntiColoured == 2) ||
 	(idColoured == 2 && idAntiColoured == 3))) ||
       (a == 10 &&
        ((idColoured == 0 && idAntiColoured == 4) ||
 	(idColoured == 2 && idAntiColoured == 1) ||
 	(idColoured == 4 && idAntiColoured == 3) ||
 	(idColoured == 3 && idAntiColoured == 2)));
   }
 
   if ( basis == id33bar33bar8 ) {
     return
       (a == 0 &&
        ((idColoured == 0 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 3) ||
 	(idColoured == 2 && idAntiColoured == 1))) ||
       (a == 1 &&
        ((idColoured == 0 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 1) ||
 	(idColoured == 2 && idAntiColoured == 3))) ||
       (a == 2 &&
        ((idColoured == 0 && idAntiColoured == 3) ||
 	(idColoured == 2 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 1))) ||
       (a == 3 &&
        ((idColoured == 0 && idAntiColoured == 1) ||
 	(idColoured == 2 && idAntiColoured == 4) ||
 	(idColoured == 4 && idAntiColoured == 3)));
   }
 
   throw Exception() << "SimpleColourBasis2::colourConnected(): Cannot handle colour configuration" << Exception::runerror;
 
   return false;
 
 }
 
 map<size_t,vector<vector<size_t> > > SimpleColourBasis2::basisList(const vector<PDT::Colour>& basis) const {
 
   if ( id33bar.empty() )
     makeIds();
 
   map<size_t,vector<vector<size_t> > > blist;
   vector<vector<size_t> > structures;
   vector<size_t> structure;
 
   if ( basis == id88 ) {
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structures.push_back(structure);
     blist[0] = structures;
     return blist;
   }
 
   if ( basis == id33bar ) {
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structures.push_back(structure);
     blist[0] = structures;
     return blist;
   }
 
   if ( basis == id888 ) {
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structure.push_back(2);
     structures.push_back(structure);
     blist[0] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structure.push_back(1);
     structures.push_back(structure);
     blist[1] = structures;
     return blist;
   }
 
   if ( basis == id33bar8 ) {
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structure.push_back(1);
     structures.push_back(structure);
     blist[0] = structures;
     return blist;
   }
 
   if ( basis == id8888 ) {
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(1);
     structure.push_back(2);
     structures.push_back(structure);
     blist[0] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(1);
     structure.push_back(3);
     structures.push_back(structure);
     blist[1] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(2);
     structure.push_back(3);
     structures.push_back(structure);
     blist[2] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structure.push_back(2);
     structure.push_back(3);
     structures.push_back(structure);
     blist[3] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structure.push_back(3);
     structure.push_back(2);
     structures.push_back(structure);
     blist[4] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structure.push_back(1);
     structure.push_back(3);
     structures.push_back(structure);
     blist[5] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structure.push_back(3);
     structure.push_back(1);
     structures.push_back(structure);
     blist[6] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structure.push_back(1);
     structure.push_back(2);
     structures.push_back(structure);
     blist[7] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structure.push_back(2);
     structure.push_back(1);
     structures.push_back(structure);
     blist[8] = structures;
     return blist;
   }
 
   if ( basis == id33bar88 ) {
     structures.clear();
     structure.clear();
     structure.push_back(2);
     structure.push_back(3);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structures.push_back(structure);
     blist[0] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structure.push_back(3);
     structure.push_back(1);
     structures.push_back(structure);
     blist[1] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structure.push_back(2);
     structure.push_back(1);
     structures.push_back(structure);
     blist[2] = structures;
     return blist;
   }
 
   if ( basis == id33bar33bar ) {
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(2);
     structure.push_back(1);
     structures.push_back(structure);
     blist[0] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(2);
     structure.push_back(3);
     structures.push_back(structure);
     blist[1] = structures;
     return blist;
   }
 
   if ( basis == id88888 ) {
     structures.clear();
     structure.clear();
     structure.push_back(3);
     structure.push_back(4);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structure.push_back(2);
     structures.push_back(structure);
     blist[0] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(2);
     structure.push_back(4);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structure.push_back(3);
     structures.push_back(structure);
     blist[1] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(2);
     structure.push_back(3);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structure.push_back(4);
     structures.push_back(structure);
     blist[2] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(3);
     structure.push_back(4);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structure.push_back(1);
     structures.push_back(structure);
     blist[3] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(1);
     structure.push_back(4);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structure.push_back(3);
     structures.push_back(structure);
     blist[4] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(1);
     structure.push_back(3);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structure.push_back(4);
     structures.push_back(structure);
     blist[5] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(2);
     structure.push_back(4);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structure.push_back(1);
     structures.push_back(structure);
     blist[6] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(1);
     structure.push_back(4);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structure.push_back(2);
     structures.push_back(structure);
     blist[7] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(1);
     structure.push_back(2);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structure.push_back(4);
     structures.push_back(structure);
     blist[8] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(2);
     structure.push_back(3);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(0);
     structure.push_back(4);
     structure.push_back(1);
     structures.push_back(structure);
     blist[9] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(1);
     structure.push_back(3);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(0);
     structure.push_back(4);
     structure.push_back(2);
     structures.push_back(structure);
     blist[10] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(1);
     structure.push_back(2);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(0);
     structure.push_back(4);
     structure.push_back(3);
     structures.push_back(structure);
     blist[11] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(4);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(1);
     structure.push_back(2);
     structure.push_back(3);
     structures.push_back(structure);
     blist[12] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(1);
     structure.push_back(2);
     structure.push_back(4);
     structures.push_back(structure);
     blist[13] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(4);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(1);
     structure.push_back(3);
     structure.push_back(2);
     structures.push_back(structure);
     blist[14] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(1);
     structure.push_back(3);
     structure.push_back(4);
     structures.push_back(structure);
     blist[15] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(1);
     structure.push_back(4);
     structure.push_back(2);
     structures.push_back(structure);
     blist[16] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(1);
     structure.push_back(4);
     structure.push_back(3);
     structures.push_back(structure);
     blist[17] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(2);
     structure.push_back(3);
     structure.push_back(4);
     structures.push_back(structure);
     blist[18] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(2);
     structure.push_back(4);
     structure.push_back(3);
     structures.push_back(structure);
     blist[19] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structure.push_back(2);
     structure.push_back(3);
     structure.push_back(4);
     structures.push_back(structure);
     blist[20] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structure.push_back(2);
     structure.push_back(4);
     structure.push_back(3);
     structures.push_back(structure);
     blist[21] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structure.push_back(3);
     structure.push_back(2);
     structure.push_back(4);
     structures.push_back(structure);
     blist[22] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structure.push_back(3);
     structure.push_back(4);
     structure.push_back(2);
     structures.push_back(structure);
     blist[23] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structure.push_back(4);
     structure.push_back(2);
     structure.push_back(3);
     structures.push_back(structure);
     blist[24] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structure.push_back(4);
     structure.push_back(3);
     structure.push_back(2);
     structures.push_back(structure);
     blist[25] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structure.push_back(1);
     structure.push_back(3);
     structure.push_back(4);
     structures.push_back(structure);
     blist[26] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structure.push_back(1);
     structure.push_back(4);
     structure.push_back(3);
     structures.push_back(structure);
     blist[27] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structure.push_back(3);
     structure.push_back(1);
     structure.push_back(4);
     structures.push_back(structure);
     blist[28] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structure.push_back(3);
     structure.push_back(4);
     structure.push_back(1);
     structures.push_back(structure);
     blist[29] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structure.push_back(4);
     structure.push_back(1);
     structure.push_back(3);
     structures.push_back(structure);
     blist[30] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structure.push_back(4);
     structure.push_back(3);
     structure.push_back(1);
     structures.push_back(structure);
     blist[31] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structure.push_back(1);
     structure.push_back(2);
     structure.push_back(4);
     structures.push_back(structure);
     blist[32] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structure.push_back(1);
     structure.push_back(4);
     structure.push_back(2);
     structures.push_back(structure);
     blist[33] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structure.push_back(2);
     structure.push_back(1);
     structure.push_back(4);
     structures.push_back(structure);
     blist[34] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structure.push_back(2);
     structure.push_back(4);
     structure.push_back(1);
     structures.push_back(structure);
     blist[35] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structure.push_back(4);
     structure.push_back(1);
     structure.push_back(2);
     structures.push_back(structure);
     blist[36] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structure.push_back(4);
     structure.push_back(2);
     structure.push_back(1);
     structures.push_back(structure);
     blist[37] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(4);
     structure.push_back(1);
     structure.push_back(2);
     structure.push_back(3);
     structures.push_back(structure);
     blist[38] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(4);
     structure.push_back(1);
     structure.push_back(3);
     structure.push_back(2);
     structures.push_back(structure);
     blist[39] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(4);
     structure.push_back(2);
     structure.push_back(1);
     structure.push_back(3);
     structures.push_back(structure);
     blist[40] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(4);
     structure.push_back(2);
     structure.push_back(3);
     structure.push_back(1);
     structures.push_back(structure);
     blist[41] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(4);
     structure.push_back(3);
     structure.push_back(1);
     structure.push_back(2);
     structures.push_back(structure);
     blist[42] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(4);
     structure.push_back(3);
     structure.push_back(2);
     structure.push_back(1);
     structures.push_back(structure);
     blist[43] = structures;
     return blist;
   }
 
   if ( basis == id33bar888 ) {
     structures.clear();
     structure.clear();
     structure.push_back(2);
     structure.push_back(3);
     structure.push_back(4);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structures.push_back(structure);
     blist[0] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(2);
     structure.push_back(4);
     structure.push_back(3);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structures.push_back(structure);
     blist[1] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(3);
     structure.push_back(4);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structure.push_back(1);
     structures.push_back(structure);
     blist[2] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(2);
     structure.push_back(4);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structure.push_back(1);
     structures.push_back(structure);
     blist[3] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(2);
     structure.push_back(3);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(0);
     structure.push_back(4);
     structure.push_back(1);
     structures.push_back(structure);
     blist[4] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structure.push_back(3);
     structure.push_back(4);
     structure.push_back(1);
     structures.push_back(structure);
     blist[5] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(2);
     structure.push_back(4);
     structure.push_back(3);
     structure.push_back(1);
     structures.push_back(structure);
     blist[6] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structure.push_back(2);
     structure.push_back(4);
     structure.push_back(1);
     structures.push_back(structure);
     blist[7] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structure.push_back(4);
     structure.push_back(2);
     structure.push_back(1);
     structures.push_back(structure);
     blist[8] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(4);
     structure.push_back(2);
     structure.push_back(3);
     structure.push_back(1);
     structures.push_back(structure);
     blist[9] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(4);
     structure.push_back(3);
     structure.push_back(2);
     structure.push_back(1);
     structures.push_back(structure);
     blist[10] = structures;
     return blist;
   }
 
   if ( basis == id33bar33bar8 ) {
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(4);
     structure.push_back(3);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(2);
     structure.push_back(1);
     structures.push_back(structure);
     blist[0] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(4);
     structure.push_back(1);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(2);
     structure.push_back(3);
     structures.push_back(structure);
     blist[1] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(3);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(2);
     structure.push_back(4);
     structure.push_back(1);
     structures.push_back(structure);
     blist[2] = structures;
     structures.clear();
     structure.clear();
     structure.push_back(0);
     structure.push_back(1);
     structures.push_back(structure);
     structure.clear();
     structure.push_back(2);
     structure.push_back(4);
     structure.push_back(3);
     structures.push_back(structure);
     blist[3] = structures;
     return blist;
   }
 
   throw Exception() << "SimpleColourBasis2::basisList(): Cannot handle colour configuration" << Exception::runerror;
 
   return blist;
 
 }
 
 void SimpleColourBasis2::makeIds() const {
 
   id88 = vector<PDT::Colour>(2,PDT::Colour8);
 
   id33bar.push_back(PDT::Colour3);
   id33bar.push_back(PDT::Colour3bar);
 
   id888 = vector<PDT::Colour>(3,PDT::Colour8);
 
   id33bar8 = id33bar;
   id33bar8.push_back(PDT::Colour8);
 
   id8888 = vector<PDT::Colour>(4,PDT::Colour8);
 
   id33bar88 = id33bar8;
   id33bar88.push_back(PDT::Colour8);
 
   id33bar33bar = id33bar;
   id33bar33bar.push_back(PDT::Colour3);
   id33bar33bar.push_back(PDT::Colour3bar);
 
   id88888 = vector<PDT::Colour>(5,PDT::Colour8);
 
   id33bar888 = id33bar88;
   id33bar888.push_back(PDT::Colour8);
 
   id33bar33bar8 = id33bar33bar;
   id33bar33bar8.push_back(PDT::Colour8);
 
 }
 
 
 // If needed, insert default implementations of virtual function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 void SimpleColourBasis2::persistentOutput(PersistentOStream &) const {}
 
 void SimpleColourBasis2::persistentInput(PersistentIStream &, int) {}
 
 
 // *** Attention *** The following static variable is needed for the type
 // description system in ThePEG. Please check that the template arguments
 // are correct (the class and its base class), and that the constructor
 // arguments are correct (the class name and the name of the dynamically
 // loadable library where the class implementation can be found).
 DescribeClass<SimpleColourBasis2,ColourBasis>
   describeHerwigSimpleColourBasis2("Herwig::SimpleColourBasis2", "Herwig.so");
 
 void SimpleColourBasis2::Init() {
 
   static ClassDocumentation<SimpleColourBasis2> documentation
     ("SimpleColourBasis2 implements the colour algebra needed for "
      "processes with four coloured legs at NLO. It mainly "
      "serves as an example for the general ColourBasis interface.");
 
 }
 
diff --git a/MatrixElement/Matchbox/Utility/SimpleColourBasis2.h b/MatrixElement/Matchbox/Utility/SimpleColourBasis2.h
--- a/MatrixElement/Matchbox/Utility/SimpleColourBasis2.h
+++ b/MatrixElement/Matchbox/Utility/SimpleColourBasis2.h
@@ -1,211 +1,233 @@
 // -*- C++ -*-
 //
 // SimpleColourBasis2.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_SimpleColourBasis2_H
 #define Herwig_SimpleColourBasis2_H
 //
 // This is the declaration of the SimpleColourBasis2 class.
 //
 
 #include "Herwig/MatrixElement/Matchbox/Utility/ColourBasis.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup Matchbox
  * \author Simon Platzer
  *
  * \brief SimpleColourBasis2 implements the colour algebra needed for
  * processes with four coloured legs at NLO. It mainly serves as an
  * example for the general ColourBasis interface.
  *
  */
 class SimpleColourBasis2: public ColourBasis {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   SimpleColourBasis2();
 
   /**
    * The destructor.
    */
   virtual ~SimpleColourBasis2();
   //@}
 
 public:
 
   /**
    * Prepare the basis for the normal ordered legs and return the
    * dimensionality of the basis.
    */
   virtual size_t prepareBasis(const vector<PDT::Colour>&);
 
   /**
    * Return the scalar product of basis tensors labelled a and b in
    * the basis used for the given normal ordered legs.
    */
   virtual double scalarProduct(size_t a, size_t b,
 			       const vector<PDT::Colour>& abBasis) const;
 
   /**
    * Return the matrix element of a colour charge
    * <c_{n+1,a}|T_i|c_{n,b}> between basis tensors a and b, with
    * respect to aBasis and bBasis
    */
   virtual double tMatrixElement(size_t i, size_t a, size_t b,
 				const vector<PDT::Colour>& aBasis,
-				const vector<PDT::Colour>& bBasis) const;
+				const vector<PDT::Colour>& bBasis,
+				size_t k, size_t l,
+				const map<size_t,size_t>& dict) const;
+
+  /*
+   * Temporary to make it compile
+   */
+  virtual double sMatrixElement(size_t, size_t, size_t,
+				const vector<PDT::Colour>&,
+				const vector<PDT::Colour>&,
+				size_t, size_t,
+				const map<size_t,size_t>&
+				) const {
+    assert( 0 == 1 );
+    return 0;
+  }
+
+  /**
+   * Return true, if this colour basis supports gluon splittings.
+   */
+  virtual bool canSplitGluons() const {
+    return false;
+  }
 
   /**
    * Return true, if a large-N colour connection exists for the
    * given external legs and basis tensor.
    */
   virtual bool colourConnected(const cPDVector&,
 			       const vector<PDT::Colour>&,
 			       const pair<int,bool>&, 
 			       const pair<int,bool>&, 
 			       size_t) const;
 
   /**
    * Return true, if the colour basis is capable of assigning colour
    * flows.
    */
   virtual bool haveColourFlows() const { return true; }
 
   /**
    * Create ids for bases
    */
   void makeIds() const;
 
   /**
    * Return a map of basis tensor indices to vectors identifying a
    * certain ordering corresponding to the given colour structure. May
    * not be supported by all colour basis implementations.
    */
   virtual map<size_t,vector<vector<size_t> > > basisList(const vector<PDT::Colour>&) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * id for 88
    */
   mutable vector<PDT::Colour> id88;
 
   /**
    * id for 33bar
    */
   mutable vector<PDT::Colour> id33bar;
 
   /**
    * id for 888
    */
   mutable vector<PDT::Colour> id888;
 
   /**
    * id for 33bar8
    */
   mutable vector<PDT::Colour> id33bar8;
 
   /**
    * id for 8888
    */
   mutable vector<PDT::Colour> id8888;
 
   /**
    * id for 33bar88
    */
   mutable vector<PDT::Colour> id33bar88;
 
   /**
    * id for 33bar33bar
    */
   mutable vector<PDT::Colour> id33bar33bar;
 
   /**
    * id for 88888
    */
   mutable vector<PDT::Colour> id88888;
 
   /**
    * id for 33bar888
    */
   mutable vector<PDT::Colour> id33bar888;
 
   /**
    * id for 33bar33bar8
    */
   mutable vector<PDT::Colour> id33bar33bar8;
 
 private:
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   SimpleColourBasis2 & operator=(const SimpleColourBasis2 &) = delete;
 
 };
 
 }
 
 #endif /* Herwig_SimpleColourBasis2_H */
diff --git a/Sampling/exsample/cell.h b/Sampling/exsample/cell.h
--- a/Sampling/exsample/cell.h
+++ b/Sampling/exsample/cell.h
@@ -1,307 +1,304 @@
 // -*- C++ -*-
 //
 // cell.h is part of ExSample -- A Library for Sampling Sudakov-Type Distributions
 //
 // Copyright (C) 2008-2017 Simon Platzer -- simon.plaetzer@desy.de, The Herwig Collaboration
 //
 // ExSample is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 #ifndef EXSAMPLE_cell_h_included
 #define EXSAMPLE_cell_h_included
 
 #include "utility.h"
 #include "adaption_info.h"
 #include "statistics.h"
 
 namespace exsample {
 
   /// \brief Information contained in a leaf cell
   class cell_info {
 
   public:
 
     /// the default constructor
     cell_info();
 
     /// construct from boundaries and adaption info
     cell_info(const std::vector<double>& ll,
 	      const std::vector<double>& ur,
 	      const adaption_info& ainfo);
 
     /// construct from boundaries, flags for variables to be sampled,
     /// and adaption info
     cell_info(const std::vector<double>& ll,
 	      const std::vector<double>& ur,
 	      const std::vector<bool>& sampled_variables,
 	      const adaption_info& ainfo);
 
   public:
 
     /// generate a flat trial point in this cell
     template<class Random>
     void select(Random&,
 		std::vector<double>&);
 
     /// generate a flat trial point in this cell
     /// only for the variables falgged as true
     template<class Random>
     void select(Random&,
 		std::vector<double>&,
 		const std::vector<bool>&);
 
     /// indicate a function value for the given point
     void selected(const std::vector<double>&,
 		  double,
 		  const adaption_info&);
 
     /// indicate that a point has been
     /// accepted in this cell
     void accept() { ++accepted_; }
 
     /// reject a previously accepted event
     void reject() { --accepted_; }
 
   public:
 
     /// return true, if below efficiency threshold
     bool bad(const adaption_info& ainfo) const {
       return ((static_cast<double>(accepted_)/static_cast<double>(attempted_)) < 
 	      ainfo.efficiency_threshold);
     }
 
     /// suggest a split and indicate wether it is worth
     /// to be performed
     std::pair<std::size_t,double> get_split(const adaption_info&,
 					    bool&) const;
 
     /// explore this cell performing a flat sampling,
     /// updating the given statistics object and pre-filling
     /// the efficiency histogram by a trial unweighting
     template<class Random, class Function, class SlaveStatistics>
     void explore(Random&, const adaption_info&, Function*, statistics*,
-		 SlaveStatistics& opt, double detuning);
+		 SlaveStatistics& opt);
 
     /// explore this cell in a more refined way, which
     /// is however not suited for already calculating integrals
     /// and stuff
     template<class Random, class Function>
-    void explore(Random&, const adaption_info&, Function*,
-		 double detuning);
+    void explore(Random&, const adaption_info&, Function*);
 
   public:
 
     /// get the current overestimate
     double overestimate() const { return overestimate_; }
 
     /// return the position of the last maximum
     const std::vector<double>& last_max_position() const { return last_max_position_; }
 
     /// set the current overestimate and maximum position
-    void overestimate(double v, const std::vector<double>& pos,
-		      double detuning) { 
-      overestimate_ = detuning * v;
+    void overestimate(double v, const std::vector<double>& pos) { 
+      overestimate_ = v;
       last_max_position_ = pos;
     }
 
     /// get the volume
     double volume() const { return volume_; }
 
     /// get the lower left corner
     const std::vector<double>& lower_left() const { return lower_left_; }
 
     /// get the upper right corner
     const std::vector<double>& upper_right() const { return upper_right_; }
 
     /// get the number of attempted events
     unsigned long attempted() const { return attempted_; }
 
     /// get the number of accepted events
     unsigned long accepted() const { return accepted_; }
 
   public:
 
     /// return the number of missing events
     /// for the given parameter bin id
     int parametric_missing(const bit_container<parameter_hash_bits>& id) const;
 
     /// set the number of missing events
     /// for the given parameter bin id
     void parametric_missing(const bit_container<parameter_hash_bits>& id, int n);
 
     /// increase to the number of missing events
     /// for the given parameter bin id
     void increase_parametric_missing(const bit_container<parameter_hash_bits>& id);
 
     /// decrease to the number of missing events
     /// for the given parameter bin id
     void decrease_parametric_missing(const bit_container<parameter_hash_bits>& id);
 
     /// return true, if the cell is compensating in
     /// at least one parameter bin
     bool parametric_compensating() const {
       return !parametric_missing_map_.empty();
     }
 
     /// return true, if the cell contains the
     /// indicated parameter point
     bool contains_parameter(const std::vector<double>& point,
 			    const std::vector<bool>& sampled) const;
 
   public:
 
     /// put to ostream
     template<class OStream>
     void put(OStream& os) const;
 
     /// get from istream
     template<class IStream>
     void get(IStream& is);
 
   private:
 
     /// the value of the overestimate in this cell
     double overestimate_;
 
     /// the volume of this cell
     double volume_;
 
     /// the lower left corner of this cell
     std::vector<double> lower_left_;
 
     /// the upper right corner of this cell
     std::vector<double> upper_right_;
 
     /// midpoint of this cell
     std::vector<double> mid_point_;
 
     /// the position of the last encountered
     /// maximum in this cell
     std::vector<double> last_max_position_;
 
     /// left-right statistics of average weight
     std::vector<std::pair<double,double> > avg_weight_;
 
     /// the number of attempts in this cell
     unsigned long attempted_;
 
     /// the number of accepted events in this cell
     unsigned long accepted_;
 
     /// an optional map of parameter bin ids
     /// to the number of missing events
     std::map<bit_container<parameter_hash_bits>,int> parametric_missing_map_;
 
   };
 
   /// \brief the general cell class
   class cell {
 
   public:
 
     /// default constructor
     cell();
 
     /// construct from boundaries and adaption info
     cell(const std::vector<double>& ll,
 	 const std::vector<double>& ur,
 	 const adaption_info& ainfo);
 
     /// construct from boundaries, flags for variables to be sampled,
     /// and adaption info
     cell(const std::vector<double>& ll,
 	 const std::vector<double>& ur,
 	 const std::vector<bool>& sampled_variables,
 	 const adaption_info& ainfo);
 
     /// copy constructor
     cell(const cell& x);
 
     /// assignment
     cell& operator=(const cell& x);
 
   public:
 
     /// split this cell, exploring the
     /// child not containing the current overestimate
     template<class Random, class Function>
     std::pair<cell,cell> split(std::pair<std::size_t,double> split_d,
 			       Random& rnd_gen,
 			       Function* f,
 			       const adaption_info& ainfo,
 			       const std::vector<bool>& sampled = 
-			       std::vector<bool>(),
-			       double detuning = 1.0);
+			       std::vector<bool>());
 
   public:
 
     /// return the split dimension
     std::size_t split_dimension() const { return split_dimension_; }
 
     /// return the split value
     double split_point() const { return split_point_; }
 
     /// return the integral
     double integral() const { return integral_; }
 
     /// access the integral
     double& integral() { return integral_; }
 
     /// set the integral
     void integral(double v) { integral_ = v; }
 
     /// access the number of missing events
     int& missing_events() { return missing_events_; }
 
     /// return the number of missing events
     int missing_events() const { return missing_events_; }
 
     /// set the number of missing events
     void missing_events(int n) { missing_events_ = n; }
 
     /// access the cell_info object
     cell_info& info() { assert(cell_info_); return *cell_info_; }
 
     /// return the cell_info object
     const cell_info& info() const { assert(cell_info_); return *cell_info_; }
 
   public:
 
     /// put to ostream
     template<class OStream>
     void put(OStream& os) const;
 
     /// get from istream
     template<class IStream>
     void get(IStream& is);
 
   private:
 
     /// the dimension along this cell
     /// was split
     std::size_t split_dimension_;
 
     /// the value, where this cell was split
     double split_point_;
 
     /// the integral of the absolute value
     /// of the overestimate over all the
     /// children cells
     double integral_;
 
     /// the number of missing events in this cell
     int missing_events_;
 
     /// a pointer to the cell info object,
     /// if this is a leaf cell
     std::unique_ptr<cell_info> cell_info_;
 
 
   };
 
 }
 
 #include "cell.icc"
 
 #endif // EXSAMPLE_cell_h_included
diff --git a/Sampling/exsample/cell.icc b/Sampling/exsample/cell.icc
--- a/Sampling/exsample/cell.icc
+++ b/Sampling/exsample/cell.icc
@@ -1,490 +1,487 @@
 // -*- C++ -*-
 //
 // cell.icc is part of ExSample -- A Library for Sampling Sudakov-Type Distributions
 //
 // Copyright (C) 2008-2017 Simon Platzer -- simon.plaetzer@desy.de, The Herwig Collaboration
 //
 // ExSample is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 namespace exsample {
 
 
   template<class Random>
   void cell_info::select (Random& rnd_gen,
 			  std::vector<double>& p) {
     std::transform(lower_left_.begin(),lower_left_.end(),
 		   upper_right_.begin(),p.begin(),
 		   rnd_gen);
     ++attempted_;
   }
 
 
   template<class Random>
   void cell_info::select (Random& rnd_gen,
 			  std::vector<double>& p,
 			  const std::vector<bool>& sample) {
     conditional_transform(lower_left_.begin(),lower_left_.end(),
 			  upper_right_.begin(),sample.begin(),
 			  p.begin(),rnd_gen);
     ++attempted_;
   }
 
 
 
   template<class Random, class Function, class SlaveStatistics>
   void cell_info::explore(Random& rnd_gen,
 			  const adaption_info& ainfo,
 			  Function* function, statistics* stats,
-			  SlaveStatistics& opt,
-			  double detuning) {
+			  SlaveStatistics& opt) {
     function->start_presampling();
     unsigned long n_sampled = 0;
     std::vector<double> ll = lower_left_;
     std::vector<double> ur = upper_right_;
     double val = 0.;
     std::vector<double> pos (ll.size());
     std::vector< std::pair<double,std::vector<double> > > vals;
     unsigned long ivalnonzero = 0;
     while (n_sampled < ainfo.presampling_points) {
       std::transform(ll.begin(),ll.end(),
 		     ur.begin(),pos.begin(),
 		     rnd_gen);
-      val = function->evaluate(pos) * detuning;
+      val = function->evaluate(pos);
       vals.push_back( std::pair<double,std::vector<double> > (val,pos) );
       if ( val != 0 ) ivalnonzero++;
       ++n_sampled;
     }
     while ( ivalnonzero > 0 ) {
       double avg = 0;
       double err = 0;
       double maxval = 0;
       std::vector<double> maxpos (ll.size());
       unsigned long imax(0);
       for ( unsigned long ival=0; ival < vals.size(); ival++ ) {
         val = std::abs(vals[ival].first);
         if ( val == 0 ) continue;
         avg += val;
         err += sqr(val);
         if ( val > maxval ) {
           maxval = val;
           maxpos = vals[ival].second;
           imax = ival;
         }
       }
       avg /= ivalnonzero;
       err /= ivalnonzero;
       err = sqrt(err-sqr(avg));
       if ( maxval <= avg+sqrt(ivalnonzero/2.)*err ) {
         overestimate_ = maxval;
         last_max_position_ = maxpos;
         break;
       }
       vals.erase(vals.begin()+imax);
       ivalnonzero--;
     }
     
     for ( unsigned long ival=0; ival < vals.size(); ival++ ) {
       val = vals[ival].first;
       stats->presampled(val);
       opt.select(val);
       selected(pos,std::abs(val),ainfo);
     }
 
     function->stop_presampling();
   }
 
 
   template<class Random, class Function>
   void cell_info::explore (Random& rnd_gen,
-			   const adaption_info& ainfo, Function* function,
-			   double detuning) {
+			   const adaption_info& ainfo, Function* function) {
     function->start_presampling();
     unsigned long n_sampled = 0;
     std::vector<double> ll = lower_left_;
     std::vector<double> ur = upper_right_;
     double val = 0.;
     std::vector<double> pos (ll.size());
     std::vector< std::pair<double,std::vector<double> > > vals;
     while (n_sampled < ainfo.presampling_points) {
       std::transform(ll.begin(),ll.end(),
 		     ur.begin(),pos.begin(),
 		     rnd_gen);
-      val = function->evaluate(pos) * detuning;
+      val = function->evaluate(pos);
       if ( std::abs(val) > 0 )
         vals.push_back( std::pair<double,std::vector<double> > (std::abs(val),pos) );
       ++n_sampled;
     }
     while ( vals.size() > 0 ) {
       double avg = 0;
       double err = 0;
       double maxval = 0;
       std::vector<double> maxpos (ll.size());
       unsigned long imax(0);
       for ( unsigned long ival=0; ival < vals.size(); ival++ ) {
         double thisval = vals[ival].first;
         avg += thisval;
         err += sqr(thisval);
         if ( thisval > maxval ) {
           maxval = thisval;
           maxpos = vals[ival].second;
           imax = ival;
         }
       }
       avg /= vals.size();
       err /= vals.size();
       err = sqrt(err-sqr(avg));
       if ( maxval <= avg+sqrt(vals.size()/2.)*err ) {
         overestimate_ = maxval;
         last_max_position_ = maxpos;
         break;
       }
       vals.erase(vals.begin()+imax);
     }
 
     function->stop_presampling();
   }
 
 
   template<class OStream>
   void cell_info::put (OStream& os) const {
     os << overestimate_;
     ostream_traits<OStream>::separator(os);
     os << volume_;
     ostream_traits<OStream>::separator(os);
     os << lower_left_.size();
     ostream_traits<OStream>::separator(os);
     for (std::size_t k = 0; k < lower_left_.size(); ++k) {
       os << lower_left_[k];
       ostream_traits<OStream>::separator(os);
     }
     for (std::size_t k = 0; k < upper_right_.size(); ++k) {
       os << upper_right_[k];
       ostream_traits<OStream>::separator(os);
     }
     for (std::size_t k = 0; k < mid_point_.size(); ++k) {
       os << mid_point_[k];
       ostream_traits<OStream>::separator(os);
     }
     for (std::size_t k = 0; k < last_max_position_.size(); ++k) {
       os << last_max_position_[k];
       ostream_traits<OStream>::separator(os);
     }
     for (std::size_t k = 0; k < avg_weight_.size(); ++k) {
       os << avg_weight_[k].first;
       ostream_traits<OStream>::separator(os);
       os << avg_weight_[k].second;
       ostream_traits<OStream>::separator(os);
     }
     os << attempted_;
     ostream_traits<OStream>::separator(os);
     os << accepted_;
     ostream_traits<OStream>::separator(os);
     os << parametric_missing_map_.size();
     ostream_traits<OStream>::separator(os);
     for ( std::map<bit_container<parameter_hash_bits>,int>::const_iterator p =
 	    parametric_missing_map_.begin(); p != parametric_missing_map_.end(); ++p ) {
       p->first.put(os);
       os << p->second;
       ostream_traits<OStream>::separator(os);
     }
   }
 
 
   template<class IStream>
   void cell_info::get (IStream& is) {
     std::size_t dim;
     is >> overestimate_ >> volume_ >> dim;
     lower_left_.resize(dim);
     for (std::size_t k = 0; k < lower_left_.size(); ++k) {
       is >> lower_left_[k];
     }
     upper_right_.resize(dim);
     for (std::size_t k = 0; k < upper_right_.size(); ++k) {
       is >> upper_right_[k];
     }
     mid_point_.resize(dim);
     for (std::size_t k = 0; k < mid_point_.size(); ++k) {
       is >> mid_point_[k];
     }
     last_max_position_.resize(dim);
     for (std::size_t k = 0; k < last_max_position_.size(); ++k) {
       is >> last_max_position_[k];
     }
     avg_weight_.resize(dim);
     for (std::size_t k = 0; k < avg_weight_.size(); ++k) {
       is >> avg_weight_[k].first >> avg_weight_[k].second;
     }
     is >> attempted_ >> accepted_ >> dim;
     for ( size_t k = 0; k < dim; ++k ) {
       bit_container<parameter_hash_bits> in;
       in.get(is);
       is >> parametric_missing_map_[in];
     }
   }
 
   template<class Random, class Function>
   std::pair<cell,cell > 
   cell::split (std::pair<std::size_t,double> split_d,
 	       Random& rnd_gen,
 	       Function* function,
 	       const adaption_info& ainfo,
-	       const std::vector<bool>& sampled,
-	       double detuning) {
+	       const std::vector<bool>& sampled) {
     assert(!missing_events() && !info().parametric_compensating());
     split_dimension_ = split_d.first;
     split_point_ = split_d.second;
     std::vector<double> lower_left1 = info().lower_left();
     std::vector<double> upper_right1 = info().upper_right();
     std::vector<double> lower_left2 = info().lower_left();
     std::vector<double> upper_right2 = info().upper_right();
     upper_right1[split_dimension_] = split_point_;
     lower_left2[split_dimension_] = split_point_;
     std::pair<cell,cell> children;
     if (sampled.empty())
       children = std::pair<cell,cell>(cell(lower_left1,upper_right1,ainfo),
 				      cell(lower_left2,upper_right2,ainfo));
     else
       children = std::pair<cell,cell> (cell(lower_left1,upper_right1,sampled,ainfo),
 				       cell(lower_left2,upper_right2,sampled,ainfo));
     if (info().last_max_position()[split_dimension_] <= split_point_) {
-      children.first.info().overestimate(info().overestimate(),info().last_max_position(),1.0);
-      children.second.info().explore(rnd_gen,ainfo,function,detuning);
+      children.first.info().overestimate(info().overestimate(),info().last_max_position());
+      children.second.info().explore(rnd_gen,ainfo,function);
     } else {
-      children.second.info().overestimate(info().overestimate(),info().last_max_position(),1.0);
-      children.first.info().explore(rnd_gen,ainfo,function,detuning);
+      children.second.info().overestimate(info().overestimate(),info().last_max_position());
+      children.first.info().explore(rnd_gen,ainfo,function);
     }
     cell_info_.reset(0);
     children.first.integral(children.first.info().volume() * children.first.info().overestimate());
     children.second.integral(children.second.info().volume() * children.second.info().overestimate());
     return children;
   }
 
 
   template<class OStream>
   void cell::put (OStream& os) const {
     os << split_dimension_;
     ostream_traits<OStream>::separator(os);
     os << split_point_;
     ostream_traits<OStream>::separator(os);
     os << integral_;
     ostream_traits<OStream>::separator(os);
     os << missing_events_;
     ostream_traits<OStream>::separator(os);
     if (cell_info_) {
       os << "has_cell_info";
       ostream_traits<OStream>::separator(os);
       cell_info_->put(os);
     } else {
       os << "has_no_cell_info";
       ostream_traits<OStream>::separator(os);
     }
   }
 
 
   template<class IStream>
   void cell::get (IStream& is) {
     std::string info_tag;
     is >> split_dimension_ >> split_point_
        >> integral_ >> missing_events_ 
        >> info_tag;
     if (info_tag == "has_cell_info") {
       cell_info_.reset(new cell_info());
       cell_info_->get(is);
     }
   }
 
   inline cell_info::cell_info()
     : overestimate_(0.), volume_(0.),
       lower_left_(), upper_right_(), mid_point_(),
       last_max_position_(), avg_weight_(),
       attempted_(0), accepted_(0) {}
 
   inline cell_info::cell_info(const std::vector<double>& ll,
 			      const std::vector<double>& ur,
 			      const adaption_info& ainfo)
     : overestimate_(0.), volume_(),
       lower_left_(ll), upper_right_(ur), mid_point_(),
       last_max_position_(),
       avg_weight_(std::vector<std::pair<double,double> >
 		  (ainfo.dimension,std::make_pair(0.,0.))),
       attempted_(0), accepted_(0) {
 
     std::vector<double> delta;
     std::transform(ur.begin(),ur.end(),
 		   ll.begin(),std::back_inserter(delta),
 		   std::minus<double>());
       
     volume_ =
       std::accumulate(delta.begin(),delta.end(),1.,std::multiplies<double>());
 
     std::transform(ur.begin(),ur.end(),
 		   ll.begin(),std::back_inserter(mid_point_),
 		   std::plus<double>());
 
     for (std::size_t k = 0; k < ainfo.dimension; ++k)
       mid_point_[k] /= 2.;
 
   }
 
   inline cell_info::cell_info(const std::vector<double>& ll,
 			      const std::vector<double>& ur,
 			      const std::vector<bool>& sampled_variables,
 			      const adaption_info& ainfo)
     : overestimate_(0.), volume_(),
       lower_left_(ll), upper_right_(ur), mid_point_(),
       last_max_position_(),
       avg_weight_(std::vector<std::pair<double,double> >
 		  (ainfo.dimension,std::make_pair(0.,0.))),
       attempted_(0), accepted_(0) {
 
     std::vector<double> delta;
     conditional_transform(ur.begin(),ur.end(),
 			  ll.begin(),sampled_variables.begin(),
 			  std::back_inserter(delta),
 			  std::minus<double>());
 
     volume_ = 
       std::accumulate(delta.begin(),delta.end(),1.,std::multiplies<double>());
 
     std::transform(ur.begin(),ur.end(),
 		   ll.begin(),std::back_inserter(mid_point_),
 		   std::plus<double>());
 
     for (std::size_t k = 0; k < ainfo.dimension; ++k)
       mid_point_[k] /= 2.;
 
   }
 
 
   inline int cell_info::parametric_missing(const bit_container<parameter_hash_bits>& id) const {
     std::map<bit_container<parameter_hash_bits>,int>::const_iterator mit
       = parametric_missing_map_.find(id);
     if (mit == parametric_missing_map_.end())
       return 0;
     return mit->second;
   }
 
   inline void cell_info::parametric_missing(const bit_container<parameter_hash_bits>& id, int n) {
     if (n == 0) {
       std::map<bit_container<parameter_hash_bits>,int>::iterator mit
 	= parametric_missing_map_.find(id);	
       if (mit != parametric_missing_map_.end())
 	parametric_missing_map_.erase(mit);
       return;
     }
     parametric_missing_map_[id] = n;
   }
 
   inline void cell_info::increase_parametric_missing(const bit_container<parameter_hash_bits>& id) {
     std::map<bit_container<parameter_hash_bits>,int>::iterator mit
       = parametric_missing_map_.find(id);	
     if (mit != parametric_missing_map_.end()) {
       mit->second += 1;
       if (mit->second == 0) parametric_missing_map_.erase(mit);
     } else parametric_missing_map_[id] = 1;
   }
 
   inline void cell_info::decrease_parametric_missing(const bit_container<parameter_hash_bits>& id) {
     std::map<bit_container<parameter_hash_bits>,int>::iterator mit
       = parametric_missing_map_.find(id);	
     if (mit != parametric_missing_map_.end()) {
       mit->second -= 1;
       if (mit->second == 0) parametric_missing_map_.erase(mit);
     } else assert(false);
   }
 
   inline void cell_info::selected(const std::vector<double>& p,
 				  double weight,
 				  const adaption_info& ainfo) {
     for (std::size_t k = 0; k < p.size(); ++k) {
       if (ainfo.adapt[k]) {
 	if (p[k] < mid_point_[k])
 	  avg_weight_[k].first += weight;
 	else
 	  avg_weight_[k].second += weight;
       }
     }
   }
 
   inline std::pair<std::size_t,double> cell_info::get_split (const adaption_info& ainfo,
 							     bool& worth) const {
     std::size_t split_d = 0;
     double gain = 0.;
     for (std::size_t k = 0; k < ainfo.dimension; ++k) {
       double xgain = 0.;
       double left = avg_weight_[k].first;
       double right = avg_weight_[k].second;
       if (left+right > 0.) {
 	xgain = std::abs(left-right)/(left+right);
       }
       if (xgain > gain) {
 	gain = xgain;
 	split_d = k;
       }
     }
     worth = (gain >= ainfo.gain_threshold);
     return std::make_pair(split_d,mid_point_[split_d]);
   }
 
   inline bool cell_info::contains_parameter (const std::vector<double>& point,
 					     const std::vector<bool>& sampled) const {
     std::vector<double>::const_iterator p = point.begin();
     std::vector<double>::const_iterator l = lower_left_.begin();
     std::vector<double>::const_iterator u = upper_right_.begin();
     std::vector<bool>::const_iterator f = sampled.begin();
     for (; p < point.end(); ++p, ++f, ++l, ++u)
       if (!(*f)) {
 	if (((*l) > (*p)) ||
 	    ((*u) < (*p)))
 	  return false;
       }
     return true;
   }
 
 
   inline cell::cell()
     : split_dimension_(0), split_point_(0.),
       integral_(0.), missing_events_(0),
       cell_info_(nullptr) {}
 
   inline cell::cell(const std::vector<double>& ll,
 		    const std::vector<double>& ur,
 		    const adaption_info& ainfo)
     : split_dimension_(0), split_point_(0.),
       integral_(0.), missing_events_(0),
       cell_info_(new cell_info(ll,ur,ainfo)) {}
 
   inline cell::cell(const std::vector<double>& ll,
 		    const std::vector<double>& ur,
 		    const std::vector<bool>& sampled_variables,
 		    const adaption_info& ainfo)
     : split_dimension_(0), split_point_(0.),
       integral_(0.), missing_events_(0),
       cell_info_(new cell_info(ll,ur,sampled_variables,ainfo)) {}
 
   inline cell::cell(const cell& x)
     : split_dimension_(x.split_dimension_),
       split_point_(x.split_point_),
       integral_(x.integral_), 
       missing_events_(x.missing_events_),
       cell_info_(nullptr) {
     if (x.cell_info_)
       cell_info_.reset(new cell_info(*x.cell_info_));
   }      
 
   inline cell& cell::operator=(const cell& x) {
     if (this == &x)
       return *this;
     split_dimension_ = x.split_dimension_;
     split_point_ = x.split_point_;
     integral_ = x.integral_;
     missing_events_ = x.missing_events_;
     if (x.cell_info_)
       cell_info_.reset(new cell_info(*x.cell_info_));
     return *this;
   }
 
 
 }
diff --git a/Sampling/exsample/exponential_generator.icc b/Sampling/exsample/exponential_generator.icc
--- a/Sampling/exsample/exponential_generator.icc
+++ b/Sampling/exsample/exponential_generator.icc
@@ -1,386 +1,388 @@
 // -*- C++ -*-
 //
 // exponential_generator.icc is part of ExSample -- A Library for Sampling Sudakov-Type Distributions
 //
 // Copyright (C) 2008-2017 Simon Platzer -- simon.plaetzer@desy.de, The Herwig Collaboration
 //
 // ExSample is licenced under version 3 of the GPL, see COPYING for details.
 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
 //
 //
 namespace exsample {
 
   template<class Function, class Random>
   void exponential_generator<Function,Random>::initialize() {
     adaption_info_.dimension = function_->dimension();
     adaption_info_.lower_left = function_->support().first;
     adaption_info_.upper_right = function_->support().second;
     if (adaption_info_.adapt.empty())
       adaption_info_.adapt = std::vector<bool>(adaption_info_.dimension,true);
     evolution_variable_ = function_->evolution_variable();
     evolution_cutoff_ = function_->evolution_cutoff();
     sample_variables_ = function_->variable_flags();
     sample_other_variables_ = sample_variables_;
     sample_other_variables_[evolution_variable_] = false;
     last_point_.resize(adaption_info_.dimension);
     parametric_selector_ = parametric_selector(&last_point_,sample_other_variables_);
     exponent_selector_ = parametric_selector(&last_point_,sample_variables_);
     missing_accessor_ = parametric_missing_accessor(&last_parameter_bin_);
     parametric_sampler_ = parametric_sampling_selector<rnd_generator<Random> > 
       (&last_point_,&last_parameter_bin_,sample_other_variables_,rnd_gen_);
     if (initialized_) return;
     splits_ = 0;
     for ( std::size_t k = 0; k < adaption_info_.dimension; ++k ) {
       if ( sample_other_variables_[k] )
 	continue;
       parameter_splits_[k].push_back(adaption_info_.lower_left[k]);
       parameter_splits_[k].push_back(adaption_info_.upper_right[k]);
     }
     root_cell_ = 
       binary_tree<cell>(cell(adaption_info_.lower_left,
 			     adaption_info_.upper_right,
 			     sample_other_variables_,
 			     adaption_info_));
-    root_cell_.value().info().explore(rnd_gen_,adaption_info_,function_,detuning_);
+    root_cell_.value().info().explore(rnd_gen_,adaption_info_,function_);
     root_cell_.value().integral(root_cell_.value().info().volume() * root_cell_.value().info().overestimate());
     last_exponent_integrand_.resize(1);
     check_events_ = adaption_info_.presampling_points;
     initialized_ = true;
   }
 
   template<class Function, class Random>
   bool exponential_generator<Function,Random>::split () {
     if (adaption_info_.freeze_grid <= accepts_)
       return false;
     if (compensating_)
       return false;
     if (!(*last_cell_).info().bad(adaption_info_)) return false;
     bool dosplit = false;
     std::pair<std::size_t,double> sp =
       (*last_cell_).info().get_split(adaption_info_,dosplit);
     if (!dosplit) return false;
     if (!adaption_info_.adapt[sp.first]) return false;
     if (splits_ == parameter_hash_bits/2)
       return false;
     ++splits_;
     last_cell_.node().split((*last_cell_).split(sp,rnd_gen_,function_,adaption_info_,
-						sample_other_variables_,detuning_));
+						sample_other_variables_));
     if ( !sample_other_variables_[sp.first] ) {
       if ( std::find(parameter_splits_[sp.first].begin(),parameter_splits_[sp.first].end(),sp.second)
 	   == parameter_splits_[sp.first].end() ) {
 	parameter_splits_[sp.first].push_back(sp.second);
 	std::sort(parameter_splits_[sp.first].begin(),parameter_splits_[sp.first].end());
 	if ( sp.first == evolution_variable_ ) {
 	  last_exponent_integrand_.push_back(0.);
 	}
       }
     }
     did_split_ = true;
     last_point_ = function_->parameter_point();
     root_cell_.tree_accumulate(parametric_selector_,integral_accessor_,std::plus<double>());
     exponents_.clear();
     get_exponent();
     return true;
   }
 
   template<class Function, class Random>
   void exponential_generator<Function,Random>::get_exponent () {
     last_parameter_bin_.reset();
     root_cell_.subtree_hash (exponent_selector_,last_parameter_bin_);
     last_exponent_ = exponents_.find(last_parameter_bin_);
     if (last_exponent_ != exponents_.end())
       return;
     exponents_[last_parameter_bin_] = linear_interpolator();
     last_exponent_ = exponents_.find(last_parameter_bin_);
     double old_evo = last_point_[evolution_variable_];
     std::vector<double>::iterator exp_it = last_exponent_integrand_.begin();
     for (std::vector<double>::iterator esp = parameter_splits_[evolution_variable_].begin();
 	 esp < std::prev(parameter_splits_[evolution_variable_].end()); ++esp, ++exp_it) {
       last_point_[evolution_variable_] = (*esp + *std::next(esp))/2.;
       *exp_it = root_cell_.accumulate(parametric_selector_,integral_accessor_,std::plus<double>());
     }
     exp_it = std::prev(last_exponent_integrand_.end());
     double total = 0.;
     for (std::vector<double>::iterator esp = std::prev(parameter_splits_[evolution_variable_].end());
 	 esp > parameter_splits_[evolution_variable_].begin(); --esp, --exp_it) {
       last_exponent_->second.set_interpolation(*esp,total);
       total += (*exp_it) * ((*esp) - (*std::prev(esp)));
     }
     last_exponent_->second.set_interpolation(parameter_splits_[evolution_variable_].front(),total);
     last_point_[evolution_variable_] = old_evo;
   }
 
   template<class Function, class Random>
   std::set<std::vector<double> > 
   exponential_generator<Function,Random>::parameter_points() {
     std::set<std::vector<double> > res;
     std::vector<double> pt(adaption_info_.dimension,0.);
     recursive_parameter_points(res,pt,0);
     return res;
   }
 
   template<class Function, class Random>
   void exponential_generator<Function,Random>::
   recursive_parameter_points(std::set<std::vector<double> >& res,
 			     std::vector<double>& pt,
 			     size_t current) {
     if ( current == adaption_info_.dimension ) {
       res.insert(pt);
       return;
     }
     if ( sample_variables_[current] ) {
       recursive_parameter_points(res,pt,current+1);
       return;
     }
     for ( std::vector<double>::const_iterator sp =
 	    parameter_splits_[current].begin(); 
 	  sp != std::prev(parameter_splits_[current].end()); ++sp ) {
       pt[current] = (*sp + *std::next(sp))/2.;
       recursive_parameter_points(res,pt,current+1);
     }
   }
 
   template<class Function, class Random>
   void exponential_generator<Function,Random>::compensate() {
     if (!did_split_ || !docompensate_) {
       assert(did_split_ || last_cell_ == root_cell_.begin());
       exponents_.clear();
-      last_cell_->info().overestimate(last_value_,last_point_,detuning_);
+      last_cell_->info().overestimate(last_value_,last_point_);
       last_cell_->integral(last_cell_->info().volume() * last_cell_->info().overestimate());
       last_point_ = function_->parameter_point();
       get_exponent();
       return;
     }
     std::vector<double> themaxpoint = last_point_;
     std::set<std::vector<double> > id_points
       = parameter_points();
     for ( std::set<std::vector<double> >::const_iterator id =
 	    id_points.begin(); id != id_points.end(); ++id ) {
       last_point_ = *id;
       get_exponent();
     }
     std::map<bit_container<parameter_hash_bits>,linear_interpolator >
       old_exponents = exponents_;
     double old_oe = last_cell_->info().overestimate();
-    last_cell_->info().overestimate(last_value_,themaxpoint,detuning_);
+    last_cell_->info().overestimate(last_value_,themaxpoint);
     last_cell_->integral(last_cell_->info().volume() * last_cell_->info().overestimate());
     exponents_.clear();
     for ( std::set<std::vector<double> >::const_iterator id =
 	    id_points.begin(); id != id_points.end(); ++id ) {
       last_point_ = *id;
       get_exponent();
       std::map<bit_container<parameter_hash_bits>,linear_interpolator >::iterator
 	old_exp = old_exponents.find(last_parameter_bin_);
       std::map<bit_container<parameter_hash_bits>,linear_interpolator >::iterator
 	new_exp = exponents_.find(last_parameter_bin_);
       assert(old_exp != old_exponents.end() && new_exp != exponents_.end());
       double old_norm = 1. - std::exp(-(old_exp->second)(adaption_info_.lower_left[evolution_variable_]));
       double new_norm = 1. - std::exp(-(new_exp->second)(adaption_info_.lower_left[evolution_variable_]));
       for (binary_tree<cell>::iterator it = root_cell_.begin();
 	   it != root_cell_.end(); ++it) {
 	if ( !it->info().contains_parameter(last_point_,sample_variables_) )
 	  continue;
 	double old_int = 0.;
 	double new_int = 0.;
 	for ( std::vector<double>::const_iterator sp = parameter_splits_[evolution_variable_].begin();
 	      sp != std::prev(parameter_splits_[evolution_variable_].end()); ++sp ) {
 	  if ( *sp >= it->info().lower_left()[evolution_variable_] &&
 	       *sp < it->info().upper_right()[evolution_variable_] ) {
 	    double xl = *sp;
 	    double xxl = *std::next(sp);
 	    double old_al = 
 	      (old_exp->second.interpolation()[xxl] - old_exp->second.interpolation()[xl]) /
 	      (xxl-xl);
 	    double old_bl = 
 	      (xxl * old_exp->second.interpolation()[xl] - 
 	       xl * old_exp->second.interpolation()[xxl]) /
 	      (xxl-xl);
 	    double new_al = 
 	      (new_exp->second.interpolation()[xxl] - new_exp->second.interpolation()[xl]) /
 	      (xxl-xl);
 	    double new_bl = 
 	      (xxl * new_exp->second.interpolation()[xl] - 
 	       xl * new_exp->second.interpolation()[xxl]) /
 	      (xxl-xl);
 	    if ( std::abs(old_al) > std::numeric_limits<double>::epsilon() ) {
 	      old_int += (exp(-(old_al*xl+old_bl)) - exp(-(old_al*xxl+old_bl)))/old_al;
 	    } else {
 	      old_int += (xxl-xl)*exp(-old_bl);
 	    }
 	    if ( std::abs(new_al) > std::numeric_limits<double>::epsilon() ) {
 	      new_int += (exp(-(new_al*xl+new_bl)) - exp(-(new_al*xxl+new_bl)))/new_al;
 	    } else {
 	      new_int += (xxl-xl)*exp(-new_bl);
 	    }
 	  }
 	}
 	double scaling;
 	if (it != last_cell_) {
 	  if (old_int > std::numeric_limits<double>::epsilon() &&
 	      new_int > std::numeric_limits<double>::epsilon())
 	    scaling = ((old_norm * new_int) /
 		       (new_norm * old_int)) - 1.;
 	  else
 	    scaling = 0.;
 	} else {
 	  if (old_int > std::numeric_limits<double>::epsilon() &&
 	      new_int > std::numeric_limits<double>::epsilon())
 	    scaling = ((last_value_ * old_norm * new_int) /
 		       (old_oe * new_norm * old_int)) - 1.;
 	  else
 	    scaling = 0.;
 	}
 	it->info().parametric_missing(last_parameter_bin_,
 				      it->info().parametric_missing(last_parameter_bin_) +
 				      static_cast<int>(round(scaling * it->info().attempted())));
 	if (it->info().parametric_missing(last_parameter_bin_) != 0) {
 	  compensating_ = true;
 	}
       }
     }
     last_point_ = function_->parameter_point();
   }
 
   template<class Function, class Random>
   double exponential_generator<Function,Random>::generate(double enhance) {
+    if ( enhance == 0.0 )
+      return 0.;
     if (compensating_) {
       compensating_ = false;
       for (binary_tree<cell>::iterator it = root_cell_.begin();
 	   it != root_cell_.end(); ++it)
 	if (it->info().parametric_compensating()) {
 	  compensating_ = true;
 	  break;
 	}
       parametric_sampler_.compensate(compensating_);
     }
     last_point_ = function_->parameter_point();
     if (last_point_[evolution_variable_] < evolution_cutoff_) {
       return 0.;
     }
     unsigned long n_hit_miss = 0;
     unsigned long n_select = 0;
     double minus_log_r;
     root_cell_.tree_accumulate(parametric_selector_,integral_accessor_,std::plus<double>());
     get_exponent();
     while (true) {
       n_select = 0;
-      minus_log_r = -std::log(rnd_gen_())/enhance +
+      minus_log_r = -std::log(rnd_gen_())/enhance/detuning_ +
 	last_exponent_->second(last_point_[evolution_variable_]);
       if (!last_exponent_->second.invertible(minus_log_r)) {
 	return 0.;
       }
       try {
 	last_point_[evolution_variable_] = last_exponent_->second.unique_inverse(minus_log_r);
       } catch (constant_interpolation& c) {
 	last_point_[evolution_variable_] = rnd_gen_(c.range.first,c.range.second);
       }
       assert(std::isfinite(last_point_[evolution_variable_]));
       if (last_point_[evolution_variable_] < evolution_cutoff_) {
 	return 0.;
       }
       ++attempts_;
       if (compensating_) {
 	root_cell_.tree_accumulate(missing_accessor_,std::plus<int>());
       }
       if (parameter_splits_[evolution_variable_].size() > 2)
 	root_cell_.tree_accumulate(parametric_selector_,integral_accessor_,std::plus<double>());
       if (did_split_)
 	while ((last_cell_ = root_cell_.select(parametric_sampler_)) == root_cell_.end()) {
 	  root_cell_.tree_accumulate(missing_accessor_,std::plus<int>());
 	  if(++n_select > adaption_info_.maxtry)
 	    throw selection_maxtry();
 	}
       else
 	last_cell_ = root_cell_.begin();
       last_cell_->info().select(rnd_gen_,last_point_,sample_other_variables_);
       last_value_ = function_->evaluate(last_point_);
       assert(last_value_ >= 0.);
       last_cell_->info().selected(last_point_,last_value_,adaption_info_);
       if (last_value_ > last_cell_->info().overestimate()) {
 	if ( std::abs(last_value_)/last_cell_->info().overestimate() > 2. ) {
 	  last_value_ = 
 	    last_cell_->info().overestimate()*
 	    (1.+exp(2.*(2.-std::abs(last_value_)/last_cell_->info().overestimate())));
 	}
 	compensate();
 	throw exponential_regenerate();
       } 
       if (last_cell_->info().attempted() % check_events_ == 0) {
 	if (split()) {
 	  throw exponential_regenerate();
 	}
       }
-      if (last_value_/last_cell_->info().overestimate() > rnd_gen_()) {
-	function_->accept(last_point_,enhance*last_value_,enhance*last_cell_->info().overestimate());
+      if (last_value_/last_cell_->info().overestimate()/detuning_ > rnd_gen_()) {
+	function_->accept(last_point_,enhance*last_value_,enhance*detuning_*last_cell_->info().overestimate());
 	break;
       }
       if ( last_value_ != 0.0 ) {
-	function_->veto(last_point_,enhance*last_value_,enhance*last_cell_->info().overestimate());
+	function_->veto(last_point_,enhance*last_value_,enhance*detuning_*last_cell_->info().overestimate());
       }
       if(++n_hit_miss > adaption_info_.maxtry)
 	throw hit_and_miss_maxtry();
     }
     if (last_value_ == 0.)
       return 0.;
     ++accepts_;
     ++check_events_;
     last_cell_->info().accept();
     return 1.;
   }
 
 
   template<class Function, class Random>
   template<class OStream>
   void exponential_generator<Function,Random>::put (OStream& os) const {
     os << check_events_; ostream_traits<OStream>::separator(os);
     adaption_info_.put(os);
     root_cell_.put(os);
     os << did_split_; ostream_traits<OStream>::separator(os);
     os << initialized_; ostream_traits<OStream>::separator(os);
     os << evolution_variable_; ostream_traits<OStream>::separator(os);
     os << evolution_cutoff_; ostream_traits<OStream>::separator(os);
     os << sample_variables_; ostream_traits<OStream>::separator(os);
     os << sample_other_variables_; ostream_traits<OStream>::separator(os);
     os << parameter_splits_; ostream_traits<OStream>::separator(os);
     // last_cell_ is selected new so we ignore it here
     os << last_point_; ostream_traits<OStream>::separator(os);
     os << last_value_; ostream_traits<OStream>::separator(os);
     last_parameter_bin_.put(os);
     os << exponents_.size(); ostream_traits<OStream>::separator(os);
     for ( std::map<bit_container<parameter_hash_bits>,linear_interpolator >::const_iterator
 	    ex = exponents_.begin(); ex != exponents_.end() ; ++ex ) {
       ex->first.put(os);
       ex->second.put(os);
     }
     os << last_exponent_integrand_; ostream_traits<OStream>::separator(os);
     os << compensating_; ostream_traits<OStream>::separator(os);
     os << attempts_; ostream_traits<OStream>::separator(os);
     os << accepts_; ostream_traits<OStream>::separator(os);
     os << splits_; ostream_traits<OStream>::separator(os);
     os << docompensate_; ostream_traits<OStream>::separator(os);
   }
 
   template<class Function, class Random>
   template<class IStream>
   void exponential_generator<Function,Random>::get (IStream& is) {
     is >> check_events_;
     adaption_info_.get(is);
     root_cell_.get(is);
     is >> did_split_ >> initialized_ >> evolution_variable_
        >> evolution_cutoff_ >> sample_variables_ >> sample_other_variables_
        >> parameter_splits_;
     // last_cell_ is selected new so we ignore it here
     is >> last_point_ >> last_value_;
     last_parameter_bin_.get(is);
     size_t dim; is >> dim;
     for ( size_t k = 0; k < dim ; ++k ) {
       bit_container<parameter_hash_bits> key;
       key.get(is);
       exponents_[key].get(is);
     }
     is >> last_exponent_integrand_;
     last_exponent_ = exponents_.find(last_parameter_bin_);
     is >> compensating_ >> attempts_ >> accepts_ >> splits_ >> docompensate_;
   }
 
 }
diff --git a/Shower/Dipole/Base/Dipole.cc b/Shower/Dipole/Base/Dipole.cc
--- a/Shower/Dipole/Base/Dipole.cc
+++ b/Shower/Dipole/Base/Dipole.cc
@@ -1,438 +1,455 @@
 // -*- C++ -*-
 //
 // Dipole.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 Dipole class.
 //
 
 #include "Dipole.h"
 #include "Herwig/Shower/Dipole/Utility/DipolePartonSplitter.h"
 
 using namespace Herwig;
 
 Dipole::Dipole()
   : theParticles(), thePDFs(),
     theFractions(1.0,1.0), theIndices(),
     theDecaying(false,false),
     theOffShell(false,false),
     theScales(0.0*GeV,0.0*GeV) {}
 
 
 Dipole::Dipole(const pair<PPtr,PPtr>& newParticles,
 	       const pair<PDF,PDF>& newPDFs,
 	       pair<double,double> newFractions,
 	       pair<Energy,Energy> newScales)
 
   : theParticles(newParticles), 
     thePDFs(newPDFs),
     theFractions(newFractions), theIndices(),
     theDecaying(false,false),
     theOffShell(false,false),
     theScales(newScales) {
   theIndices.first = DipoleIndex(theParticles.first->dataPtr(),
 				 theParticles.second->dataPtr(),
 				 newPDFs.first,newPDFs.second,
 				 theDecaying.first,theDecaying.second,
 				 theOffShell.first,theOffShell.second);
   theIndices.second = theIndices.first;
   theIndices.second.swap();
 }
 
 Dipole::Dipole(const pair<PPtr,PPtr>& newParticles,
 	       const pair<PDF,PDF>& newPDFs,
 	       pair<double,double> newFractions,
 	       pair<bool,bool> decaying,
 	       pair<bool,bool> offShell,
 	       pair<Energy,Energy> newScales)
   : theParticles(newParticles), 
     thePDFs(newPDFs),
     theFractions(newFractions), theIndices(),
     theDecaying(decaying),
     theOffShell(offShell),
     theScales(newScales) {
   theIndices.first = DipoleIndex(theParticles.first->dataPtr(),
 				 theParticles.second->dataPtr(),
 				 newPDFs.first,newPDFs.second,
 				 theDecaying.first,theDecaying.second,
 				 theOffShell.first,theOffShell.second);
   theIndices.second = theIndices.first;
   theIndices.second.swap();
     }
 
 void Dipole::update() {
   theIndices.first = DipoleIndex(theParticles.first->dataPtr(),
 				 theParticles.second->dataPtr(),
 				 thePDFs.first,thePDFs.second,
 				 theDecaying.first,theDecaying.second,
 				 theOffShell.first,theOffShell.second);
   theIndices.second = theIndices.first;
   theIndices.second.swap();
   assert(DipolePartonSplitter::colourConnected(theParticles.first,
                                                theParticles.second));
 }
 
 pair<Dipole,Dipole> Dipole::split(DipoleSplittingInfo& dsplit,
-				  bool colourSpectator) const {  
+				  bool colourSpectator,
+				  bool subleadingNc) const {  
  // check contracts
   assert(dsplit.splittingKinematics());
   assert(dsplit.emitterData() && dsplit.emissionData() && dsplit.spectatorData());
   if ( !colourSpectator ) {
     assert(index(dsplit.configuration()) == dsplit.index());
     assert(emitterX(dsplit.configuration()) == dsplit.emitterX());
     assert(spectatorX(dsplit.configuration()) == dsplit.spectatorX());
   } else {
     assert(emitterX(dsplit.configuration()) == dsplit.emitterX());
     assert(emitterPDF(dsplit.configuration()) == dsplit.index().emitterPDF());
     assert((dsplit.configuration().first ? 
             theParticles.first->dataPtr() : 
             theParticles.second->dataPtr())
 	   == dsplit.index().emitterData());
   }
 
   // generate full kinematics
   dsplit.splittingKinematics()->generateKinematics(
                        emitter(dsplit.configuration())->momentum(),
 		       spectator(dsplit.configuration())->momentum(),
 		       dsplit);
 
 
   // Treat the case of decay splittings as backward evolution.
   // i.e. Put the new emitter and new emission or new spectator
   // and new emission respectively into the new dipoles.
   bool emitter_decay = dsplit.index().incomingDecayEmitter();
   if ( emitter_decay )
     assert(false);
   bool spectator_decay = dsplit.index().incomingDecaySpectator();
   
   tPPtr oldSpectator = spectator(dsplit.configuration());
   PPtr newSpectator;
 
   // get a new spectator
   if ( !colourSpectator ) {
     newSpectator = 
       dsplit.spectatorData()->produceParticle(
 		dsplit.splittingKinematics()->lastSpectatorMomentum());
 
     DipolePartonSplitter::change(oldSpectator,
 				 newSpectator,
 	 spectatorPDF(dsplit.configuration()).pdf(), spectator_decay);
 
     dsplit.spectator(oldSpectator);
     dsplit.splitSpectator(newSpectator);
   } else {
     newSpectator = oldSpectator;
   }
 
   // perform the splitting
   tPPtr oldEmitter = emitter(dsplit.configuration());
-  PPtr newEmitter = 
-    dsplit.emitterData()->produceParticle(
-               dsplit.splittingKinematics()->lastEmitterMomentum());
-  PPtr newEmission = 
-    dsplit.emissionData()->produceParticle(
-               dsplit.splittingKinematics()->lastEmissionMomentum());
+  PPtr newEmitter, newEmission;
+  double z = dsplit.lastZ();
+  // Do not swap momenta for splittings different from g->gg or
+  // initial state emitters 
+  bool noSwap = !(dsplit.emitterData()->id() == ParticleID::g
+		  && dsplit.emissionData()->id() == ParticleID::g )
+    || dsplit.index().initialStateEmitter();
+  if ( noSwap || z > UseRandom::rnd(1.0) ) {
+    newEmitter = 
+      dsplit.emitterData()->produceParticle(
+					    dsplit.splittingKinematics()->lastEmitterMomentum());
+    newEmission = 
+      dsplit.emissionData()->produceParticle(
+					     dsplit.splittingKinematics()->lastEmissionMomentum());
+  } else {
+    newEmitter = 
+      dsplit.emitterData()->produceParticle(
+					    dsplit.splittingKinematics()->lastEmissionMomentum());
+    newEmission = 
+      dsplit.emissionData()->produceParticle(
+					     dsplit.splittingKinematics()->lastEmitterMomentum());
+  }
 
   newEmitter->scale(sqr(dsplit.lastPt()));
   newEmission->scale(sqr(dsplit.lastPt()));
   newSpectator->scale(oldSpectator->scale());
 
   DipolePartonSplitter::split(oldEmitter,newEmitter,newEmission,
            oldSpectator,emitterPDF(dsplit.configuration()).pdf(), emitter_decay);
 
   dsplit.emitter(oldEmitter);
   dsplit.splitEmitter(newEmitter);
   dsplit.emission(newEmission);
 
   double emitter_x = emitterX(dsplit.configuration()) / dsplit.lastEmitterZ();
   double spectator_x = spectatorX(dsplit.configuration()) / dsplit.lastSpectatorZ();
 
   PDF emitter_pdf = emitterPDF(dsplit.configuration());
   PDF spectator_pdf = spectatorPDF(dsplit.configuration());
 
   // Communicate off-shell parton flags
   // Note that as gluons aren't off-shell, the only possibility
   // in qcd splittings is gluon emissions off an off-shell emitter
   // -> off-shell emitter => off-shell new emitter
   bool emitter_off_shell = dsplit.index().offShellEmitter();
   bool spectator_off_shell = dsplit.index().offShellSpectator();  
   
   // now check how we need to arrange the children
 
   // assignment is 0 = emitter, 1 = emission, 2 = spectator
   int left = 0;
   int middle = 1;
   int right = 2;
 
   if (dsplit.configuration().first) {
 
     // spectator is unique
     right = 2;
 
     // middle is the one connecting to the spectator
     if (DipolePartonSplitter::colourConnected(newSpectator,newEmission)) {
       middle = 1;
       left = 0;
     } else {
       assert(DipolePartonSplitter::colourConnected(newSpectator,newEmitter));
       middle = 0;
       left = 1;
     }
 
   } else {
 
     // spectator is unique
     left = 2;
 
     // middle is the one connecting to the spectator
     if (DipolePartonSplitter::colourConnected(newSpectator,newEmission)) {
       middle = 1;
       right = 0;
     } else {
       assert(DipolePartonSplitter::colourConnected(newSpectator,newEmitter));
       middle = 0;
       right = 1;
     }
 
   }
 
   pair<PPtr,PPtr> left_particles;
   pair<PPtr,PPtr> right_particles;
 
   pair<PDF,PDF> left_pdfs;
   pair<PDF,PDF> right_pdfs;
 
   pair<double,double> left_fractions;
   pair<double,double> right_fractions;
 
   // Pairs containing indicators for decayed particles
   pair<bool,bool> left_decays = {false,false};
   pair<bool,bool> right_decays = {false,false};
 
   // Pairs containing indicators for off-shell particles
   pair<bool, bool> left_off_shells = {false,false};
   pair<bool, bool> right_off_shells = {false,false};
   
   switch (left) {
 
   case 0:
     if (emitter_decay) {
       assert(false);
       left_decays.first = emitter_decay; 
     }
     left_particles.first = newEmitter;
     left_pdfs.first = emitter_pdf;
     left_fractions.first = emitter_x;
     left_off_shells.first = emitter_off_shell;
 
     break;
 
   case 1:
     left_particles.first = newEmission;
     left_pdfs.first = PDF();
     left_fractions.first = 1.;
     left_decays.first = false;
     left_off_shells.first = false;
     break;
 
   case 2:
     left_particles.first = newSpectator;
     left_pdfs.first = spectator_pdf;
     left_fractions.first = spectator_x;
     left_decays.first = spectator_decay;
     left_off_shells.first = spectator_off_shell;
     break;
   }
 
   switch (middle) {
 
   case 0:
     if (emitter_decay) {
       assert(false);
       left_decays.second = emitter_decay;
     }
     left_particles.second = newEmitter;
     left_pdfs.second = emitter_pdf;
     left_fractions.second = emitter_x;
     left_off_shells.second = emitter_off_shell;
     break;
 
   case 1:
     left_particles.second = newEmission;
     left_pdfs.second = PDF();
     left_fractions.second = 1.;
     left_decays.second = false;
     left_off_shells.second = false;
     break;
 
   case 2:
     left_decays.second = spectator_decay;
     left_particles.second = newSpectator;
     left_pdfs.second = spectator_pdf;
     left_fractions.second = spectator_x;
     left_off_shells.second = spectator_off_shell;
     break;
 
   }
 
   right_particles.first = left_particles.second;
   right_pdfs.first = left_pdfs.second;
   right_fractions.first = left_fractions.second;
   right_decays.first = left_decays.second;
   right_off_shells.first = left_off_shells.second;
 
   switch (right) {
 
   case 0:
     if (emitter_decay) {
       assert(false);
       right_decays.second = emitter_decay;
     }
     right_particles.second = newEmitter;
     right_pdfs.second = emitter_pdf;
     right_fractions.second = emitter_x;
     right_off_shells.second = emitter_off_shell;
     break;
 
   case 1:
     right_particles.second = newEmission;
     right_pdfs.second = PDF();
     right_fractions.second = 1.;
     right_decays.second = false;
     right_off_shells.second = false;
     break;
 
   case 2:
     right_particles.second = newSpectator;
     right_pdfs.second = spectator_pdf;
     right_fractions.second = spectator_x;
     right_decays.second = spectator_decay;
     right_off_shells.second = spectator_off_shell;
     break;
 
   }  
 
   Energy scale = dsplit.lastPt();
 
   return { Dipole(left_particles, left_pdfs, left_fractions,
 		  left_decays, left_off_shells, {scale,scale}),
 	   Dipole(right_particles, right_pdfs, right_fractions,
 		  right_decays, right_off_shells, {scale,scale})};
 
 }
 
 void Dipole::tmpsplit(DipoleSplittingInfo& dsplit,
                                   bool colourSpectator) const {
   
     // generate full kinematics
      dsplit.splittingKinematics()->generateKinematics(emitter(dsplit.configuration())->momentum(),
                                                    spectator(dsplit.configuration())->momentum(),
                                                    dsplit);
   
   tPPtr oldSpectator = spectator(dsplit.configuration());
   PPtr newSpectator;
   
     // get a new spectator
   if ( !colourSpectator ) {
       newSpectator =
       dsplit.spectatorData()->produceParticle(dsplit.splittingKinematics()->lastSpectatorMomentum());
     dsplit.spectator(oldSpectator);
     dsplit.splitSpectator(newSpectator);
   } else {
     newSpectator = oldSpectator;
   }
   
     // perform the splitting
   tPPtr oldEmitter = emitter(dsplit.configuration());
     PPtr newEmitter =
     dsplit.emitterData()->produceParticle(dsplit.splittingKinematics()->lastEmitterMomentum());
     PPtr newEmission =
     dsplit.emissionData()->produceParticle(dsplit.splittingKinematics()->lastEmissionMomentum());
   
     dsplit.emitter(oldEmitter);
     dsplit.splitEmitter(newEmitter);
     dsplit.emission(newEmission);  
 }
 
 
 void Dipole::recoil (DipoleSplittingInfo& dsplit) {
 
   // check contracts
   assert(dsplit.splittingKinematics());
   assert(dsplit.spectatorData());
   assert(spectatorX(dsplit.spectatorConfiguration()) 
                  == dsplit.spectatorX());
   assert(spectatorPDF(dsplit.spectatorConfiguration()) 
                    == dsplit.index().spectatorPDF());
   assert((dsplit.spectatorConfiguration().first ? 
 			theParticles.first->dataPtr() : 
    			theParticles.second->dataPtr())
 	 == dsplit.index().spectatorData());
 
   tPPtr oldSpectator = spectator(dsplit.spectatorConfiguration());
   PPtr newSpectator = 
       dsplit.spectatorData()->produceParticle(
 			dsplit.splittingKinematics()->lastSpectatorMomentum());
   DipolePartonSplitter::change(oldSpectator,newSpectator,
                   spectatorPDF(dsplit.spectatorConfiguration()).pdf());
 
   newSpectator->scale(sqr(dsplit.lastPt()));
 
   dsplit.spectator(oldSpectator);
   dsplit.splitSpectator(newSpectator);
 
   if ( dsplit.spectatorConfiguration().first ) {
     theParticles.second = newSpectator;
     theFractions.second /= dsplit.lastSpectatorZ();
   } else {
     theParticles.first = newSpectator;
     theFractions.first /= dsplit.lastSpectatorZ();
   }
 
 }
 
 void Dipole::print(ostream& os) const {
 
   os << "--- ";
   // Check for decays first
   if ( theDecaying.first || theDecaying.second) {
     assert(!(theDecaying.first && theDecaying.second));
     if ( theDecaying.first && !theDecaying.second )
       os << "Decay IF";
     else if ( theDecaying.second && !theDecaying.first )
       os << "Decay FI";
   }
   else if ( !thePDFs.first.pdf() && !thePDFs.second.pdf() )
     os << "FF";
   else if ( thePDFs.first.pdf() && !thePDFs.second.pdf() )
     os << "IF";
   else if ( !thePDFs.first.pdf() && thePDFs.second.pdf() )
     os << "FI";
   else
     os << "II";
   os << " Dipole ------------------------------------------------------------------\n";
 
   if ( !theParticles.first || !theParticles.second ) {
     os << "  ***  This Dipole has not been setup properly.  ***\n";
   } else {
 
     os << " particles\n"
        << *theParticles.first
        << *theParticles.second;
 
     os << " scales/GeV = ("
        << (theScales.first/GeV) << ","
        << (theScales.second/GeV) << ")  fractions = ("
        << theFractions.first << "," << theFractions.second << ")\n";
   }
 
   os << "--------------------------------------------------------------------------------\n";
 
   os << flush;
 
 }
diff --git a/Shower/Dipole/Base/Dipole.h b/Shower/Dipole/Base/Dipole.h
--- a/Shower/Dipole/Base/Dipole.h
+++ b/Shower/Dipole/Base/Dipole.h
@@ -1,337 +1,338 @@
 // -*- C++ -*-
 //
 // Dipole.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_Dipole_H
 #define HERWIG_Dipole_H
 //
 // This is the declaration of the Dipole class.
 //
 
 #include "Herwig/Shower/Dipole/Kinematics/DipoleSplittingKinematics.h"
 #include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer, Stephen Webster, Johannes Bellm
  *
  * \brief The Dipole class is used by the dipole shower to
  * represent a dipole of two coloured partons.
  *
  */
 class Dipole {
 
 public:
 
   /**
    * The default constructor
    */
   Dipole();
   
   /**
    * The standard constructor
    */
   Dipole(const pair<PPtr,PPtr>& newParticles,
 	 const pair<PDF,PDF>& newPDFs,
 	 pair<double,double> newFractions,
 	 pair<Energy,Energy> newScales);
 
   /**
    * The standard constructor
    */
   Dipole(const pair<PPtr,PPtr>& newParticles,
 	 const pair<PDF,PDF>& newPDFs,
 	 pair<double,double> newFractions,
 	 const pair<bool,bool> decaying = pair<bool,bool>(false,false),
 	 const pair<bool,bool> offShell = pair<bool,bool>(false,false),
 	 pair<Energy,Energy> newScales = pair<Energy,Energy>(ZERO,ZERO));
 
 
 public:
 
   /**
    * Get the left particle.
    */
   tPPtr leftParticle() const { return theParticles.first; }
 
   /**
    * Get the right particle.
    */
   tPPtr rightParticle() const { return theParticles.second; }
 
   /**
    * Get the left PDF.
    */
   const PDF& leftPDF() const { return thePDFs.first; }
 
   /**
    * Get the right PDF.
    */
   const PDF& rightPDF() const { return thePDFs.second; }
 
   /**
    * Get the left fraction.
    */
   double leftFraction() const { return theFractions.first; }
 
   /**
    * Get the right fraction.
    */
   double rightFraction() const { return theFractions.second; }
 
   /**
    * Get the bool indicating
    * incoming decay for the left
    * particle, for debugging only.
    */
   bool leftDecaying() { return theDecaying.first; }
 
   /**
    * Get the bool indicating
    * incoming decay for the right
    * particle, for debugging only.
    */
   bool rightDecaying() { return theDecaying.second; }
 
   /**
    * Set the left particle.
    */
   void leftParticle(PPtr p) { theParticles.first = p; }
 
   /**
    * Set the right particle.
    */
   void rightParticle(PPtr p) { theParticles.second = p; }
 
   /**
    * Set the left PDF
    */
   void leftPDF(const PDF& p) { thePDFs.first = p; }
 
   /**
    * Set the right PDF
    */
   void rightPDF(const PDF& p) { thePDFs.second = p; }
 
   /**
    * Set the momentum fraction for the left particle.
    */
   void leftFraction(double x) { theFractions.first = x; }
 
   /**
    * Set the momentum fraction for the right particle.
    */
   void rightFraction(double x) { theFractions.second = x; }
 
   /**
    * Get the scale for the left particle.
    */
   Energy leftScale() const { return theScales.first; }
 
   /**
    * Set the scale for the left particle.
    */
   void leftScale(Energy s) { theScales.first = s; }
 
   /**
    * Get the scale for the right particle.
    */
   Energy rightScale() const { return theScales.second; }
 
   /**
    * Set the scale for the right particle.
    */
   void rightScale(Energy s) { theScales.second = s; }
 
   /**
    * Set the decayed particle indicator
    * for the left particle
    */
   void leftDecaying(bool decaying) { theDecaying.first = decaying; }
 
   /**
    * Set the decayed particle indicator
    * for the right particle
    */
   void rightDecaying(bool decaying) { theDecaying.second = decaying; }
 
   /**
    * Update information, if modified.
    */
   void update();
 
 public:
 
   /**
    * Return the dipole index for the selected
    * emitter-spectator assignment.
    */
   const DipoleIndex& index(pair<bool,bool> conf) const {
     return conf.first ? theIndices.first : theIndices.second;
   }
 
   /**
    * Set the first index
    */
   void setFirstIndex(DipoleIndex s){theIndices.first=s;}
 
   /**
    * Set the first index
    */
   void setSecondIndex(DipoleIndex s){theIndices.second=s;}
 
   /**
    * Return the emitter particle for the
    * selected configuration.
    */
   tPPtr emitter(pair<bool,bool> conf) const {
     return conf.first ? theParticles.first : theParticles.second;
   }
 
   /**
    * Return the spectator particle for the
    * selected configuration.
    */
   tPPtr spectator(pair<bool,bool> conf) const {
     return conf.first ? theParticles.second : theParticles.first;
   }
 
   /**
    * Return the scale associated to the emitter
    * for the selected configuration.
    */
   Energy emitterScale(pair<bool,bool> conf) const {
     return conf.first ? theScales.first : theScales.second;
   }
 
   /**
    * Set the scale associated to the emitter
    * for the selected configuration.
    */
   void emitterScale(pair<bool,bool> conf, Energy scale) {
     (conf.first ? theScales.first : theScales.second) = scale;
   }
 
   /**
    * Return the momentum fraction of the emitter
    * for the selected configuration.
    */
   double emitterX(pair<bool,bool> conf) const {
     return conf.first ? theFractions.first : theFractions.second;
   }
 
   /**
    * Return the PDF of the emitter
    * for the selected configuration.
    */
   const PDF& emitterPDF(pair<bool,bool> conf) const {
     return conf.first ? thePDFs.first : thePDFs.second;
   }
 
   /**
    * Return the momentum fraction of the spectator
    * for the selected configuration.
    */
   double spectatorX(pair<bool,bool> conf) const {
     return conf.first ? theFractions.second : theFractions.first;
   }
 
   /**
    * Return the PDF of the spectator
    * for the selected configuration.
    */
   const PDF& spectatorPDF(pair<bool,bool> conf) const {
     return conf.first ? thePDFs.second : thePDFs.first;
   }
 
 public:
 
   /**
    * Split this dipole according to the given splitting.
    * If colourSpectator is true, do not change the spectator.
    */
   pair<Dipole,Dipole> split (DipoleSplittingInfo& dsplit,
-			     bool colourSpectator) const;
+			     bool colourSpectator,
+			     bool subleadingNc = false) const;
 
   /**
    * As split, but without touching the event record.
    * Needed to produce a phase space point as it would 
    * be after calling split.
    */
   void tmpsplit (DipoleSplittingInfo& dsplit,
                              bool colourSpectator) const;
 
 
   /**
    * Produce a new spectator according to the
    * given splitting.
    */
   void recoil (DipoleSplittingInfo& dsplit);
 
 public:
 
   /**
    * Put information to ostream
    */
   void print(ostream&) const;
 
 private:
 
   /**
    * The particles forming the dipole
    */
   pair<PPtr,PPtr> theParticles;
 
   /**
    * The PDF objects.
    */
   pair<PDF,PDF> thePDFs;
 
   /**
    * The momentum fractions associated
    * to the incoming particles
    */
   pair<double,double> theFractions;
 
   /**
    * The dipole indices, if the first or second particle
    * is considered as emitter.
    */
   pair<DipoleIndex,DipoleIndex> theIndices;
 
   /**
    * Indicates if either the first or the second parton 
    * is incoming to a decay.
    */
   pair<bool,bool> theDecaying;
 
   /** 
    * Indicates if either the first or second parton
    * can be off-shell (required for sampling).
    **/
   pair<bool,bool> theOffShell;
   
   /**
    * The scale associated to the first and second
    * particle, respectively.
    */
   pair<Energy,Energy> theScales;
 
 };
 
 inline ostream& operator << (ostream& os, const Dipole& di) {
   di.print(os);
   return os;
 }
 
 }
 
 #endif /* HERWIG_Dipole_H */
diff --git a/Shower/Dipole/Base/DipoleEventRecord.cc b/Shower/Dipole/Base/DipoleEventRecord.cc
--- a/Shower/Dipole/Base/DipoleEventRecord.cc
+++ b/Shower/Dipole/Base/DipoleEventRecord.cc
@@ -1,1608 +1,1965 @@
 // -*- C++ -*-
 //
 // DipoleEventRecord.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 DipoleEventRecord class.
 //
 
 #include "DipoleEventRecord.h"
 #include "Herwig/Shower/Dipole/DipoleShowerHandler.h"
 #include "Herwig/Shower/Dipole/Utility/DipolePartonSplitter.h"
 #include "Herwig/Shower/ShowerHandler.h"
 #include "ThePEG/PDT/DecayMode.h"
 #include "Herwig/Decay/HwDecayerBase.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "ThePEG/PDF/PartonExtractor.h"
 #include "Herwig/Shower/RealEmissionProcess.h"
+#include "Herwig/MatrixElement/Matchbox/Base/MatchboxMEBase.h"
+#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
+
 #include <boost/utility.hpp>
 #include <algorithm>
 #include <iterator>
 
 using namespace Herwig;
 
 PList DipoleEventRecord::colourOrdered(PPair & in,
                                        PList & out) {
   
   PList colour_ordered;
   size_t done_size = out.size();
   
   if (in.first->coloured())
     ++done_size;
   if (in.second && in.second->coloured())
     ++done_size;
   
   while (colour_ordered.size() != done_size) {
     
     PPtr current;
     
     // start with singlets, as long as we have some
     
     if (find(colour_ordered.begin(),colour_ordered.end(),in.first) ==
         colour_ordered.end() && in.first->coloured()) {
       if (!in.first->hasColour() || !in.first->hasAntiColour())
 	current = in.first;
     }
     
     if (!current) {
       for (PList::iterator p = out.begin();
            p != out.end(); ++p) {
         if (find(colour_ordered.begin(),colour_ordered.end(),*p) ==
             colour_ordered.end() && (**p).coloured()) {
           if (!(**p).hasColour() || !(**p).hasAntiColour()) {
             current = *p;
             break;
           }
         }
       }
     }
     
     if (!current) {
       if (in.second && find(colour_ordered.begin(),colour_ordered.end(),in.second) ==
           colour_ordered.end() && in.second->coloured()) {
         if (!in.second->hasColour() || !in.second->hasAntiColour())
 	  current = in.second;
       }
     }
     
     // then go on with anything else
     
     if (!current) {
       if (find(colour_ordered.begin(),colour_ordered.end(),in.first) ==
           colour_ordered.end() && in.first->coloured()) {
         current = in.first;
       }
     }
     
     if (!current) {
       for (PList::iterator p = out.begin();
            p != out.end(); ++p) {
         if (find(colour_ordered.begin(),colour_ordered.end(),*p) ==
             colour_ordered.end() && (**p).coloured()) {
           current = *p;
           break;
         }
       }
     }
     
     if (!current) {
       if (in.second && find(colour_ordered.begin(),colour_ordered.end(),in.second) ==
           colour_ordered.end() && in.second->coloured()) {
         current = in.second;
       }
     }
     
     assert(current);
     
     PPtr next;
     Ptr<ColourLine>::ptr walk_the_line;
     
     while (true) {
       
       if (!walk_the_line) {
         if (current->hasColour()) {
           walk_the_line = current->colourLine();
         }
         else if (current->hasAntiColour()) {
           walk_the_line = current->antiColourLine();
         }
       }
       
       if (!next)
 	for (tPVector::const_iterator p = walk_the_line->coloured().begin();
 	     p != walk_the_line->coloured().end(); ++p) {
 	  if (*p == current)
 	    continue;
 	  if (find(out.begin(),out.end(),*p) != out.end() ||
 	      *p == in.first ||
 	      (in.second && *p == in.second)) {
 	    next = *p;
 	    if (next->hasColour() && next->hasAntiColour()) {
 	      walk_the_line = walk_the_line == next->colourLine() ? next->antiColourLine() : next->colourLine();
 	    }
 	    break;
 	  }
 	}
       
       if (!next)
 	for (tPVector::const_iterator p = walk_the_line->antiColoured().begin();
 	     p != walk_the_line->antiColoured().end(); ++p) {
 	  if (*p == current)
 	    continue;
 	  if (find(out.begin(),out.end(),*p) != out.end() ||
 	      *p == in.first ||
 	      (in.second && *p == in.second)) {
 	    next = *p;
 	    if (next->hasColour() && next->hasAntiColour()) {
 	      walk_the_line = walk_the_line == next->colourLine() ? next->antiColourLine() : next->colourLine();
 	    }
 	    break;
 	  }
 	}
 
       assert(next);
 
       colour_ordered.push_back(current);
       current = next;
 
       // done if next is not a gluon or next is already in colour_ordered
 
       if ((current->hasColour() && !current->hasAntiColour()) ||
 	  (!current->hasColour() && current->hasAntiColour())) {
 	colour_ordered.push_back(current);
 	break;
       }
 
       if (next->hasColour() && next->hasAntiColour()) {
 	if (find(colour_ordered.begin(),colour_ordered.end(),next) != colour_ordered.end())
 	  break;
       }
 
       next = PPtr();
 
     }
 
   }  
 
   return colour_ordered;
 
 }
 
 void DipoleEventRecord::popChain() { 
   assert(!theChains.empty());
   theDoneChains.push_back(DipoleChain());
   theDoneChains.back().dipoles().splice(theDoneChains.back().dipoles().begin(),theChains.front().dipoles());
   theChains.pop_front();
 }
 
 void DipoleEventRecord::popChain(list<DipoleChain>::iterator ch) {
   assert(!theChains.empty());
   theDoneChains.push_back(DipoleChain());
   theDoneChains.back().dipoles().splice(theDoneChains.back().dipoles().begin(),ch->dipoles());
   theChains.erase(ch);
 }
 
 void DipoleEventRecord::popChains(const list<list<DipoleChain>::iterator>& chs) {
 
   assert(!theChains.empty());
 
   for ( list<list<DipoleChain>::iterator>::const_iterator ch =
 	  chs.begin(); ch != chs.end(); ++ch ) {
     theDoneChains.push_back(DipoleChain());
     theDoneChains.back().dipoles().splice(theDoneChains.back().dipoles().begin(),(*ch)->dipoles());
   }
 
   for ( list<list<DipoleChain>::iterator>::const_iterator ch =
 	  chs.begin(); ch != chs.end(); ++ch )
     theChains.erase(*ch);
 
 }
 
 DipoleIndex 
 DipoleEventRecord::mergeIndex(list<Dipole>::iterator firstDipole, const pair<bool,bool>& whichFirst,
 			      list<Dipole>::iterator secondDipole, const pair<bool,bool>& whichSecond) const {
   tcPDPtr emitterData = 
     whichFirst.first ? firstDipole->leftParticle()->dataPtr() : firstDipole->rightParticle()->dataPtr();
   tcPDPtr spectatorData = 
     whichSecond.first ? secondDipole->leftParticle()->dataPtr() : secondDipole->rightParticle()->dataPtr();
   const PDF& emitterPDF =
     whichFirst.first ? firstDipole->leftPDF() : firstDipole->rightPDF();
   const PDF& spectatorPDF =
     whichSecond.first ? secondDipole->leftPDF() : secondDipole->rightPDF();
   return DipoleIndex(emitterData,spectatorData,emitterPDF,spectatorPDF);
 }
 
 
 SubleadingSplittingInfo 
 DipoleEventRecord::mergeSplittingInfo(list<DipoleChain>::iterator firstChain, list<Dipole>::iterator firstDipole, 
 				      const pair<bool,bool>& whichFirst,
 				      list<DipoleChain>::iterator secondChain, list<Dipole>::iterator secondDipole, 
 				      const pair<bool,bool>& whichSecond) const {
   SubleadingSplittingInfo res;
   res.index(mergeIndex(firstDipole,whichFirst,secondDipole,whichSecond));
   res.emitter(whichFirst.first ? firstDipole->leftParticle() : firstDipole->rightParticle());
   res.spectator(whichSecond.first ? secondDipole->leftParticle() : secondDipole->rightParticle());
   res.emitterX(whichFirst.first ? firstDipole->leftFraction() : firstDipole->rightFraction());
   res.spectatorX(whichSecond.first ? secondDipole->leftFraction() : secondDipole->rightFraction());
   res.configuration(whichFirst);
   res.spectatorConfiguration(whichSecond);
   res.emitterChain(firstChain);
   res.emitterDipole(firstDipole);
   res.spectatorChain(secondChain);
   res.spectatorDipole(secondDipole);
   return res;
 }
 
 void DipoleEventRecord::getSubleadingSplittings(list<SubleadingSplittingInfo>& res) {
   static pair<bool,bool> left(true,false);
   static pair<bool,bool> right(false,true);
   res.clear();
   for ( list<DipoleChain>::iterator cit = theChains.begin();
 	cit != theChains.end(); ++cit ) {
     for ( list<Dipole>::iterator dit = cit->dipoles().begin();
 	  dit != cit->dipoles().end(); ++dit ) {
       for ( list<Dipole>::iterator djt = dit;
 	    djt != cit->dipoles().end(); ++djt ) {
 	res.push_back(mergeSplittingInfo(cit,dit,left,cit,djt,left));
 	res.push_back(mergeSplittingInfo(cit,dit,right,cit,djt,right));
 	if ( dit != djt ) {
 	  res.push_back(mergeSplittingInfo(cit,dit,left,cit,djt,right));
 	  res.push_back(mergeSplittingInfo(cit,dit,right,cit,djt,left));
 	}
       }
     }
     list<DipoleChain>::iterator cjt = cit; ++cjt;
     for ( ; cjt != theChains.end(); ++cjt ) {
       for ( list<Dipole>::iterator dit = cit->dipoles().begin();
 	    dit != cit->dipoles().end(); ++dit ) {
 	for ( list<Dipole>::iterator djt = cjt->dipoles().begin();
 	      djt != cjt->dipoles().end(); ++djt ) {
 	  res.push_back(mergeSplittingInfo(cit,dit,left,cjt,djt,left));
 	  res.push_back(mergeSplittingInfo(cit,dit,right,cjt,djt,right));
 	  res.push_back(mergeSplittingInfo(cit,dit,left,cjt,djt,right));
 	  res.push_back(mergeSplittingInfo(cit,dit,right,cjt,djt,left));
 	}
       }
     }
   }
 }
 
 void DipoleEventRecord::splitSubleading(SubleadingSplittingInfo& dsplit,
 					pair<list<Dipole>::iterator,list<Dipole>::iterator>& childIterators,
 					DipoleChain*& firstChain, DipoleChain*& secondChain) {
   if ( dsplit.emitterDipole() == dsplit.spectatorDipole() ) {
     assert(dsplit.emitterChain() == dsplit.spectatorChain());
     split(dsplit.emitterDipole(),dsplit.emitterChain(),dsplit,
 	  childIterators,firstChain,secondChain,false);
   } else {
     // first need to recoil, then split
     recoil(dsplit.spectatorDipole(),dsplit.spectatorChain(),dsplit);
     split(dsplit.emitterDipole(),dsplit.emitterChain(),dsplit,
 	  childIterators,firstChain,secondChain,true);
   }
 }
 
 void DipoleEventRecord::findChains(const PList& ordered, 
 				   const set<long>& offShellPartons,
 				   const bool decay) {
   
   // All uses of findChains should guarantee
   // a non-empty list of particles
   assert( !ordered.empty() );
   
   theChains.clear();
   theDoneChains.clear();
 
   DipoleChain current_chain;
 
   // this whole thing needs to have a more elegant implementation at some point
 
   bool startIsTriplet =
     (ordered.front()->hasColour() && !ordered.front()->hasAntiColour()) ||
     (!ordered.front()->hasColour() && ordered.front()->hasAntiColour());
   bool endIsTriplet =
     (ordered.back()->hasColour() && !ordered.back()->hasAntiColour()) ||
     (!ordered.back()->hasColour() && ordered.back()->hasAntiColour());
 
 
   if (!( ordered.size() == 2 && startIsTriplet && endIsTriplet)) {
     
     PList::const_iterator theStart = ordered.begin();
     bool onceMore = false;
 
     for (PList::const_iterator p = ordered.begin();
 	 p != ordered.end(); ++p) {
 
       PList::const_iterator next_it =
 	p != --ordered.end() ? std::next(p) : ordered.begin();
 
       if (!DipolePartonSplitter::colourConnected(*p,*next_it)) {
 	// it may have happened that we need to close the chain due to another
 	// chain starting right now; see the above global comment for this fix
 	bool startIsOctet =
 	  (**theStart).hasColour() && (**theStart).hasAntiColour();
 	bool endIsOctet =
 	  (**p).hasColour() && (**p).hasAntiColour();
 	if ( DipolePartonSplitter::colourConnected(*p,*theStart) &&
 	     startIsOctet && endIsOctet ) {
 	  swap(next_it,theStart);
 	  onceMore = true;
 	} else {
           theStart = next_it;
           current_chain.check();
           // Randomize the chains agains biasing of directions.
           if(UseRandom::rndbool()) theChains.push_back(current_chain);
 	  else theChains.insert(theChains.begin(),current_chain);
           current_chain.dipoles().clear();
           continue;
 	}
       }
 
       pair<bool,bool> initial_state (false,false);
       initial_state.first = (*p == incoming().first || *p == incoming().second);
       initial_state.second = (*next_it == incoming().first || *next_it == incoming().second);
 
       pair<int,int> which_in (-1,-1);
       if (initial_state.first)
 	which_in.first = *p == incoming().first ? 0 : 1;
       if (initial_state.second)
 	which_in.second = *next_it == incoming().first ? 0 : 1;
 
       pair<double,double> xs (1.,1.);
       if (initial_state.first)
 	xs.first = *p == incoming().first ? fractions().first : fractions().second;
       if (initial_state.second)
 	xs.second = *next_it == incoming().first ? fractions().first : fractions().second;
 
       pair<PDF,PDF> pdf;
 
       if ( which_in.first == 0 )
 	pdf.first = pdfs().first;
       else if ( which_in.first == 1 )
 	pdf.first = pdfs().second;
 
       if ( which_in.second == 0 )
 	pdf.second = pdfs().first;
       else if ( which_in.second == 1 )
 	pdf.second = pdfs().second;
       
       // In the case of a decay process register which
       // parton is incoming to the decay
       pair<bool,bool> decayed_parton (false,false);
       if (decay) {
         decayed_parton.first = (*p == currentDecay()->incoming()[0].first);
         decayed_parton.second = (*next_it == currentDecay()->incoming()[0].first);
       }
      
       // Identify if either parton can have an off-shell mass
       // The first test for partons with zero nominal mass should
       // avoid issues of e.g. non-zero mass gluons
       pair<bool,bool> off_shell (false,false);
 
       // Note we could do away with the offShellPartons set but,
       // to be safe in the case of an off-shell parton with a mass
       // *very* close to its on-shell mass, we would need to include tests on the
       // offShell indicators in the DipoleIndex == and < operators AND
       // in canHandle and canHandleEquivalent in each massive kernel.
       // Testing these in every splitting will probably be more expensive
       // than doing the following checks for each hard process and decay process
 
       // Only do off-shell check if the nominal mass is non-zero
       if ( (*p)->nominalMass() != ZERO ) {
 	if ( offShellPartons.find(abs((*p)->id())) != offShellPartons.end() )
 	  off_shell.first = true;
 	else 
 	  assert( abs((*p)->mass() - (*p)->nominalMass()) < (*p)->nominalMass()*1.e-5
 		  && "There is an off-shell coloured particle in the hard process or a decay"
 		  "which  needs to be added to DipoleShowerHandler:OffShellInShower." );
       }
      
       if ( (*next_it)->nominalMass() != ZERO ) {
 	if ( offShellPartons.find(abs((*next_it)->id())) != offShellPartons.end() )
 	  off_shell.second = true;
 	else
 	  assert( abs((*next_it)->mass() - (*next_it)->nominalMass())
 		  < (*next_it)->nominalMass()*1.e-5
 		  && "There is an off-shell coloured particle in the hard process or a decay"
 		  "which  needs to be added to DipoleShowerHandler:OffShellInShower." );
       }
 
       
       current_chain.dipoles().push_back(Dipole({*p,*next_it},pdf,xs,
 					       decayed_parton, off_shell));
       
       if ( onceMore ) {
         next_it = theStart;
         current_chain.check();
         // Randomize the chains agains biasing of directions.
         if(UseRandom::rndbool()) theChains.push_back(current_chain);
         else theChains.insert(theChains.begin(),current_chain);
         current_chain.dipoles().clear();
         onceMore = false;
       }
       
     }
   } else {
     
     // treat 2 -> singlet, singlet -> 2 and 1 + singlet -> 1 + singlet special
     // to prevent duplicate dipole
 
     assert(DipolePartonSplitter::colourConnected(ordered.front(),ordered.back()));
 
     pair<bool,bool> initial_state (false,false);
     initial_state.first = (ordered.front() == incoming().first || ordered.front() == incoming().second);
     initial_state.second = (ordered.back() == incoming().first || ordered.back() == incoming().second);
 
     pair<int,int> which_in (-1,-1);
     if (initial_state.first)
       which_in.first = ordered.front() == incoming().first ? 0 : 1;
     if (initial_state.second)
       which_in.second = ordered.back() == incoming().first ? 0 : 1;
 
     pair<double,double> xs (1.,1.);
     if (initial_state.first)
       xs.first = ordered.front() == incoming().first ? fractions().first : fractions().second;
     if (initial_state.second)
       xs.second = ordered.back() == incoming().first ? fractions().first : fractions().second;
 
     pair<PDF,PDF> pdf;
 
     if ( which_in.first == 0 )
       pdf.first = pdfs().first;
     else if ( which_in.first == 1 )
       pdf.first = pdfs().second;
 
     if ( which_in.second == 0 )
       pdf.second = pdfs().first;
     else if ( which_in.second == 1 )
       pdf.second = pdfs().second;
     
     
     // In the case of a decay process register which
     // parton is incoming to the decay
     pair<bool,bool> decayed_parton (false,false);
     if (decay) {
       decayed_parton.first = (ordered.front() == currentDecay()->incoming()[0].first);
       decayed_parton.second = (ordered.back() == currentDecay()->incoming()[0].first);
     }
 
     
     // Identify if either parton can have an off-shell mass
     // The first test for partons with zero nominal mass should
     // avoid issues of e.g. non-zero mass gluons
     pair<bool,bool> off_shell (false,false);
 
     // Only do off-shell check if the nominal mass is non-zero
     if ( ordered.front()->nominalMass() != ZERO ) {
       if ( offShellPartons.find(abs(ordered.front()->id())) != offShellPartons.end() )
 	off_shell.first = true;
       else
 	assert( abs(ordered.front()->mass() - ordered.front()->nominalMass())
 		< ordered.front()->nominalMass()*1.e-5
 		&& "There is an off-shell coloured particle in the hard process or a decay"
 		"which  needs to be added to DipoleShowerHandler:OffShellInShower." );
     }
    
     if ( ordered.back()->nominalMass() != ZERO ) {
       if ( offShellPartons.find(abs(ordered.back()->id())) != offShellPartons.end() )
 	off_shell.second = true;
       else
 	assert( abs(ordered.back()->mass() - ordered.back()->nominalMass())
 		< ordered.back()->nominalMass()*1.e-5
 		&& "There is an off-shell coloured particle in the hard process or a decay"
 		"which  needs to be added to DipoleShowerHandler:OffShellInShower." );
     }
         
     current_chain.dipoles().push_back(Dipole({ordered.front(),ordered.back()},
 					     pdf,xs, decayed_parton, off_shell));
     
   }
 
   if (!current_chain.dipoles().empty()) {
     current_chain.check();
     // Randomize the chains agains biasing of directions.
     if(UseRandom::rndbool()) theChains.push_back(current_chain);
     else theChains.insert(theChains.begin(),current_chain);
   }
 
 }
 
 const map<PPtr,PPtr>&
 DipoleEventRecord::prepare(tSubProPtr subpro,
                            tStdXCombPtr xc,
 			   StepPtr step,
                            const pair<PDF,PDF>& pdf,tPPair beam,
 			   bool firstInteraction,
 			   const set<long>& offShellPartons,
 			   bool dipoles) {
   // set the subprocess
   subProcess(subpro);
   // clear the event record
   outgoing().clear();
   theHard.clear();
   theOriginals.clear();
   theDecays.clear();
   theCurrentDecay = PerturbativeProcessPtr();
+
+  subEmDone = 0;
+  if ( doSubleadingNc && firstInteraction ) {
+
+    theDensityOperator.clear();
+    continueSubleadingNc = true;
+   
+    const Ptr<MatchboxXComb>::tptr MBXCombPtr
+      = dynamic_ptr_cast<Ptr<MatchboxXComb>::tptr >(xc);
+    if ( !MBXCombPtr ) {
+      throw Exception() << "Cannot cast StandardXComb as MatchboxXComb. "
+			<< "Matchbox is required for "
+			<< "colour matrix element corrections."
+			<< Exception::runerror; 
+    }
+    // Set the colour basis if it has not been set
+    if ( !theDensityOperator.colourBasis() ) {
+      theDensityOperator.colourBasis(MBXCombPtr->matchboxME()->matchboxAmplitude()->colourBasis());
+    } else if ( theDensityOperator.colourBasis() != 
+	 MBXCombPtr->matchboxME()->matchboxAmplitude()->colourBasis() ) {
+      throw Exception() << "The colour basis used in the colour matrix "
+			<< "element corrections should not change between events. "
+			<< Exception::runerror; 
+    }
+
+  } else {
+    continueSubleadingNc = false;
+  }
+
   // extract incoming particles
   PPair in = subpro->incoming();
   // get the incoming momentum fractions
   // don't take these from the XComb as it may be null
   pair<double,double> xs;
   ThePEG::Direction<0> dir(true);
   xs.first = in.first->momentum().dirPlus()/beam.first->momentum().dirPlus();
   dir.reverse();
   xs.second = in.second->momentum().dirPlus()/beam.second->momentum().dirPlus();
+
   xcombPtr(xc);
   pdfs() = pdf;
   fractions() = xs;
   // use ShowerHandler to split up the hard process
   PerturbativeProcessPtr hard;
   DecayProcessMap decay;
 
   // Special handling for the first interaction:
   // If a post subprocess handler (e.g. QED radiation)
   // is applied, there may be particles in the step object not
   // present in the subprocess object (other than any remnants).
   // These need to be included in any transformations due to
   // II splittings in ::update.
   if ( firstInteraction ) {
 
     // Initialise a PVector for the outgoing
     tPVector hardProcOutgoing;
 
     // Include all outgoing particles that are not remnants
     for ( auto & part : step->particles() )
       if ( part->id() != 82 ) {
 	hardProcOutgoing.push_back(part);
       }
     ShowerHandler::currentHandler()->splitHardProcess(hardProcOutgoing,
 						      hard, decay);
   }
 
   // For secondary collisions we must use the
   // subProcess object and not the step as the
   // step stores all outgoing from the entire collision
   else
     ShowerHandler::currentHandler()->splitHardProcess(tPVector(subpro->outgoing().begin(),
 							       subpro->outgoing().end()),
 						      hard,decay);
   
   // vectors for originals and copies of the particles
   vector<PPtr> original;
   vector<PPtr> copies;
   // fill originals
   for(unsigned int ix=0;ix<2;++ix)
     original.push_back(hard->incoming()[ix].first);
   for(unsigned int ix=0;ix<hard->outgoing().size();++ix)
     original.push_back(hard->outgoing()[ix].first);
   for(DecayProcessMap::const_iterator it=decay.begin();it!=decay.end();++it) {
     fillFromDecays(it->second, original);
   }
   // and make copies
   for ( vector<PPtr>::const_iterator p = original.begin();
 	p != original.end(); ++p ) {
     PPtr copy = new_ptr(Particle(**p));
     copies.push_back(copy);
     theOriginals[*p] = copy;
   }
   // isolate the colour of the copies from the originals
   colourIsolate(original,copies);
   
   // set the incoming particles
   incoming().first = copies[0];
   ParticleVector children = incoming().first->children();
   for ( ParticleVector::const_iterator c = children.begin();
 	c != children.end(); ++c )
     incoming().first->abandonChild(*c);
   incoming().second = copies[1];
   children = incoming().second->children();
   for ( ParticleVector::const_iterator c = children.begin();
 	c != children.end(); ++c )
     incoming().second->abandonChild(*c);
   
   // set the outgoing particles for the hard process
   for(unsigned int ix=0;ix<hard->outgoing().size();++ix) {
     if(hard->outgoing()[ix].first->coloured())
       outgoing().push_back(theOriginals[hard->outgoing()[ix].first]);
     else
       theHard.push_back(theOriginals[hard->outgoing()[ix].first]);
   }
 
   if ( dipoles ) {
     PList cordered = colourOrdered(incoming(),outgoing());
     if ( !cordered.empty() )
       findChains(cordered, offShellPartons, false);
   }
   
   
   
   // sort out the decays
   for(auto const & dec : decay) {
     
     // If the decay particle is in original it needs
     // to be added to the decays and the decay needs to be
     // changed to the copied particles.
     if ( theOriginals.find(dec.second->incoming()[0].first) != theOriginals.end() ) {
       theDecays[theOriginals[dec.second->incoming()[0].first]] = dec.second;
       PerturbativeProcessPtr decayProc = theDecays[theOriginals[dec.second->incoming()[0].first]];
       separateDecay(decayProc);
     }
     
     else {
       assert( find( copies.begin(), copies.end(), dec.second->incoming()[0].first ) != copies.end() );
       theDecays[dec.second->incoming()[0].first] = dec.second;
     }
   }
   
   
   PList::const_iterator XFirst, XLast;
 
   if ( !theHard.empty() ) {
     XFirst = theHard.begin();
     XLast = theHard.end();
   } else {
     XFirst = outgoing().begin();
     XLast = outgoing().end();
   }
 
   thePX = (**XFirst).momentum();
   ++XFirst;
   for ( ; XFirst != XLast; ++XFirst )
     thePX += (**XFirst).momentum();
   identifyEventType();
+
+
+  if ( doSubleadingNc ) {
+    theParticlesBefore.clear();
+    theParticlesAfter.clear();
+    theMomentaAfter.clear();
+    theParticleIndices.clear();
+    
+    // Set the particles and fill the dictionary
+    theParticleIndices[incoming().first] = 0;
+    theParticleIndices[incoming().second] = 1;
+    size_t i = 2;
+    theParticlesAfter.reserve(2 + outgoing().size()  + theHard.size());
+    theParticlesAfter.push_back(incoming().first->dataPtr());
+    theParticlesAfter.push_back(incoming().second->dataPtr());
+    theMomentaAfter.push_back(incoming().first->momentum());
+    theMomentaAfter.push_back(incoming().second->momentum());
+    for ( PList::const_iterator it = outgoing().begin(); it != outgoing().end(); it++ ) {
+      theParticlesAfter.push_back((*it)->dataPtr());
+      theMomentaAfter.push_back((*it)->momentum());
+      theParticleIndices[*it] = i;
+      i++;
+    }
+    // theHard is not added to theParticleIndices, as they aren't needed there
+    for ( PList::const_iterator it = theHard.begin(); it != theHard.end(); it++ ) {
+      theParticlesAfter.push_back((*it)->dataPtr());
+      theMomentaAfter.push_back((*it)->momentum());
+    }
+
+    // theParticlesAfter is required for fill
+    const Ptr<MatchboxXComb>::tptr MBXCombPtr
+      = dynamic_ptr_cast<Ptr<MatchboxXComb>::tptr >(xc);
+    if ( !MBXCombPtr ) {
+      throw Exception() << "Cannot cast StandardXComb as MatchboxXComb. "
+			<< "Matchbox is required for "
+			<< "colour matrix element corrections."
+			<< Exception::runerror; 
+    }
+    theDensityOperator.fill(MBXCombPtr,theParticlesAfter,theMomentaAfter);
+  }
+  
   return theOriginals;
   
 }
 
 void DipoleEventRecord::slimprepare(tSubProPtr subpro,
                                     tStdXCombPtr xc,
                                     const pair<PDF,PDF>& pdf,tPPair beam,			 
 				    const set<long>& offShellPartons,
                                     bool dipoles) {
   // set the subprocess
   subProcess(subpro);
   // clear the event record
   outgoing().clear();
   theHard.clear();
   theOriginals.clear();
   theDecays.clear();
   theCurrentDecay = PerturbativeProcessPtr();
   // extract incoming particles
   PPair in = subpro->incoming();
   // get the beam
   // get the incoming momentum fractions
   // don't take these from the XComb as it may be null
   pair<double,double> xs;
   ThePEG::Direction<0> dir(true);
   xs.first = in.first->momentum().dirPlus()/beam.first->momentum().dirPlus();
   dir.reverse();
   xs.second = in.second->momentum().dirPlus()/beam.second->momentum().dirPlus();
   xcombPtr(xc);
   
   pdfs() = pdf;
   fractions() = xs;
   incoming()  = in;
   
   for(unsigned int ix=0;ix<subpro->outgoing().size();++ix) {
     if(subpro->outgoing()[ix]->coloured())
       outgoing().push_back(subpro->outgoing()[ix]);
   }
   
   
   if ( dipoles ) {
     PList cordered = colourOrdered(incoming(),outgoing());
     if ( !cordered.empty() )
       findChains(cordered, offShellPartons, false);
   }
   
 }
 
 
 void DipoleEventRecord::fillFromDecays(PerturbativeProcessPtr decayProc, vector<PPtr>& original) {
   
   // Loop over the outgoing of the given perturbative process
   for ( auto const & outIt : decayProc->outgoing() ) {
     
     // Add the outgoing particle to the vector of original particles
     original.push_back(outIt.first);
     
     // Iterate through the outgoing
     if ( outIt.second )
       fillFromDecays( outIt.second, original);
   }
 }
 
 
 void DipoleEventRecord::separateDecay(PerturbativeProcessPtr decayProc) {
   
   // Iteratively replace all entries in the incoming
   // with their copies.
   for ( auto  & inIt : decayProc->incoming() ) {
     
     if ( theOriginals.find( inIt.first ) != theOriginals.end() )
       inIt.first = theOriginals[inIt.first];
   }
   
   // Iteratively replace all entries in the outgoing
   // with their copies.
   for ( auto  & outIt : decayProc->outgoing()) {
     
     if ( theOriginals.count( outIt.first ) )
       outIt.first = theOriginals[outIt.first];
     
     if ( outIt.second )
       separateDecay(outIt.second);
   }
 }
 
 
 void DipoleEventRecord::clear() {
   ShowerEventRecord::clear();
   theDecays.clear();
   theHard.clear();
   theChains.clear();
   theDoneChains.clear();
   theOriginals.clear();
+  theDensityOperator.clear();
+  theParticlesBefore.clear();
+  theParticlesAfter.clear();
+  theMomentaAfter.clear();
+  theNextDecays.clear();
 }
 
 
 
-
 pair<PVector,PVector> DipoleEventRecord::tmpupdate(DipoleSplittingInfo& dsplit) {
   
   PVector inc;
   PVector out;
   
   tcPPtr IF = incoming().first;
   tcPPtr IS = incoming().second;
   
   tcPPtr DE = dsplit.emitter();
   tcPPtr DS = dsplit.spectator();
   
   if ( IF != DE && IF != DS ) {
     PPtr p = IF->data().produceParticle(IF->momentum());
     inc.push_back(p);
   }
   else if ( IF == DE ) inc.push_back( dsplit.splitEmitter() );
   else if ( IF == DS ) inc.push_back( dsplit.splitSpectator() );
   
   if ( IS != DE && IS != DS ) {
     PPtr p = IS->data().produceParticle(IS->momentum());
     inc.push_back(p);
   }
   else if ( IS == DE ) inc.push_back( dsplit.splitEmitter() );
   else if ( IS == DS ) inc.push_back( dsplit.splitSpectator() );
   
   
   if ( IF != DE && IS != DE)
     out.push_back( dsplit.splitEmitter());
   
   if ( IF != DS && IS != DS)
     out.push_back( dsplit.splitSpectator());
   
   out.push_back( dsplit.emission());
   
   for ( tcPPtr h : theHard ){
     PPtr p = h->data().produceParticle(h->momentum());
     if ( dsplit.splittingKinematics()->doesTransform() ) {
-      p->set5Momentum( dsplit.splittingKinematics()->transform(p->momentum()) );
+      dsplit.splittingKinematics()->transform(p);
     }
     out.push_back(p);
   }
   
   for ( tcPPtr p : outgoing() )
     if ( p != DE &&
-	 p != DS &&
-	 p != dsplit.emission() ){
+         p != DS &&
+         p != dsplit.emission() ){
     
       PPtr ou = p->data().produceParticle(p->momentum());;
       if ( dsplit.splittingKinematics()->doesTransform() ){
-	ou->set5Momentum( dsplit.splittingKinematics()->transform(ou->momentum()) );
+        dsplit.splittingKinematics()->transform(ou);
       }
       out.push_back(ou);
     }
   return {inc,out};
 }
 
 
+
 void DipoleEventRecord::update(DipoleSplittingInfo& dsplit) {
+
+  if ( continueSubleadingNc ) {
+    subEmDone++;
+    theParticlesBefore = theParticlesAfter;
+  }
   if ( incoming().first == dsplit.emitter() ) {
     intermediates().push_back(dsplit.emitter());
     incoming().first = dsplit.splitEmitter();
     fractions().first /= dsplit.lastEmitterZ();
+    if ( continueSubleadingNc ) {
+      theParticleIndices[dsplit.splitEmitter()] = 0;
+      theParticlesAfter[0] = dsplit.splitEmitter()->dataPtr();
+      theEmitterEmissionIndices.first = 0;
+      theEmitterEmissionIndices.second.first = 0;
+    }
   } else if ( incoming().first == dsplit.spectator() ) {
     intermediates().push_back(dsplit.spectator());
     incoming().first = dsplit.splitSpectator();
-    fractions().first /= dsplit.lastSpectatorZ();    
+    fractions().first /= dsplit.lastSpectatorZ();
+    if ( continueSubleadingNc ) {
+      theParticleIndices[dsplit.splitSpectator()] = 0;
+      theParticlesAfter[0] = dsplit.splitSpectator()->dataPtr();
+      theSpectatorIndices.first = 0;
+      theSpectatorIndices.second = 0;
+    }
   }
 
   if ( incoming().second == dsplit.emitter() ) {
     intermediates().push_back(dsplit.emitter());
     incoming().second = dsplit.splitEmitter();
     fractions().second /= dsplit.lastEmitterZ();
+    if ( continueSubleadingNc ) {
+      theParticleIndices[dsplit.splitEmitter()] = 1;
+      theParticlesAfter[1] = dsplit.splitEmitter()->dataPtr();
+      theEmitterEmissionIndices.first = 1;
+      theEmitterEmissionIndices.second.first = 1;
+    }
   } else if ( incoming().second == dsplit.spectator() ) {
     intermediates().push_back(dsplit.spectator());
     incoming().second = dsplit.splitSpectator();
     fractions().second /= dsplit.lastSpectatorZ();    
+    if ( continueSubleadingNc ) {
+      theParticleIndices[dsplit.splitSpectator()] = 1;
+      theParticlesAfter[1] = dsplit.splitSpectator()->dataPtr();
+      theSpectatorIndices.first = 1;
+      theSpectatorIndices.second = 1;
+    }
   }
 
   PList::iterator pos;
 
   pos = find(outgoing().begin(), outgoing().end(), dsplit.emitter());
   if (pos != outgoing().end()) {
     intermediates().push_back(*pos);
     *pos = dsplit.splitEmitter();
+    if ( continueSubleadingNc ) {
+      // The two first elements in theParticlesBefore/After are the incoming
+      theEmitterEmissionIndices.first = 2 + distance(outgoing().begin(), pos);
+      theEmitterEmissionIndices.second.first = theEmitterEmissionIndices.first;
+      theParticlesAfter[theEmitterEmissionIndices.second.first] = dsplit.splitEmitter()->dataPtr();
+      theParticleIndices[dsplit.splitEmitter()] = theEmitterEmissionIndices.second.first;
+    }
   }
 
   pos = find(outgoing().begin(), outgoing().end(), dsplit.spectator());
   if (pos != outgoing().end()) {
     intermediates().push_back(*pos);
     *pos = dsplit.splitSpectator();
+    if ( continueSubleadingNc ) {
+      // The two first elements in theParticlesBefore/After are the incoming
+      theSpectatorIndices.first = 2 + distance(outgoing().begin(), pos);
+      theSpectatorIndices.second = theSpectatorIndices.first;
+      theParticlesAfter[theSpectatorIndices.second] = dsplit.splitSpectator()->dataPtr();
+      theParticleIndices[dsplit.splitSpectator()] = theSpectatorIndices.second;
+    }
+  }
+
+  if ( continueSubleadingNc ) {
+    theEmitterEmissionIndices.second.second = 2 + outgoing().size();
+    theParticlesAfter.insert(theParticlesAfter.begin()+theEmitterEmissionIndices.second.second,
+			     dsplit.emission()->dataPtr());
+    theMomentaAfter.insert(theMomentaAfter.begin()+theEmitterEmissionIndices.second.second,
+			   dsplit.emission()->momentum());
+    theParticleIndices[dsplit.emission()] = theEmitterEmissionIndices.second.second;
   }
 
   outgoing().push_back(dsplit.emission());
 
   if (dsplit.splittingKinematics()->doesTransform()) {
 
+    for (PList::iterator h = theHard.begin();
+         h != theHard.end(); ++h)
+      dsplit.splittingKinematics()->transform(*h);
+
     for (PList::iterator p = intermediates().begin();
-	 p != intermediates().end(); ++p) {
-      (**p).set5Momentum(dsplit.splittingKinematics()->transform((**p).momentum()));
-    }
-
-    for (PList::iterator h = theHard.begin();
-	 h != theHard.end(); ++h) {
-      (**h).set5Momentum(dsplit.splittingKinematics()->transform((**h).momentum()));
-    }
+         p != intermediates().end(); ++p) 
+      dsplit.splittingKinematics()->transform(*p);
 
     for (PList::iterator p = outgoing().begin();
          p != outgoing().end(); ++p) {
       if ((*p) != dsplit.splitEmitter() &&
 	  (*p) != dsplit.splitSpectator() &&
 	  (*p) != dsplit.emission())
-	(**p).set5Momentum(dsplit.splittingKinematics()->transform((**p).momentum()));
+        dsplit.splittingKinematics()->transform(*p);	
     }
+    
+    if ( continueSubleadingNc ) {
+      theMomentaAfter[0] = incoming().first->momentum();
+      theMomentaAfter[1] = incoming().second->momentum();
+      size_t i = 2;
+      for (PList::iterator p = outgoing().begin();
+	   p != outgoing().end(); p++) {
+	theMomentaAfter[i] = (*p)->momentum();
+	i++;
+      }
+      for (PList::iterator p = theHard.begin();
+       	   p != theHard.end(); p++) {
+       	theMomentaAfter[i] = (*p)->momentum();
+       	i++;
+      }
+    }
+    
+  } else if ( continueSubleadingNc ) {
+    theMomentaAfter[theEmitterEmissionIndices.second.first] = dsplit.splitEmitter()->momentum();//
+    theMomentaAfter[theSpectatorIndices.second] = dsplit.splitSpectator()->momentum();//
   }
-  
+
+  // Stop with subleading emissions if the limit has been reached
+  if ( doSubleadingNc ) 
+    if ( subEmDone == subleadingNcEmissionsLimit ) 
+      continueSubleadingNc = false;
+
   // Handle updates related to decays
   // Showering of decay processes
   // Treat the evolution of the incoming
   // decayed particle as in backward evolution
 
   if ( dsplit.isDecayProc() ) {
     
     // Create a pointer to the decay process
     PerturbativeProcessPtr decayProc = currentDecay();
     
     // Add the emission to the outgoing of the decay process
     decayProc->outgoing().push_back( {dsplit.emission(), PerturbativeProcessPtr() });
     // Bools to be used throughout
     const bool decayedEmtr = dsplit.index().incomingDecayEmitter();
     const bool decayedSpec = dsplit.index().incomingDecaySpectator();
     
     
     /*
       In the current implementation, **following the hard process**
       all particles in theDecays evolve independently
       e.g. if we have W -> XYZ where all X, Y and Z need to be
       showered and decayed, we only identify them as needing decaying
       (and hence put them in theDecays) AFTER showering the decay of W.
       Hence, XYZ are not even in theDecays until W has been fully
       showered and then they are decayed and showered completely independently
       KEY POINT - Never need to update other entries of theDecays
     
       Note: The PPtr in theDecays should remain unchanged and all changes
       should be made to the relative PerturbativeProcess.
     */
     
     // Splittings from dipoles in the decay process which
     // do not have the decayed parton as emitter or spectator.
     // Update the decay process in theDecays
     if ( !decayedEmtr && !decayedSpec ) {
       
       // Find and replace the old spectator and
       // emitter in the outgoing of the decay process
       bool decayProcEm = false;
       bool decayProcSp = false;
       
       for ( auto & outIt : decayProc->outgoing() ) {
         if ( !decayProcEm && outIt.first == dsplit.emitter() ) {
           outIt = {dsplit.splitEmitter(), PerturbativeProcessPtr()};
           decayProcEm = true;
         }
         
         if ( !decayProcSp && outIt.first == dsplit.spectator() ) {
           outIt = {dsplit.splitSpectator(), PerturbativeProcessPtr() };
           decayProcSp = true;
         }
-        
+	
         if ( decayProcEm && decayProcSp )
 	  break;
       }
       
       // Test that nothing strange is happening
       assert( (decayProcEm && decayProcSp) );
       
       return;
     }
     
     
     // The spectator is the decayed particle
     else if ( decayedSpec ) {
       
       // Update the dipole event record intermediates
       intermediates().push_back(dsplit.splitSpectator());
       
       // Update the the decayProcess incoming
       decayProc->incoming().clear();
       decayProc->incoming().push_back({dsplit.splitSpectator(),decayProc});
       
       // Update the decay process outgoing
       // Replace the old emitter with the new emitter
       for ( auto & outEmtrIt : decayProc->outgoing() ) {
         if ( outEmtrIt.first == dsplit.emitter() ){
           outEmtrIt = {dsplit.splitEmitter(), PerturbativeProcessPtr() };
           break;
         }
       }
       
       // Perform the recoil transformation
       // Find all particles in the recoil system
       PList recoilSystem;
       for ( auto const & outIt : decayProc->outgoing() ) {
         if ( outIt.first != dsplit.splitEmitter() && outIt.first != dsplit.emission() ) {
           recoilSystem.push_back(outIt.first);
         }
       }
       dsplit.splittingKinematics()->decayRecoil( recoilSystem );
       
       return;
     }
     
     
     // The emitter is the decayed particle
     else  {
       throw Exception()
 	<< "DipoleEventRecord: The emitter as a decayed particle is currently not implemented."
 	<< Exception::runerror;
       
       assert( currentDecay()->incoming()[0].first == dsplit.emitter() && decayedEmtr && !decayedSpec );
       
       // Update the dipole event record intermediates
       intermediates().push_back(dsplit.splitEmitter());
       
       // Update the the decayProcess incoming
       decayProc->incoming().clear();
       decayProc->incoming().push_back({dsplit.splitEmitter(),decayProc});
       
       // Update the decay process outgoing
       // Replace the old spectator with the new spectator
       for (auto & outSpecIt : decayProc->outgoing() ) {
         if ( outSpecIt.first == dsplit.spectator() ){
           outSpecIt = { dsplit.splitSpectator(), PerturbativeProcessPtr() };
           break;
         }
       }
       
       // Perform the recoil transformation
       assert(dsplit.splittingKinematics()->isDecay());
       // Find all particles in the recoil system
       PList recoilSystem;
       for ( auto const & outIt : decayProc->outgoing() ) {
         if ( outIt.first != dsplit.splitSpectator() && outIt.first != dsplit.emission() ) {
           recoilSystem.push_back(outIt.first);
         }
       }
       dsplit.splittingKinematics()->decayRecoil( recoilSystem );
       
       return;
     }
     
   }
+
+  if ( continueSubleadingNc ) {
+    // Fixed alphaS
+    double alphaS = 0.118;
+
+    map<pair<size_t,size_t>,Complex> Vijk;
+    double Vtemp;
+    const Lorentz5Momentum pEmission = dsplit.emission()->momentum();
+
+    // Special cases for the density operator evolution
+    // g->qqbar splitting
+    bool splitAGluon = (dsplit.emitter()->id() == ParticleID::g) && 
+      (dsplit.emission()->id() != ParticleID::g);
+    // initial state g->qqbar splitting 
+    bool initialGluonSplitting = (dsplit.splitEmitter()->id() == ParticleID::g) && 
+      (dsplit.emission()->id() != ParticleID::g);
+    if ( initialGluonSplitting )
+      assert(dsplit.splitEmitter() == incoming().first
+	     || dsplit.splitEmitter() == incoming().second);
+
+    // Set up the dictionary
+    std::tuple<size_t,size_t,size_t> tmpTuple;
+    map<size_t,size_t> tmpMap;
+    size_t n = theEmitterEmissionIndices.second.second;
+    theEmissionsMap.clear();
+    if ( splitAGluon || initialGluonSplitting ) {
+      tmpTuple = std::make_tuple(theEmitterEmissionIndices.first,
+				 theEmitterEmissionIndices.second.first,
+				 theEmitterEmissionIndices.second.second);
+      tmpMap.clear();
+      for ( size_t j = 0; j < theParticlesBefore.size(); j++ ) {
+	if ( j != theEmitterEmissionIndices.first )
+	  tmpMap[j] = j; 
+      }
+      theEmissionsMap[tmpTuple] = tmpMap;
+    } else {
+      for ( size_t i = 0; i < theParticlesBefore.size(); i++ ) {
+	if ( theParticlesBefore[i]->coloured() ) {
+	  tmpTuple = std::make_tuple(i,i,n);
+	  tmpMap.clear();
+	  for ( size_t j = 0; j < theParticlesBefore.size(); j++ ) {
+	    if ( j != i )
+	      tmpMap[j] = j; 
+	  }
+	  theEmissionsMap[tmpTuple] = tmpMap;
+	}
+      }
+    }
+
+    Energy2 pEmitpEmis;
+    Energy2 pEmispSpec;
+
+    Lorentz5Momentum pEmitter;
+    Lorentz5Momentum pSpectator;
+
+    // Calculate all required dipole factors
+    int i,k;
+    typedef map<std::tuple<size_t,size_t,size_t>,map<size_t,size_t> > dictMap;
+    for(dictMap::const_iterator ijit = theEmissionsMap.begin();
+	ijit != theEmissionsMap.end(); ijit++) {
+      i = std::get<1>(ijit->first);
+      pEmitter = theMomentaAfter[i];
+      pEmitpEmis = pEmitter*pEmission;
+      for(dictMap::const_iterator kit = theEmissionsMap.begin();
+	  kit != theEmissionsMap.end(); kit++) {
+	// For gluon splitting ijit == kit
+	if ( ijit != kit ) {
+	  k = std::get<1>(kit->first);
+	  pSpectator = theMomentaAfter[k];
+	  pEmispSpec = pEmission*pSpectator;
+	  Vtemp = 4*Constants::pi*alphaS*dipoleKernelForEvolution(i, k,
+								  pEmitter*pSpectator, pEmitpEmis, 
+								  pEmispSpec);
+	  Vijk.insert(make_pair(make_pair(i,k),Complex(Vtemp,0.0)));
+	} else if ( splitAGluon || initialGluonSplitting ) {
+	  k = std::get<1>(kit->first);
+	  Vijk.insert(make_pair(make_pair(i,k),Complex(1.0,0.0)));
+	}
+      }
+    }
+
+    theDensityOperator.evolve(Vijk,theParticlesBefore,theParticlesAfter,
+			      theEmissionsMap,splitAGluon,initialGluonSplitting);
+  }
+}
+
+double 
+DipoleEventRecord::dipoleKernelForEvolution(size_t em, size_t spec,
+					    Energy2 pEmitpSpec, Energy2 pEmitpEmis, 
+					    Energy2 pEmispSpec) {
+  double Vijk;
+
+  if ( densityOperatorEvolution == 3 ) {
+    if ( em == theEmitterEmissionIndices.second.first && 
+	 spec == theSpectatorIndices.second ) { 
+      Vijk = 1.0;
+    } else {
+      Vijk = 0.0;
+    }
+  } else if ( densityOperatorEvolution == 2 ) {
+    Vijk = 1.0;
+  } else {
+    if ( densityOperatorEvolution == 0 ) {
+      if ( pEmitpEmis < densityOperatorCutoff ) pEmitpEmis = densityOperatorCutoff; 
+      if ( pEmispSpec < densityOperatorCutoff ) pEmispSpec = densityOperatorCutoff;
+    }
+    Vijk = ((pEmitpSpec)/GeV2)/((pEmitpEmis/GeV2)*
+				(pEmispSpec/GeV2));
+  }
+  
+  return Vijk;
 }
 
 void
 DipoleEventRecord::split(list<Dipole>::iterator dip,
                          list<DipoleChain>::iterator ch,
                          DipoleSplittingInfo& dsplit,
                          pair<list<Dipole>::iterator,list<Dipole>::iterator>& childIterators,
                          DipoleChain*& firstChain, DipoleChain*& secondChain,
                          bool colourSpectator) {
   
   static DipoleChain empty;
-  pair<Dipole,Dipole> children = dip->split(dsplit,colourSpectator);
+
+  pair<Dipole,Dipole> children = dip->split(dsplit,colourSpectator,
+					    continueSubleadingNc);
 
   list<Dipole>::iterator breakup =
     ch->insertSplitting(dip,children,childIterators);
 
   if ( breakup == ch->dipoles().end() ) {
     firstChain = &(*ch);
     secondChain = &empty;
   } else {
 
     DipoleChain other;
     other.dipoles().splice(other.dipoles().end(),ch->dipoles(),breakup,ch->dipoles().end());
 
     chains().push_back(other);
     firstChain = &(*ch);
     secondChain = &(chains().back());
 
     // explicitly fix iterators in case the splice implementation
     // at hand does invalidate iterators (the SGI docu says, it doesn't,
     // but it seems that this behaviour is not part of the standard)
     childIterators.first = --firstChain->dipoles().end();
     childIterators.second = secondChain->dipoles().begin();  }
   
   if ( !colourSpectator ) {
     update(dsplit); // otherwise done by recoil(...)
     
   }
 }
 
+ 
 
 pair<PVector,PVector> DipoleEventRecord::tmpsplit(list<Dipole>::iterator dip,
                                                   list<DipoleChain>::iterator ,
                                                   DipoleSplittingInfo& dsplit,
                                                   pair<list<Dipole>::iterator,list<Dipole>::iterator>& ,
                                                   DipoleChain*& , DipoleChain*& ,
                                                   bool colourSpectator) {
   
   
   dip->tmpsplit(dsplit,colourSpectator);
   return tmpupdate(dsplit); // otherwise done by recoil(...)
   
 }
 
 void DipoleEventRecord::recoil(list<Dipole>::iterator dip,
                                list<DipoleChain>::iterator ch,
                                DipoleSplittingInfo& dsplit) {
   
   dip->recoil(dsplit);
   ch->updateDipole(dip);
 
   update(dsplit);
 
 }
 
 list<pair<list<Dipole>::iterator,list<DipoleChain>::iterator> >
 DipoleEventRecord::inDipoles() {
 
   list<pair<list<Dipole>::iterator,list<DipoleChain>::iterator> > res;
 
   for ( list<DipoleChain>::iterator chit = theDoneChains.begin();
 	chit != theDoneChains.end(); ++chit ) {
 
     bool haveOne = false;
 
     for ( list<Dipole>::iterator dit = chit->dipoles().begin();
 	  dit != chit->dipoles().end(); ++dit ) {
       if ( dit->leftPDF().pdf() || dit->rightPDF().pdf() ) {
 	haveOne = true;
 	break;
       }
     }
 
     if ( haveOne ) {
       theChains.splice(theChains.begin(),theDoneChains,chit);
       for ( list<Dipole>::iterator dit = theChains.front().dipoles().begin();
 	    dit != theChains.front().dipoles().end(); ++dit ) {
         if ( dit->leftPDF().pdf() || dit->rightPDF().pdf() ) {
           res.push_back({dit,theChains.begin()});
         }
       }
     }
 
   }
 
   return res;
 
 }
 
-void DipoleEventRecord::transform(const SpinOneLorentzRotation& rot) {
+void DipoleEventRecord::transform(const LorentzRotation& rot) {
 
 
   Lorentz5Momentum tmp;
 
   for (PList::iterator p = intermediates().begin();
        p != intermediates().end(); ++p) {
-    tmp = (**p).momentum(); tmp = rot * tmp;
+    tmp = (**p).momentum();
+    if ( (*p)->spinInfo() )
+      (*p)->spinInfo()->transform(tmp, rot);
+    tmp = rot * tmp;
     (**p).set5Momentum(tmp);
   }
 
   for (PList::iterator h = theHard.begin();
        h != theHard.end(); ++h) {
-    tmp = (**h).momentum(); tmp = rot * tmp;
+    tmp = (**h).momentum();
+    if ( (*h)->spinInfo() )
+      (*h)->spinInfo()->transform(tmp, rot);
+    tmp = rot * tmp;
     (**h).set5Momentum(tmp);
   }
 
   for (PList::iterator p = outgoing().begin();
        p != outgoing().end(); ++p) {
-    tmp = (**p).momentum(); tmp = rot * tmp;
+    tmp = (**p).momentum();
+    if ( (*p)->spinInfo() )
+      (*p)->spinInfo()->transform(tmp, rot);
+    tmp = rot * tmp;
     (**p).set5Momentum(tmp);
   }
 
 }
 
 tPPair DipoleEventRecord::fillEventRecord(StepPtr step, bool firstInteraction, bool) {
 
   PPtr inSubPro = subProcess()->incoming().first;
   PPtr inParticle;
   
   if ( !(inSubPro->parents().empty()) )
     inParticle = inSubPro->parents()[0];
   else
     inParticle = inSubPro;
   
   PPtr inParton = theOriginals[inSubPro];
   theOriginals.erase(inSubPro);
   updateColour(incoming().first,true);
   
   if ( inParticle != inSubPro )
     inParticle->abandonChild(inSubPro);
   inParton->addChild(inSubPro);
   if ( inParticle != inSubPro )
     inParticle->addChild(incoming().first);
   intermediates().push_back(inSubPro);
   intermediates().push_back(inParton);
   
   // Repeat all the above for the second incoming particle
   inSubPro = subProcess()->incoming().second;
   if ( !(inSubPro->parents().empty()) )
     inParticle = inSubPro->parents()[0];
   else
     inParticle = inSubPro;
   inParton = theOriginals[inSubPro];
   theOriginals.erase(inSubPro);
   updateColour(incoming().second,true);
   if ( inParticle != inSubPro )
     inParticle->abandonChild(inSubPro);
   inParton->addChild(inSubPro);
   if ( inParticle != inSubPro )
     inParticle->addChild(incoming().second);
   intermediates().push_back(inSubPro);
   intermediates().push_back(inParton);
   
   // theOriginals is populated in ::prepare and contains all of the incoming and outgoing particles of the original hard process
   // Here outgoing particles from theOriginals are added into the intermediates()
   while ( !theOriginals.empty() ) {
     PPtr outSubPro = theOriginals.begin()->first;
     PPtr outParton = theOriginals.begin()->second;
     // workaround for OS X Mavericks LLVM libc++
 #ifdef _LIBCPP_VERSION
     map<PPtr,PPtr>::const_iterator beg = theOriginals.begin();
 #else
     map<PPtr,PPtr>::iterator beg = theOriginals.begin();
 #endif
     theOriginals.erase(beg);
     updateColour(outParton,true);
     outSubPro->addChild(outParton);
     intermediates().push_back(outSubPro);
   }
   
   // Update the intermediates of the step
   step->addIntermediates(intermediates().begin(),intermediates().end());
   
   for (auto const & p : outgoing())
     step->addDecayProduct( p );
   
   for (auto const & p : theHard)
     step->addDecayProduct( p );
   
   if ( firstInteraction &&
        (incoming().first->coloured() ||
 	incoming().second->coloured() ) ) {
     ShowerHandler::currentHandler()->lastExtractor()
       ->newRemnants(subProcess()->incoming(),incoming(),step);
   }
   
   step->addIntermediate(incoming().first);
   step->addIntermediate(incoming().second);
   
   return incoming();
   
 }
 
 
  bool DipoleEventRecord::prepareDecay( PerturbativeProcessPtr decayProc,
 				       const set<long>& offShellPartons ) {
   
   // Create objects containing the incoming and outgoing partons,
   // required as inputs for colourOrdered.
   PList out;
   for( auto const & dec : decayProc->outgoing()) {
     if(dec.first->coloured()) {
       out.push_back(dec.first);
     }
   }
   
   // Only need to shower if we have coloured outgoing particles
   if ( out.empty() )
     return false;
   
   else {
     // For the incoming, use a PPair containing the incoming and a null pointer
     PPair in;
     in.first = decayProc->incoming()[0].first;
     
-    // Create an ordered list of particles
-    PList cordered;
-    cordered = colourOrdered(in,out);
+
+    // Chains are found later if the subleading shower is used
+    if ( !doSubleadingNc ) {
+      // Create an ordered list of particles
+      PList cordered;
+      cordered = colourOrdered(in,out);
     
-    // Find the dipole chains for this decay
-    findChains(cordered, offShellPartons, true);
-    
+      // Find the dipole chains for this decay
+      findChains(cordered,offShellPartons,true);
+    }    
     return true;
   }
 }
 
 Energy DipoleEventRecord::decay(PPtr incoming, bool& powhegEmission) {
   // get the process
   PerturbativeProcessPtr process = theDecays[incoming];
   assert(process);
   //tDMPtr decayMode = new_ptr(DecayMode());
   tDMPtr decayMode = DMPtr();
   // Do not decay particles that have already been decayed
   // Note the herwig decayer deals with colour connections
   if ( process->outgoing().empty() ) {
     process->incoming()[0].first = incoming;
     DecayProcessMap decay;
     // Decay the particle, returning a pointer to the decay mode
     decayMode = ShowerHandler::currentHandler()->decay(process,decay,true);
   }
   
   
   // Sort out the colour connections of particles already decayed
   else {
     // sort out the colour of the incoming
     map<tColinePtr,tColinePtr> cmap;
     if(incoming->colourLine())
       cmap[process->incoming()[0].first->colourLine()] = incoming->colourLine();
     if(incoming->antiColourLine())
       cmap[process->incoming()[0].first->antiColourLine()] = incoming->antiColourLine();
     // fix colours of outgoing
     for(auto const & outg : process->outgoing()) {
       map<tColinePtr,tColinePtr>::iterator it =
 	cmap.find(outg.first->colourLine());
       if(it!=cmap.end()) {
         ColinePtr c1=outg.first->colourLine();
         c1->removeColoured(outg.first);
         it->second->addColoured(outg.first);
       }
       it = cmap.find(outg.first->antiColourLine());
       if(it!=cmap.end()) {
         ColinePtr c1=outg.first->antiColourLine();
         c1->removeAntiColoured(outg.first);
         it->second->addAntiColoured(outg.first);
       }
     }
     // swap the incoming
     process->incoming()[0].first = incoming;
   }
   
   // Set the scale of all particles involved in the decay process to the
   // mass of the decaying particle
   
   // Initialise the scale for the evolution of
   // the parton shower following the decay
   Energy showerScale = ZERO;
   
   // Set the scale for the evolution of the shower
   showerScale = process->incoming()[0].first->momentum().m();
   
   Energy2 decayScaleSqr = sqr( showerScale );
   process->incoming()[0].first->scale( decayScaleSqr );
   
   for(auto & outg : process->outgoing()) {
     outg.first->scale( decayScaleSqr );
   }
   
   // Update the decaying particle in the process and the event
   PList::iterator posOut = find(outgoing().begin(), outgoing().end(), incoming);
   PList::iterator posHard = find(hard().begin(), hard().end(), incoming);
   assert((posOut!=outgoing().end() && posHard==hard().end()) ||
          (posOut==outgoing().end() && posHard!=hard().end()) );
   
   
   if ( posOut!=outgoing().end() ) {
     outgoing().erase(posOut);
   }
   
   else {
     hard().erase(posHard);
   }
   intermediates().push_back(process->incoming()[0].first);
   
   // Populate the children of the incoming
   for(auto const & outg : process->outgoing()) {
     PPtr outgoing = outg.first;
     process->incoming()[0].first->addChild(outgoing);
   }
   
   
   // If a decayed particle is not decayed above,
   // e.g. a W in a 3-body top decay, find its decaymode.
   if ( powhegEmission && !decayMode ) {
     
     string tag = incoming->dataPtr()->name() + "->";
     
     // Must use OrderedParticles for a tag search
     ShowerHandler::OrderedParticles decayOut;
     for(auto const & outg : process->outgoing()) {
       decayOut.insert(outg.first->dataPtr());
     }
     
     // Construct the tag
     for(auto const & dec : decayOut) {
       if( dec!=*decayOut.begin() ) tag += ",";
       tag +=dec->name();
     }
     tag += ";";
     
     // Find the decay mode
     decayMode = ShowerHandler::currentHandler()->findDecayMode(tag);
   }
   
   
   
   // Perform the powheg emission
   if ( powhegEmission ) {
 
     if ( decayMode ) {
 
       HwDecayerBasePtr decayer;
       decayer = dynamic_ptr_cast<HwDecayerBasePtr>(decayMode->decayer());
 
       if ( decayer->hasPOWHEGCorrection() ) {
 
 	// Construct a real emission process and populate its
 	// incoming and outcoming prior to any powheg emission
 	RealEmissionProcessPtr born = new_ptr( RealEmissionProcess() );
 	born->bornIncoming().push_back( incoming );
 
 	for(auto const & outg : process->outgoing()) {
 	  born->bornOutgoing().push_back(outg.first);
 	}
         
 	// Generate any powheg emission, returning 'real'
         RealEmissionProcessPtr real = decayer->generateHardest( born );
         
 	// If an emission has been attempted
 	// (Note if the emission fails, a null ptr is returned)
         if ( real ) {
 	  
           showerScale = real->pT()[ShowerInteraction::QCD];
 
 	  // If an emission is generated sort out the particles
 	  if ( !real->outgoing().empty() ) {
 	    
 	    // Update the decay process
 	    // Note: Do not use the new incoming particle
 	    PPtr oldEmitter;
 	    PPtr newEmitter;
 	    
 	    // Use the name recoiler to avoid confusion with
 	    // the spectator in the POWHEGDecayer
 	    // i.e. the recoiler can be coloured or non-coloured
           PPtr oldRecoiler;
           PPtr newRecoiler;
           
           if ( real->emitter() == 1 ) {
             oldEmitter = real->bornOutgoing()[0];
             oldRecoiler = real->bornOutgoing()[1];
             newEmitter = real->outgoing()[0];
             newRecoiler = real->outgoing()[1];
           }
           else if ( real->emitter() == 2) {
             oldEmitter = real->bornOutgoing()[1];
             oldRecoiler = real->bornOutgoing()[0];
             newEmitter = real->outgoing()[1];
             newRecoiler = real->outgoing()[0];
           }
           
           PPtr emitted = real->outgoing()[ real->emitted()-1];
           
 	  // Update the scales
           newRecoiler->scale(oldRecoiler->scale());
           
           newEmitter->scale(sqr(showerScale));
           emitted->scale(sqr(showerScale));
           
 	  // Update the colour flow of the new outgoing particles
 	  // Note the emitted and newEmitter are already colour
 	  // connected by the powheg emission function
           emitted->incomingColour(oldEmitter, oldEmitter->id()<0);
           
           if ( newRecoiler->coloured() )
 	    newRecoiler->incomingColour(oldRecoiler, oldRecoiler->id()<0);
           
 	  // Update the children of the outgoing
           oldRecoiler->addChild( newRecoiler );
           oldEmitter->addChild( newEmitter );
           oldEmitter->addChild( emitted );
           
           
 	  // Note: The particles in the pert proc outgoing and both outgoing
 	  // vectors of the real emission proc are in the same order
           for(unsigned int ix=0;ix<real->bornOutgoing().size();++ix) {
             
 	    // Update the decay process
             assert(process->outgoing()[ix].first == real->bornOutgoing()[ix]);
             process->outgoing()[ix].first = real->outgoing()[ix];
             
 	    // Add the outgoing from the born
 	    // decay to the event intermediates
             intermediates().push_back(real->bornOutgoing()[ix]);
           }
           
 	  // Add the emitted to the outgoing of the decay process
           process->outgoing().push_back( { emitted, PerturbativeProcessPtr() } );
 	  }
 
 
 	  // Else, if no emission above pTmin, set particle scales
 	  else {
 	    for(auto & outg : process->outgoing()) {
 	      outg.first->scale( sqr(showerScale) );
 	    }
 	    powhegEmission = false;
 	  }
 
 	}
 	
 	// No powheg emission occurred:
         else
 	  powhegEmission = false;
         
       }
       
       // No powheg emission occurred:
       else
 	powhegEmission = false;
     }
     
     // No powheg emission occurred:
     else
       powhegEmission = false;
   }
   
   // Copy the outgoing from the decay
   // process to the event record
   for(auto const & outg : process->outgoing()) {
     if ( outg.first->coloured() )
       outgoing().push_back(outg.first);
     else
       hard().push_back(outg.first);
   }
   
   return showerScale;
 }
 
 void DipoleEventRecord::updateDecayMom( PPtr decayParent, PerturbativeProcessPtr decayProc ) {
   
   // Only particles that have already been decayed
   // should be passed to this function
   assert( !(decayProc->outgoing().empty()) );
   
   // Create a list of the children to update their momenta
   PList children;
   for ( auto const & outg : decayProc->outgoing() ) {
     children.push_back( outg.first );
   }
   
   // Boost the children
   PList::iterator beginChildren = children.begin();
   PList::iterator endChildren = children.end();
-  ThePEG::UtilityBase::setMomentum(beginChildren, endChildren, decayParent->momentum().vect() );
+
+  const Momentum3 transformMom = decayParent->momentum().vect();
+  Lorentz5Momentum sum = ThePEG::UtilityBase::sumMomentum(beginChildren, endChildren);
+  LorentzRotation rot = ThePEG::UtilityBase::transformToCMS(sum);
+  rot = ThePEG::UtilityBase::transformFromCMS
+    (Lorentz5Momentum(transformMom, sqrt(transformMom.mag2() + sum.m2()))) * rot;
+      
+  // Must transform the spinInfo using the momentum prior to transforming
+  for ( const auto& p : children ) {
+    if ( p->spinInfo() )
+      p->spinInfo()->transform(p->momentum(),rot);
+  }
+      
+  ThePEG::UtilityBase::transform(beginChildren, endChildren, rot );
+
 }
 
 
 void DipoleEventRecord::updateDecayChainMom( PPtr decayParent, PerturbativeProcessPtr decayProc ) {
   
   // Note - this updates the momenta of the
   // outgoing of the given decay process
   
   // Update the momenta of the outgoing from this decay
   updateDecayMom( decayParent, decayProc );
   
   // Iteratively update the momenta of the rest of the decay chain
   for ( auto & outg : decayProc->outgoing() ) {
 
     // If a child has a corresponding pert proc
     // then it has decay products
     if ( outg.second ) {
 
       for ( auto & dec : theDecays ) {
-        if(dec.second==outg.second) {
-          dec.first->setMomentum(outg.first->momentum());
+        if ( dec.second == outg.second ) {
+
+          // If the particle has spininfo
+          if ( dec.first->spinInfo() ) {
+            
+            // Copied from DipoleVertexRecord::updateSpinInfo,
+            // would be better to use a common function
+            // Update any spin information
+            const Lorentz5Momentum& oldMom = dec.first->momentum();
+            const Lorentz5Momentum& newMom = outg.first->momentum();
+            
+            // Rotation from old momentum to +ve z-axis
+            LorentzRotation oldToZAxis;
+            Axis axisOld(oldMom.vect().unit());
+            if( axisOld.perp2() > 1e-12 ) {
+              double sinth(sqrt(1.-sqr(axisOld.z())));
+              oldToZAxis.rotate( -acos(axisOld.z()),Axis(-axisOld.y()/sinth,axisOld.x()/sinth,0.));
+            }
+            
+            // Rotation from new momentum to +ve z-axis
+            LorentzRotation newToZAxis;
+            Axis axisNew(newMom.vect().unit());
+            if( axisNew.perp2() > 1e-12 ) {
+              double sinth(sqrt(1.-sqr(axisNew.z())));
+              newToZAxis.rotate( -acos(axisNew.z()),Axis(-axisNew.y()/sinth,axisNew.x()/sinth,0.));
+            }
+            
+            // Boost from old momentum to new momentum along z-axis
+            Lorentz5Momentum momOldRotated = oldToZAxis*Lorentz5Momentum(oldMom);
+            Lorentz5Momentum momNewRotated = newToZAxis*Lorentz5Momentum(newMom);
+            
+            Energy2 a = sqr(momOldRotated.z()) + sqr(momNewRotated.t());
+            Energy2 b = 2.*momOldRotated.t()*momOldRotated.z();
+            Energy2 c = sqr(momOldRotated.t()) - sqr(momNewRotated.t());
+            double beta;
+            
+            // The rotated momentum should always lie along the +ve z-axis
+            if ( momOldRotated.z() > ZERO )
+              beta = (-b + sqrt(sqr(b)-4.*a*c)) / 2. / a;
+            else
+              beta = (-b - sqrt(sqr(b)-4.*a*c)) / 2. / a;
+            
+            LorentzRotation boostOldToNew(0., 0., beta);
+            
+            // Total transform
+            LorentzRotation transform = (newToZAxis.inverse())*boostOldToNew*oldToZAxis;
+
+            // Transform spin info and mom
+            dec.first->spinInfo()->transform(oldMom, transform);
+          }
+
+          dec.first->setMomentum(outg.first->momentum());          
           break;
         }
       }
       
       // Iteratively update any decay products
       if ( !outg.second->outgoing().empty() )
 	updateDecayChainMom( outg.first, outg.second );
     }
   }
 }
 
 
 void DipoleEventRecord::updateDecays(PerturbativeProcessPtr decayProc, bool iterate) {
   
   // Note - This does not update the momenta of the outgoing
   // of decayProc. 
   // i.e. it is for use following the (non-)showering 
   // of a decay when the daughter momentum are correct.
   // With iterate = true, this updates the rest of the decay chain.
+
+  // Update the list of next decays
+  if ( decayProc == theCurrentDecay && !theNextDecays.empty() ) {
+    assert( theNextDecays.back() == decayProc->incoming()[0].first );
+    theNextDecays.pop_back();
+  }
   
   // Loop over the outgoing from this decay
   for ( auto & outg : decayProc->outgoing() ) {
         if ( outg.second && !outg.second->outgoing().empty() ) {
       // Outgoing particles which have already been decayed
       PPtr newDecayed = outg.first;
       PerturbativeProcessPtr newDecayProc = outg.second;
       
       // Update the outgoing momenta from this decay
       updateDecayMom( newDecayed, newDecayProc);
       
       // If this decay is already in theDecays then erase it
       for ( auto const & dec : theDecays ) {
         if(dec.second==newDecayProc) {
           theDecays.erase(dec.first);
           break;
         }
       }
       // Add to theDecays
       theDecays[newDecayed] = newDecayProc;
-      //assert(theDecays[newDecayed]->incoming()[0].second==decayProc);
-      
+
+      // Update the list of next decays
+      if ( decayProc = theCurrentDecay )
+        theNextDecays.push_back(newDecayed);
+	
       // Iteratively update theDecays from the decay chain
       if ( iterate ) 
 	updateDecays( newDecayProc );
       
 	}
     
     // Deal with any outgoing which need to be decayed
     else if ( ShowerHandler::currentHandler()->decaysInShower(outg.first->id()) ) {
       PerturbativeProcessPtr newDecay=new_ptr(PerturbativeProcess());
       newDecay->incoming().push_back({ outg.first , decayProc } );
       theDecays[outg.first] = newDecay;
       
+      // Update the list of next decays
+      if ( decayProc )
+        theNextDecays.push_back(outg.first);
+      
     }
   }
   
 }
 
 
 void DipoleEventRecord::debugLastEvent(ostream& os) const {
   
   bool first = ShowerHandler::currentHandler()->firstInteraction();
   
   os << "--- DipoleEventRecord ----------------------------------------------------------\n";
   
   os << " the " << (first ? "hard" : "secondary") << " subprocess is:\n"
      << (*subProcess());
 
   os << " using PDF's " << pdfs().first.pdf() << " and " 
      << pdfs().second.pdf() << "\n";
 
   os << " chains showering currently:\n";
 
   for ( list<DipoleChain>::const_iterator chit = theChains.begin();
 	chit != theChains.end(); ++chit )
     os << (*chit);
 
   os << " chains which finished showering:\n";
 
   for ( list<DipoleChain>::const_iterator chit = theDoneChains.begin();
 	chit != theDoneChains.end(); ++chit )
     os << (*chit);
 
   os << "--------------------------------------------------------------------------------\n";
 
   os << flush;
 
 }
diff --git a/Shower/Dipole/Base/DipoleEventRecord.h b/Shower/Dipole/Base/DipoleEventRecord.h
--- a/Shower/Dipole/Base/DipoleEventRecord.h
+++ b/Shower/Dipole/Base/DipoleEventRecord.h
@@ -1,511 +1,719 @@
 // -*- C++ -*-
 //
 // DipoleEventRecord.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_DipoleEventRecord_H
 #define HERWIG_DipoleEventRecord_H
 //
 // This is the declaration of the DipoleEventRecord class.
 //
 
 #include "Herwig/Shower/ShowerEventRecord.h"
 #include "Herwig/Shower/PerturbativeProcess.h"
 #include "ThePEG/PDF/PDF.h"
 #include "Dipole.h"
 #include "DipoleChain.h"
+#include "Herwig/MatrixElement/Matchbox/Utility/DensityOperator.h"
+
+#include <tuple>
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer, Johannes Bellm
  *
  * \brief Generalized dipole splitting info to deal with subleading-N
  * splittings.
  */
 class SubleadingSplittingInfo
   : public DipoleSplittingInfo {
 
 public:
 
   /**
    * Default constructor
    */
   SubleadingSplittingInfo()
     : DipoleSplittingInfo() {}
 
   /**
    * Get the iterator of the emitter dipole chain
    */
   list<DipoleChain>::iterator emitterChain() const { return theEmitterChain; }
 
   /**
    * Get the iterator of the emitter dipole
    */
   list<Dipole>::iterator emitterDipole() const { return theEmitterDipole; }
 
   /**
    * Get the iterator of the spectator dipole chain
    */
   list<DipoleChain>::iterator spectatorChain() const { return theSpectatorChain; }
 
   /**
    * Get the iterator of the spectator dipole
    */
   list<Dipole>::iterator spectatorDipole() const { return theSpectatorDipole; }
 
   /**
    * Get the starting scale
    */
   Energy startScale() const { return theStartScale; }
-
+  
   /**
    * Set the iterator of the emitter dipole chain
    */
   void emitterChain(list<DipoleChain>::iterator it) { theEmitterChain = it; }
 
   /**
    * Set the iterator of the emitter dipole
    */
   void emitterDipole(list<Dipole>::iterator it) { theEmitterDipole = it; }
 
   /**
    * Set the iterator of the spectator dipole chain
    */
   void spectatorChain(list<DipoleChain>::iterator it) { theSpectatorChain = it; }
 
   /**
    * Set the iterator of the spectator dipole
    */
   void spectatorDipole(list<Dipole>::iterator it) { theSpectatorDipole = it; }
 
   /**
    * Set the starting scale
    */
   void startScale(Energy s) { theStartScale = s; }
 
 private:
 
   /**
    * Iterator of the emitter dipole chain
    */
   list<DipoleChain>::iterator theEmitterChain;
 
   /**
    * Iterator of the emitter dipole
    */
   list<Dipole>::iterator theEmitterDipole;
 
   /**
    * Iterator of the spectator dipole chain
    */
   list<DipoleChain>::iterator theSpectatorChain;
 
   /**
    * Iterator of the spectator dipole
    */
   list<Dipole>::iterator theSpectatorDipole;
 
   /**
    * The starting scale
    */
   Energy theStartScale;
 
 };
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer, Stephen Webster
  *
  * \brief The DipoleEventRecord class is 
  * used internally by the dipole shower.
  */
 class DipoleEventRecord : public ShowerEventRecord {
 
 public:
 
   /**
    * The default constructor.
    */
   DipoleEventRecord() {}
 
   /**
    * The default destructor just cleans up.
    */
   ~DipoleEventRecord() { clear(); }
 
 public:
 
   /**
    * Return any non-coloured outgoing particles in the
    * current subprocess.
    */
   PList& hard() { return theHard; }
 
   /**
    * Return any non-coloured outgoing particles in the
    * current subprocess.
    */
   const PList& hard() const { return theHard; }
 
   /**
    * Return the momentum of the hard system
    */
   const Lorentz5Momentum& pX() const { return thePX; }
 
   /**
+   * Return the particles after emission.
+   */
+  cPDVector& particlesAfter() { return theParticlesAfter; }
+  
+  /**
+   * Return the particles after emission.
+   */
+  const cPDVector& particlesAfter() const { return theParticlesAfter; }
+  
+  /**
+   * Return the particles before emission.
+   */
+  cPDVector& particlesBefore() { return theParticlesBefore; }
+  
+  /**
+   * Return the particles before emission.
+   */
+  const cPDVector& particlesBefore() const { return theParticlesBefore; }
+
+  /**
+   * Return the momenta after emission.
+   */
+  vector<Lorentz5Momentum>& momentaAfter() { return theMomentaAfter; }
+  
+  /**
+   * Return the momenta after emission.
+   */
+  const vector<Lorentz5Momentum>& momentaAfter() const { return theMomentaAfter; }
+
+  /**
+   * Return the dictionary for the particles
+   */
+  map<PPtr,size_t>& particleIndices() { return theParticleIndices; }
+
+  /**
+   * Return the dictionary for the particles
+   */
+  const map<PPtr,size_t>& particleIndices() const { return theParticleIndices; }
+
+  /**
+   * Return the density operator
+   */
+  DensityOperator& densityOperator() { return theDensityOperator; }
+
+  /**
+   * Return the density operator
+   */
+  const DensityOperator& densityOperator() const { return theDensityOperator; }
+  
+  /**
+   * Set the subleading Nc flag and the number of emissions to calculate
+   * subleading Nc corrections for.
+   */
+  void setSubleadingNc( bool doSub, size_t emissionsLimit ) { 
+    doSubleadingNc = doSub;
+    continueSubleadingNc = doSub;
+    subleadingNcEmissionsLimit = emissionsLimit;
+  }
+  
+  /**
+   * Get the continue subleading Nc flag.
+   */
+  bool getContinueSubleadingNc() const { return continueSubleadingNc; }
+
+  /**
+   * Set the scheme and cutoff for the density operator evolution.
+   */
+  void setDensityOperatorEvolution( int scheme, Energy2 cutoff ) {
+    densityOperatorEvolution = scheme;
+    densityOperatorCutoff = cutoff;
+  }
+
+  /**
+   * Calculates the dipole kernel to use for the density operator evolution. Takes
+   * the index of the emitter and spectator, and momentum invariants.
+   */
+  double dipoleKernelForEvolution(size_t em, size_t spec, 
+				  Energy2 pEmitpSpec, Energy2 pEmitpEmis, 
+				  Energy2 pEmispSpec);
+
+  /**
    * Transform all intermediate, hard and outgoing
-   * partciles using the given transformation.
+   * particles using the given transformation.
+   * Also update their spinInfo if applicable.
    */
-  void transform(const SpinOneLorentzRotation& rot);
+  void transform(const LorentzRotation& rot);
 
 public:
 
   /**
    * Return the dipole chains to be showered.
    */
   const list<DipoleChain>& chains() const { return theChains; }
 
   /**
    * Access the dipole chains to be showered.
    */
   list<DipoleChain>& chains() { return theChains; }
 
   /**
    * Return the dipole chains which ceased evolving.
    */
   const list<DipoleChain>& doneChains() const { return theDoneChains; }
 
   /**
    * Access the dipole chains which ceased evolving.
    */
   list<DipoleChain>& doneChains() { return theDoneChains; }
 
   /**
    * Return true, if there are chains to be
    * showered.
    */
   bool haveChain() const { return !theChains.empty(); }
 
   /**
    * Return the current dipole chain
    */
   DipoleChain& currentChain() { assert(haveChain()); return theChains.front(); }
 
   /**
    * Pop the current dipole chain
    */
   void popChain();
 
   /**
    * Remove the given chain.
    */
   void popChain(list<DipoleChain>::iterator);
 
   /**
    * Remove the given chains.
    */
   void popChains(const list<list<DipoleChain>::iterator>&);
 
   /**
    * Create a merged dipole index given two independent dipoles;
    * the first dipole is to provide the emitter.
    */
   DipoleIndex 
   mergeIndex(list<Dipole>::iterator firstDipole, const pair<bool,bool>& whichFirst,
 	     list<Dipole>::iterator secondDipole, const pair<bool,bool>& whichSecond) const;
 
   /**
    * Create a SubleadingSplitingInfo given two independent dipoles;
    * the first dipole is to provide the emitter.
    */
   SubleadingSplittingInfo 
   mergeSplittingInfo(list<DipoleChain>::iterator firstChain, list<Dipole>::iterator firstDipole, 
 		     const pair<bool,bool>& whichFirst,
 		     list<DipoleChain>::iterator secondChain, list<Dipole>::iterator secondDipole, 
 		     const pair<bool,bool>& whichSecond) const;
 
   /**
    * Return a list of all possible subleading-N emitting pairs
    */
   void getSubleadingSplittings(list<SubleadingSplittingInfo>&);
 
 public:
 
   /**
    * Split the dipole pointed to by the given iterator.
    * Return references to the affected chains, and update
    * iterators pointing to the children in the returned
    * chains.
    */
 
   void split(list<Dipole>::iterator dip,
 	     DipoleSplittingInfo& dsplit,
 	     pair<list<Dipole>::iterator,list<Dipole>::iterator>& childIterators,
 	     DipoleChain*& firstChain, DipoleChain*& secondChain) {
     split(dip,theChains.begin(),dsplit,childIterators,firstChain,secondChain,false);
   }
 
   /**
    * Split the dipole pointed to by the given iterator
    * in the indicated chain, indicating a splitting with
    * a colour spectator.
    * Return references to the affected chains, and update
    * iterators pointing to the children in the returned
    * chains.
    */
   void split(list<Dipole>::iterator dip,
 	     list<DipoleChain>::iterator ch,
 	     DipoleSplittingInfo& dsplit,
 	     pair<list<Dipole>::iterator,list<Dipole>::iterator>& childIterators,
 	     DipoleChain*& firstChain, DipoleChain*& secondChain,
 	     bool colourSpectator = true);
   
   /**
    * As split, but not touching the acctual event record.
    */
   
   pair<PVector,PVector> tmpsplit(list<Dipole>::iterator dip,
              DipoleSplittingInfo& dsplit,
              pair<list<Dipole>::iterator,list<Dipole>::iterator>& childIterators,
              DipoleChain*& firstChain, DipoleChain*& secondChain) {
     return tmpsplit(dip,theChains.begin(),dsplit,childIterators,firstChain,secondChain,false);
   }
   
   /**
    * As split, but not touching the acctual event record.
    */
   pair<PVector,PVector> tmpsplit(list<Dipole>::iterator dip,
              list<DipoleChain>::iterator ch,
              DipoleSplittingInfo& dsplit,
              pair<list<Dipole>::iterator,list<Dipole>::iterator>& childIterators,
              DipoleChain*& firstChain, DipoleChain*& secondChain,
              bool colourSpectator = true);
 
 
   /**
    * Let the given dipole take the recoil of 
    * the indicated splitting.
    */
   void recoil(list<Dipole>::iterator dip,
 	      list<DipoleChain>::iterator ch,
 	      DipoleSplittingInfo& dsplit);
 
   /**
    * Peform a subleading-N splitting
    */
   void splitSubleading(SubleadingSplittingInfo& dsplit,
 		       pair<list<Dipole>::iterator,list<Dipole>::iterator>& childIterators,
 		       DipoleChain*& firstChain, DipoleChain*& secondChain);
 
   /**
    * Update the particles upon insertion of the
    * given splitting.
    */
   void update(DipoleSplittingInfo& dsplit);
   
   /**
    * As update, but not touching the acctual event record.
    */
   pair<PVector,PVector> tmpupdate(DipoleSplittingInfo& dsplit);
 
   /**
+   * Inverse of update, updateInverse(update(dsplit)) would return the 
+   * event record to the state if update would not have been called.
+   */
+  void updateInverse(DipoleSplittingInfo& dsplit);
+
+  /**
    * Return the dipole(s) containing the incoming
    * partons after the evolution has ended. Put back
    * the chains containing these to the chains to be
    * showered.
    */
   list<pair<list<Dipole>::iterator,list<DipoleChain>::iterator> >
   inDipoles();
 
   /**
    * Fill the given step and return incoming partons.
    */
   tPPair fillEventRecord(StepPtr step, bool firstInteraction, bool realigned);
 
 public:
 
   /**
    * Prepare the event record for the given
    * subprocess.
    */
   const map<PPtr,PPtr>& prepare(tSubProPtr subpro,
                                 tStdXCombPtr xc,
 				StepPtr step,
                                 const pair<PDF,PDF>& pdf,
 				tPPair beam,
 				bool firstInteraction,
 				const set<long>& offShellPartons,
                                 bool dipoles = true);
   /**
    * Prepare the event record for the given
    * subprocess.
    */
   void slimprepare(tSubProPtr subpro,
 		   tStdXCombPtr xc,
 		   const pair<PDF,PDF>& pdf,tPPair beam,
 		   const set<long>& offShellPartons,
 		   bool dipoles = true);
 
   /**
    * Clear the event record: Give up ownership
    * on any object involved in the evolution.
    */
   virtual void clear();
 
+  /**
+   * Prepare the dipole chains for the eventRecord after
+   * the subleading shower
+   */
+  void prepareChainsSubleading(const bool decay) {
+    static set<long> empty;
+    continueSubleadingNc = false;
+    PList cordered = colourOrdered(incoming(),outgoing());
+    findChains(cordered,empty,decay);
+  }
+
 public:
 
   /**
    * Print event record at current state.
    */
   void debugLastEvent(ostream&) const;
 
 public:
 
   /**
    *  Get the decays
    */
   map<PPtr,PerturbativeProcessPtr> & decays() {return theDecays;}
 
   /**
    * Used in DipoleEventRecord::prepare.
    * Add the outgoing particles from a perturbative 
    * process to the vector of original particles. 
    * Iterates through decay chains.
    **/
   void fillFromDecays(PerturbativeProcessPtr decayProc, vector<PPtr>& original);
 
   /**
    * Used in DipoleEventRecord::prepare.
    * Replace the particles in the given 
    * perturbative process with their copies from the 
    * map, theOriginals.
    * Iterates through decays chains.
    **/
   void separateDecay(PerturbativeProcessPtr decayProc);
 
   /**
    *  Decay the particle
    */
   Energy decay(PPtr incoming, bool& powhegEmission);
 
   /**
    * Prepare the event record for the showering of a decay.
    * Return false if the decay does not need to be showered.
    **/
   bool prepareDecay(PerturbativeProcessPtr decayProc,
 				const set<long>& offShellPartons);
 
   /**
    * Boost the momentum of the outgoing of the given 
    * perturbative process to the momentum of given particle.
    **/
   void updateDecayMom(PPtr decayParent, PerturbativeProcessPtr decayProc);
 
   /**
    * Iteratively update the momenta of all
    * particles in a decay chain, starting 
    * with the outgoing from the given parent
    **/
   void updateDecayChainMom(PPtr decayParent, PerturbativeProcessPtr decayProc);
 
   /**
    * Update theDecays following the decay and/or
    * showering of a decay particle.
    * With iteration switched on (true) this will
    * update theDecays with the entire decay chain.
    `**/
   void updateDecays(PerturbativeProcessPtr decayProc, bool iterate = true);
 
   /**
    *  Access current decay process
    */
   PerturbativeProcessPtr currentDecay() {return theCurrentDecay;}
 
   /**
    *  Set current decay process
    */
   void currentDecay(PerturbativeProcessPtr in) {theCurrentDecay=in;}
 
+  /**
+   * Return the next particle to be decayed.
+   */
+  PPtr nextDecay() {
+    if ( !theNextDecays.empty() )
+      return theNextDecays.back();
+    else
+      return PPtr();
+  }
+  
 
   // SW - Changed from protected to public so that functions can be used in DipoleShowerHandler
 public:
 
   /**
    * Find the chains to be showered.
    * The decay bool avoids mixing up decaying particles in hard and decay processes
    */
   void findChains(const PList& ordered, 
 		  const set<long>& offShellpartons,
 		  const bool decay = false);
 
   /**
    * Sort the coloured partons into a colour ordered ensemble.
    */
   PList colourOrdered(PPair & in,PList & out);
 
 
 private:
 
   struct getMomentum {
     const Lorentz5Momentum& operator() (PPtr particle) const {
       return particle->momentum();
     }
   };
 
   /**
    * The momentum of the hard system
    */
   Lorentz5Momentum thePX;
 
   /**
    * Any non-coloured outgoing particles in the
    * current subprocess.
    */
   PList theHard;
 
   /**
    * Map originals to copies.
    */
   map<PPtr,PPtr> theOriginals;
 
   /**
    * The dipole chains currently showered.
    */
   list<DipoleChain> theChains;
 
   /**
    * The dipole chains which ceased evolving.
    */
   list<DipoleChain> theDoneChains;
+  
+  /**
+   * Particles after the emission.
+   */
+  cPDVector theParticlesAfter;
+  
+  /**
+   * Particles before the emission.
+   */
+  cPDVector theParticlesBefore;
+  
+  /**
+   * Momenta of the particles after emission.
+   */
+  vector<Lorentz5Momentum> theMomentaAfter;
+  
+  /**
+   * Pair of the emitters index before emission and both the emitters
+   * and the emissions indices after emission, 
+   * <emitter_before,<emitter_after,emission> >
+   */
+  pair<size_t,pair<size_t,size_t> > theEmitterEmissionIndices;
+  
+  /**
+   * Pair of the spectators index before and after emission.
+   */
+  pair<size_t,size_t> theSpectatorIndices;
+  
+  /**
+   * The density operator.
+   */
+  DensityOperator theDensityOperator;
+
+  /**
+   * Switch on or off for subleading Nc corrections.
+   */
+  bool doSubleadingNc;
+  
+  /**
+   * Flag to keep track of when to stop calculating colour
+   * matrix element corrections.
+   */
+  bool continueSubleadingNc;
+  
+  /**
+   * Number of emissions to calculate subleading Nc corrections for.
+   */
+  size_t subleadingNcEmissionsLimit;
+
+  /**
+   * Current number of subleading emissions.
+   */
+  size_t subEmDone;
+
+  
+  /**
+   * Dictionary for particles before emission.
+   */
+  map<PPtr,size_t> theParticleIndices;
+
+  /**
+   * Integer used to set which method of evolving the density operator
+   * to use:
+   * 0 - Vijk is Eikonal but there is a cutoff.
+   * 1 - Vijk is Eikonal.
+   * 2 - Vijk=1 for all i,j,k.
+   * 3 - Semi-leading Nc, Vijk=0 for all 
+   */
+  int densityOperatorEvolution;
+
+  /**
+   * Cutoff scale for the invariants (e.g. pEmitter*pEmission) in the 
+   * Eikonal dipole kernel, Vijk.
+   */
+  Energy2 densityOperatorCutoff;
+
+  /**
+   * Dictionary for emissions, maps the three indices
+   * - emitter before emission
+   * - emitter after emission
+   * - emission
+   * to another map of the indices before emission mapped to the indices after
+   * emission (except the emitters index)
+   */
+  map<std::tuple<size_t,size_t,size_t>,map<size_t,size_t> > theEmissionsMap;
 
   /**
    * The coloured partons that can be off-shell
    * To only be filled by DipoleShowerHandler.
    **/
 
 
   
 private:
 
   /**
    * Storage of the particles which need to be decayed
    */
   map<PPtr,PerturbativeProcessPtr> theDecays;
 
   /**
    *
    */
   PerturbativeProcessPtr theCurrentDecay;
+
+  /**
+   * List of unstable particles, the decay to be performed
+   * and/or showered next is always at the back.
+   * This list is required to force the dipole shower to shower one decay
+   * chain at a time, without jumping between decay chains.
+   * Note this is not *required* but this is the most 
+   * obvious/intuitive way to treat the decays.
+   **/
+  PList theNextDecays;
+
 };
 
 
 }
 
 #endif /* HERWIG_DipoleEventRecord_H */
diff --git a/Shower/Dipole/Base/DipoleSplittingGenerator.cc b/Shower/Dipole/Base/DipoleSplittingGenerator.cc
--- a/Shower/Dipole/Base/DipoleSplittingGenerator.cc
+++ b/Shower/Dipole/Base/DipoleSplittingGenerator.cc
@@ -1,875 +1,910 @@
 // -*- C++ -*-
 //
 // DipoleSplittingGenerator.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 DipoleSplittingGenerator class.
 //
 #include <config.h>
 #include "DipoleSplittingGenerator.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Repository/EventGenerator.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 #include "Herwig/Shower/Dipole/DipoleShowerHandler.h"
+#include "ThePEG/Repository/UseRandom.h"
 
 using namespace Herwig;
 
 DipoleSplittingGenerator::DipoleSplittingGenerator() 
   : HandlerBase(),
     theExponentialGenerator(0), prepared(false), presampling(false),
     theDoCompensate(false), theSplittingWeight(1.) {
   if ( ShowerHandler::currentHandler() )
     setGenerator(ShowerHandler::currentHandler()->generator());
 }
 
 DipoleSplittingGenerator::~DipoleSplittingGenerator() {
   if ( theExponentialGenerator ) {
     delete theExponentialGenerator;
     theExponentialGenerator = 0;
   }
 }
 
 IBPtr DipoleSplittingGenerator::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr DipoleSplittingGenerator::fullclone() const {
   return new_ptr(*this);
 }
 
 void DipoleSplittingGenerator::wrap(Ptr<DipoleSplittingGenerator>::ptr other) {
   assert(!prepared);
   theOtherGenerator = other;
 }
 
 void DipoleSplittingGenerator::resetVariations() {
   for ( map<string,double>::iterator w = currentWeights.begin();
 	w != currentWeights.end(); ++w )
     w->second = 1.;
 }
 
 void DipoleSplittingGenerator::veto(const vector<double>&, double p, double r) {
   double factor = 1.;
   if ( splittingReweight() ) {
     if ( ( ShowerHandler::currentHandler()->firstInteraction() &&
           splittingReweight()->firstInteraction() ) ||
 	 ( !ShowerHandler::currentHandler()->firstInteraction() &&
 	   splittingReweight()->secondaryInteractions() ) ) {
-      factor = splittingReweight()->evaluate(generatedSplitting);
-      theSplittingWeight *= (r-factor*p)/(r-p);
+      if ( !splittingReweight()->hintOnly(generatedSplitting) ) {
+	factor = 
+	  splittingReweight()->evaluate(generatedSplitting)/splittingReweight()->hint(generatedSplitting);
+	theSplittingWeight *= (r-factor*p)/(r-p);
+	theSplittingWeightVector.push_back(std::make_tuple(generatedSplitting.lastPt(),(r-factor*p)/(r-p),false));
+      }
     }
   }
   splittingKernel()->veto(generatedSplitting, factor*p, r, currentWeights);
 }
 
 void DipoleSplittingGenerator::accept(const vector<double>&, double p, double r) {
   double factor = 1.;
   if ( splittingReweight() ) {
     if ( ( ShowerHandler::currentHandler()->firstInteraction() &&
           splittingReweight()->firstInteraction() ) ||
 	 ( !ShowerHandler::currentHandler()->firstInteraction() &&
 	   splittingReweight()->secondaryInteractions() ) ) {
-      factor = splittingReweight()->evaluate(generatedSplitting);
-      theSplittingWeight *= factor;
+      if ( !splittingReweight()->hintOnly(generatedSplitting) ) {
+	factor = 
+	  splittingReweight()->evaluate(generatedSplitting)/splittingReweight()->hint(generatedSplitting);
+	theSplittingWeight *= factor;
+        theSplittingWeightVector.push_back(std::make_tuple(generatedSplitting.lastPt(),factor,true));
+      } else {
+	theSplittingWeightVector.push_back(std::make_tuple(generatedSplitting.lastPt(),1.0,true));
+      }
     }
   }
   splittingKernel()->accept(generatedSplitting, factor*p, r, currentWeights);
 }
 
 void DipoleSplittingGenerator::prepare(const DipoleSplittingInfo& sp) {
 
   generatedSplitting = sp;
 
   generatedSplitting.splittingKinematics(splittingKernel()->splittingKinematics());
+  // The splitting kernel is needed for spin correlations
+  generatedSplitting.splittingKernel(splittingKernel());
   generatedSplitting.splittingParameters().resize(splittingKernel()->nDimAdditional());
 
   if ( wrapping() ) {
     generatedSplitting.emitterData(theSplittingKernel->emitter(generatedSplitting.index()));  
     generatedSplitting.spectatorData(theSplittingKernel->spectator(generatedSplitting.index()));  
     generatedSplitting.emissionData(theSplittingKernel->emission(generatedSplitting.index()));  
     parameters.resize(theOtherGenerator->nDim());
     prepared = true;
     return;
   }
 
   generatedSplitting.emitterData(splittingKernel()->emitter(generatedSplitting.index()));  
   generatedSplitting.spectatorData(splittingKernel()->spectator(generatedSplitting.index()));  
   generatedSplitting.emissionData(splittingKernel()->emission(generatedSplitting.index()));  
 
   presampledSplitting = generatedSplitting;
 
   prepared = true;
 
   parameters.resize(nDim());
 
   theExponentialGenerator = 
     new exsample::exponential_generator<DipoleSplittingGenerator,UseRandom>();
   theExponentialGenerator->sampling_parameters().maxtry = maxtry();
   theExponentialGenerator->sampling_parameters().presampling_points = presamplingPoints();
   theExponentialGenerator->sampling_parameters().freeze_grid = freezeGrid();
   theExponentialGenerator->detuning(detuning());
   theExponentialGenerator->docompensate(theDoCompensate);
   theExponentialGenerator->function(this);
   theExponentialGenerator->initialize();
 }
 
 void DipoleSplittingGenerator::fixParameters(const DipoleSplittingInfo& sp,
 					     Energy optHardPt) {
 
   assert(generator());
 
   assert(!presampling);
   assert(prepared);
 
   assert(sp.index() == generatedSplitting.index());
 
   generatedSplitting.scale(sp.scale());
 
   // If dealing with a decay, need to set recoilMass
   if ( generatedSplitting.index().incomingDecaySpectator() ||    
        generatedSplitting.index().incomingDecayEmitter() ) 
     generatedSplitting.recoilMass(sp.recoilMass());
 
   // Need to copy emitter and spectator masses
   generatedSplitting.emitterMass(sp.emitterMass());
   generatedSplitting.spectatorMass(sp.spectatorMass());
   
   // Counter to track if there is an off-shell
   // emitter AND/OR spectator
   int count = parameters.size()-1;    
 
   // Off shell spectator mass
   if ( sp.index().offShellSpectator() ) {
     parameters[count] = sp.spectatorMass()/generator()->maximumCMEnergy();
     count -= 1;
   }
   
   // Off shell emitter mass
   if ( sp.index().offShellEmitter() )
     parameters[count] = sp.emitterMass()/generator()->maximumCMEnergy();
 
   
   // If not a decay, point[3] samples over the dipole scale
   if ( !sp.index().incomingDecaySpectator() && !sp.index().incomingDecayEmitter() )
     parameters[3] = sp.scale()/generator()->maximumCMEnergy();
   // If it is a decay, point[3] samples over the recoilMass
   else 
     parameters[3] = sp.recoilMass()/generator()->maximumCMEnergy();
   
   generatedSplitting.hardPt(sp.hardPt());
 
   parameters[0] = splittingKinematics()->ptToRandom(optHardPt == ZERO ? 
 						    generatedSplitting.hardPt() : 
 						    min(generatedSplitting.hardPt(),optHardPt),
 						    sp.scale(),
 						    sp.emitterX(), sp.spectatorX(),
 						    generatedSplitting.index(),
 						    *splittingKernel());
 
   size_t shift = 4;
 
   if ( generatedSplitting.index().emitterPDF().pdf() &&
        generatedSplitting.index().spectatorPDF().pdf() ) {
     generatedSplitting.emitterX(sp.emitterX());
     generatedSplitting.spectatorX(sp.spectatorX());
     parameters[4] = sp.emitterX();
     parameters[5] = sp.spectatorX();
     shift += 2;
   }
 
   if ( generatedSplitting.index().emitterPDF().pdf() &&
        !generatedSplitting.index().spectatorPDF().pdf() ) {
     generatedSplitting.emitterX(sp.emitterX());
     parameters[4] = sp.emitterX();
     ++shift;
   }
 
   if ( !generatedSplitting.index().emitterPDF().pdf() &&
        generatedSplitting.index().spectatorPDF().pdf() ) {
     generatedSplitting.spectatorX(sp.spectatorX());
     parameters[4] = sp.spectatorX();
     ++shift;
   }
 
   if ( splittingKernel()->nDimAdditional() )
     copy(sp.lastSplittingParameters().begin(),
          sp.lastSplittingParameters().end(),
          parameters.begin()+shift);
 
   if ( sp.emitter() )
     generatedSplitting.emitter(sp.emitter());
 
   if ( sp.spectator() )
     generatedSplitting.spectator(sp.spectator());
 
 }
 
 int DipoleSplittingGenerator::nDim() const {
 
   assert(!wrapping());
   assert(prepared);
 
   // Note this use of [3] for either the scale or the recoil mass
   // is a bit of a nasty hack.
   int ret = 4; // 0 pt, 1 z, 2 phi, 3 scale or recoilMass, 4/5 xs + parameters
 
   if ( generatedSplitting.index().emitterPDF().pdf() ) {
     ++ret;
   }  
 
   if ( generatedSplitting.index().spectatorPDF().pdf() ) {
     ++ret;
   }  
 
   ret += splittingKernel()->nDimAdditional();
   assert(splittingKernel()->nDimAdditional() == 0);
 
   // Put off-shell spectator mass at back [-1]
   // followed by off-shell emitter mass (i.e. [-1] or [-2])
 
   // Off-shell emitter
   if ( generatedSplitting.index().offShellEmitter() )
     ++ret;
   
   // Off-shell spectator
   if ( generatedSplitting.index().offShellSpectator() )
     ++ret;
   
   
   return ret;
 
 }
 
 const vector<bool>& DipoleSplittingGenerator::sampleFlags() {
 
   assert(!wrapping());
 
   if ( !theFlags.empty() )
     return theFlags;
 
   theFlags.resize(nDim(),false);
   theFlags[0] = true; theFlags[1] = true; theFlags[2] = true; // 0 pt, 1 z, 2 phi
   return theFlags;
 }
 
 const pair<vector<double>,vector<double> >& DipoleSplittingGenerator::support() {
 
   assert(!wrapping());
 
   if ( !theSupport.first.empty() )
     return theSupport;
 
   vector<double> lower(nDim(),0.);
   vector<double> upper(nDim(),1.);
 
   pair<double,double> kSupport = 
     generatedSplitting.splittingKinematics()->kappaSupport(generatedSplitting);
 
   pair<double,double> xSupport = 
     generatedSplitting.splittingKinematics()->xiSupport(generatedSplitting);
 
   lower[0] = kSupport.first;
   lower[1] = xSupport.first;
 
   upper[0] = kSupport.second;
   upper[1] = xSupport.second;
 
   theSupport.first = lower;
   theSupport.second = upper;
 
   return theSupport;
 
 }
 
 void DipoleSplittingGenerator::startPresampling() {
   assert(!wrapping());
   splittingKernel()->startPresampling(generatedSplitting.index());
   presampling = true;
 }
 
 void DipoleSplittingGenerator::stopPresampling() {
   assert(!wrapping());
   splittingKernel()->stopPresampling(generatedSplitting.index());
   presampling = false;
 }
 
 bool DipoleSplittingGenerator::haveOverestimate() const {
 
   assert(!wrapping());
   assert(prepared);
 
   return 
     generatedSplitting.splittingKinematics()->haveOverestimate() &&
     splittingKernel()->haveOverestimate(generatedSplitting);
 
 }
 
 double DipoleSplittingGenerator::overestimate(const vector<double>& point) {
 
   assert(!wrapping());
   assert(prepared);
   assert(!presampling);
   assert(haveOverestimate());
 
   if ( ! generatedSplitting.splittingKinematics()->generateSplitting(point[0],point[1],point[2],
 								     generatedSplitting,
 								     *splittingKernel()) )
     return 0.;
 
   generatedSplitting.splittingKinematics()->prepareSplitting(generatedSplitting);
 
   return 
     ( generatedSplitting.splittingKinematics()->jacobianOverestimate() * 
       splittingKernel()->overestimate(generatedSplitting) );
 
 }
 
 double DipoleSplittingGenerator::invertOverestimateIntegral(double value) const {
 
   assert(!wrapping());
   assert(prepared);
   assert(!presampling);
   assert(haveOverestimate());
 
   return 
     splittingKernel()->invertOverestimateIntegral(generatedSplitting,value);
 
 }
 
 double DipoleSplittingGenerator::evaluate(const vector<double>& point) {
 
   assert(!wrapping());
   assert(prepared);
   assert(generator());
 
   DipoleSplittingInfo& split =
     ( !presampling ? generatedSplitting : presampledSplitting );
 
   split.continuesEvolving();
   size_t shift = 4;
 
   if ( presampling ) {
 
     // Counter to track if there is an off-shell
     // emitter AND/OR spectator
     int count = parameters.size()-1;    
 
     // Sample over off-shell emitter and spectator masss
     // Do not sample if zero mass or off-shell
     if ( split.index().spectatorData()->mass() != ZERO ) {
       if ( !split.index().offShellSpectator() )
 	split.spectatorMass(split.index().spectatorData()->mass());
       else {
 	split.spectatorMass(point[count] * generator()->maximumCMEnergy());
 	count -= 1;
       }
     }
 
     if ( split.index().emitterData()->mass() != ZERO ) {
       if ( !split.index().offShellEmitter() ) 
 	split.emitterMass(split.index().emitterData()->mass());
       else
 	split.emitterMass(point[count] * generator()->maximumCMEnergy());
     }
     
     // If not a decay, point[3] samples over the dipole scale
     if ( ! split.index().incomingDecaySpectator()
 	 && ! split.index().incomingDecayEmitter() )
       split.scale(point[3] * generator()->maximumCMEnergy());
       
     // For dipoles containing a decayed spectator:
     // 1) Use point[3] to sample over the recoil mass
     // 2) The dipole scale is the spectator mass
     else if ( split.index().incomingDecaySpectator() ) {
       split.recoilMass(point[3] * generator()->maximumCMEnergy());
       assert(split.spectatorMass() != ZERO );
       split.scale(split.spectatorMass());
     }
     // Not currently intended to work with decaying emitters
     else
       assert(false);
     
     if ( split.index().emitterPDF().pdf() &&
 	 split.index().spectatorPDF().pdf() ) {
       split.emitterX(point[4]);
       split.spectatorX(point[5]);
       shift += 2;
     }
   
     if ( split.index().emitterPDF().pdf() &&
 	 !split.index().spectatorPDF().pdf() ) {
       split.emitterX(point[4]);
       ++shift;
     }
   
     if ( !split.index().emitterPDF().pdf() &&
 	 split.index().spectatorPDF().pdf() ) {
       split.spectatorX(point[4]);
       ++shift;
     }
   
     if ( splittingKernel()->nDimAdditional() )
       copy(point.begin()+shift,point.end(),split.splittingParameters().begin());
   
     split.hardPt(split.splittingKinematics()->ptMax(split.scale(),
 						    split.emitterX(),
 						    split.spectatorX(),
 						    split,
 						    *splittingKernel()));
   }
 
   if ( ! split.splittingKinematics()->generateSplitting(point[0],
                                                         point[1],
                                                         point[2],
                                                         split,
                                                         *splittingKernel()) ) {
     split.lastValue(0.);
     return 0.;
   }
 
   split.splittingKinematics()->prepareSplitting(split);
 
   if ( split.stoppedEvolving() ) {
     split.lastValue(0.);
     return 0.;
   }
 
   if ( !presampling )
     splittingKernel()->clearAlphaPDFCache();
   double kernel = splittingKernel()->evaluate(split);
   double jac = split.splittingKinematics()->jacobian();
 
   // multiply in the profile scales when relevant
   assert(ShowerHandler::currentHandler());
   if ( ShowerHandler::currentHandler()->firstInteraction() &&
        ShowerHandler::currentHandler()->profileScales() &&
        !presampling ) {
     Energy hard = ShowerHandler::currentHandler()->hardScale();
     if ( hard > ZERO )
       kernel *= ShowerHandler::currentHandler()->profileScales()->
                 hardScaleProfile(hard,split.lastPt());
   }
 
   split.lastValue( abs(jac) * kernel );
 
   if ( ! isfinite(split.lastValue()) ) {
     generator()->log() << "DipoleSplittingGenerator:evaluate():"
                <<"problematic splitting kernel encountered for "
 		       << splittingKernel()->name() << "\n" << flush;
     split.lastValue(0.0);
   }
   if ( kernel < 0. )
     return 0.;
   return split.lastValue();
 
 }
 
 void DipoleSplittingGenerator::doGenerate(map<string,double>& variations,
 					  Energy optCutoff) {
 
   assert(!wrapping());
 
   double res = 0.;
 
   Energy startPt = generatedSplitting.hardPt();
   double optKappaCutoff = 0.0;
   if ( optCutoff > splittingKinematics()->IRCutoff() ) {
     optKappaCutoff = splittingKinematics()->ptToRandom(optCutoff,
 						       generatedSplitting.scale(),
 						       generatedSplitting.emitterX(), 
 						       generatedSplitting.spectatorX(),
 						       generatedSplitting.index(),
 						       *splittingKernel());
   }
 
   resetVariations();
   theSplittingWeight = 1.;
   double enhance = 1.;
+  bool detuningOff = false;
   if ( splittingReweight() ) {
     if ( ( ShowerHandler::currentHandler()->firstInteraction() &&
           splittingReweight()->firstInteraction() ) ||
 	 ( !ShowerHandler::currentHandler()->firstInteraction() &&
 	   splittingReweight()->secondaryInteractions() ) ) {
       enhance = splittingReweight()->hint(generatedSplitting);
+      if ( splittingReweight()->hintOnly(generatedSplitting) )
+	detuningOff = true;
     }
   }
 
+  bool hintOnly = false;
+  if ( splittingReweight() ) hintOnly = splittingReweight()->hintOnly(generatedSplitting);
   while (true) {
+    theExponentialGenerator->detuning(detuning());
+    if ( detuningOff )
+      theExponentialGenerator->detuning(1.0);
     try {
       if ( optKappaCutoff == 0.0 ) {
+        theSplittingWeightVector.clear();
 	res = theExponentialGenerator->generate(enhance);
       } else {
+	theSplittingWeightVector.clear();
 	res = theExponentialGenerator->generate(optKappaCutoff,enhance);
       }
+      //Partial unweighting
+      if ( partialUnweighting && !hintOnly ) {
+	if ( abs(theSplittingWeight)/theReferenceWeight < 1.0 ) {
+	  double r = UseRandom::rnd(1.0);
+	  if ( abs(theSplittingWeight)/theReferenceWeight < r ) {
+	    theSplittingWeight = 1.;
+	    continue;
+	  } else {
+	    theSplittingWeight = theSplittingWeight/abs(theSplittingWeight)*theReferenceWeight;
+	  }
+	}
+      }
     } catch (exsample::exponential_regenerate&) {
       resetVariations();
       theSplittingWeight = 1.;
       generatedSplitting.hardPt(startPt);
       continue;
     } catch (exsample::hit_and_miss_maxtry&) {
       throw DipoleShowerHandler::RedoShower();
     } catch (exsample::selection_maxtry&) {
       throw DipoleShowerHandler::RedoShower();
     }
     break;
   }
 
   for ( map<string,double>::const_iterator w = currentWeights.begin();
 	w != currentWeights.end(); ++w ) {
     map<string,double>::iterator v = variations.find(w->first);
     if ( v != variations.end() )
       v->second *= w->second;
     else
       variations[w->first] = w->second;
   }
 
   if ( res == 0. ) {
     generatedSplitting.lastPt(0.0*GeV);
     generatedSplitting.didStopEvolving();
   } else {
 
     generatedSplitting.continuesEvolving();
 
     if ( theMCCheck )
       theMCCheck->book(generatedSplitting.emitterX(),
 		       generatedSplitting.spectatorX(),
 		       generatedSplitting.scale(),
 		       startPt,
 		       generatedSplitting.lastPt(),
 		       generatedSplitting.lastZ(),
 		       1.);
 
   }
 
 }
 
 Energy DipoleSplittingGenerator::generate(const DipoleSplittingInfo& split,
 					  map<string,double>& variations,
 					  Energy optHardPt,
 					  Energy optCutoff) {
   fixParameters(split,optHardPt);
 
   if ( wrapping() ) {
     return theOtherGenerator->generateWrapped(generatedSplitting,variations,optHardPt,optCutoff);
   }
 
   doGenerate(variations,optCutoff);
 
   return generatedSplitting.lastPt();
 
 }
 
 double DipoleSplittingGenerator::sudakovExpansion(const DipoleSplittingInfo& split,
                                                   Energy down,Energy fixedScale){
   fixParameters(split);
   if ( wrapping() ) {
     return theOtherGenerator->wrappedSudakovExpansion( generatedSplitting, down,fixedScale);
   }
   return dosudakovExpansion( split, down,fixedScale);
 }
 
 double DipoleSplittingGenerator::sudakov(const DipoleSplittingInfo& split,Energy down){
   fixParameters(split);
   if ( wrapping() ) {
     return theOtherGenerator->wrappedSudakov( generatedSplitting, down);
   }
   return dosudakov( split, down);
 }
 
 
 
 double DipoleSplittingGenerator::dosudakovExpansion(const DipoleSplittingInfo& ,
                                                     Energy down,Energy fixedScale){
     assert(down > splittingKinematics()->IRCutoff());
   
   double optKappaCutoffd =
       splittingKinematics()->ptToRandom(down,
                                         generatedSplitting.scale(),
                                         generatedSplitting.emitterX(),
                                         generatedSplitting.spectatorX(),
                                         generatedSplitting.index(),
                                         *splittingKernel());
   
   
   double optKappaCutoffu = splittingKinematics()->ptToRandom(generatedSplitting.hardPt(),
                                                              generatedSplitting.scale(),
                                                              generatedSplitting.emitterX(),
                                                              generatedSplitting.spectatorX(),
                                                              generatedSplitting.index(),
                                                              *splittingKernel());
   
   
   pair<double,double> xSupport =
     generatedSplitting.splittingKinematics()->xiSupport(generatedSplitting);
 
   
     vector<double> RN;
     RN.resize(3);
     double res=0.;
     double resq=0.;
     double varx=10.;
     int k=0;
   
     generatedSplitting.setCalcFixedExpansion(true);
     generatedSplitting.fixedScale(fixedScale);
     
     while (  k<1000 ){
       k+=1.;
       RN[0]= optKappaCutoffd+(optKappaCutoffu-optKappaCutoffd)*UseRandom::rnd(); //PT
       RN[1]=xSupport.first+UseRandom::rnd()*(xSupport.second-xSupport.first); //
       RN[2]= UseRandom::rnd(); //PHI
       double tmp=(xSupport.second-xSupport.first)*
 		 (optKappaCutoffu-optKappaCutoffd)*
                  evaluate(RN);
       res+= tmp;
       resq+=pow(tmp,2.);
       if(k%50==0.){
 	varx=sqrt((resq/pow(1.*k,2)-pow(res,2)/pow(1.*k,3)))/(res/(1.0*k));
         if(varx<theSudakovAccuracy)break;
       }
     }
     generatedSplitting.setCalcFixedExpansion(false);
 
     return -res/(1.0*k);
 }
 
 
 
 double DipoleSplittingGenerator::dosudakov(const DipoleSplittingInfo& ,Energy down){
   
     
 
   double optKappaCutoffd = splittingKinematics()->ptToRandom(down,
                                                             generatedSplitting.scale(),
                                                             generatedSplitting.emitterX(),
                                                             generatedSplitting.spectatorX(),
                                                             generatedSplitting.index(),
                                                             *splittingKernel());
   
   
   double optKappaCutoffu = splittingKinematics()->ptToRandom(generatedSplitting.hardPt(),
                                                             generatedSplitting.scale(),
                                                             generatedSplitting.emitterX(),
                                                             generatedSplitting.spectatorX(),
                                                             generatedSplitting.index(),
                                                             *splittingKernel());
  
 
 
   pair<double,double> kSupport =
     generatedSplitting.splittingKinematics()->kappaSupport(generatedSplitting);
 
   assert(kSupport.first==0&&kSupport.second==1);
 
   pair<double,double> xSupport =
     generatedSplitting.splittingKinematics()->xiSupport(generatedSplitting);
 
  
     vector<double> RN;
     RN.resize(3);
   
     double res=0.;
     double resq=0.;
     double var=10.;
     double varx=10.;
     int k=0;
   while (((k<40.||var>theSudakovAccuracy)&&k<50000)){
     k+=1.;
     RN[0]= optKappaCutoffd+(optKappaCutoffu-optKappaCutoffd)*UseRandom::rnd(); //PT
     RN[1]=xSupport.first+UseRandom::rnd()*(xSupport.second-xSupport.first); //Z
     RN[2]=UseRandom::rnd(); //PHI
     double tmp=(xSupport.second-xSupport.first)*
 	       (optKappaCutoffu-optKappaCutoffd)*
                evaluate(RN);
     
     res+= tmp;
     resq+=pow(tmp,2.);
     if(k%20==0.){
       varx=sqrt((resq/pow(1.*k,2)-pow(res,2)/pow(1.*k,3)));
       var=  (exp(-(res)/(1.0*k)+varx)-exp(-(res)/(1.0*k)-varx))/exp(-res/(1.0*k));
     }      
 
   }
  
   
     return exp(-res/(1.0*k));
     
 }
 
 
 double DipoleSplittingGenerator::wrappedSudakovExpansion(DipoleSplittingInfo& split,
                                                 Energy down,Energy fixedScale) {
   
   assert(!wrapping());
   
   DipoleSplittingInfo backup = generatedSplitting;
   generatedSplitting = split;
   
   fixParameters(split);
   double res=dosudakovExpansion( split, down,fixedScale);
   
   split = generatedSplitting;
   generatedSplitting = backup;
   
   return res;
   
 }
 
 double DipoleSplittingGenerator::wrappedSudakov(DipoleSplittingInfo& split,
 						 Energy down) {
 
   assert(!wrapping());
 
   DipoleSplittingInfo backup = generatedSplitting;
   generatedSplitting = split;
   
   fixParameters(split);
   double res=dosudakov( split, down);
 
   split = generatedSplitting;
   generatedSplitting = backup;
 
   return res;
 
 }
 
 Energy DipoleSplittingGenerator::generateWrapped(DipoleSplittingInfo& split,
 						 map<string,double>& variations,
 						 Energy optHardPt,
 						 Energy optCutoff) {
 
   assert(!wrapping());
 
   DipoleSplittingInfo backup = generatedSplitting;
   generatedSplitting = split;
 
   fixParameters(split,optHardPt);
 
   try {
     doGenerate(variations,optCutoff);
   } catch (...) {
     split = generatedSplitting;
     generatedSplitting = backup;
     throw;
   }
 
   Energy pt = generatedSplitting.lastPt();
 
   split = generatedSplitting;
   generatedSplitting = backup;
 
   return pt;
 
 }
 
 void DipoleSplittingGenerator::completeSplitting(DipoleSplittingInfo& sp) const {
   pair<bool,bool> conf = sp.configuration();
   sp = generatedSplitting;
   sp.configuration(conf);
 }
 
 Ptr<DipoleSplittingKernel>::tptr DipoleSplittingGenerator::splittingKernel() const { 
   if ( wrapping() )
     return theOtherGenerator->splittingKernel();
   return theSplittingKernel;
 }
 
 Ptr<DipoleSplittingReweight>::tptr DipoleSplittingGenerator::splittingReweight() const { 
   if ( wrapping() )
     return theOtherGenerator->splittingReweight();
   return theSplittingReweight;
 }
 
 Ptr<DipoleSplittingKinematics>::tptr DipoleSplittingGenerator::splittingKinematics() const { 
   if ( wrapping() )
     return theOtherGenerator->splittingKinematics();
   return theSplittingKernel->splittingKinematics();
 }
 
 void DipoleSplittingGenerator::splittingKernel(Ptr<DipoleSplittingKernel>::tptr sp) { 
   theSplittingKernel = sp;
   if ( theSplittingKernel->mcCheck() )
     theMCCheck = theSplittingKernel->mcCheck();
 }
 
 void DipoleSplittingGenerator::splittingReweight(Ptr<DipoleSplittingReweight>::tptr sp) { 
   theSplittingReweight = sp;
 }
 
 void DipoleSplittingGenerator::debugGenerator(ostream& os) const {
 
   os << "--- DipoleSplittingGenerator ---------------------------------------------------\n";
 
   os << " generating splittings using\n"
      << " splittingKernel = " << splittingKernel()->name()
      << " splittingKinematics = " << generatedSplitting.splittingKinematics()->name() << "\n"
      << " to sample splittings of type:\n";
 
   os << generatedSplitting;
 
   os << "--------------------------------------------------------------------------------\n";
 
 }
 
 void DipoleSplittingGenerator::debugLastEvent(ostream& os) const {
 
   os << "--- DipoleSplittingGenerator ---------------------------------------------------\n";
 
   os << " last generated event:\n";
 
   os << generatedSplitting;
 
   os << "--------------------------------------------------------------------------------\n";
 
 }
 
 // If needed, insert default implementations of virtual function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void DipoleSplittingGenerator::persistentOutput(PersistentOStream & os) const {
   os << theOtherGenerator << theSplittingKernel << theSplittingReweight << theMCCheck << theDoCompensate;
 }
 
 void DipoleSplittingGenerator::persistentInput(PersistentIStream & is, int) {
   is >> theOtherGenerator >> theSplittingKernel >> theSplittingReweight >> theMCCheck >> theDoCompensate;
 }
 
 ClassDescription<DipoleSplittingGenerator> DipoleSplittingGenerator::initDipoleSplittingGenerator;
 // Definition of the static class description member.
 
 void DipoleSplittingGenerator::Init() {
 
   static ClassDocumentation<DipoleSplittingGenerator> documentation
     ("DipoleSplittingGenerator is used by the dipole shower "
      "to sample splittings from a given dipole splitting kernel.");
 
 
   static Reference<DipoleSplittingGenerator,DipoleSplittingKernel> interfaceSplittingKernel
     ("SplittingKernel",
      "Set the splitting kernel to sample from.",
      &DipoleSplittingGenerator::theSplittingKernel, false, false, true, false, false);
 
   static Reference<DipoleSplittingGenerator,DipoleSplittingReweight> interfaceSplittingReweight
     ("SplittingReweight",
      "Set the splitting reweight.",
      &DipoleSplittingGenerator::theSplittingReweight, false, false, true, true, false);
 
   static Reference<DipoleSplittingGenerator,DipoleMCCheck> interfaceMCCheck
     ("MCCheck",
      "[debug option] MCCheck",
      &DipoleSplittingGenerator::theMCCheck, false, false, true, true, false);
 
   interfaceMCCheck.rank(-1);
 
 }
 
diff --git a/Shower/Dipole/Base/DipoleSplittingGenerator.h b/Shower/Dipole/Base/DipoleSplittingGenerator.h
--- a/Shower/Dipole/Base/DipoleSplittingGenerator.h
+++ b/Shower/Dipole/Base/DipoleSplittingGenerator.h
@@ -1,513 +1,548 @@
 // -*- C++ -*-
 //
 // DipoleSplittingGenerator.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_DipoleSplittingGenerator_H
 #define HERWIG_DipoleSplittingGenerator_H
 //
 // This is the declaration of the DipoleSplittingGenerator class.
 //
 
 #include "ThePEG/Handlers/HandlerBase.h"
 
 #include "Herwig/Shower/Dipole/Kernels/DipoleSplittingKernel.h"
 #include "DipoleSplittingReweight.h"
 #include "Herwig/Shower/Dipole/Utility/DipoleMCCheck.h"
 #include "Herwig/Sampling/exsample/exponential_generator.h"
 
+#include <tuple>
+
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer, Johannes Bellm
  *
  * \brief DipoleSplittingGenerator is used by the dipole shower
  * to sample splittings from a given dipole splitting kernel.
  *
  * @see \ref DipoleSplittingGeneratorInterfaces "The interfaces"
  * defined for DipoleSplittingGenerator.
  */
 class DipoleSplittingGenerator: public HandlerBase {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   DipoleSplittingGenerator();
 
   /**
    * The destructor.
    */
   virtual ~DipoleSplittingGenerator();
   //@}
 
 public:
 
   /**
    * Return the dipole splitting kernel.
    */
   Ptr<DipoleSplittingKernel>::tptr splittingKernel() const;
 
   /**
    * Return the dipole splitting reweight.
    */
   Ptr<DipoleSplittingReweight>::tptr splittingReweight() const;
 
   /**
    * Return the dipole splitting kinematics.
    */
   Ptr<DipoleSplittingKinematics>::tptr splittingKinematics() const;
 
   /**
    * Set the dipole splitting kernel.
    */
   void splittingKernel(Ptr<DipoleSplittingKernel>::tptr sp);
 
   /**
    * Set the dipole splitting reweight.
    */
   void splittingReweight(Ptr<DipoleSplittingReweight>::tptr sp);
 
   /**
    * Make a wrapper around another generator.
    */
   void wrap(Ptr<DipoleSplittingGenerator>::ptr other);
 
   /**
    * Return true, if this is actually a wrapper around
    * another splitting generator.
    */
   bool wrapping() const { return theOtherGenerator; }
 
 public:
 
   /**
    * Reset the current variations to one
    */
   void resetVariations();
 
   /**
    * Prepare to fill the given splitting.
    */
   void prepare(const DipoleSplittingInfo&);
 
   /**
    * Fix parameters from the given DipoleSplittingInfo
    * and generate the next splitting. Return the
    * pt selected for the next splitting.
    */
   Energy generate(const DipoleSplittingInfo&,
 		  map<string,double>& variations,
 		  Energy optHardPt = ZERO,
 		  Energy optCutoff = ZERO);
 
   /**
    * Fix parameters from the fiven DipoleSplittingInfo
    * and generate the next splitting. Return the
    * pt selected for the next splitting when called
    * from a wrapping generator.
    */
   Energy generateWrapped(DipoleSplittingInfo&,
 			 map<string,double>& variations,
 			 Energy optHardPt = ZERO,
 			 Energy optCutoff = ZERO);
 
   /**
    * Complete the given splitting.
    */
   void completeSplitting(DipoleSplittingInfo&) const;
 
   /**
    * Return the last generated splitting
    */
   const DipoleSplittingInfo& lastSplitting() const { return generatedSplitting; }
   
  
     /// Sample the Sudakov in monte carlo fashion.
   double sudakov(const DipoleSplittingInfo&,Energy down);
     /// do the actiual calculation of the sudakov exponent.
   double dosudakov(const DipoleSplittingInfo&,Energy down);
     /// wrapper for sudakovExpansion for identical dipoles.
   double wrappedSudakov(DipoleSplittingInfo& split,Energy down);
     /// Sample the Sudakov exponent for sudakovExpansion weights
   double sudakovExpansion(const DipoleSplittingInfo&,Energy down,Energy fixedScale);
     /// do the actual calculation for the sudakov expansion.
   double dosudakovExpansion(const DipoleSplittingInfo&,Energy down,Energy fixedScale);
     /// wrapper for sudakovExpansion
   double wrappedSudakovExpansion(DipoleSplittingInfo& split,Energy down,Energy fixedScale);
 
+  /**
+   * Turn on partial unweighting and set the reference weight.
+   */
+  void doPartialUnweighting(double wref) {
+    partialUnweighting = true;
+    theReferenceWeight = wref;
+  }
 
 public:
 
   /**
    * Print debug information on the splitting
    * handled.
    */
   void debugGenerator(ostream&) const;
 
   /**
    * Print debug information on the last
    * generated event.
    */
   void debugLastEvent(ostream&) const;
 
 protected:
 
   /**
    * Update parameters given a splitting.
    */
   void fixParameters(const DipoleSplittingInfo&,
 		     Energy optHardPt = ZERO);
 
   /**
    * With the parameters previuosly supplied
    * through fixParameters generate the next
    * splitting.
    */
   void doGenerate(map<string,double>& variations,
 		  Energy optCutoff = ZERO);
 
 public:
 
   /**
    * Return the number of random numbers
    * needed to sample this kernel.
    */
   int nDim() const;
 
   /**
    * Flag, which variables are free variables.
    */
   const vector<bool>& sampleFlags();
 
   /**
    * Return the support of the splitting kernel.
    * The lower bound on the first variable is
    * assumed to correspond to the cutoff on the
    * evolution variable.
    */
   const pair<vector<double>,vector<double> >& support();
 
   /**
    * Return the parameter point associated to the splitting
    * previously supplied through fixParameters.
    */
   const vector<double>& parameterPoint() const { return parameters; }
 
   /**
    * Indicate that presampling of this kernel
    * will be performed in the next calls to
    * evaluate until stopPresampling() is called.
    */
   void startPresampling();
 
   /**
    * Indicate that presampling of this kernel
    * is done until startPresampling() is called.
    */
   void stopPresampling();
 
   /**
    * Return the number of points to presample this
    * splitting generator.
    */
   unsigned long presamplingPoints() const { return splittingKernel()->presamplingPoints(); }
 
   /**
    * Return the maximum number of trials
    * to generate a splitting.
    */
   unsigned long maxtry() const { return splittingKernel()->maxtry(); }
 
   /**
    * Return the number of accepted points after which the grid should
    * be frozen
    */
   unsigned long freezeGrid() const { return splittingKernel()->freezeGrid(); }
 
   /**
    * Return the detuning factor applied to the sampling overestimate kernel
    */
   double detuning() const { return splittingKernel()->detuning(); }
 
   /**
    * Return true, if this splitting generator
    * is able to deliver an overestimate to the sampled
    * kernel.
    */
   bool haveOverestimate() const;
 
   /**
    * Return an overestimate to the sampled kernel.
    */
   double overestimate(const vector<double>&);
 
   /**
    * Invert the integral over the overestimate to equal
    * the given value.
    */
   double invertOverestimateIntegral(double) const;
 
   /**
    * Evalute the splitting kernel.
    */
   double evaluate(const vector<double>&);
 
   /**
    * Indicate that a veto with the given kernel value and overestimate has occured.
    */
   void veto(const vector<double>&, double p, double r);
 
   /**
    * Indicate that an accept with the given kernel value and overestimate has occured.
    */
   void accept(const vector<double>&, double p, double r);
 
   /**
    * Return the weight associated to the currently generated splitting
    */
   double splittingWeight() const {
     if ( wrapping() )
       return theOtherGenerator->splittingWeight();
     return theSplittingWeight;
   }
 
   /**
    * True, if sampler should apply compensation
    */
   void doCompensate(bool yes = true) { theDoCompensate = yes; }
 
+  /**
+   * Return the weight vector associated to the currently generated splitting
+   */
+  vector<std::tuple<Energy,double,bool> > splittingWeightVector() const {
+    if ( wrapping() )
+      return theOtherGenerator->splittingWeightVector();
+    return theSplittingWeightVector;
+  }
+
 public:
 
   /**@name Wrap to the exsample2 interface until this is finally cleaned up. */
   //@{
 
   inline const vector<bool>& variable_flags () {
     return sampleFlags();
   }
 
   inline size_t evolution_variable () const { return 0; }
 
   inline double evolution_cutoff () { return support().first[0]; }
 
   inline const vector<double>& parameter_point () const {
     return parameterPoint();
   }
 
   inline void start_presampling () { 
     startPresampling();
   }
 
   inline void stop_presampling () { 
     stopPresampling();
   }
 
   inline size_t dimension () const { 
     return nDim();
   }
 
   inline unsigned long presampling_points () const { 
     return presamplingPoints();
   }
 
   //@}
 
 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 private:
 
   /**
    * Pointer to another generator to wrap around.
    */
   Ptr<DipoleSplittingGenerator>::ptr theOtherGenerator;
 
   /**
    * The dipole splitting kernel to sample
    * splitting from.
    */
   Ptr<DipoleSplittingKernel>::ptr theSplittingKernel;
 
   /**
    * The dipole splitting reweight.
    */
   Ptr<DipoleSplittingReweight>::ptr theSplittingReweight;
 
   /**
    * Pointer to the exponential generator
    */
   exsample::exponential_generator<DipoleSplittingGenerator,UseRandom>*
   theExponentialGenerator;
 
   /**
    * The dipole splitting to be completed.
    */
   DipoleSplittingInfo generatedSplitting;
 
   /**
    * A backup of the dipole splitting to be
    * completed, if this generator is presampled.
    */
   DipoleSplittingInfo presampledSplitting;
 
   /**
    * True, if prepared to sample splittings
    * of a given kind.
    */
   bool prepared;
 
   /**
    * Wether or not the kernel is currently
    * being presampled.
    */
   bool presampling;
 
   /**
    * The parameter point.
    */
   vector<double> parameters;
 
   /**
    * The sampling flags
    */
   vector<bool> theFlags;
 
   /**
    * The support.
    */
   pair<vector<double>,vector<double> > theSupport;
 
   /**
    * Pointer to a check histogram object
    */
   Ptr<DipoleMCCheck>::ptr theMCCheck;
 
   /**
    * True, if sampler should apply compensation
    */
   bool theDoCompensate;
 
   /**
    * The currently used weight map
    */
   map<string,double> currentWeights;
 
   /**
    * The weight associated to the currently generated splitting
    */
   double theSplittingWeight;
 
 
   /**
    * Sudakov sampling accuracy
    */
   double theSudakovAccuracy=0.05;
 
+  /**
+   * Reference weight to improve convergence for subleading Nc
+   * corrections (by reducing time spent on events with very
+   * small weights)
+   */
+  double theReferenceWeight;
+
+  /**
+   * Flag for partial unweighting.
+   */
+  bool partialUnweighting = false;
+
+  /**
+   * The scale, weight and a bool for all veto steps and the accept step.
+   * The bool is false for a veto step and true for an accept step.
+   */
+  vector<std::tuple<Energy,double,bool> > theSplittingWeightVector;
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<DipoleSplittingGenerator> initDipoleSplittingGenerator;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   DipoleSplittingGenerator & operator=(const DipoleSplittingGenerator &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of DipoleSplittingGenerator. */
 template <>
 struct BaseClassTrait<Herwig::DipoleSplittingGenerator,1> {
   /** Typedef of the first base class of DipoleSplittingGenerator. */
   typedef HandlerBase NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the DipoleSplittingGenerator class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::DipoleSplittingGenerator>
   : public ClassTraitsBase<Herwig::DipoleSplittingGenerator> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::DipoleSplittingGenerator"; }
   /**
    * The name of a file containing the dynamic library where the class
    * DipoleSplittingGenerator is implemented. It may also include several, space-separated,
    * libraries if the class DipoleSplittingGenerator depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_DipoleSplittingGenerator_H */
diff --git a/Shower/Dipole/Base/DipoleSplittingInfo.h b/Shower/Dipole/Base/DipoleSplittingInfo.h
--- a/Shower/Dipole/Base/DipoleSplittingInfo.h
+++ b/Shower/Dipole/Base/DipoleSplittingInfo.h
@@ -1,791 +1,807 @@
 // -*- C++ -*-
 //
 // DipoleSplittingInfo.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_DipoleSplittingInfo_H
 #define HERWIG_DipoleSplittingInfo_H
 //
 // This is the declaration of the DipoleIndex and DipoleSplittingInfo classes.
 //
 
 #include "ThePEG/PDF/PDF.h"
 #include "ThePEG/PDT/ParticleData.h"
 
 #include "Herwig/Shower/Dipole/Kinematics/DipoleSplittingKinematics.h"
+#include "Herwig/Shower/Dipole/Kernels/DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 class DipoleSplittingKinematics;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer, Stephen Webster
  *
  * \brief DipoleIndex is used to index splitting generators
  * for a particular dipole.
  *
  */
 class DipoleIndex {
 
 public:
 
   /**
    * The default constructor.
    */
   DipoleIndex();
 
   /**
    * The standard constructor
    */
   DipoleIndex(tcPDPtr newEmitter, tcPDPtr newSpectator,
 	      const PDF& newEmitterPDF = PDF(), const PDF& newSpectatorPDF = PDF(),
 	      const bool decayingEmitter = false, const bool decayingSpectator = false,
 	      const bool offShellEmitter = false, const bool offShellSpectator = false);
 
 public:
 
   /**
    * Compare for equality.
    */
   bool operator ==(const DipoleIndex& x) const;
 
   /**
    * Compare for ordering.
    */
   bool operator <(const DipoleIndex& x) const;
 
   /**
    * Swap emitter and spectator.
    */
   void swap();
 
   /**
    * Produce a pair of dipole indices given
    * a particle data object for the emission.
    * The ME correction is ignored in the children.
    * The emission is inserted between the emitter
    * and spectator, being a spectator in the first
    * dipole index containing the original emitter,
    * and an emitter in the second dipole, containing
    * the original spectator.
    */
   pair<DipoleIndex,DipoleIndex> split(tcPDPtr) const;
 
 public:
   
   /**
    * Return the emitter particle data object.
    */
   tcPDPtr emitterData() const { return theEmitterData; }
 
   /**
    * Return true, if the emitter is an incoming parton
    */
   bool initialStateEmitter() const { return theInitialStateEmitter; }
 
   /**
    * Return true, if the emitter is incoming to a decay
    */
   bool incomingDecayEmitter() const { return theIncomingDecayEmitter; }
 
   /**
    * Return true, if the emitter can be off-shell
    */
   bool offShellEmitter() const { return theOffShellEmitter; }
   //bool offShellEmitter() const { return theEmitterData->width() != ZERO; }
 
   /**
    * Return the PDF object associated with the emitter
    */
   const PDF& emitterPDF() const { return theEmitterPDF; }
 
   /**
    * Return the spectator particle data object.
    */
   tcPDPtr spectatorData() const { return theSpectatorData; }
 
   /**
    * Return true, if the spectator is an incoming parton
    */
   bool initialStateSpectator() const { return theInitialStateSpectator; }
 
   /**
    * Return true, if the spectator is incoming to a decay
    */
   bool incomingDecaySpectator() const { return theIncomingDecaySpectator; }
 
   /**
    * Return true, if the spectator can be off-shell
    */
   bool offShellSpectator() const { return theOffShellSpectator; }
   //bool offShellSpectator() const { return theSpectatorData->width() != ZERO; }
 
   /**
    * Return the PDF object associated with the spectator
    */
   const PDF& spectatorPDF() const { return theSpectatorPDF; }
 
 public:
 
   /**
    * Put information to ostream
    */
   void print(ostream&) const;
 
 private:
 
   /**
    * The particle data object of the emitter.
    */
   tcPDPtr theEmitterData;
 
   /**
    * Whether or not the emitter is an incoming parton.
    */
   bool theInitialStateEmitter;
 
   /**
    * Whether or not the emitter is incoming to a decay.
    */
   bool theIncomingDecayEmitter;
 
   /**
    * Can the emitter be off-shell?
    */
   bool theOffShellEmitter;
   
   /**
    * The PDF object for the emitter.
    */
   PDF theEmitterPDF;
 
   /**
    * The particle data object of the spectator.
    */
   tcPDPtr theSpectatorData;
 
   /**
    * Whether or not the spectator is an incoming parton.
    */
   bool theInitialStateSpectator;
 
   /**
    * Whether or not the spectator is incoming to a decay.
    */
   bool theIncomingDecaySpectator;
   
   /**
    * Can the spectator be off-shell?
    */
   bool theOffShellSpectator;
 
   /**
    * The PDF object for the spectator.
    */
   PDF theSpectatorPDF;
 
 };
 
 inline ostream& operator << (ostream& os, const DipoleIndex& di) {
   di.print(os);
   return os;
 }
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer
  *
  * \brief DipoleSplittingInfo contains all parameters to generate a full
  * dipole splitting.
  *
  */
 class DipoleSplittingInfo {
 
 public:
 
   /**
    * The default constructor.
    */
   DipoleSplittingInfo();
 
   /**
    * Destructor
    */
   virtual ~DipoleSplittingInfo() {}
   
 
   /**
    * Standard constructor.
    */
   DipoleSplittingInfo(DipoleIndex ind,pair<bool,bool> conf,double emitX,
                       double spectX,tPPtr emit,tPPtr spect){
        	theIndex=ind;
 	theConfiguration=conf;
 	theEmitterX=emitX;
        	theSpectatorX=spectX;
 	theEmitter=emit;
 	theSpectator=spect;
   }
   
 
 public:
 
   /**
    * Assign data from another splitting info
    */
   void fill(const DipoleSplittingInfo&);
 
 public:
 
   /**
    * Return the dipole index
    */
   const DipoleIndex& index() const { return theIndex; }
 
   /**
    * Return which of the particles
    * in the dipole should be considered emitter (true)
    * and spectator (false)
    */
   const pair<bool,bool>& configuration() const { return theConfiguration; }
 
   /**
    * Get the configuration marking the spectator
    */
   const pair<bool,bool>& spectatorConfiguration() const { return theSpectatorConfiguration; }
 
   /**
    * Return the particle data object of the emitter
    * after the splitting.
    */
   tcPDPtr emitterData() const { return theEmitterData; }
 
   /**
    * Return the particle data object of the emission
    * after the splitting.
    */
   tcPDPtr emissionData() const { return theEmissionData; }
 
   /**
    * Return the particle data object of the spectator
    * after the splitting.
    */
   tcPDPtr spectatorData() const { return theSpectatorData; }
 
   /**
    * Return the momentum fraction of the emitter.
    */
   double emitterX() const { return theEmitterX; }
 
   /**
    * Return the momentum fraction of the spectator.
    */
   double spectatorX() const { return theSpectatorX; }
 
 public:
 
   /**
    * Return a pointer to the DipoleSplittingKinematics object
    * which is to be used to perform the splitting.
    */
   Ptr<DipoleSplittingKinematics>::tptr splittingKinematics() const { return theSplittingKinematics; }
 
   /**
+   * Return a pointer to the DipoleSplittingKernel object
+   * which is used to perform the splitting.
+   **/
+  Ptr<DipoleSplittingKernel>::tptr splittingKernel() const { return theSplittingKernel;}
+
+  /**
    * Return the dipole scale
    */
   Energy scale() const { return theScale; }
 
   /**
    * Return whether or not this dipole is 
    * part of a decay process.
    **/
   bool isDecayProc() const { return theIsDecayProc; }
 
   /**
    * Return the mass of the recoil system
    * in decay dipoles.
    */
   Energy recoilMass() const { return theRecoilMass; }
 
   /**
    * Return the spectator mass
    * (to cope with off-shell particles)
    **/
   Energy spectatorMass() const { return theSpectatorMass; }
   
   /**
    * Return the emitter mass
    * (to cope with off-shell particles)
    **/
   Energy emitterMass() const { return theEmitterMass; }
   
   /**
    * Return the pt below which this
    * splitting has been generated.
    */
   Energy hardPt() const { return theHardPt; }
 
   /**
    * Return the last generated pt
    */
   Energy lastPt() const { return theLastPt; }
 
   /**
    * Return the last generated momentum fraction.
    */
   double lastZ() const { return theLastZ; }
 
   /**
    * Return the last generated azimuthal angle.
    */
   double lastPhi() const { return theLastPhi; }
 
   /**
    * Return the momentum fraction, by which the emitter's
    * momentum fraction should be divided after the splitting.
    */
   double lastEmitterZ() const { return theLastEmitterZ; }
 
   /**
    * Return the momentum fraction, by which the spectator's
    * momentum fraction should be divided after the splitting.
    */
   double lastSpectatorZ() const { return theLastSpectatorZ; }
 
   /**
    * Return any additional parameters needed to
    * evaluate the splitting kernel or to generate the 
    * full splitting.
    */
   const vector<double>& lastSplittingParameters() const { return theLastSplittingParameters; }
 
   /**
    * Return true, if this splitting will terminate
    * the evolution of the dipole considered.
    */
   bool stoppedEvolving() const { return theStoppedEvolving; }
 
 public:
 
   /**
    * Set the index.
    */
   void index(const DipoleIndex& ind) { theIndex = ind; }
 
   /**
    * Set the DipoleSplittingKinematics object
    */
   void splittingKinematics(Ptr<DipoleSplittingKinematics>::tptr newSplittingKinematics) {
     theSplittingKinematics = newSplittingKinematics;
   }
 
   /**
+   * Set the DipoleSplittingKernel object
+   */
+  void splittingKernel( Ptr<DipoleSplittingKernel>::tptr newSplittingKernel){
+    theSplittingKernel = newSplittingKernel;
+  }
+
+  /**
    * Set the particle data object of the emitter
    * after the splitting.
    */
   void emitterData(tcPDPtr p) { theEmitterData = p; }
 
   /**
    * Set the particle data object of the emission
    * after the splitting.
    */
   void emissionData(tcPDPtr p) { theEmissionData = p; }
 
   /**
    * Set the particle data object of the spectator
    * after the splitting.
    */
   void spectatorData(tcPDPtr p) { theSpectatorData = p; }
 
   /**
    * Set the dipole scale
    */
   void scale(Energy s) { theScale = s; }
   
   /**
    * Set whether or not this dipole is 
    * part of a decay process.
    **/
   void isDecayProc(bool isDecayProc) { theIsDecayProc = isDecayProc; }
 
   /**
    * Set the mass of the recoil system
    * in decay dipoles
    */
-  void recoilMass(Energy mass) { theRecoilMass = mass; }
+  void recoilMass(Energy mass) { theRecoilMass = mass; }  
 
   /**
    * Set the spectator mass
    * (to cope with off-shell particles)
    **/
   void spectatorMass(Energy mass){ theSpectatorMass = mass; }
   
   /**
    * Set the emitter mass 
    * (to cope with off-shell particles)
    **/
   void emitterMass(Energy mass){ theEmitterMass = mass; }
   
   /**
    * Set the emitter's momentum fraction
    */
   void emitterX(double x) { theEmitterX = x; }
 
   /**
    * Set the spectator's momentum fraction
    */
   void spectatorX(double x) { theSpectatorX = x; }
 
   /**
    * Set the pt below which this
    * splitting has been generated.
    */
   void hardPt(Energy p) { theHardPt = p; }
-  
+
   /**
    * Set the last generated pt
    */
   void lastPt(Energy p) { theLastPt = p; }
 
   /**
    * Set the last generated momentum fraction.
    */
   void lastZ(double z) { theLastZ = z; }
 
   /**
    * Set the last generated azimuthal angle.
    */
   void lastPhi(double p) { theLastPhi = p; }
 
   /**
    * Set the momentum fraction, by which the emitter's
    * momentum fraction should be divided after the splitting.
    */
   void lastEmitterZ(double z) { theLastEmitterZ = z; }
 
   /**
    * Set the momentum fraction, by which the spectator's
    * momentum fraction should be divided after the splitting.
    */
   void lastSpectatorZ(double z) { theLastSpectatorZ = z; }
 
   /**
    * Return the last splitting kernel value encountered.
    */
   double lastValue() const { return theLastValue; }
 
   /**
    * Set the last splitting kernel value encountered.
    */
   void lastValue(double v) { theLastValue = v; }
 
   /**
    * Set the flag to calculate the Sudakov with fixed scales.
    */
   void setCalcFixedExpansion(bool c){theCalcFixedExpansion=c;}
   
   /**
    * Flag to calculate the Sudakov with fixed scales.
    */
   bool calcFixedExpansion()const{ return theCalcFixedExpansion;}
   
  /**
    * Fixed scale for Sudakov sampling with fixed scales.
    */
   Energy fixedScale() const{return theFixedScale;}
   
  /**
    * Set the fixed scale.
    */
   void fixedScale(Energy fix){ theFixedScale=fix;}
   
   /**
    * Set the last splitting parameters.
    */
   void lastSplittingParameters(const vector<double>& p) { theLastSplittingParameters = p; }
 
   /**
    * Access the splitting parameters
    */
   vector<double>& splittingParameters() { return theLastSplittingParameters; }
 
   /**
    * Indicate that this splitting will terminate
    * the evolution of the dipole considered.
    */
   void didStopEvolving() { theStoppedEvolving = true; }
 
   /**
    * Indicate that this splitting will not terminate
    * the evolution of the dipole considered.
    */
   void continuesEvolving() { theStoppedEvolving = false; }
 
   /**
    * Reset the configuration.
    */
   void configuration(const pair<bool,bool>& newConfig) { theConfiguration = newConfig; }
 
   /**
    * Set the configuration marking the spectator
    */
   void spectatorConfiguration(const pair<bool,bool>& conf) { theSpectatorConfiguration = conf; }
 
 public:
 
   /**
    * Set a pointer to the emitter parton before emission.
    */
   void emitter(tPPtr newEmitter) { theEmitter = newEmitter; }
 
   /**
    * Set a pointer to the spectator parton before emission.
    */
   void spectator(tPPtr newSpectator) { theSpectator = newSpectator; }
 
   /**
    * Set a pointer to the emitter parton after emission.
    */
   void splitEmitter(tPPtr newEmitter) { theSplitEmitter = newEmitter; }
 
   /**
    * Set a pointer to the spectator parton after emission.
    */
   void splitSpectator(tPPtr newSpectator) { theSplitSpectator = newSpectator; }
 
   /**
    * Set a pointer to the emitted parton.
    */
   void emission(tPPtr newEmission) { theEmission = newEmission; }
 
   /**
    * Return a pointer to the emitter parton before emission.
    */
   tPPtr emitter() const { return theEmitter; }
 
   /**
    * Return a pointer to the spectator parton before emission.
    */
   tPPtr spectator() const { return theSpectator; }
 
   /**
    * Return a pointer to the emitter parton after emission.
    */
   tPPtr splitEmitter() const { return theSplitEmitter; }
 
   /**
    * Return a pointer to the spectator parton after emission.
    */
   tPPtr splitSpectator() const { return theSplitSpectator; }
 
   /**
    * Return a pointer to the emitted parton.
    */
   tPPtr emission() const { return theEmission; }
 
 public:
 
   /**
    * Put information to ostream
    */
   void print(ostream&) const;
 
 private:
 
   /**
    * The DipoleIndex associated 
    * with this splitting.
    */
   DipoleIndex theIndex;
 
   /**
    * Flags indicateing which of the particles
    * in the dipole should be considered emitter (true)
    * and spectator (false)
    */
   pair<bool,bool> theConfiguration;
 
   /**
    * The configuration marking the spectator
    */
   pair<bool,bool> theSpectatorConfiguration;
 
   /**
    * The particle data object of the emitter
    * after the splitting.
    */
   tcPDPtr theEmitterData;
 
   /**
    * The particle data object of the emission
    * after the splitting.
    */
   tcPDPtr theEmissionData;
 
   /**
    * The particle data object of the spectator
    * after the splitting.
    */
   tcPDPtr theSpectatorData;
 
   /**
    * A pointer to the DipoleSplittingKinematics object
    * which is to be used to perform the splitting.
    */
   Ptr<DipoleSplittingKinematics>::tptr theSplittingKinematics;
+  
+  /**
+   * A pointer to the DipoleSplittingKernel object
+   * which is used to perform the splitting.
+   **/
+  Ptr<DipoleSplittingKernel>::tptr theSplittingKernel;
 
   /**
    * The scale for this dipole.
    */
   Energy theScale;
 
   /**
    * Whether or not this dipole comes from a decay process.
    */
   bool theIsDecayProc;
 
   /**
    * The mass of the recoil system in
    * decay dipoles.
    */
   Energy theRecoilMass;
 
-
   /**
    * The mass of the emitter.
    * (To account for off-shell).
    */
   Energy theEmitterMass;
   
   /**
    * The mass of the spectator.
    * (To account for off-shell).
    */
   Energy theSpectatorMass;
 
-
-  
-
   /**
    * The momentum fraction of the emitter.
    */
   double theEmitterX;
 
   /**
    * The momentum fraction of the spectator.
    */
   double theSpectatorX;
 
   /**
    * The pt below which this splitting has 
    * been generated.
    */
   Energy theHardPt;
 
   /**
    * The last generated pt
    */
   Energy theLastPt;
 
   /**
    * The last generated momentum fraction.
    */
   double theLastZ;
 
   /**
    * The last calculated zPrime required for massive FF
    * and decay kinematics dipoles.
    * zPrime := qi.nk / (qi+qj).nk (qj = emission momentum)
    */
   // Note: Not required in current implementation
   //double theLastZPrime;
 
   /**
    * The last generated azimuthal angle.
    */
   double theLastPhi;
 
   /**
    * The momentum fraction, by which the emitter's
    * momentum fraction should be divided after the splitting.
    */
   double theLastEmitterZ;
 
   /**
    * The momentum fraction, by which the spectator's
    * momentum fraction should be divided after the splitting.
    */
   double theLastSpectatorZ;
 
   /**
    * The last splitting kernel value encountered.
    */
   double theLastValue;
 
   /**
    * Any additional parameters needed to
    * evaluate the splitting kernel or to generate the 
    * full splitting.
    */
   vector<double> theLastSplittingParameters;
 
   /**
    * True, if this splitting will terminate
    * the evolution of the dipole considered.
    */
   bool theStoppedEvolving;
 
   /**
    * A pointer to the emitter parton before emission.
    */
   PPtr theEmitter;
 
   /**
    * A pointer to the spectator parton before emission.
    */
   PPtr theSpectator;
 
   /**
    * A pointer to the emitter parton after emission.
    */
   PPtr theSplitEmitter;
 
   /**
    * A pointer to the spectator parton after emission.
    */
   PPtr theSplitSpectator;
 
   /**
    * A pointer to the emitted parton.
    */
   PPtr theEmission;
 
   /**
    * Flag to calculate Splitting kernels with a fixed scale
    * and without alphas/2pi
    **/
   bool theCalcFixedExpansion;
   
   /**
    * Fixed scale for Sudakov evaluation.
    */
   Energy theFixedScale;
   
   
 
 };
 
 inline ostream& operator << (ostream& os, const DipoleSplittingInfo& di) {
   di.print(os);
   return os;
 }
 
 }
 
 #endif /* HERWIG_DipoleSplittingInfo_H */
diff --git a/Shower/Dipole/Base/DipoleSplittingReweight.h b/Shower/Dipole/Base/DipoleSplittingReweight.h
--- a/Shower/Dipole/Base/DipoleSplittingReweight.h
+++ b/Shower/Dipole/Base/DipoleSplittingReweight.h
@@ -1,175 +1,197 @@
 // -*- C++ -*-
 //
 // DipoleSplittingReweight.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_DipoleSplittingReweight_H
 #define HERWIG_DipoleSplittingReweight_H
 //
 // This is the declaration of the DipoleSplittingReweight class.
 //
 
 #include "ThePEG/Handlers/HandlerBase.h"
 #include "DipoleSplittingInfo.h"
 
 #include "Herwig/Shower/Dipole/DipoleShowerHandler.fh"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer
  *
  * \brief DipoleSplittingReweight is used by the dipole shower
  * to reweight splittings from a given dipole splitting kernel.
  *
  * @see \ref DipoleSplittingReweightInterfaces "The interfaces"
  * defined for DipoleSplittingReweight.
  */
 class DipoleSplittingReweight: public HandlerBase {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   DipoleSplittingReweight();
 
   /**
    * The destructor.
    */
   virtual ~DipoleSplittingReweight();
   //@}
 
 public:
 
   /**
    * Return true, if the reweighting should be applied to the first
    * interaction
    */
   virtual bool firstInteraction() const { return true; }
 
   /**
    * Return true, if the reweighting should be applied to the secondary
    * interactions
    */
   virtual bool secondaryInteractions() const { return false; }
 
   /**
    * Update the pointer to the currently active dipole shower handler object.
    */
   void updateCurrentHandler();
 
   /**
    * Return the pointer to the currently active dipole shower handler object.
    */
   Ptr<DipoleShowerHandler>::tptr currentHandler() const;
 
   /**
    * Return the reweighting factor for the given splitting type.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const = 0;
 
   /**
    * Return an enhancement hint for the sampling of the un-reweighted
    * splitting kernel
    */
   virtual double hint(const DipoleSplittingInfo&) const {
     return 1.;
   }
 
+  /**
+   * Return true, if the reweight can be entirely absorbed into the hint. A
+   * possible detuning will be switched off.
+   */
+  virtual bool hintOnly(const DipoleSplittingInfo&) const {
+    return false;
+  }
+
+  /**
+   * Set the factor in front of enhance used by the veto algorithm.
+   */
+  virtual void reweightFactor(const double) {
+    return;
+  }
+
+  /**
+   * Scaling factor for negative reweights.
+   */
+  virtual void negativeScaling(const double) {
+    return;
+  }
+
 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();
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static AbstractClassDescription<DipoleSplittingReweight> initDipoleSplittingReweight;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   DipoleSplittingReweight & operator=(const DipoleSplittingReweight &) = delete;
 
   /**
    * A pointer to the currently active dipole shower handler object.
    */
   Ptr<DipoleShowerHandler>::tptr theCurrentHandler;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of DipoleSplittingReweight. */
 template <>
 struct BaseClassTrait<Herwig::DipoleSplittingReweight,1> {
   /** Typedef of the first base class of DipoleSplittingReweight. */
   typedef HandlerBase NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the DipoleSplittingReweight class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::DipoleSplittingReweight>
   : public ClassTraitsBase<Herwig::DipoleSplittingReweight> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::DipoleSplittingReweight"; }
   /**
    * The name of a file containing the dynamic library where the class
    * DipoleSplittingReweight is implemented. It may also include several, space-separated,
    * libraries if the class DipoleSplittingReweight depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_DipoleSplittingReweight_H */
diff --git a/Shower/Dipole/DipoleShowerHandler.cc b/Shower/Dipole/DipoleShowerHandler.cc
--- a/Shower/Dipole/DipoleShowerHandler.cc
+++ b/Shower/Dipole/DipoleShowerHandler.cc
@@ -1,1384 +1,1918 @@
   // -*- C++ -*-
   //
   // DipoleShowerHandler.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 DipoleShowerHandler class.
   //
 
 #include <config.h>
 #include "DipoleShowerHandler.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Interface/RefVector.h"
 #include "ThePEG/Interface/Parameter.h"
 #include "ThePEG/Interface/ParVector.h"
 #include "ThePEG/Interface/Switch.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
   // include theses to have complete types
 #include "Herwig/PDF/MPIPDF.h"
 #include "Herwig/PDF/MinBiasPDF.h"
 #include "Herwig/PDF/HwRemDecayer.h"
 
 #include "Herwig/Shower/Dipole/Utility/DipolePartonSplitter.h"
 #include "Herwig/MatrixElement/Matchbox/Base/MergerBase.h"
 
 #include "Herwig/MatrixElement/Matchbox/Base/SubtractedME.h"
 #include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h"
 #include <queue>
 
 using namespace Herwig;
 
 bool DipoleShowerHandler::firstWarn = true;
 
 DipoleShowerHandler::DipoleShowerHandler() :
   ShowerHandler(), chainOrderVetoScales(true),
   nEmissions(0), discardNoEmissions(false), firstMCatNLOEmission(false),
   thePowhegDecayEmission(true),
+  //theAnalyseSpinCorrelations(false),
   realignmentScheme(0),
+  doSubleadingNc(false),subleadingNcEmissionsLimit(0),
+  densityOperatorEvolution(0),densityOperatorCutoff(1.0*GeV2),
+  doPartialUnweightingAtEmission(false),
+  doPartialUnweighting(false),referenceWeight(0.1),
+  cmecReweightFactor(1.0),negCMECScaling(1.0),
   verbosity(0), printEvent(0), nTries(0),
   didRadiate(false), didRealign(false),
   theRenormalizationScaleFreeze(1.*GeV),
   theFactorizationScaleFreeze(2.*GeV), theDoCompensate(false),
   theFreezeGrid(500000), theDetuning(1.0),
   maxPt(ZERO), muPt(ZERO),
   theInputColouredOffShellInShower(),
   theZBoundaries(1) {}
 
 DipoleShowerHandler::~DipoleShowerHandler() {}
 
 IBPtr DipoleShowerHandler::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr DipoleShowerHandler::fullclone() const {
   return new_ptr(*this);
 }
 
 
 
 void  DipoleShowerHandler::cascade(tPVector ) {
   throw Exception()
   << "DipoleShowerHandler: Dipoleshower not implemented as second shower."
   << "Check your setup or contact Herwig authors."
   << Exception::runerror;
 }
 
 
 tPPair DipoleShowerHandler::cascade(tSubProPtr sub, XCombPtr,
                                     Energy optHardPt, Energy optCutoff) {
-
+  
   useMe();
   
   prepareCascade(sub);
   resetWeights();
   
   if ( !doFSR() && ! doISR() )
+    return sub->incoming();
+
+  eventRecord().setSubleadingNc(doSubleadingNc,
+				subleadingNcEmissionsLimit);
+  eventRecord().clear();
+  eventRecord().prepare(sub,dynamic_ptr_cast<tStdXCombPtr>(lastXCombPtr()),newStep(),pdfs(),
+			ShowerHandler::currentHandler()->generator()->currentEvent()->incoming(),
+			firstInteraction(), offShellPartons(),
+                        !doSubleadingNc);
+  if ( doSubleadingNc ) {
+    if ( !theSplittingReweight ) {
+      throw Exception() << "No splitting reweight was found. "
+			<< "A ColourMatrixElementCorrection "
+			<< "splitting reweight is required "
+			<< "for the subleading colour shower."
+			<< Exception::runerror; 
+    }
+    //Set the evolution scheme for the density operator
+    eventRecord().setDensityOperatorEvolution( densityOperatorEvolution, densityOperatorCutoff );
+    //Set the CMEC reweight factor
+    theSplittingReweight->reweightFactor(cmecReweightFactor);
+    theSplittingReweight->negativeScaling(negCMECScaling);
+    theSplittingReweight->updateCurrentHandler();
+  }
+
+  // SW: Removed simple test on doFSR and doISR and moved
+  // here to account for the case of a hard event involving
+  // no coloured particles but with unstable outgoing particles
+  if ( !doFSR() && ! doISR() && eventRecord().decays().empty() )
   return sub->incoming();
-  
-  eventRecord().clear();
-  eventRecord().prepare(sub, dynamic_ptr_cast<tStdXCombPtr>(lastXCombPtr()), newStep(), pdfs(), 
-			ShowerHandler::currentHandler()->generator()->currentEvent()->incoming(),		    
- 			firstInteraction(), offShellPartons());
-  if ( eventRecord().outgoing().empty() && !doISR() )
-  return sub->incoming();
-  if ( !eventRecord().incoming().first->coloured() &&
+  if ( !doISR() &&
+       eventRecord().outgoing().empty() &&
+       eventRecord().decays().empty() )
+    return sub->incoming();
+  if ( !doFSR() &&
+       !eventRecord().incoming().first->coloured() &&
       !eventRecord().incoming().second->coloured() &&
-      !doFSR() )
+       eventRecord().decays().empty() )
   return sub->incoming();
   
   nTries = 0;
   
+  // Clear the vertex record for spin correlations
+  if ( spinCorrelations() ) //|| theAnalyseSpinCorrelations )
+    vertexRecord().clear();
+  
   while ( true ) {
     
     try {
       
       didRadiate = false;
       didRealign = false;
       
       if ( eventRecord().truncatedShower() ) {
         throw Exception() << "Inconsistent hard emission set-up in DipoleShowerHandler::cascade. "
         << "No truncated shower needed with DipoleShowerHandler.  Add "
         << "'set MEMatching:TruncatedShower No' to input file."
         << Exception::runerror;
       }
       
       hardScales(lastXCombPtr()->lastShowerScale());
       
       if ( verbosity > 1 ) {
         generator()->log() << "DipoleShowerHandler starting off:\n";
         eventRecord().debugLastEvent(generator()->log());
         generator()->log() << flush;
       }
       
       unsigned int nEmitted = 0;
       
       if ( firstMCatNLOEmission ) {
         
         if ( !eventRecord().isMCatNLOHEvent() )
         nEmissions = 1;
         else
         nEmissions = 0;
         
       }
       
       if ( !firstMCatNLOEmission ) {
         
         doCascade(nEmitted,optHardPt,optCutoff);
         
         if ( discardNoEmissions ) {
           if ( !didRadiate )
           throw Veto();
           if ( nEmissions )
           if ( nEmissions < nEmitted )
           throw Veto();
         }
         
       } else {
         
         if ( nEmissions == 1 )
         doCascade(nEmitted,optHardPt,optCutoff);
         
       }
       
       if ( intrinsicPtGenerator ) {
         if ( eventRecord().incoming().first->coloured() &&
             eventRecord().incoming().second->coloured() ) {
-          SpinOneLorentzRotation rot =
+          LorentzRotation rot =
           intrinsicPtGenerator->kick(eventRecord().incoming(),
                                      eventRecord().intermediates());
           eventRecord().transform(rot);
         }
       }
       
       didRealign = realign();
+    
       constituentReshuffle();
+
+      // backup subleading switch if decays fail
+      bool doneSubleadingNc = doSubleadingNc;
+
+      // subleading N can't handle decays
+      doSubleadingNc = false;
+
+      try {
       
         // Decay and shower any particles that require decaying
       while ( !eventRecord().decays().empty() ) {
 	
         map<PPtr,PerturbativeProcessPtr>::const_iterator decayIt = eventRecord().decays().begin();
+        if ( eventRecord().nextDecay() ) {
+          decayIt = eventRecord().decays().find(eventRecord().nextDecay() );
+        }
+        else {
           // find the decay to do, one with greatest width and parent showered
         while(find(eventRecord().outgoing().begin(),eventRecord().outgoing().end(),decayIt->first)==
               eventRecord().outgoing().end() &&
               find(eventRecord().hard().begin(),eventRecord().hard().end(),decayIt->first)==
               eventRecord().hard().end()) ++decayIt;
+        }
+	
         assert(decayIt!=eventRecord().decays().end());
         PPtr incoming = decayIt->first;
         eventRecord().currentDecay(decayIt->second);
         
           // Use this to record if an emission actually happens
         bool powhegEmission = !( nEmissions && nEmitted==nEmissions) ? thePowhegDecayEmission : false;
         
           // Decay the particle / sort out its pert proc
         Energy showerScale = eventRecord().decay(incoming, powhegEmission);
         
           // Following the decay, the bool powheg emission is updated
           // to indicate whether or not an emission occurred
         if ( powhegEmission )
         nEmitted += 1;
         
           // Check that there is only one particle incoming to the decay
         assert(eventRecord().currentDecay()->incoming().size()==1);
         
           // Prepare the event record for the showering of the decay
         bool needToShower = eventRecord().prepareDecay(eventRecord().currentDecay(),
 						       offShellPartons());
         
           // Only need to shower if we have coloured outgoing particles
         if ( needToShower ) {
           
             // The decays currently considered produce a maximum of 2 chains (with powheg emission)
             // so all dipole should have the same scale as returned by the decay function.
           assert( eventRecord().chains().size() <= 2 );
           for ( auto  & ch : eventRecord().chains()) {
             for ( auto  & dip : ch.dipoles()) {
               assert ( showerScale > ZERO );
               dip.leftScale( showerScale );
               dip.rightScale( showerScale );
             }
           }
+      
+          // Prepare vertex record for spin correlations in decay shower
+          if ( spinCorrelations() )
+            vertexRecord().prepareParticleDecay(incoming);
+      
             // Perform the cascade
           doCascade(nEmitted,optHardPt,optCutoff,true);
           
+          if ( spinCorrelations() )
+            vertexRecord().updateParticleDecay();
+      
             // Do the constituent mass shell reshuffling
           decayConstituentReshuffle(eventRecord().currentDecay());
           
         }
         
           // Update the decays, adding any decays and updating momenta
         eventRecord().updateDecays(eventRecord().currentDecay());
         
-        eventRecord().decays().erase(decayIt);
+	  eventRecord().decays().erase(decayIt);
+
+	}
+
+      } catch(...) {
+
+	// reset flag
+	doSubleadingNc = doneSubleadingNc;
+	throw;
+
       }
-      
+
+      doSubleadingNc = doneSubleadingNc;
       
       break;
       
     } catch (RedoShower&) {
       
       resetWeights();
       
       if ( ++nTries > maxtry() )
       throw ShowerTriesVeto(maxtry());
       
       eventRecord().clear();
       eventRecord().prepare(sub, dynamic_ptr_cast<tStdXCombPtr>(lastXCombPtr()), newStep(), pdfs(),
                             ShowerHandler::currentHandler()->generator()->currentEvent()->incoming(),
-			    firstInteraction(), offShellPartons());
+			    firstInteraction(), offShellPartons(),
+                            !doSubleadingNc);
+      if ( doSubleadingNc ) {
+	theSplittingReweight->updateCurrentHandler();
+      }
       
       continue;
       
     } catch (...) {
       throw;
     }
     
   }
   
   tPPair incoming=eventRecord().fillEventRecord(newStep(),firstInteraction(),didRealign);
   setDidRunCascade(true);
   return incoming;
 }
 
 
+
   // Reshuffle the outgoing partons from the hard process onto their constituent mass shells
 void DipoleShowerHandler::constituentReshuffle() {
   
   if ( constituentReshuffler &&  ShowerHandler::currentHandler()->retConstituentMasses() ) {
     if ( eventRecord().decays().empty() ) {
       constituentReshuffler->reshuffle(eventRecord().outgoing(),
                                        eventRecord().incoming(),
                                        eventRecord().intermediates());
       return;
     }
     
     else {
       PList decaying;
       for(auto const & dec : eventRecord().decays())
       decaying.push_back(dec.first);
       
       constituentReshuffler->hardProcDecayReshuffle( decaying,
                                                     eventRecord().outgoing(),
                                                     eventRecord().hard(),
                                                     eventRecord().incoming(),
                                                     eventRecord().intermediates());
     }
   }
   
     // After reshuffling the hard process, the decays need to be updated
     // as this is not done in reshuffle
   vector<pair<PPtr,PerturbativeProcessPtr> > decays;
   for(auto const & dec : eventRecord().decays() )
   decays.push_back({dec.first,dec.second});
   
   
   for(auto const & dec : decays) {
     
     PPtr unstable = dec.first;
     PList::iterator pos = find(eventRecord().intermediates().begin(),
                                eventRecord().intermediates().end(),
                                dec.first);
     
       // Update the PPtr in theDecays
     if(pos!=eventRecord().intermediates().end()) {
       unstable = *pos;
       while(!unstable->children().empty()) {
         unstable = unstable->children()[0];
       }
       eventRecord().decays().erase(dec.first);
       eventRecord().decays()[unstable] = dec.second;
       
         // Update the momenta of any other particles in the decay chain
         // (for externally provided events)
       if ( !(eventRecord().decays()[unstable]->outgoing().empty()) )
       eventRecord().updateDecayChainMom( unstable , eventRecord().decays()[unstable]);
     }
     
     else {
       if ( !(eventRecord().decays()[unstable]->outgoing().empty()) ) {
           // Update the momenta of any other particles in the decay chain
           // (for externally provided events)
           // Note this needs to be done for all decaying particles in the
           // outgoing/hard regardless of whether that particle radiated
           // or was involved in the reshuffling, this is due to the
           // transformation performed for IILightKinematics.
         if ( (find(eventRecord().outgoing().begin(),
                    eventRecord().outgoing().end(), unstable) != eventRecord().outgoing().end())
             || (find(eventRecord().hard().begin(),
                      eventRecord().hard().end(), unstable) != eventRecord().hard().end()) )
         eventRecord().updateDecayChainMom( unstable , eventRecord().decays()[unstable]);
         
       }
     }
   }
   
   eventRecord().currentDecay(PerturbativeProcessPtr());
 }
 
 
   // Reshuffle outgoing partons from a decay process onto their constituent mass shells
 void DipoleShowerHandler::decayConstituentReshuffle(PerturbativeProcessPtr decayProc) {
   
   
   
   if ( Debug::level  > 2  ){
   
       // Test this function by comparing the
       // invariant mass of the outgoing decay
       // systems before and after reshuffling
     Lorentz5Momentum testOutMomBefore (ZERO,ZERO,ZERO,ZERO);
     Energy testInvMassBefore = ZERO;
     
     for ( auto const & testDecayOutItBefore : decayProc->outgoing() ) {
       testOutMomBefore += testDecayOutItBefore.first->momentum();
     }
     
     testInvMassBefore = testOutMomBefore.m();
     
     
       // decayReshuffle updates both the event record and the decay perturbative process
     if ( constituentReshuffler && ShowerHandler::currentHandler()->retConstituentMasses()) {
       constituentReshuffler->decayReshuffle(decayProc,
                                             eventRecord().outgoing(),
                                             eventRecord().hard(),
                                             eventRecord().intermediates());
     }
     
     Lorentz5Momentum testOutMomAfter (ZERO,ZERO,ZERO,ZERO);
     Energy testInvMassAfter = ZERO;
     
     for ( auto const &  testDecayOutItAfter : decayProc->outgoing() ) {
       
       testOutMomAfter += testDecayOutItAfter.first->momentum();
       
     }
     
     testInvMassAfter = testOutMomAfter.m();
     
     Energy incomingMass = decayProc->incoming()[0].first->momentum().m();
     assert( abs(testInvMassBefore-incomingMass)/GeV < 1e-5 );
     assert( abs(testInvMassBefore-testInvMassAfter)/GeV < 1e-5);
     
     
   }else{
       // decayReshuffle updates both the event record and the decay perturbative process
     if ( constituentReshuffler && ShowerHandler::currentHandler()->retConstituentMasses() ) {
       constituentReshuffler->decayReshuffle(decayProc,
                                             eventRecord().outgoing(),
                                             eventRecord().hard(),
                                             eventRecord().intermediates());
     }
     return;
   }
   
 }
 
   // Sets the scale of each particle in the dipole chains by finding the smallest
   //of several upper bound energy scales: the CMEnergy of the event,
   //the transverse mass of outgoing particles, the hardScale (maxPT or maxQ)
   //calculated for each dipole (in both configurations) and the veto scale for each particle
 void DipoleShowerHandler::hardScales(Energy2 muf)  {
   
     // Initalise maximum pt as max CMEnergy of the event
   maxPt = generator()->maximumCMEnergy();
   
   if ( restrictPhasespace() ) {
       // First interaction == hard collision (i.e. not a MPI collision)
     if ( !hardScaleIsMuF() || !firstInteraction() ) {
       if ( !eventRecord().outgoing().empty() ) {
         for ( auto const &  p : eventRecord().outgoing() )
 	       maxPt = min(maxPt,p->momentum().mt());
       }
         //Look at any non-coloured outgoing particles in the current subprocess
       else {
         assert(!eventRecord().hard().empty());
         Lorentz5Momentum phard(ZERO,ZERO,ZERO,ZERO);
         for ( auto const & p : eventRecord().hard())
         phard += p->momentum();
         Energy mhard = phard.m();
         maxPt = mhard;
       }
       maxPt *= hardScaleFactor();
     }
     else {
       maxPt = hardScaleFactor()*sqrt(muf);
     }
     muPt = maxPt;
   } else {
     muPt = hardScaleFactor()*sqrt(muf);
   }
-  
-  
-  for ( auto  & ch : eventRecord().chains()) {
+
+  if ( doSubleadingNc ) {
+    return;
+  }
+
+ for ( auto  & ch : eventRecord().chains()) {
     
       // Note that minVetoScale is a value for each DipoleChain, not each dipole
       // It will contain the minimum veto scale from all of the dipoles in the chain
     Energy minVetoScale = -1.*GeV;
     
     for ( auto  & dip : ch.dipoles()) {
       
         // max scale per config
       Energy maxFirst = ZERO;
       Energy maxSecond = ZERO;
       
         // Loop over the kernels for the given dipole.
         // For each dipole configuration, calculate ptMax (or QMax if virtuality ordering)
         // for each kernel and find the maximum
       for ( auto const & k : kernels) {
         
         pair<bool,bool> conf = {true,false};
         
         if ( k->canHandle(dip.index(conf)) ) {
             // Look in DipoleChainOrdering for this
           Energy scale =
           evolutionOrdering()->hardScale(dip.emitter(conf),dip.spectator(conf),
                                          dip.emitterX(conf),dip.spectatorX(conf),
                                          *k,dip.index(conf));
           maxFirst = max(maxFirst,scale);
         }
         
         conf = {false,true};
         
         if ( k->canHandle(dip.index(conf)) ) {
           Energy scale =
           evolutionOrdering()->hardScale(dip.emitter(conf),dip.spectator(conf),
                                          dip.emitterX(conf),dip.spectatorX(conf),
                                          *k,dip.index(conf));
           maxSecond = max(maxSecond,scale);
         }
         
       }
       
         // Find the maximum value from comparing the maxScale found from maxPt and the vetoScale of the particle
       if ( dip.leftParticle()->vetoScale() >= ZERO ) {
         maxFirst = min(maxFirst,sqrt(dip.leftParticle()->vetoScale()));
         
           // minVetoScale is a value for each DipoleChain, not each dipole
           // It contains the minimum veto scale for all the dipoles in the entire DipoleChain
         if ( minVetoScale >= ZERO )
         minVetoScale = min(minVetoScale,sqrt(dip.leftParticle()->vetoScale()));
         else
         minVetoScale = sqrt(dip.leftParticle()->vetoScale());
       }
       
       if ( dip.rightParticle()->vetoScale() >= ZERO ) {
         maxSecond = min(maxSecond,sqrt(dip.rightParticle()->vetoScale()));
         if ( minVetoScale >= ZERO )
         minVetoScale = min(minVetoScale,sqrt(dip.rightParticle()->vetoScale()));
         else
         minVetoScale = sqrt(dip.rightParticle()->vetoScale());
       }
       
         // Set the emitterScale for both members of each dipole
       maxFirst = min(maxPt,maxFirst);
       dip.emitterScale({true,false},maxFirst);
       
       maxSecond = min(maxPt,maxSecond);
       dip.emitterScale({false,true},maxSecond);
       
     }
     
       // if the smallest veto scale (i.e. from all of the dipoles)
       // is smaller than the scale calculated for a particular
       // particle in a particular dipole,
       // replace the scale with the veto scale
     if ( !evolutionOrdering()->independentDipoles() &&
         chainOrderVetoScales &&
         minVetoScale >= ZERO ) {
       for ( auto  & dip : ch.dipoles() ) {
         dip.leftScale(min(dip.leftScale(),minVetoScale));
         dip.rightScale(min(dip.rightScale(),minVetoScale));
       }
     }
     
   }
   
 }
 
+void DipoleShowerHandler::hardScalesSubleading(list<DipoleSplittingInfo> candidates,
+					       Energy hardPt) {
+
+  maxPt = hardPt;//generator()->maximumCMEnergy();
+
+  // Note that minVetoScale is a value for each competing dipole (i.e. all dipoles
+  // for the subleading shower.
+  // It will contain the minimum veto scale from all of the dipoles
+  Energy minVetoScale = -1.*GeV;
+
+  for ( list<DipoleSplittingInfo>::iterator cand = candidates.begin();
+	cand != candidates.end(); ++cand ) {
+
+      // max scale
+      Energy maxScale = ZERO;
+
+      // Loop over kernels
+      for ( vector<Ptr<DipoleSplittingKernel>::ptr>::iterator k =
+	      kernels.begin(); k != kernels.end(); ++k ) {
+	
+	if ( (**k).canHandle(cand->index()) ) {
+	  Energy scale =
+	    evolutionOrdering()->hardScale(cand->emitter(),cand->spectator(),
+					 cand->emitterX(),cand->spectatorX(),
+					 **k,cand->index());
+	  maxScale = max(maxScale,scale);
+	}
+
+      }
+
+      if ( cand->emitter()->vetoScale() >= ZERO ) {
+	maxScale = min(maxScale,sqrt(cand->emitter()->vetoScale()));
+	if ( minVetoScale >= ZERO )
+	  minVetoScale = min(minVetoScale,sqrt(cand->emitter()->vetoScale()));
+	else
+	  minVetoScale = sqrt(cand->emitter()->vetoScale());
+      }
+
+      maxScale = min(maxPt,maxScale);
+      cand->scale(maxScale);
+
+    }
+
+    if ( !evolutionOrdering()->independentDipoles() &&
+	 chainOrderVetoScales &&
+	 minVetoScale >= ZERO ) {
+      for ( list<DipoleSplittingInfo>::iterator cand = candidates.begin();
+	    cand != candidates.end(); ++cand ) {
+	cand->scale(min(cand->scale(),minVetoScale));
+      }
+    }
+
+}
+
+
+
+void DipoleShowerHandler::addCandidates(PPair particles,
+					list<DipoleSplittingInfo>& clist) const {
+
+  DipoleSplittingInfo candidate;
+  Energy2 scale = ZERO;
+  pair<bool,bool> is(particles.first == eventRecord().incoming().first,
+		     particles.second == eventRecord().incoming().second);
+  if ( (is.first && !is.second) ||
+       (!is.first && is.second) ) {
+    scale = -(particles.first->momentum() - particles.second->momentum()).m2();
+  } else {
+    scale = (particles.first->momentum() + particles.second->momentum()).m2();
+  }
+
+  DipoleIndex index(particles.first->dataPtr(),particles.second->dataPtr(),
+		    is.first ? eventRecord().pdfs().first : PDF(),
+		    is.second ? eventRecord().pdfs().second : PDF());
+
+  candidate.scale(sqrt(scale));
+
+  candidate.index(index);
+  candidate.configuration(make_pair(true,false));
+  candidate.emitter(particles.first);
+  candidate.emitterX(is.first ? eventRecord().fractions().first : 1.0);
+  candidate.spectator(particles.second);
+  candidate.spectatorX(is.second ? eventRecord().fractions().second : 1.0);
+
+  clist.push_back(candidate);
+
+  index.swap();
+
+  candidate.index(index);
+  candidate.configuration(make_pair(false,true));
+  candidate.emitter(particles.second);
+  candidate.emitterX(is.second ? eventRecord().fractions().second : 1.0);
+  candidate.spectator(particles.first);
+  candidate.spectatorX(is.first ? eventRecord().fractions().first : 1.0);
+
+  clist.push_back(candidate);
+
+}
+
+void DipoleShowerHandler::getCandidates(list<DipoleSplittingInfo>& clist) const {
+
+  clist.clear();
+
+  for ( PList::const_iterator i = eventRecord().outgoing().begin(); 
+	i != eventRecord().outgoing().end(); ++i ) {
+    PList::const_iterator j = i; ++j;
+    for ( ; j != eventRecord().outgoing().end(); ++j ) {
+      addCandidates(make_pair(*i,*j),clist);
+    }
+    // Changed order of *i and inc().first
+    if ( eventRecord().incoming().first->coloured() )
+      addCandidates(make_pair(eventRecord().incoming().first,*i),clist);
+    if ( eventRecord().incoming().second->coloured() )
+      addCandidates(make_pair(*i,eventRecord().incoming().second),clist);
+  }
+
+  if ( eventRecord().incoming().first->coloured() && eventRecord().incoming().second->coloured() ) {
+    addCandidates(eventRecord().incoming(),clist);
+  }
+
+}
+
+void DipoleShowerHandler::performSplitting(DipoleSplittingInfo& split) const {
+
+  Ptr<DipoleSplittingKinematics>::tptr kinematics = split.splittingKinematics();
+  kinematics->generateKinematics(split.emitter()->momentum(),
+				 split.spectator()->momentum(),
+				 split);
+
+  split.splitEmitter(split.emitterData()->produceParticle(kinematics->lastEmitterMomentum()));
+  split.splitSpectator(split.spectatorData()->produceParticle(kinematics->lastSpectatorMomentum()));
+  split.emission(split.emissionData()->produceParticle(kinematics->lastEmissionMomentum()));
+
+  // Setting resolution scales for the particles
+  split.emission()->scale(sqr(split.lastPt()));
+  split.splitEmitter()->scale(sqr(split.lastPt()));
+  split.splitSpectator()->scale(split.spectator()->scale());
+
+  PVector neighbours;
+  if ( DipolePartonSplitter::colourConnected(split.emitter(),
+					     eventRecord().incoming().first) &&
+       split.emitter() != eventRecord().incoming().first )
+    neighbours.push_back(eventRecord().incoming().first);
+  if ( DipolePartonSplitter::colourConnected(split.emitter(),
+					     eventRecord().incoming().second) &&
+       split.emitter() != eventRecord().incoming().second )
+    neighbours.push_back(eventRecord().incoming().second);
+  for ( PList::const_iterator p = eventRecord().outgoing().begin(); 
+	p != eventRecord().outgoing().end(); ++p ) {
+    if ( *p == split.emitter() )
+      continue;
+    if ( DipolePartonSplitter::colourConnected(split.emitter(),*p) )
+      neighbours.push_back(*p);
+  }
+  assert(neighbours.size() == 1 || neighbours.size() == 2 );
+  if ( neighbours.size() == 2 ) {
+    if ( UseRandom::rnd() < 0.5 )
+      swap(neighbours[0],neighbours[1]);
+  }
+
+  DipolePartonSplitter::split(split.emitter(),split.splitEmitter(),split.emission(),
+			      neighbours.front(),split.index().initialStateEmitter(),false);
+  DipolePartonSplitter::change(split.spectator(),split.splitSpectator(),
+			       split.index().initialStateSpectator(),false);
+}
+
+Energy DipoleShowerHandler::nextSubleadingSplitting(Energy hardPt,
+						    Energy optHardPt, Energy optCutoff,
+						    const bool decay) {
+
+  list<DipoleSplittingInfo> candidates;
+  getCandidates(candidates);
+
+  hardScalesSubleading(candidates,hardPt);
+  for ( list<DipoleSplittingInfo>::iterator cand = candidates.begin();
+   	cand != candidates.end(); cand++ ) {
+    cand->scale(hardPt);
+  }
+
+
+  list<DipoleSplittingInfo>::iterator split = candidates.end();
+
+  // Winner of all dipoles
+  DipoleSplittingInfo winner;
+  // Winner for the current iteration of the for loop
+  DipoleSplittingInfo candWinner;
+  Energy winnerScale = 0.0*GeV;
+
+  Energy nextScale = 0.0*GeV;
+
+  for ( list<DipoleSplittingInfo>::iterator cand = candidates.begin();
+	cand != candidates.end(); cand++ ) {
+    nextScale = getWinner(candWinner,
+			  cand->index(),
+			  cand->emitterX(),cand->spectatorX(),
+			  make_pair(true,false),
+			  cand->emitter(),cand->spectator(),
+			  hardPt,
+			  optHardPt,
+			  optCutoff);
+    if ( nextScale > winnerScale ) {
+      winnerScale = nextScale;
+      winner = candWinner;
+      split = cand;
+      winnerIndex = winningKernelIndex;//check
+    }
+  }
+
+  if ( split == candidates.end() )
+    return ZERO;
+
+  if ( decay )
+    winner.isDecayProc( true );
+  
+  split->fill(winner);
+
+  performSplitting(*split);
+  eventRecord().update(*split);
+
+  for ( list<DipoleSplittingInfo>::iterator dip = candidates.begin();
+	dip != candidates.end(); ++dip ) {
+    if ( dip == split )
+      continue;
+    dip->emission(split->emission());
+    if ( dip->emitter() == split->emitter() ) {
+      dip->splitEmitter(split->splitEmitter());
+    } else {
+      dip->splitEmitter(dip->emitter());
+    }
+    if ( dip->spectator() == split->spectator() ) {
+      dip->splitSpectator(split->splitSpectator());
+    } else {
+      dip->splitSpectator(dip->spectator());
+    }
+  }
+
+  // Update the ShowerHandler of the splitting reweight.
+  if ( doSubleadingNc ) {
+    theSplittingReweight->updateCurrentHandler();
+  }
+
+  return split->lastPt();
+
+}
+
+
 Energy DipoleShowerHandler::getWinner(DipoleSplittingInfo& winner,
                                       const Dipole& dip,
                                       pair<bool,bool> conf,
                                       Energy optHardPt,
                                       Energy optCutoff) {
   return
   getWinner(winner,dip.index(conf),
             dip.emitterX(conf),dip.spectatorX(conf),
             conf,dip.emitter(conf),dip.spectator(conf),
             dip.emitterScale(conf),optHardPt,optCutoff);
 }
 
 Energy DipoleShowerHandler::getWinner(SubleadingSplittingInfo& winner,
                                       Energy optHardPt,
                                       Energy optCutoff) {
   return
   getWinner(winner,winner.index(),
             winner.emitterX(),winner.spectatorX(),
             winner.configuration(),
             winner.emitter(),winner.spectator(),
             winner.startScale(),optHardPt,optCutoff);
 }
 
 Energy DipoleShowerHandler::getWinner(DipoleSplittingInfo& winner,
                                       const DipoleIndex& index,
                                       double emitterX, double spectatorX,
                                       pair<bool,bool> conf,
                                       tPPtr emitter, tPPtr spectator,
                                       Energy startScale,
                                       Energy optHardPt,
                                       Energy optCutoff) {
   
   if ( !index.initialStateEmitter() &&
       !doFSR() ) {
     winner.didStopEvolving();
     return 0.0*GeV;
   }
   
   if ( index.initialStateEmitter() &&
       !doISR() ) {
     winner.didStopEvolving();
     return 0.0*GeV;
   }
+
+  if ( index.incomingDecaySpectator()
+       && !doFSR() ) {
+    winner.didStopEvolving();
+    return 0.0*GeV;
+  }
   
   // Currently do not split IF dipoles so
   // don't evaluate them in order to avoid
   // exceptions in the log
   if ( index.incomingDecayEmitter() ) {
     winner.didStopEvolving();
     return 0.0*GeV;
   }
   
   DipoleSplittingInfo candidate;
   candidate.index(index);
   candidate.configuration(conf);
   candidate.emitterX(emitterX);
   candidate.spectatorX(spectatorX);
-  
+  candidate.emitter(emitter);
+  candidate.spectator(spectator);
+
   if ( generators().find(candidate.index()) == generators().end() )
   getGenerators(candidate.index(),theSplittingReweight);
   
   //
   // NOTE -- needs proper fixing at some point
   //
   // For some very strange reason, equal_range gives back
   // key ranges it hasn't been asked for. This particularly
   // happens e.g. for FI dipoles of the same kind, but different
   // PDF (hard vs MPI PDF). I can't see a reason for this,
   // as DipoleIndex properly implements comparison for equality
   // and (lexicographic) ordering; for the time being, we
   // use equal_range, extented by an explicit check for wether
   // the key is indeed what we wanted. See line after (*) comment
   // below.
   //
   // SW - Update 04/01/2016: Note - This caused a bug for me as I did not
   // include equality checks on the decay booleans in the == definition
   
   pair<GeneratorMap::iterator,GeneratorMap::iterator> gens
   = generators().equal_range(candidate.index());
   
   Energy winnerScale = 0.0*GeV;
   GeneratorMap::iterator winnerGen = generators().end();
   
   for ( GeneratorMap::iterator gen = gens.first; gen != gens.second; ++gen ) {
-    
-      // (*) see NOTE above
+
+    if ( doPartialUnweighting )
+      gen->second->doPartialUnweighting(referenceWeight);
+
+    // (*) see NOTE above
     if ( !(gen->first == candidate.index()) )
     continue;
     
     if ( startScale <= gen->second->splittingKinematics()->IRCutoff() )
     continue;
     
     Energy dScale =
     gen->second->splittingKinematics()->dipoleScale(emitter->momentum(),
                                                     spectator->momentum());
 
     // in very exceptional cases happening in DIS
     if ( std::isnan( double(dScale/MeV) ) )
     throw RedoShower();
     
     candidate.scale(dScale);
     
       // Calculate the mass of the recoil system
       // for decay dipoles
     if ( candidate.index().incomingDecaySpectator() || candidate.index().incomingDecayEmitter() ) {
       Energy recoilMass = gen->second->splittingKinematics()->recoilMassKin(emitter->momentum(),
                                                                             spectator->momentum());
       candidate.recoilMass(recoilMass);
     }
 
     // Store emitter and spectator masses, needed in kinematics
     if ( candidate.index().emitterData()->mass() != ZERO ) {
       if ( !candidate.index().offShellEmitter() )
 	candidate.emitterMass( emitter->nominalMass() );  
       else
 	candidate.emitterMass( emitter->mass() );  
     }
     
     if ( candidate.index().spectatorData()->mass() != ZERO ) {
       if ( !candidate.index().offShellSpectator() )
 	candidate.spectatorMass( spectator->nominalMass() );  
       else
 	candidate.spectatorMass( spectator->mass() );  
     }
     
     
     candidate.continuesEvolving();
     Energy hardScale = evolutionOrdering()->maxPt(startScale,candidate,*(gen->second->splittingKernel()));
     
     Energy maxPossible =
     gen->second->splittingKinematics()->ptMax(candidate.scale(),
                                               candidate.emitterX(), candidate.spectatorX(),
                                               candidate,
                                               *gen->second->splittingKernel());
     
     Energy ircutoff =
     optCutoff < gen->second->splittingKinematics()->IRCutoff() ?
     gen->second->splittingKinematics()->IRCutoff() :
     optCutoff;
     
     if ( maxPossible <= ircutoff ) {
       continue;
     }
     if ( maxPossible >= hardScale ){
       candidate.hardPt(hardScale);
     }
     else {
       hardScale = maxPossible;
       candidate.hardPt(maxPossible);
     }
 
     gen->second->generate(candidate,currentWeights(),optHardPt,optCutoff);
     Energy nextScale = evolutionOrdering()->evolutionScale(
                       gen->second->lastSplitting(),*(gen->second->splittingKernel()));
     
     if ( nextScale > winnerScale ) {
       winner.fill(candidate);
       gen->second->completeSplitting(winner);
       winnerGen = gen;
       winnerScale = nextScale;
+      if ( continueSubleadingNc() )
+	winningKernelIndex = kernelIndex+1;//check
     }
     
+    if ( continueSubleadingNc() ) {
+      kernelIndex++;//check
+      scales.push_back(nextScale);//check
+      theWeightsVector.push_back(gen->second->splittingWeightVector());
+    }
+
     reweight(reweight() * gen->second->splittingWeight());
     
   }
   
   if ( winnerGen == generators().end() ) {
     winner.didStopEvolving();
     return 0.0*GeV;
   }
   
   if ( winner.stoppedEvolving() )
   return 0.0*GeV;
   
   return winnerScale;
   
 }
 
 void DipoleShowerHandler::doCascade(unsigned int& emDone,
                                     Energy optHardPt,
                                     Energy optCutoff,
                                     const bool decay) {
   
   if ( nEmissions )
     if ( emDone == nEmissions )
       return;
-  
+
+  if ( doSubleadingNc ) {
+    unsigned int subEmDone = 0;
+    // Set the starting scale
+    Energy hardPt = muPt;
+
+    double wref = referenceWeight;
+    while ( subEmDone < subleadingNcEmissionsLimit && hardPt != ZERO && continueSubleadingNc() ) {
+      // Clear out the weights from the earlier step
+      theWeightsVector.clear();
+      kernelIndex = 0;//check
+      scales.clear();//check
+
+      hardPt = nextSubleadingSplitting( hardPt, optHardPt, optCutoff, decay );
+
+      // Partial unweighting
+      if ( doPartialUnweightingAtEmission ) {
+	const double w = reweight();
+	if ( abs(w) < wref ) {
+	  if ( abs(w)/wref < UseRandom::rnd() ) {
+	    // Set weight to zero and end this event
+	    reweight(0.0);
+	    return;
+	  } else
+	    reweight( wref*w/abs(w) );
+	}
+	// Update the reference weight after emission
+	wref *= referenceWeight;
+      }
+
+      // When the winning scale is larger than the cutoff
+      // remove the added weights that are under the winning scale
+      if ( hardPt != ZERO ) {
+        Energy maxq = 0.0*GeV;
+	size_t iwinner = theWeightsVector.size();//check
+	for ( size_t i = 0; i < theWeightsVector.size(); i++ ) {
+	  if ( theWeightsVector[i].size() > 0 ) {
+	    // get<2> is true for an accept step.
+	    if ( std::get<2>(theWeightsVector[i].back()) 
+		 && std::get<0>(theWeightsVector[i].back()) > maxq) {
+	      maxq = std::get<0>(theWeightsVector[i].back());
+	      iwinner = i;//check
+	    }
+	  }
+	}
+
+        assert(winnerIndex-1 == iwinner);//check
+
+	double correctionWeight = 1.0;
+	for ( size_t i = 0; i < theWeightsVector.size(); i++ ) {
+	  for ( size_t j = 0; j < theWeightsVector[i].size(); j++ ) {
+	    if ( std::get<0>(theWeightsVector[i][j]) < maxq )
+	      correctionWeight *= std::get<1>(theWeightsVector[i][j]);
+	  }
+	}
+	reweight(reweight()/correctionWeight);
+      }
+
+      // Increment the number of subleading Nc emissions done
+      subEmDone++;
+      // Stop if the limit of emissions is reached
+      if ( nEmissions )
+	if ( ++emDone == nEmissions )
+	  return;
+    }
+
+    // Subleading shower done, prepare chains for the standard
+    // dipole shower
+    eventRecord().prepareChainsSubleading( decay );
+    // Set scales
+    for ( list<DipoleChain>::iterator ch = eventRecord().chains().begin();
+	  ch != eventRecord().chains().end(); ch++ ) {
+      for ( list<Dipole>::iterator dp = ch->dipoles().begin();
+	    dp != ch->dipoles().end(); dp++ ) {
+	dp->emitterScale(make_pair(true,false),hardPt);
+	dp->emitterScale(make_pair(false,true),hardPt);
+      }
+    }
+    
+  }
+
+
   DipoleSplittingInfo winner;
   DipoleSplittingInfo dipoleWinner;
   
   
   while ( eventRecord().haveChain() ) {
     
      // allow the dipole chain to be rearranged according to arXiv:1801.06113
     if( _rearrange && ( _rearrangeNEmissions < 0 || _rearrangeNEmissions >= int(emDone) ) ){
       eventRecord().currentChain().rearrange(_dipmax,_diplong);
     }
 
     if ( verbosity > 2 ) {
       generator()->log() << "DipoleShowerHandler selecting splittings for the chain:\n"
       << eventRecord().currentChain() << flush;
     }
     
     list<Dipole>::iterator winnerDip = eventRecord().currentChain().dipoles().end();
     Energy winnerScale = 0.0*GeV;
     Energy nextLeftScale = 0.0*GeV;
     Energy nextRightScale = 0.0*GeV;
     for ( list<Dipole>::iterator dip = eventRecord().currentChain().dipoles().begin();
          dip != eventRecord().currentChain().dipoles().end(); ++dip ) {
       
       nextLeftScale = getWinner(dipoleWinner,*dip,{true,false},optHardPt,optCutoff);
       if ( nextLeftScale > winnerScale ) {
         winnerScale = nextLeftScale;
         winner = dipoleWinner;
         winnerDip = dip;
       }
       
       nextRightScale = getWinner(dipoleWinner,*dip,{false,true},optHardPt,optCutoff);
       if ( nextRightScale > winnerScale ) {
         winnerScale = nextRightScale;
         winner = dipoleWinner;
         winnerDip = dip;
       }
       
       if ( evolutionOrdering()->independentDipoles() ) {
         Energy dipScale = max(nextLeftScale,nextRightScale);
         if ( dip->leftScale() > dipScale )
         dip->leftScale(dipScale);
         if ( dip->rightScale() > dipScale )
         dip->rightScale(dipScale);
       }
     }
     
     if ( verbosity > 1 ) {
       if ( winnerDip != eventRecord().currentChain().dipoles().end() )
       generator()->log() << "DipoleShowerHandler selected the splitting:\n"
 			   << winner << " for the dipole\n"
 			   << (*winnerDip) << flush;
       else
       generator()->log() << "DipoleShowerHandler could not select a splitting above the IR cutoff\n"
 			   << flush;
     }
     
       // pop the chain if no dipole did radiate
     if ( winnerDip == eventRecord().currentChain().dipoles().end() ) {
       eventRecord().popChain();
       if ( theEventReweight && eventRecord().chains().empty() )
       if ( (theEventReweight->firstInteraction() && firstInteraction()) ||
           (theEventReweight->secondaryInteractions() && !firstInteraction()) ) {
         double w = theEventReweight->weightCascade(eventRecord().incoming(),
                                                    eventRecord().outgoing(),
                                                    eventRecord().hard(),theGlobalAlphaS);
         reweight(reweight()*w);
       }
       continue;
     }
     
       // otherwise perform the splitting
       // but first see if the emission would produce a configuration in the ME region.
     if (   theMergingHelper
 	&& eventHandler()->currentCollision()
 	&& !decay
 	&& firstInteraction() ) {
       if (theMergingHelper->maxLegs()>eventRecord().outgoing().size()+
                                       eventRecord().hard().size()
                                       +2){//incoming
         
 	if (theMergingHelper->mergingScale()<winnerScale && 
             theMergingHelper->emissionProbability() < UseRandom::rnd()) {
             
           theMergingHelper->setEmissionProbability(0.);
 
           const bool transparent=true;
           if (transparent) {
             pair<list<Dipole>::iterator,list<Dipole>::iterator> tmpchildren;
             DipoleSplittingInfo tmpwinner=winner;
             DipoleChain* tmpfirstChain = nullptr;
             DipoleChain* tmpsecondChain = nullptr;
             
             auto New=eventRecord().tmpsplit(winnerDip,tmpwinner,
                                             tmpchildren,tmpfirstChain,
                                             tmpsecondChain);
             
             
             if (theMergingHelper->matrixElementRegion(New.first,
                                                       New.second,
                                                       winnerScale,
                                                       theMergingHelper->mergingScale())) {
               optHardPt=winnerScale;
               continue;
             }
           }else{
             optHardPt=winnerScale;
             continue;
             
           }
         }
       }
     }
     if(theMergingHelper&&firstInteraction())
        optHardPt=ZERO;  
   
    
     
     didRadiate = true;
     
     eventRecord().isMCatNLOSEvent(false);
     eventRecord().isMCatNLOHEvent(false);
     
     pair<list<Dipole>::iterator,list<Dipole>::iterator> children;
     
     DipoleChain* firstChain = nullptr;
     DipoleChain* secondChain = nullptr;
     
+    // Generate the azimuthal angle 
+    if ( spinCorrelations() ) 
+      vertexRecord().generatePhi(winner,*winnerDip);
+
+    if ( decay )
+      winner.isDecayProc( true );
+    
       // Note: the dipoles are updated in eventRecord().split(....) after the splitting,
       // hence the entire cascade is handled in doCascade
       // The dipole scales are updated in dip->split(....)
     
     if ( decay )
     winner.isDecayProc( true );
 
     eventRecord().split(winnerDip,winner,children,firstChain,secondChain);
+
+    // Update the vertex record following the splitting
+    if ( spinCorrelations() )
+      vertexRecord().update(winner);
+
     assert(firstChain && secondChain);
     evolutionOrdering()->setEvolutionScale(winnerScale,winner,*firstChain,children);
     if ( !secondChain->dipoles().empty() )
     evolutionOrdering()->setEvolutionScale(winnerScale,winner,*secondChain,children);
     
     if ( verbosity > 1 ) {
       generator()->log() << "DipoleShowerHandler did split the last selected dipole into:\n"
       << (*children.first) << (*children.second) << flush;
     }
     
     if ( verbosity > 2 ) {
       generator()->log() << "After splitting the last selected dipole, "
       << "DipoleShowerHandler encountered the following chains:\n"
       << (*firstChain) << (*secondChain) << flush;
     }
     
     if ( theEventReweight )
     if ( (theEventReweight->firstInteraction() && firstInteraction()) ||
         (theEventReweight->secondaryInteractions() && !firstInteraction()) ) {
       double w = theEventReweight->weight(eventRecord().incoming(),
                                           eventRecord().outgoing(),
                                           eventRecord().hard(),theGlobalAlphaS);
       reweight(reweight()*w);
     }
     
     if ( nEmissions )
     if ( ++emDone == nEmissions )
     return;
   }
   
 }
 
 bool DipoleShowerHandler::realign() {
   
   if ( !didRadiate && !intrinsicPtGenerator )
   return false;
   
   if ( eventRecord().incoming().first->coloured() ||
       eventRecord().incoming().second->coloured() ) {
     
     if ( eventRecord().incoming().first->momentum().perp2()/GeV2 < 1e-10 &&
         eventRecord().incoming().second->momentum().perp2()/GeV2 < 1e-10 )
     return false;
     
     pair<Lorentz5Momentum,Lorentz5Momentum> inMomenta
     (eventRecord().incoming().first->momentum(),
      eventRecord().incoming().second->momentum());
     
-    SpinOneLorentzRotation transform((inMomenta.first+inMomenta.second).findBoostToCM());
+    LorentzRotation transform((inMomenta.first+inMomenta.second).findBoostToCM());
     
     Axis dir = (transform * inMomenta.first).vect().unit();
     Axis rot (-dir.y(),dir.x(),0);
     double theta = dir.theta();
     
     if ( lastParticles().first->momentum().z() < ZERO )
     theta = -theta;
     
     transform.rotate(-theta,rot);
     
     inMomenta.first = transform*inMomenta.first;
     inMomenta.second = transform*inMomenta.second;
     
     assert(inMomenta.first.z() > ZERO &&
            inMomenta.second.z() < ZERO);
     
     Energy2 sHat =
     (eventRecord().incoming().first->momentum() +
      eventRecord().incoming().second->momentum()).m2();
     
     pair<Energy,Energy> masses(eventRecord().incoming().first->mass(),
                                eventRecord().incoming().second->mass());
     pair<Energy,Energy> qs;
     
     if ( !eventRecord().incoming().first->coloured() ) {
       assert(masses.second == ZERO);
       qs.first = eventRecord().incoming().first->momentum().z();
       qs.second = (sHat-sqr(masses.first))/(2.*(qs.first+sqrt(sqr(masses.first)+sqr(qs.first))));
     } else if ( !eventRecord().incoming().second->coloured() ) {
       assert(masses.first == ZERO);
       qs.second = eventRecord().incoming().second->momentum().z();
       qs.first = (sHat-sqr(masses.second))/(2.*(qs.second+sqrt(sqr(masses.second)+sqr(qs.second))));
     } else {
       assert(masses.first == ZERO && masses.second == ZERO);
       if ( realignmentScheme == 0 ) {
         double yX = eventRecord().pX().rapidity();
         double yInt = (transform*eventRecord().pX()).rapidity();
         double dy = yX-yInt;
         qs.first = (sqrt(sHat)/2.)*exp(dy);
         qs.second = (sqrt(sHat)/2.)*exp(-dy);
       } else if ( realignmentScheme == 1 ) {
         Energy sS = sqrt((lastParticles().first->momentum() +
                           lastParticles().second->momentum()).m2());
         qs.first = eventRecord().fractions().first * sS / 2.;
         qs.second = eventRecord().fractions().second * sS / 2.;
       }
     }
     
     double beta =
     (qs.first-qs.second) /
     ( sqrt(sqr(masses.first)+sqr(qs.first)) +
      sqrt(sqr(masses.second)+sqr(qs.second)) );
     transform.boostZ(beta);
     
     Lorentz5Momentum tmp;
     
     if ( eventRecord().incoming().first->coloured() ) {
       tmp = eventRecord().incoming().first->momentum();
       tmp = transform * tmp;
       eventRecord().incoming().first->set5Momentum(tmp);
     }
     if ( eventRecord().incoming().second->coloured() ) {
       tmp = eventRecord().incoming().second->momentum();
       tmp = transform * tmp;
       eventRecord().incoming().second->set5Momentum(tmp);
     }
     eventRecord().transform(transform);
     return true;
     
   }
   
   return false;
   
 }
 
 void DipoleShowerHandler::resetAlphaS(Ptr<AlphaSBase>::tptr as) {
   
   for ( auto & k : kernels) {
     if ( !k->alphaS() )
     k->alphaS(as);
     k->renormalizationScaleFreeze(theRenormalizationScaleFreeze);
     k->factorizationScaleFreeze(theFactorizationScaleFreeze);
   }
   
     // clear the generators to be rebuild
     // actually, there shouldn't be any generators
     // when this happens.
   generators().clear();
   
 }
 
 void DipoleShowerHandler::resetReweight(Ptr<DipoleSplittingReweight>::tptr rw) {
   for ( auto &  g : generators() )
   g.second->splittingReweight(rw);
 }
 
 void DipoleShowerHandler::getGenerators(const DipoleIndex& ind,
                                         Ptr<DipoleSplittingReweight>::tptr rw) {
   
   bool gotone = false;
   
   for ( auto &  k : kernels ) {
     if ( k->canHandle(ind) ) {
       
       if ( verbosity > 0 ) {
         generator()->log() << "DipoleShowerHandler encountered the dipole configuration\n"
         << ind << " in event number "
         << eventHandler()->currentEvent()->number()
         << "\nwhich can be handled by the splitting kernel '"
         << k->name() << "'.\n" << flush;
       }
       
       gotone = true;
       Ptr<DipoleSplittingGenerator>::ptr nGenerator =
       new_ptr(DipoleSplittingGenerator());
       nGenerator->doCompensate(theDoCompensate);
       nGenerator->splittingKernel(k);
       if ( renormalizationScaleFactor() != 1. )
       nGenerator->splittingKernel()->renormalizationScaleFactor(renormalizationScaleFactor());
       if ( factorizationScaleFactor() != 1. )
       nGenerator->splittingKernel()->factorizationScaleFactor(factorizationScaleFactor());
       if ( !nGenerator->splittingReweight() )
       nGenerator->splittingReweight(rw);
       nGenerator->splittingKernel()->freezeGrid(theFreezeGrid);
       nGenerator->splittingKernel()->detuning(theDetuning);
       
       GeneratorMap::const_iterator equivalent = generators().end();
       
       for ( GeneratorMap::const_iterator eq = generators().begin();
            eq != generators().end(); ++eq ) {
         if ( !eq->second->wrapping() )
         if ( k->canHandleEquivalent(ind,*(eq->second->splittingKernel()),eq->first) ) {
           
           equivalent = eq;
           
           if ( verbosity > 0 ) {
             generator()->log() << "The dipole configuration "
             << ind
             << " can equivalently be handled by the existing\n"
             << "generator for configuration "
             << eq->first << " using the kernel '"
             << eq->second->splittingKernel()->name()
             << "'\n" << flush;
           }
           
           break;
           
         }
       }
       
       if ( equivalent != generators().end() ) {
         nGenerator->wrap(equivalent->second);
       }
       
       DipoleSplittingInfo dummy;
       dummy.index(ind);
       nGenerator->prepare(dummy);
       
       generators().insert({ind,nGenerator});
       
     }
   }
   
   if ( !gotone ) {
     throw Exception()
       << "DipoleShowerHandler could not "
       << "find a splitting kernel which is able "
       << "to handle splittings off the dipole "
       << ind << ".\n"
       << "Please check the input files."
       << Exception::runerror;
   }
   
 }
 
   // If needed, insert default implementations of virtual function defined
   // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 void DipoleShowerHandler::doinit() {
   ShowerHandler::doinit();
   if ( theGlobalAlphaS )
   resetAlphaS(theGlobalAlphaS);
   // copy off-shell particle ids before showering from input vector to the 
   // set used in the simulation
   if ( theColouredOffShellInShower.empty() ) {
     for(unsigned int ix=0;ix<theInputColouredOffShellInShower.size();++ix)
       theColouredOffShellInShower.insert(abs(theInputColouredOffShellInShower[ix]));
   }
   // work out which shower phase space to use for the matching
   bool zChoice0 = false;
   bool zChoice1 = false;
   size_t zChoiceOther = false;
   for ( auto & k : kernels) {
     if ( k->splittingKinematics()->openZBoundaries() == 0 )
       zChoice0 = true;
     else if ( k->splittingKinematics()->openZBoundaries() == 1 )
       zChoice1 = true;
     else
       zChoiceOther = true;
     // either inconsistent or other option which cannot be handled by the matching
     if ( zChoice0 && zChoice1 ) {
       zChoiceOther = true; break;
     }
   }
   if ( zChoiceOther )
     theZBoundaries = 2;
   else if ( zChoice1 )
     theZBoundaries = 1;
   else if ( zChoice0 )
     theZBoundaries = 0;
 }
 
 void DipoleShowerHandler::dofinish() {
   ShowerHandler::dofinish();
 }
 
 void DipoleShowerHandler::doinitrun() {
   ShowerHandler::doinitrun();
 }
 
 void DipoleShowerHandler::persistentOutput(PersistentOStream & os) const {
   os << kernels << theEvolutionOrdering
      << constituentReshuffler << intrinsicPtGenerator
      << theGlobalAlphaS << chainOrderVetoScales
      << nEmissions << discardNoEmissions << firstMCatNLOEmission
      << thePowhegDecayEmission
+    //<< theAnalyseSpinCorrelations
+     << doSubleadingNc << subleadingNcEmissionsLimit
+     << densityOperatorEvolution << ounit(densityOperatorCutoff,GeV2)
+     << doPartialUnweightingAtEmission
+     << doPartialUnweighting << referenceWeight
+     << cmecReweightFactor << negCMECScaling
      << realignmentScheme << verbosity << printEvent
      << ounit(theRenormalizationScaleFreeze,GeV)
      << ounit(theFactorizationScaleFreeze,GeV)
      << theShowerApproximation
      << theDoCompensate << theFreezeGrid << theDetuning
      << theEventReweight << theSplittingReweight << ounit(maxPt,GeV)
      << ounit(muPt,GeV)<< theMergingHelper << theColouredOffShellInShower
      << theInputColouredOffShellInShower
      << _rearrange << _dipmax << _diplong << _rearrangeNEmissions << theZBoundaries;
 }
 
 void DipoleShowerHandler::persistentInput(PersistentIStream & is, int) {
   is >> kernels >> theEvolutionOrdering
      >> constituentReshuffler >> intrinsicPtGenerator
      >> theGlobalAlphaS >> chainOrderVetoScales
      >> nEmissions >> discardNoEmissions >> firstMCatNLOEmission
      >> thePowhegDecayEmission
+    //>> theAnalyseSpinCorrelations
+     >> doSubleadingNc >> subleadingNcEmissionsLimit
+     >> densityOperatorEvolution >> iunit(densityOperatorCutoff,GeV2)
+     >> doPartialUnweightingAtEmission
+     >> doPartialUnweighting >> referenceWeight
+     >> cmecReweightFactor >> negCMECScaling
      >> realignmentScheme >> verbosity >> printEvent
      >> iunit(theRenormalizationScaleFreeze,GeV)
      >> iunit(theFactorizationScaleFreeze,GeV)
      >> theShowerApproximation
      >> theDoCompensate >> theFreezeGrid >> theDetuning
      >> theEventReweight >> theSplittingReweight >> iunit(maxPt,GeV)
      >> iunit(muPt,GeV)>>theMergingHelper >> theColouredOffShellInShower
      >> theInputColouredOffShellInShower
      >> _rearrange >> _dipmax >> _diplong >> _rearrangeNEmissions >> theZBoundaries;
 }
 
 ClassDescription<DipoleShowerHandler> DipoleShowerHandler::initDipoleShowerHandler;
   // Definition of the static class description member.
 
 void DipoleShowerHandler::Init() {
   
   static ClassDocumentation<DipoleShowerHandler> documentation
   ("The DipoleShowerHandler class manages the showering using "
    "the dipole shower algorithm.",
    "The shower evolution was performed using the algorithm described in "
    "\\cite{Platzer:2009jq} and \\cite{Platzer:2011bc}.",
    "%\\cite{Platzer:2009jq}\n"
    "\\bibitem{Platzer:2009jq}\n"
    "S.~Platzer and S.~Gieseke,\n"
    "``Coherent Parton Showers with Local Recoils,''\n"
    "  JHEP {\\bf 1101}, 024 (2011)\n"
    "arXiv:0909.5593 [hep-ph].\n"
    "%%CITATION = ARXIV:0909.5593;%%\n"
    "%\\cite{Platzer:2011bc}\n"
    "\\bibitem{Platzer:2011bc}\n"
    "S.~Platzer and S.~Gieseke,\n"
    "``Dipole Showers and Automated NLO Matching in Herwig,''\n"
    "arXiv:1109.6256 [hep-ph].\n"
    "%%CITATION = ARXIV:1109.6256;%%");
   
   static RefVector<DipoleShowerHandler,DipoleSplittingKernel> interfaceKernels
   ("Kernels",
    "Set the splitting kernels to be used by the dipole shower.",
    &DipoleShowerHandler::kernels, -1, false, false, true, false, false);
   
   
   static Reference<DipoleShowerHandler,DipoleEvolutionOrdering> interfaceEvolutionOrdering
   ("EvolutionOrdering",
    "Set the evolution ordering to be used.",
    &DipoleShowerHandler::theEvolutionOrdering, false, false, true, false, false);
   
   
   static Reference<DipoleShowerHandler,ConstituentReshuffler> interfaceConstituentReshuffler
   ("ConstituentReshuffler",
    "The object to be used to reshuffle partons to their constitutent mass shells.",
    &DipoleShowerHandler::constituentReshuffler, false, false, true, true, false);
   
   
   static Reference<DipoleShowerHandler,IntrinsicPtGenerator> interfaceIntrinsicPtGenerator
   ("IntrinsicPtGenerator",
    "Set the object in charge to generate intrinsic pt for incoming partons.",
    &DipoleShowerHandler::intrinsicPtGenerator, false, false, true, true, false);
   
   static Reference<DipoleShowerHandler,AlphaSBase> interfaceGlobalAlphaS
-  ("GlobalAlphaS",
-   "Set a global strong coupling for all splitting kernels.",
-   &DipoleShowerHandler::theGlobalAlphaS, false, false, true, true, false);
-  
+    ("GlobalAlphaS",
+     "Set a global strong coupling for all splitting kernels.",
+     &DipoleShowerHandler::theGlobalAlphaS, false, false, true, true, false);
+// Start: Trying to add interface for the subleading Nc
+  static Switch<DipoleShowerHandler,bool> interfaceDoSubleadingNc
+    ("DoSubleadingNc",
+     "Switch on or off subleading Nc corrections.",
+     &DipoleShowerHandler::doSubleadingNc, true, false, false);
+  static SwitchOption interfaceDoSubleadingNcOn
+    (interfaceDoSubleadingNc,
+     "On",
+     "Switch on subleading Nc corrections.",
+     true);
+  static SwitchOption interfaceDoSubleadingNcOff
+    (interfaceDoSubleadingNc,
+     "Off",
+     "Switch off subleading Nc corrections.",
+     false);
+  // Limit for how many subleading Nc emissions should be calculated
+  static Parameter<DipoleShowerHandler,size_t> interfaceSubleadingNcEmissionsLimit
+    ("SubleadingNcEmissionsLimit",
+     "Number of emissions to calculate subleading Nc corrections for.",
+     &DipoleShowerHandler::subleadingNcEmissionsLimit,0,0,0,
+     false, false, Interface::lowerlim);
+  static Parameter<DipoleShowerHandler,int> interfaceDensityOperatorEvolution
+    ("DensityOperatorEvolution",
+     "Scheme for evolving the density operator.",
+     &DipoleShowerHandler::densityOperatorEvolution,0,0,0,
+     false, false, Interface::lowerlim);
+  static Parameter<DipoleShowerHandler,Energy2> interfaceDensityOperatorCutoff
+    ("DensityOperatorCutoff",
+     "Cutoff for momentum invariants for the density operator evolution.",
+     &DipoleShowerHandler::densityOperatorCutoff,GeV2,1.0*GeV2,0.0*GeV2,0*GeV2,
+     false, false, Interface::lowerlim);
+  static Switch<DipoleShowerHandler,bool> interfaceDoPartialUnweightingAtEmission
+    ("DoPartialUnweightingAtEmission",
+     "Switch on or off partial unweighting at the emission level.",
+     &DipoleShowerHandler::doPartialUnweightingAtEmission,true,false,false);
+  static SwitchOption interfaceDoPartialUnweightingAtEmissionOn
+    (interfaceDoPartialUnweightingAtEmission,
+     "On",
+     "Switch on partial unweighting.",
+     true);
+  static SwitchOption interfaceDoPartialUnweightingAtEmissionOff
+    (interfaceDoPartialUnweightingAtEmission,
+     "Off",
+     "Switch off partial unweighting.",
+     false);
+  static Switch<DipoleShowerHandler,bool> interfaceDoPartialUnweighting
+    ("DoPartialUnweighting",
+     "Switch on or off partial unweighting at the dipole splitting level.",
+     &DipoleShowerHandler::doPartialUnweighting,true,false,false);
+  static SwitchOption interfaceDoPartialUnweightingOn
+    (interfaceDoPartialUnweighting,
+     "On",
+     "Switch on partial unweighting.",
+     true);
+  static SwitchOption interfaceDoPartialUnweightingOff
+    (interfaceDoPartialUnweighting,
+     "Off",
+     "Switch off partial unweighting.",
+     false);
+  static Parameter<DipoleShowerHandler,double> interfaceReferenceWeight
+    ("ReferenceWeight",
+     "Reference weight for the partial unweighting.",
+     &DipoleShowerHandler::referenceWeight,0.1,0.0,0,
+     false, false, Interface::lowerlim);
+  static Parameter<DipoleShowerHandler,double> interfaceCMECReweightFactor
+    ("CMECReweightFactor",
+     "Factor used in the reweighting algorithm.",
+     &DipoleShowerHandler::cmecReweightFactor,1.0,0.0,0,
+     false, false, Interface::lowerlim);
+  static Parameter<DipoleShowerHandler,double> interfaceNegCMECScaling
+    ("NegCMECScaling",
+     "Scaling factor for the negative colour matrix element corrections (CMECs).",
+     &DipoleShowerHandler::negCMECScaling,0.0,0.0,0,
+     false, false, Interface::lowerlim);
   static Switch<DipoleShowerHandler,int> interfaceRealignmentScheme
   ("RealignmentScheme",
    "The realignment scheme to use.",
    &DipoleShowerHandler::realignmentScheme, 0, false, false);
   static SwitchOption interfaceRealignmentSchemePreserveRapidity
   (interfaceRealignmentScheme,
    "PreserveRapidity",
    "Preserve the rapidity of non-coloured outgoing system.",
    0);
   static SwitchOption interfaceRealignmentSchemeEvolutionFractions
   (interfaceRealignmentScheme,
    "EvolutionFractions",
    "Use momentum fractions as generated by the evolution.",
    1);
   static SwitchOption interfaceRealignmentSchemeCollisionFrame
   (interfaceRealignmentScheme,
    "CollisionFrame",
    "Determine realignment from collision frame.",
    2);
   
   
   static Switch<DipoleShowerHandler,bool> interfaceChainOrderVetoScales
   ("ChainOrderVetoScales",
    "[experimental] Switch the chain ordering for veto scales on or off.",
    &DipoleShowerHandler::chainOrderVetoScales, true, false, false);
   static SwitchOption interfaceChainOrderVetoScalesYes
   (interfaceChainOrderVetoScales,
    "Yes",
    "Switch on chain ordering for veto scales.",
    true);
   static SwitchOption interfaceChainOrderVetoScalesNo
   (interfaceChainOrderVetoScales,
    "No",
    "Switch off chain ordering for veto scales.",
    false);
   
   interfaceChainOrderVetoScales.rank(-1);
   
   
   static Parameter<DipoleShowerHandler,unsigned int> interfaceNEmissions
   ("NEmissions",
    "[debug option] Limit the number of emissions to be generated. Zero does not limit the number of emissions.",
    &DipoleShowerHandler::nEmissions, 0, 0, 0,
    false, false, Interface::lowerlim);
   
   interfaceNEmissions.rank(-1);
   
   
   static Switch<DipoleShowerHandler,bool> interfaceDiscardNoEmissions
   ("DiscardNoEmissions",
    "[debug option] Discard events without radiation.",
    &DipoleShowerHandler::discardNoEmissions, false, false, false);
   static SwitchOption interfaceDiscardNoEmissionsYes
   (interfaceDiscardNoEmissions,
    "Yes",
    "Discard events without radiation.",
    true);
   static SwitchOption interfaceDiscardNoEmissionsNo
   (interfaceDiscardNoEmissions,
    "No",
    "Do not discard events without radiation.",
    false);
   
   interfaceDiscardNoEmissions.rank(-1);
   
   static Switch<DipoleShowerHandler,bool> interfaceFirstMCatNLOEmission
   ("FirstMCatNLOEmission",
    "[debug option] Only perform the first MC@NLO emission.",
    &DipoleShowerHandler::firstMCatNLOEmission, false, false, false);
   static SwitchOption interfaceFirstMCatNLOEmissionYes
   (interfaceFirstMCatNLOEmission,
    "Yes",
    "Perform only the first MC@NLO emission.",
    true);
   static SwitchOption interfaceFirstMCatNLOEmissionNo
   (interfaceFirstMCatNLOEmission,
    "No",
    "Produce all emissions.",
    false);
   
   interfaceFirstMCatNLOEmission.rank(-1);
   
   
   static Parameter<DipoleShowerHandler,int> interfaceVerbosity
   ("Verbosity",
    "[debug option] Set the level of debug information provided.",
    &DipoleShowerHandler::verbosity, 0, 0, 0,
    false, false, Interface::lowerlim);
   
   interfaceVerbosity.rank(-1);
   
   
   static Parameter<DipoleShowerHandler,int> interfacePrintEvent
   ("PrintEvent",
    "[debug option] The number of events for which debugging information should be provided.",
    &DipoleShowerHandler::printEvent, 0, 0, 0,
    false, false, Interface::lowerlim);
   
   interfacePrintEvent.rank(-1);
   
   static Parameter<DipoleShowerHandler,Energy> interfaceRenormalizationScaleFreeze
   ("RenormalizationScaleFreeze",
    "The freezing scale for the renormalization scale.",
    &DipoleShowerHandler::theRenormalizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
    false, false, Interface::lowerlim);
   
   static Parameter<DipoleShowerHandler,Energy> interfaceFactorizationScaleFreeze
   ("FactorizationScaleFreeze",
    "The freezing scale for the factorization scale.",
    &DipoleShowerHandler::theFactorizationScaleFreeze, GeV, 2.0*GeV, 0.0*GeV, 0*GeV,
    false, false, Interface::lowerlim);
   
   static Switch<DipoleShowerHandler,bool> interfaceDoCompensate
   ("DoCompensate",
    "",
    &DipoleShowerHandler::theDoCompensate, false, false, false);
   static SwitchOption interfaceDoCompensateYes
   (interfaceDoCompensate,
    "Yes",
    "",
    true);
   static SwitchOption interfaceDoCompensateNo
   (interfaceDoCompensate,
    "No",
    "",
    false);
   
   static Parameter<DipoleShowerHandler,unsigned long> interfaceFreezeGrid
   ("FreezeGrid",
    "",
    &DipoleShowerHandler::theFreezeGrid, 500000, 1, 0,
    false, false, Interface::lowerlim);
   
   static Parameter<DipoleShowerHandler,double> interfaceDetuning
   ("Detuning",
    "A value to detune the overestimate kernel.",
    &DipoleShowerHandler::theDetuning, 1.0, 1.0, 0,
    false, false, Interface::lowerlim);
   
   static Reference<DipoleShowerHandler,DipoleEventReweight> interfaceEventReweight
   ("EventReweight",
    "",
    &DipoleShowerHandler::theEventReweight, false, false, true, true, false);
   
   static Reference<DipoleShowerHandler,DipoleSplittingReweight> interfaceSplittingReweight
   ("SplittingReweight",
    "Set the splitting reweight.",
    &DipoleShowerHandler::theSplittingReweight, false, false, true, true, false);
   
   
   static Switch<DipoleShowerHandler, bool> interfacePowhegDecayEmission
   ("PowhegDecayEmission",
    "Use Powheg style emission for the decays",
    &DipoleShowerHandler::thePowhegDecayEmission, true, false, false);
   
   static SwitchOption interfacePowhegDecayEmissionYes
   (interfacePowhegDecayEmission,"Yes","Powheg decay emission on", true);
   
   static SwitchOption interfacePowhegDecayEmissionNo
   (interfacePowhegDecayEmission,"No","Powheg decay emission off", false);
 
   static ParVector<DipoleShowerHandler,long> interfaceOffShellInShower
     ("OffShellInShower",
      "PDG codes of the coloured particles that can be off-shell in the process.",
      &DipoleShowerHandler::theInputColouredOffShellInShower, -1, 0l, -10000000l, 10000000l,
      false, false, Interface::limited);
 
+  /*
+    static Switch<DipoleShowerHandler, bool> interfaceAnalyseSpinCorrelations
+    ("AnalyseSpinCorrelations",
+    "Record the information required for the spin correlation analyis.",
+    &DipoleShowerHandler::theAnalyseSpinCorrelations, false, false, false);
+  
+    static SwitchOption interfaceAnalyseSpinCorrelationsYes
+    (interfaceAnalyseSpinCorrelations,"Yes","Record the information for analysing the spin correlations.", true);
+  
+    static SwitchOption interfaceAnalyseSpinCorrelationsNo
+    (interfaceAnalyseSpinCorrelations,"No","Do not record extra information.", false);
+  */
+
   static Switch<DipoleShowerHandler, bool> interfacerearrange
   ("Rearrange",
    "Allow rearranging of dipole chains according to arXiv:1801.06113",
    &DipoleShowerHandler::_rearrange, false, false, false);
 
   static SwitchOption interfacerearrangeYes
   (interfacerearrange,"Yes","_rearrange on", true);
 
   static SwitchOption interfacerearrangeNo
   (interfacerearrange,"No","_rearrange off", false);
 
   static Parameter<DipoleShowerHandler,unsigned int> interfacedipmax
   ("DipMax",
    "Allow rearrangment of color chains with ME including dipmax dipoles.",
    &DipoleShowerHandler::_dipmax, 0, 0, 0,
    false, false, Interface::lowerlim);
 
   static Parameter<DipoleShowerHandler,unsigned int> interfacediplong
   ("DipLong",
    "Dipole chains with more than dipmax dipoles are treated as long. \
     diplong=3 rearranges these chains with eeuugg MEs,  \
     diplong=4 rearranges these chains with eeuuggg MEs (slower),  \
     diplong=5 rearranges these chains with eeuugggg MEs (slow).\
     Note: Numerically there is no difference between the options. ",
    &DipoleShowerHandler::_diplong, 0, 0, 0,
    false, false, Interface::lowerlim);
 
   static Parameter<DipoleShowerHandler, int> interfacedcorrectNemissions
   ("RearrangeNEmissions",
    "Allow rearrangment of color chains up to the nth emission.",
    &DipoleShowerHandler::_rearrangeNEmissions, 0, 0, 0,
    false, false, Interface::lowerlim);
 
   
 }
+
diff --git a/Shower/Dipole/DipoleShowerHandler.h b/Shower/Dipole/DipoleShowerHandler.h
--- a/Shower/Dipole/DipoleShowerHandler.h
+++ b/Shower/Dipole/DipoleShowerHandler.h
@@ -1,603 +1,777 @@
 // -*- C++ -*-
 //
 // DipoleShowerHandler.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_DipoleShowerHandler_H
 #define HERWIG_DipoleShowerHandler_H
 //
 // This is the declaration of the DipoleShowerHandler class.
 //
 
 #include "Herwig/Shower/ShowerHandler.h"
 
 #include "Herwig/Shower/Dipole/DipoleShowerHandler.fh"
 #include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
 #include "Herwig/Shower/Dipole/Base/DipoleSplittingReweight.h"
 #include "Herwig/Shower/Dipole/Kernels/DipoleSplittingKernel.h"
 #include "Herwig/Shower/Dipole/Base/DipoleSplittingGenerator.h"
 #include "Herwig/Shower/Dipole/Base/DipoleEventRecord.h"
 #include "Herwig/Shower/Dipole/Base/DipoleEvolutionOrdering.h"
 #include "Herwig/Shower/Dipole/Base/DipoleEventReweight.h"
 #include "Herwig/Shower/Dipole/Utility/ConstituentReshuffler.h"
 #include "Herwig/Shower/Dipole/Utility/IntrinsicPtGenerator.h"
 #include "Herwig/MatrixElement/Matchbox/Base/MergerBase.h"
 #include "Herwig/MatrixElement/Matchbox/Matching/ShowerApproximation.h"
 
+#include "Herwig/Shower/Dipole/SpinCorrelations/DipoleVertexRecord.h"
+#include "Herwig/MatrixElement/Matchbox/Utility/DensityOperator.h"
+
+#include <tuple>
+
 namespace Herwig {
 
 using namespace ThePEG;
 
 /** 
  * \ingroup DipoleShower
  * \author Simon Platzer, Stephen Webster
  *
  * \brief The DipoleShowerHandler class manages the showering using
  * the dipole shower algorithm.
  *
  * @see \ref DipoleShowerHandlerInterfaces "The interfaces"
  * defined for DipoleShowerHandler.
  */
 class DipoleShowerHandler: public ShowerHandler {
 
 
  friend class Merger;
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   DipoleShowerHandler();
 
   /**
    * The destructor.
    */
   virtual ~DipoleShowerHandler();
   //@}
 
 public:
 
 
   inline void colourPrint();
 
   /**
    * Indicate a problem in the shower.
    */
   struct RedoShower {};
 
   /**
    * Insert an additional splitting kernel.
    */
   void addSplitting(Ptr<DipoleSplittingKernel>::ptr sp) {
     kernels.push_back(sp);
   }
 
   /**
    * Reset the alpha_s for all splitting kernels.
    */
   void resetAlphaS(Ptr<AlphaSBase>::tptr);
   
   
   virtual void cascade(tPVector); 
 
   /**
    * Reset the splitting reweight for all splitting kernels.
    */
   void resetReweight(Ptr<DipoleSplittingReweight>::tptr);
 
   /**
    * Return true, if the shower handler can generate a truncated 
    * shower for POWHEG style events generated using Matchbox
    */
   virtual bool canHandleMatchboxTrunc() const { return false; }
 
   /**
    * Return true, if this cascade handler will perform reshuffling from hard
    * process masses.
    */
   virtual bool isReshuffling() const { return false; }
 
   /**
    * Return the relevant hard scale to be used in the profile scales
    */
   virtual Energy hardScale() const {
     return muPt;
   }
   
   /**
    * Calculate the alpha_s value the shower uses for Q.
    */
   
   double as(Energy Q)const{return theGlobalAlphaS->value(sqr(Q));}
   
   /**
    * Return the number of scale dependent active flavours from 
    * the alpha_s object.
    */
 
   double Nf(Energy Q)const{return theGlobalAlphaS->Nf(sqr(Q));}
 
+  /*
+   * Access the vertex record
+   */
+  DipoleVertexRecord& vertexRecord() { return theVertexRecord; }
+
+  /**
+   * Return the event record
+   */
+  const DipoleVertexRecord& vertexRecord() const { return theVertexRecord; }
+
 
   /**
    * Set the pointer to the Merging Helper.
    * Used by the merging factory.
    */
   void setMerger(Ptr<MergerBase>::ptr mh){theMergingHelper=mh;}
 
 
 
+public:
+
+  /**
+   * Return the dictionary for the incoming particles and outgoing partons 
+   * in the event, will be empty if subleading Nc is turned off.
+   */
+  const map<PPtr,size_t>& particleIndices() const { return eventRecord().particleIndices(); }
+
+  /**
+   * Return the particle data vector of the particles in the event, will 
+   * be empty if subleading Nc is turned off.
+   */
+  const cPDVector& particlesAfter() const { return eventRecord().particlesAfter(); }
+
+  /**
+   * Return the density operator from the event record.
+   */
+  DensityOperator& densityOperator() { return eventRecord().densityOperator(); }
+
+  /**
+   * Return the colour matrix element correction map, will be empty if
+   * subleading Nc is turned off. NOT USED, REMOVE
+   */
+  const map<pair<vector<PDT::Colour>,pair<size_t,size_t> >,double>& correlatorMap() const {
+    return eventRecord().densityOperator().correlatorMap();
+  }
+
+  /**
+   * Return the colour basis used in the density operator. NOT USED, REMOVE
+   */
+  Ptr<ColourBasis>::tptr colourBasis() {
+    return eventRecord().densityOperator().colourBasis();
+  }
+
+  /**
+   * Return the continue subleading Nc flag from the event record.
+   */
+  bool continueSubleadingNc() const { return eventRecord().getContinueSubleadingNc(); }
+
+protected:
+
+  /**
+   * Add the possible splitting candidates given a pair of emitting particles
+   */
+  void addCandidates(PPair particles, list<DipoleSplittingInfo>& clist) const;
+
+  /**
+   * Get all possible radiating dipoles
+   */
+  void getCandidates(list<DipoleSplittingInfo>& clist) const;
+
+  /**
+   * Perform a splitting independent of any chains
+   */
+  void performSplitting(DipoleSplittingInfo&) const;
+
+  /**
+   * Generate the next subleading Nc improved splitting and return the scale
+   */
+  Energy nextSubleadingSplitting(Energy hardPt,
+				 Energy optHardPt, Energy optCutoff,
+				 const bool decay);
+
 protected:
 
   typedef multimap<DipoleIndex,Ptr<DipoleSplittingGenerator>::ptr> GeneratorMap;
 
   /**
    * The main method which manages the showering of a subprocess.
    */
   virtual tPPair cascade(tSubProPtr sub, XCombPtr xcomb) {
     return cascade(sub,xcomb,ZERO,ZERO);
   }
 
   /**
    * The main method which manages the showering of a subprocess.
    */
   tPPair cascade(tSubProPtr sub, XCombPtr xcomb, 
 		 Energy optHardPt, Energy optCutoff);
 
   /**
    * Build splitting generators for the given
    * dipole index.
    */
   void getGenerators(const DipoleIndex&,
 		     Ptr<DipoleSplittingReweight>::tptr rw =
   		     Ptr<DipoleSplittingReweight>::tptr());
 
   /**
    * Setup the hard scales.
    */
   void hardScales(Energy2 scale);
 
   /**
+   * Setup the hard scales of the dipoles after subleading emissions.//debug
+   */
+  void hardScalesSubleading(list<DipoleSplittingInfo> candidates,Energy hardPt);
+
+  /**
    * Return the evolution ordering
    */
   Ptr<DipoleEvolutionOrdering>::tptr evolutionOrdering() const { return theEvolutionOrdering; }
 
   /**
    * Reshuffle to constituent mass shells
    */
   void constituentReshuffle();
 
   /**
    * Reshuffle to constituent mass shells
    */
   void decayConstituentReshuffle( PerturbativeProcessPtr decayProc);
 
   /**
    * Access the generator map
    */
   GeneratorMap& generators() { return theGenerators; }
 
   /**
    * Access the event record
    */
   DipoleEventRecord& eventRecord() { return theEventRecord; }
 
   /**
    * Return the event record
    */
   const DipoleEventRecord& eventRecord() const { return theEventRecord; }
 
   /**
    * Return the splitting kernels.
    */
   const vector<Ptr<DipoleSplittingKernel>::ptr>& splittingKernels() const {
     return kernels;
   }
   
   /**
    * Return the set of offshell parton ids.
    **/
   const set<long>& offShellPartons() { return theColouredOffShellInShower; }
   
   /**
    * Realign the event such as to have the incoming partons along thre
    * beam axes.
    */
   bool realign();
 
   /**
    * The choice of z boundaries; 0 = restricted, 1 = open, 2 = mixed/other
    */
   virtual int showerPhaseSpaceOption() const {
     return theZBoundaries;
   }
 
 protected:
 
   /**
    * Perform the cascade.
    */
   void doCascade(unsigned int& emDone,
 		 Energy optHardPt = ZERO,
 		 Energy optCutoff = ZERO,
 		 const bool decay = false);
   /**
    * Set the number of emissions 
    **/
   void setNEmissions(unsigned int n){nEmissions=n;}
   
 
   /**
    * Get the winning splitting for the
    * given dipole and configuration.
    */
   Energy getWinner(DipoleSplittingInfo& winner,
 		   const Dipole& dip,
 		   pair<bool,bool> conf,
 		   Energy optHardPt = ZERO,
 		   Energy optCutoff = ZERO);
 
   /**
    * Get the winning splitting for the
    * given dipole and configuration.
    */
+  Energy getWinner(DipoleSplittingInfo& winner,
+		   Energy optHardPt = ZERO,
+		   Energy optCutoff = ZERO);
+
+  /**
+   * Get the winning splitting for the
+   * given dipole and configuration.
+   */
   Energy getWinner(SubleadingSplittingInfo& winner,
 		   Energy optHardPt = ZERO,
 		   Energy optCutoff = ZERO);
 
   /**
    * Get the winning splitting for the
    * given dipole and configuration.
    */
   Energy getWinner(DipoleSplittingInfo& winner,
 		   const DipoleIndex& index,
 		   double emitterX, double spectatorX,
 		   pair<bool,bool> conf,
 		   tPPtr emitter, tPPtr spectator,
 		   Energy startScale,
 		   Energy optHardPt = ZERO,
 		   Energy optCutoff = ZERO);
   
 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 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();
 
   /**
    * Finalize this object. Called in the run phase just after a
    * run has ended. Used eg. to write out statistics.
    */
   virtual void dofinish();
   //@}
 
 
 private:
 
   /**
    * The splitting kernels to be used.
    */
   vector<Ptr<DipoleSplittingKernel>::ptr> kernels;
 
   /**
    * The evolution ordering considered
    */
   Ptr<DipoleEvolutionOrdering>::ptr theEvolutionOrdering;
 
   /**
    * The ConstituentReshuffler to be used
    */
   Ptr<ConstituentReshuffler>::ptr constituentReshuffler;
 
   /**
    * The intrinsic pt generator to be used.
    */
   Ptr<IntrinsicPtGenerator>::ptr intrinsicPtGenerator;
 
   /**
    * A global alpha_s to be used for all splitting kernels.
    */
   Ptr<AlphaSBase>::ptr theGlobalAlphaS;
 
   /**
    * Apply chain ordering to events from matrix
    * element corrections.
    */
   bool chainOrderVetoScales;
 
   /**
    * Limit the number of emissions.
    * Limit applied if > 0.
    */
   unsigned int nEmissions;
 
   /**
    * Discard events which did not radiate.
    */
   bool discardNoEmissions;
 
   /**
    * Perform the first MC@NLO emission only.
    */
   bool firstMCatNLOEmission;
 
   /**
    * True if powheg style emissions are to be used in the decays
    */
   bool thePowhegDecayEmission;
 
+ /**
+   * Switch to record information required for the 
+   * nearest neighbour analysis.
+   */
+  //bool theAnalyseSpinCorrelations;
+
   /**
    * The realignment scheme
    */
   int realignmentScheme;
 
+  /**
+   * Switch on or off subleading Nc corrections
+   */
+  bool doSubleadingNc;
+  
+  /**
+   * Number of emissions to do subleading Nc corrections to.
+   */
+  size_t subleadingNcEmissionsLimit;
+
+  /**
+   * Current reference weight used for partial unweighting of the 
+   * subleading colour shower (updated each emission).
+   */
+  int currentReferenceWeight;
+
+  /**
+   * Integer used to set which method of evolving the density operator
+   * to use:
+   * 0 - Vijk is Eikonal but there is a cutoff.
+   * 1 - Vijk is Eikonal.
+   * 2 - Vijk=1 for all i,j,k.
+   * 3 - Semi-leading Nc, Vijk=0 for all 
+   */
+  int densityOperatorEvolution;
+
+  /**
+   * Cutoff scale for the invariants (e.g. pEmitter*pEmission) in the 
+   * Eikonal dipole kernel, Vijk.
+   */
+  Energy2 densityOperatorCutoff;
+
+  /**
+   * Switch on or off partial unweighting in after each subleading emission.
+   */
+  bool doPartialUnweightingAtEmission;
+
+  /**
+   * Switch on or off partial unweighting in the splitting generator.
+   */
+  bool doPartialUnweighting;
+
+  /**
+   * Reference weight for the partial unweighting.
+   */
+  double referenceWeight;
+
+  /**
+   * Factor changing the acceptance probability for the veto algorithm.
+   */
+  double cmecReweightFactor;
+
+  /**
+   * Scaling factor for the negative colour matrix element corrections.
+   */
+  double negCMECScaling;
+
 private:
 
   /**
    * The verbosity level.
    * 0 - print no info
    * 1 - print diagnostic information on setting up
    *     splitting generators etc.
    * 2 - print detailed event information for up to
    *     printEvent events.
    * 3 - print dipole chains after each splitting.
    */
   int verbosity;
 
   /**
    * See verbosity.
    */
   int printEvent;
 
 private:
 
   /**
    * The splitting generators indexed by the dipole
    * indices they can work on.
    */
   GeneratorMap theGenerators;
 
   /**
    * The evnt record used.
    */
   DipoleEventRecord theEventRecord;
 
   /**
+   * The vertex record.
+   **/
+  DipoleVertexRecord theVertexRecord;
+
+  /**
    * The number of shoer tries so far.
    */
   unsigned int nTries;
 
   /**
    * Whether or not we did radiate anything
    */
   bool didRadiate;
 
   /**
    * Whether or not we did realign the event
    */
   bool didRealign;
 
+  /**
+   * Vector of candidate splittings containing a vector of the
+   * weights, scale and a bool for every step in the reweighted 
+   * veto algorithm. The bool is true for an accept step.
+   */
+  vector<vector<std::tuple<Energy,double,bool> > > theWeightsVector;
+
+  /**
+   * Winning candidate index.
+   */
+  size_t winnerIndex;//debug
+  size_t kernelIndex;//debug
+  size_t winningKernelIndex;//debug
+  vector<Energy> scales;//debug
+
 private:
 
   /**
    * A freezing value for the renormalization scale
    */
   Energy theRenormalizationScaleFreeze;
 
   /**
    * A freezing value for the factorization scale
    */
   Energy theFactorizationScaleFreeze;
 
   /**
    * The matching subtraction, if appropriate
    */
   Ptr<ShowerApproximation>::tptr theShowerApproximation;
 
   /**
    * True, if sampler should apply compensation
    */
   bool theDoCompensate;
 
   /**
    * Return the number of accepted points after which the grid should
    * be frozen
    */
   unsigned long theFreezeGrid;
 
   /**
    * The detuning factor applied to the sampling overestimate kernel
    */
   double theDetuning;
 
   /**
    * A pointer to the dipole event reweight object
    */
   Ptr<DipoleEventReweight>::ptr theEventReweight;
 
   /**
    * A pointer to a global dipole splitting reweight
    */
   Ptr<DipoleSplittingReweight>::ptr theSplittingReweight;
 
   /**
    * True if no warnings have been issued yet
    */
   static bool firstWarn;
 
   /**
    * The shower starting scale for the last event encountered
    */
   Energy maxPt;
 
   /**
    * The shower hard scale for the last event encountered
    */
   Energy muPt;
   
   
   /**
    * The merging helper takes care of merging multiple LO and NLO
    * cross sections. Here we need to check if an emission would 
    * radiate in the matrix element region of an other multipicity.
    * If so, the emission is vetoed.
    */
   Ptr<MergerBase>::ptr theMergingHelper;
 
 
   /**
    *  PDG codes of the partons which can have an off-shell mass,
    *  this is fast storage for use during running
    */
   set<long> theColouredOffShellInShower;
 
   /**
    *  PDG codes of the partons which can have an off-shell mass,
    *  this is a vector that is interfaced so they can be changed
    */
   vector<long> theInputColouredOffShellInShower;
   
   /**
    * Allow the dipole chains to be rearranged
    */
   bool _rearrange=false;
 
   /**
    * number of maximal ME dipoles in the rearrangement.
    */
   unsigned int _dipmax=3;
 
   /**
    * If a chain is considered long (more than dipmax dipoles)
    * ME with diplong dipoles are used to test for rearrangement.
    */
   unsigned int _diplong=3;
   
   /**
    * Number of emissions to be rearranged.
    */
   int _rearrangeNEmissions=-1;
   
   /**
    * The choice of z boundaries; 0 = restricted, 1 = open, 2 = mixed/other
    */
   int theZBoundaries;
   
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<DipoleShowerHandler> initDipoleShowerHandler;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   DipoleShowerHandler & operator=(const DipoleShowerHandler &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of DipoleShowerHandler. */
 template <>
 struct BaseClassTrait<Herwig::DipoleShowerHandler,1> {
   /** Typedef of the first base class of DipoleShowerHandler. */
   typedef Herwig::ShowerHandler NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the DipoleShowerHandler class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::DipoleShowerHandler>
   : public ClassTraitsBase<Herwig::DipoleShowerHandler> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::DipoleShowerHandler"; }
   /**
    * The name of a file containing the dynamic library where the class
    * DipoleShowerHandler is implemented. It may also include several, space-separated,
    * libraries if the class DipoleShowerHandler depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_DipoleShowerHandler_H */
diff --git a/Shower/Dipole/Kernels/ColourMatrixElementCorrection.cc b/Shower/Dipole/Kernels/ColourMatrixElementCorrection.cc
new file mode 100644
--- /dev/null
+++ b/Shower/Dipole/Kernels/ColourMatrixElementCorrection.cc
@@ -0,0 +1,91 @@
+// -*- C++ -*-
+//
+// ColourMatrixElementCorrection.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
+// Copyright (C) 2002-2007 The Herwig Collaboration
+//
+// Herwig is licenced under version 2 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 ColourMatrixElementCorrection class.
+//
+
+#include "ColourMatrixElementCorrection.h"
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+
+#include "ThePEG/Persistency/PersistentOStream.h"
+#include "ThePEG/Persistency/PersistentIStream.h"
+
+#include "Herwig/Shower/Dipole/DipoleShowerHandler.h"
+
+using namespace Herwig;
+
+ColourMatrixElementCorrection::ColourMatrixElementCorrection():lambda(1.0),negCMECScaling(1.0) {}
+
+ColourMatrixElementCorrection::~ColourMatrixElementCorrection() {}
+
+IBPtr ColourMatrixElementCorrection::clone() const {
+  return new_ptr(*this);
+}
+
+IBPtr ColourMatrixElementCorrection::fullclone() const {
+  return new_ptr(*this);
+}
+
+double ColourMatrixElementCorrection::cmec(const DipoleSplittingInfo& dsplit) const {
+  // Do not calculate CMECs if the subleading Nc shower has stopped 
+  if ( !(currentHandler()->continueSubleadingNc()) ) {
+    return 1.;
+  }
+  const PPtr em = dsplit.emitter();
+  const PPtr sp = dsplit.spectator();
+  const tcPDPtr emis = dsplit.emissionData();
+  // Get the dictionary from particle pointers to herwig particle numbers
+  const map<PPtr,size_t>& theDictionary = currentHandler()->particleIndices();
+  const cPDVector& theParticles = currentHandler()->particlesAfter();
+  // Use the dictionary to find
+  // - emitter index
+  // - spectator index
+  // - emission ParticleID
+  const std::tuple<size_t,size_t,long> ikemission = std::make_tuple(theDictionary.at(em),
+								    theDictionary.at(sp),
+								    emis->id());
+  double factor = currentHandler()->densityOperator().colourMatrixElementCorrection(ikemission,theParticles);
+
+  return factor > 0.0 ? factor : negCMECScaling*factor;
+}
+
+// If needed, insert default implementations of virtual function defined
+// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
+
+
+void ColourMatrixElementCorrection::persistentOutput(PersistentOStream &) const {
+  // *** ATTENTION *** os << ; // Add all member variable which should be written persistently here.
+}
+
+void ColourMatrixElementCorrection::persistentInput(PersistentIStream &, int) {
+  // *** ATTENTION *** is >> ; // Add all member variable which should be read persistently here.
+}
+
+
+// *** Attention *** The following static variable is needed for the type
+// description system in ThePEG. Please check that the template arguments
+// are correct (the class and its base class), and that the constructor
+// arguments are correct (the class name and the name of the dynamically
+// loadable library where the class implementation can be found).
+DescribeClass<ColourMatrixElementCorrection,Herwig::DipoleSplittingReweight>
+  describeHerwigColourMatrixElementCorrection("Herwig::ColourMatrixElementCorrection", 
+					      "HwDipoleShower.so");
+
+void ColourMatrixElementCorrection::Init() {
+
+  static ClassDocumentation<ColourMatrixElementCorrection> documentation
+    ("There is no documentation for the ColourMatrixElementCorrection class");
+
+}
+
diff --git a/Shower/Dipole/Kernels/ColourMatrixElementCorrection.h b/Shower/Dipole/Kernels/ColourMatrixElementCorrection.h
new file mode 100644
--- /dev/null
+++ b/Shower/Dipole/Kernels/ColourMatrixElementCorrection.h
@@ -0,0 +1,171 @@
+// -*- C++ -*-
+//
+// ColourMatrixElementCorrection.h is a part of Herwig - A multi-purpose Monte Carlo event generator
+// Copyright (C) 2002-2007 The Herwig Collaboration
+//
+// Herwig is licenced under version 2 of the GPL, see COPYING for details.
+// Please respect the MCnet academic guidelines, see GUIDELINES for details.
+//
+#ifndef Herwig_ColourMatrixElementCorrection_H
+#define Herwig_ColourMatrixElementCorrection_H
+//
+// This is the declaration of the ColourMatrixElementCorrection class.
+//
+
+#include "Herwig/Shower/Dipole/Base/DipoleSplittingReweight.h"
+
+#include <tuple>
+
+namespace Herwig {
+
+using namespace ThePEG;
+
+/**
+ * \ingroup DipoleShower
+ * \author Johan Thoren, Simon Platzer
+ *
+ * \brief ColourMatrixElementCorrection is implementing colour matrix element
+ * corrections through the weighted Sudakov algorithm
+ *
+ * @see \ref ColourMatrixElementCorrectionInterfaces "The interfaces"
+ * defined for ColourMatrixElementCorrection.
+ */
+class ColourMatrixElementCorrection: public DipoleSplittingReweight {
+
+public:
+
+  /** @name Standard constructors and destructors. */
+  //@{
+  /**
+   * The default constructor.
+   */
+  ColourMatrixElementCorrection();
+
+  /**
+   * The destructor.
+   */
+  virtual ~ColourMatrixElementCorrection();
+  //@}
+
+public:
+
+  /**
+   * Calculate and cache the colour matrix element correction factor
+   * for the given splitting type.
+   */
+  double cmec(const DipoleSplittingInfo&) const;
+
+  /**
+   * Return the reweighting factor for the given splitting type.
+   */
+  virtual double evaluate(const DipoleSplittingInfo& s) const {
+    return cmec(s);
+  }
+
+  /**
+   * Return the absolute value of the colour matrix element correction
+   * as an enhancement hint for the sampling of the un-reweighted
+   * splitting kernel.
+   */
+  virtual double hint(const DipoleSplittingInfo& s) const {
+    if ( hintOnly(s) )
+      return cmec(s);
+    return abs(cmec(s))*lambda;
+  }
+
+  /**
+   * Return true, if the reweight can be entirely absorbed into the hint. A
+   * possible detuning will be switched off.
+   */
+  virtual bool hintOnly(const DipoleSplittingInfo& s) const {
+    return cmec(s) > 0.;
+  }
+
+  /**
+   * Set the factor in front of enhance used by the veto algorithm.
+   */
+  virtual void reweightFactor(const double c) {
+    assert(c > 0.0);
+    lambda = c;
+  }
+
+  /**
+   * Set the factor in front of enhance used by the veto algorithm.
+   */
+  virtual void negativeScaling(const double c) {
+    assert(c >= 0.0);
+    negCMECScaling = c;
+  }
+
+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;
+  //@}
+
+// If needed, insert declarations of virtual function defined in the
+// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
+
+private:
+
+  /**
+   * Factor to shuffle the magnitude of the CMEC between the splitting kernel
+   * and the weight in the reweighted veto algorithm.
+   */
+  double lambda;
+
+  /**
+   * Scaling factor multiplying all of the negative colour matrix element 
+   * corrections. The physically sensible value is 1.0, but this factor can
+   * be used to examine the effects of the negative contributions.
+   */
+  double negCMECScaling;
+
+  /**
+   * The assignment operator is private and must never be called.
+   * In fact, it should not even be implemented.
+   */
+  ColourMatrixElementCorrection & operator=(const ColourMatrixElementCorrection &);
+
+};
+
+}
+
+#endif /* Herwig_ColourMatrixElementCorrection_H */
diff --git a/Shower/Dipole/Kernels/DipoleSplittingKernel.h b/Shower/Dipole/Kernels/DipoleSplittingKernel.h
--- a/Shower/Dipole/Kernels/DipoleSplittingKernel.h
+++ b/Shower/Dipole/Kernels/DipoleSplittingKernel.h
@@ -1,520 +1,535 @@
 // -*- C++ -*-
 //
 // DipoleSplittingKernel.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_DipoleSplittingKernel_H
 #define HERWIG_DipoleSplittingKernel_H
 //
 // This is the declaration of the DipoleSplittingKernel class.
 //
 
 #include "ThePEG/Handlers/HandlerBase.h"
 #include "ThePEG/StandardModel/AlphaSBase.h"
 #include "ThePEG/PDF/PDF.h"
 
 #include "Herwig/Shower/Dipole/Utility/PDFRatio.h"
 #include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
 #include "Herwig/Shower/Dipole/Kinematics/DipoleSplittingKinematics.h"
 
+#include "ThePEG/EventRecord/RhoDMatrix.h"
+#include "Herwig/Decay/DecayMatrixElement.h"
+#include "Herwig/Decay/TwoBodyDecayMatrixElement.h"
+
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer
  *
  * \brief DipoleSplittingKernel is the base class for all kernels
  * used within the dipole shower.
  *
  * @see \ref DipoleSplittingKernelInterfaces "The interfaces"
  * defined for DipoleSplittingKernel.
  */
 class DipoleSplittingKernel: public HandlerBase {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   DipoleSplittingKernel();
 
   /**
    * The destructor.
    */
   virtual ~DipoleSplittingKernel();
   //@}
 
 public:
 
   /**
    * Return the alpha_s to be used
    */
   Ptr<AlphaSBase>::tptr alphaS() const { return theAlphaS; }
 
   /**
    * Set the alpha_s to be used
    */
   void alphaS(Ptr<AlphaSBase>::tptr ap) { theAlphaS = ap; }
 
   /**
    * Return the splitting kinematics object
    */
   Ptr<DipoleSplittingKinematics>::tptr splittingKinematics() const {
       return theSplittingKinematics; 
   }
 
   /**
    * Return the mc check object
    */
   Ptr<DipoleMCCheck>::ptr mcCheck() const { return theMCCheck; }
 
   /**
    * Set the splitting kinematics object
    */
   void splittingKinematics(Ptr<DipoleSplittingKinematics>::tptr sp) { 
     theSplittingKinematics = sp; 
   }
 
   /**
    * Return the PDFRatio object
    */
   Ptr<PDFRatio>::tptr pdfRatio() const { return thePDFRatio; }
 
   /**
    * Set the PDFRatio object
    */
   void pdfRatio(Ptr<PDFRatio>::tptr sp) { thePDFRatio = sp; }
 
   /**
    * Return the number of additional parameter
    * random variables needed to evaluate this kernel
    * except the momentum fractions of incoming partons.
    * These will be accessible through the 
    * lastSplittingParameters() container of the splitting
    * info object.
    */
   virtual int nDimAdditional() const { return 0; }
 
   /**
    * Set the freezing value for the renormalization scale
    */
   void renormalizationScaleFreeze(Energy s) { theRenormalizationScaleFreeze = s; }
 
   /**
    * Set the freezing value for the factorization scale
    */
   void factorizationScaleFreeze(Energy s) { theFactorizationScaleFreeze = s; }
 
   /**
    * Get the freezing value for the renormalization scale
    */
   Energy renormalizationScaleFreeze() const { return theRenormalizationScaleFreeze; }
 
   /**
    * Get the freezing value for the factorization scale
    */
   Energy factorizationScaleFreeze() const { return theFactorizationScaleFreeze; }
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const = 0;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const = 0;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const = 0;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const = 0;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const = 0;
 
   /**
    * Return the flavour produced, if this cannot
    * be determined from the dipole.
    */
   PDPtr flavour() const { return theFlavour; }
 
   /**
    * Return true, if this splitting kernel is supposed to work in a
    * strict large-N limit, i.e. replacing C_F by C_A/2
    */
   bool strictLargeN() const { return theStrictLargeN; }
 
 public:
 
   /**
    * Inform this splitting kernel, that it is being
    * presampled until a call to stopPresampling
    */
   virtual void startPresampling(const DipoleIndex&) {
     presampling = true;
   }
 
   /**
    * Inform this splitting kernel, that it is not being
    * presampled until a call to startPresampling
    */
   virtual void stopPresampling(const DipoleIndex&) {
     presampling = false;
   }
 
   /**
    * Return the number of points to presample this
    * splitting generator.
    */
   unsigned long presamplingPoints() const { return thePresamplingPoints; }
 
   /**
    * Return the maximum number of trials
    * to generate a splitting.
    */
   unsigned long maxtry() const { return theMaxtry; }
 
   /**
    * Return the number of accepted points after which the grid should
    * be frozen
    */
   unsigned long freezeGrid() const { return theFreezeGrid; }
 
   /**
    * Set the number of accepted points after which the grid should
    * be frozen
    */
   void freezeGrid(unsigned long n) { theFreezeGrid = n; }
 
   /**
    * Set a detuning factor to be applied to the sampling overestimate kernel
    */
   void detuning(double d) { theDetuning = d; }
 
   /**
    * Return the detuning factor applied to the sampling overestimate kernel
    */
   double detuning() const { return theDetuning; }
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const = 0;
+  
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const = 0;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) const = 0;
 
   /**
    * Clear the alphaPDF cache
    */
   void clearAlphaPDFCache() const {
     theAlphaSCache.clear();
     thePDFCache.clear();
   }
 
   /**
    * Update the variations vector at the given splitting using the indicated
    * kernel and overestimate values.
    */
   virtual void accept(const DipoleSplittingInfo&, double, double, map<string,double>&) const;
 
   /**
    * Update the variations vector at the given splitting using the indicated
    * kernel and overestimate values.
    */
   virtual void veto(const DipoleSplittingInfo&, double, double, map<string,double>&) const;
 
   /**
    * Return true, if this kernel is capable of
    * delivering an overestimate to the kernel, and
    * of inverting the integral over the overestimate
    * w.r.t. the phasepsace provided by the given
    * DipoleSplittingInfo object.
    */
   virtual bool haveOverestimate(const DipoleSplittingInfo&) const { return false; }
 
   /**
    * Return the overestimate to this splitting kernel 
    * for the given dipole splitting.
    */
   virtual double overestimate(const DipoleSplittingInfo&) const { return -1.; }
 
   /**
    * Invert the integral over the overestimate 
    * w.r.t. the phasepsace provided by the given
    * DipoleSplittingInfo object to equal
    * the given value.
    */
   virtual double invertOverestimateIntegral(const DipoleSplittingInfo&, double) const {
     return -1.; 
   }
   
   /**
    * .
    */
   bool useThisKernel() const {
     return theUseThisKernel;
   }
 
 public:
 
   /**
    * Get the factorization scale factor
    */
   double factorizationScaleFactor() const { return theFactorizationScaleFactor; }
 
   /**
    * Set the factorization scale factor
    */
   void factorizationScaleFactor(double f) { theFactorizationScaleFactor = f; }
 
   /**
    * Get the renormalization scale factor
    */
   double renormalizationScaleFactor() const { return theRenormalizationScaleFactor; }
 
   /**
    * Set the renormalization scale factor
    */
   void renormalizationScaleFactor(double f) { theRenormalizationScaleFactor = f; }
 
 protected:
 
   /**
    * Return the common factor of (alphas/2pi)*(pdf ratio)
    */
   double alphaPDF(const DipoleSplittingInfo&,
 		  Energy optScale = ZERO,
 		  double rScaleFactor = 1.0,
 		  double fScaleFactor = 1.0) const;
 
   /**
    * Return true, if the virtuality of the splitting should be used as the
    * argument of alphas rather than the pt
    */
   bool virtualitySplittingScale() const { return theVirtualitySplittingScale; }
 
 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();
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 private:
 
   /**
    * The alpha_s to be used.
    */
   Ptr<AlphaSBase>::ptr theAlphaS;
 
   /**
    * An optional 'colour screening' scale
    * for alternative intrinsic pt generation.
    */
   Energy theScreeningScale;
 
   /**
    * The splitting kinematics to be used.
    */
   Ptr<DipoleSplittingKinematics>::ptr theSplittingKinematics;
 
   /**
    * An optional PDF ratio object to be used
    * when evaluating this kernel.
    */
   Ptr<PDFRatio>::ptr thePDFRatio;
 
   /**
    * The number of points to presample this
    * splitting generator.
    */
   unsigned long thePresamplingPoints;
 
   /**
    * The maximum number of trials
    * to generate a splitting.
    */
   unsigned long theMaxtry;
 
   /**
    * Return the number of accepted points after which the grid should
    * be frozen
    */
   unsigned long theFreezeGrid;
 
   /**
    * The detuning factor applied to the sampling overestimate kernel
    */
   double theDetuning;
 
   /**
    * The flavour produced, if this cannot
    * be determined from the dipole.
    */
   PDPtr theFlavour;
 
   /**
    * Pointer to a check histogram object
    */
   Ptr<DipoleMCCheck>::ptr theMCCheck;
 
   /**
    * True, if this splitting kernel is supposed to work in a
    * strict large-N limit, i.e. replacing C_F by C_A/2
    */
   bool theStrictLargeN;
 
   /**
    * The factorization scale factor.
    */
   double theFactorizationScaleFactor;
 
   /**
    * The renormalization scale factor.
    */
   double theRenormalizationScaleFactor;
 
   /**
    * A freezing value for the renormalization scale
    */
   Energy theRenormalizationScaleFreeze;
 
   /**
    * A freezing value for the factorization scale
    */
   Energy theFactorizationScaleFreeze;
 
   /**
    * True, if the virtuality of the splitting should be used as the
    * argument of alphas rather than the pt
    */
   bool theVirtualitySplittingScale;
 
   /**
    * Implementing CMW in the kernels.
    **/
 
   unsigned int theCMWScheme=0;
 
   /**
    * Cache for alphas evaluations
    */
   mutable map<double,double> theAlphaSCache;
 
   /**
    * Cache for PDF evaluations
    */
   mutable map<double,double> thePDFCache;
 
   /**
    * True, if we are presampling
    */
   bool presampling;
 
   /**
    * True, if the kernel should be used
    */
   bool theUseThisKernel = true;
 
   
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is an abstract class with persistent data.
    */
   static AbstractClassDescription<DipoleSplittingKernel> initDipoleSplittingKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   DipoleSplittingKernel & operator=(const DipoleSplittingKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of DipoleSplittingKernel. */
 template <>
 struct BaseClassTrait<Herwig::DipoleSplittingKernel,1> {
   /** Typedef of the first base class of DipoleSplittingKernel. */
   typedef HandlerBase NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the DipoleSplittingKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::DipoleSplittingKernel>
   : public ClassTraitsBase<Herwig::DipoleSplittingKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::DipoleSplittingKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * DipoleSplittingKernel is implemented. It may also include several, space-separated,
    * libraries if the class DipoleSplittingKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_DipoleSplittingKernel_H */
diff --git a/Shower/Dipole/Kernels/FFMgx2ggxDipoleKernel.cc b/Shower/Dipole/Kernels/FFMgx2ggxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FFMgx2ggxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FFMgx2ggxDipoleKernel.cc
@@ -1,142 +1,196 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FFMgx2ggxDipoleKernel class.
 //
 
 #include "FFMgx2ggxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Parameter.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 FFMgx2ggxDipoleKernel::FFMgx2ggxDipoleKernel() 
   : DipoleSplittingKernel(){}
 
 FFMgx2ggxDipoleKernel::~FFMgx2ggxDipoleKernel() {}
 
 IBPtr FFMgx2ggxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FFMgx2ggxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool FFMgx2ggxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
     useThisKernel() &&
     ind.emitterData()->id() == ParticleID::g &&
     ind.spectatorData()->mass() != ZERO &&
     !ind.initialStateEmitter() && !ind.initialStateSpectator() &&
     !ind.incomingDecayEmitter() && !ind.incomingDecaySpectator();
 
 }
 
 bool FFMgx2ggxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
     
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     sk.emitter(b)->id() == ParticleID::g &&
     sk.emission(b)->id() == ParticleID::g &&
     abs(spectator(a)->mass()) == abs(sk.spectator(b)->mass());
 
 }
 
 tcPDPtr FFMgx2ggxDipoleKernel::emitter(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr FFMgx2ggxDipoleKernel::emission(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr FFMgx2ggxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double FFMgx2ggxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
   
   double ret = alphaPDF(split);
 
-  // These are the physical variables as used in the 
-  // standard form of the kernel (i.e. do not redefine variables or kernel)
-  const double z = split.lastZ();
-  const Energy pt = split.lastPt();
-
-  // Need zPrime to calculate y, 
-  // TODO: Should just store y in the dipole splitting info everywhere anyway!!!
-  // The only value stored in dInfo.lastSplittingParameters() should be zPrime
-
-  const double zPrime = split.lastSplittingParameters()[0];
+  // Sudakov parameterisation variables,
+  // needed to calculate y.
+  double z = split.lastZ();
+  Energy pt = split.lastPt();
   
   // Construct mass squared variables
-
-  // Construct mass squared variables
-  double muj2 = sqr(split.spectatorMass() / split.scale());
-  double bar = 1. - muj2;
+  Energy2 Qijk = sqr(split.scale());
+  Energy2 mk2 = sqr(split.spectatorMass());
+  Energy2 sbar = Qijk - mk2;
 
   // Calculate y
-  double y = sqr(pt)/sqr(split.scale()) / (bar*zPrime*(1.-zPrime));
+  double y = sqr(pt) / sbar / z / (1.-z);
 
-  double vijk = sqrt( sqr(2.*muj2+bar*(1.-y))-4.*muj2 ) / (bar*(1.-y));
+  double vijk = sqrt( sqr(2.*mk2 + sbar*(1.-y)) - 4.*mk2*Qijk ) / sbar / (1.-y);
   double viji = 1.;
 
-  double zp = 0.5*(1.+viji*vijk);
-  double zm = 0.5*(1.-viji*vijk);
+  // zi, used in dipole splitting kernel
+  double zi = split.lastSplittingParameters()[0];
 
+  double zip = 0.5*(1.+viji*vijk);
+  double zim = 0.5*(1.-viji*vijk);
+  
   // how to choose kappa?
   double kappa = 0.;
 
-  double S1=1./(1.-z*(1.-y));
-  double S2=1./(1.-(1.-z)*(1.-y));
-  double NS=(z*(1.-z)-(1.-kappa)*zp*zm-2.)/vijk;
+  double S1=1./(1.-zi*(1.-y));
+  double S2=1./(1.-(1.-zi)*(1.-y));
+  double NS=(zi*(1.-zi)-(1.-kappa)*zip*zim-2.)/vijk;
   
   if( theAsymmetryOption == 0 ){
     ret *= 3.*( S1 + 0.5 * NS);
   }else if ( theAsymmetryOption == 1 ){
-    ret *= 3.*z*( S1 +S2 + NS );
+    ret *= 3.*zi*( S1 +S2 + NS );
   }else{
     ret *= 3.*0.5*( S1 + S2 + NS );
   }
 
   return ret > 0. ? ret : 0.;  
 }
 
+vector< pair<int, Complex> >
+FFMgx2ggxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
+
+  // Need variables for the AP kernels
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
+  double v_AP_ppm = z*sqrt( z / (1.-z) );
+  double v_AP_pmp = (1.-z)*sqrt( (1.-z)/z );
+
+  //double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = -v_AP_pmp;
+
+  // Initialise variables for the distributions
+  vector< pair<int, Complex> > distPhiDep;
+  double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp)) - 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp);
+
+  distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp))/max ) );
+  distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) );
+  distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) );
+
+  return distPhiDep;
+}
+
+DecayMEPtr FFMgx2ggxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
+
+  // Need variables for the AP kernels
+  double z = dInfo.lastZ();
+  
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
+  double v_AP_ppm = z*sqrt( z / (1.-z) );
+  double v_AP_pmp = (1.-z)*sqrt( (1.-z)/z );
+
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = -v_AP_pmp;
+  
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1,PDT::Spin1)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -, 2 = +
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
+  (*kernelPhiDep)(2,2,2) = v_AP_ppp/phase;
+  (*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
+  (*kernelPhiDep)(2,2,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
+  (*kernelPhiDep)(2,0,2) = v_AP_pmp*phase;
+  (*kernelPhiDep)(0,2,2) = 0;
+  (*kernelPhiDep)(2,0,0) = 0;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FFMgx2ggxDipoleKernel::persistentOutput(PersistentOStream & os) const {
   os << theAsymmetryOption;
 }
 
 void FFMgx2ggxDipoleKernel::persistentInput(PersistentIStream & is, int) {
   is >> theAsymmetryOption;
 }
 
 ClassDescription<FFMgx2ggxDipoleKernel> FFMgx2ggxDipoleKernel::initFFMgx2ggxDipoleKernel;
 // Definition of the static class description member.
 
 void FFMgx2ggxDipoleKernel::Init() {
 
   static ClassDocumentation<FFMgx2ggxDipoleKernel> documentation
     ("FFMgx2ggxDipoleKernel");
   
   static Parameter<FFMgx2ggxDipoleKernel,int> interfacetheAsymmetryOption
   ("AsymmetryOption",
    "The asymmetry option for final state gluon spliitings.",
    &FFMgx2ggxDipoleKernel::theAsymmetryOption, 1, 0, 0,
    false, false, Interface::lowerlim);
 
 }
diff --git a/Shower/Dipole/Kernels/FFMgx2ggxDipoleKernel.h b/Shower/Dipole/Kernels/FFMgx2ggxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FFMgx2ggxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FFMgx2ggxDipoleKernel.h
@@ -1,187 +1,198 @@
 // -*- C++ -*-
 #ifndef HERWIG_FFMgx2ggxDipoleKernel_H
 #define HERWIG_FFMgx2ggxDipoleKernel_H
 //
 // This is the declaration of the FFMgx2ggxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer, Martin Stoll, Stephen Webster
  *
  * \brief FFMgx2ggxDipoleKernel implements the g -> gg
  * splitting off a final-final dipole
  *
  */
 class FFMgx2ggxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   FFMgx2ggxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~FFMgx2ggxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
   
   /**
    * Asymmetry option for final state gluon splittings.
    */ 
   
   int theAsymmetryOption=1;
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<FFMgx2ggxDipoleKernel> initFFMgx2ggxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FFMgx2ggxDipoleKernel & operator=(const FFMgx2ggxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of FFMgx2ggxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::FFMgx2ggxDipoleKernel,1> {
   /** Typedef of the first base class of FFMgx2ggxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the FFMgx2ggxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::FFMgx2ggxDipoleKernel>
   : public ClassTraitsBase<Herwig::FFMgx2ggxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::FFMgx2ggxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * FFMgx2ggxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class FFMgx2ggxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_FFMgx2ggxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FFMgx2qqxDipoleKernel.cc b/Shower/Dipole/Kernels/FFMgx2qqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FFMgx2qqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FFMgx2qqxDipoleKernel.cc
@@ -1,133 +1,195 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FFMgx2qqxDipoleKernel class.
 //
 
 #include "FFMgx2qqxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 FFMgx2qqxDipoleKernel::FFMgx2qqxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 FFMgx2qqxDipoleKernel::~FFMgx2qqxDipoleKernel() {}
 
 IBPtr FFMgx2qqxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FFMgx2qqxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool FFMgx2qqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
     useThisKernel() &&
     ind.emitterData()->id() == ParticleID::g &&
     !( ind.spectatorData()->mass() == ZERO &&
        flavour()->mass() == ZERO ) &&
     !ind.initialStateEmitter() && !ind.initialStateSpectator() &&
     !ind.incomingDecayEmitter() && !ind.incomingDecaySpectator();
 }
 
 bool FFMgx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     sk.emitter(b)->id() + sk.emission(b)->id() == 0 &&
     abs(sk.emitter(b)->id()) < 6 &&
     emitter(a)->id() == sk.emitter(b)->id() &&
     abs(sk.spectator(b)->mass()) == abs(spectator(a)->mass());
 }
 
 tcPDPtr FFMgx2qqxDipoleKernel::emitter(const DipoleIndex&) const {
   assert(flavour());
   assert(abs(flavour()->id()) < 6);
   return flavour();
 }
 
 tcPDPtr FFMgx2qqxDipoleKernel::emission(const DipoleIndex&) const {
   assert(flavour());
   assert(abs(flavour()->id()) < 6);
   return flavour()->CC();
 }
 
 tcPDPtr FFMgx2qqxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double FFMgx2qqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
   
   double ret = alphaPDF(split);
 
-    // These are the physical variables as used in the 
-    //standard form of the kernel (i.e. do not redefine variables or kernel)
+  // Sudakov parameterisation variables,
+  // needed to calculate y.
   double z = split.lastZ();
   Energy pt = split.lastPt();
 
-  // Need zPrime to calculate y, 
-  // TODO: Should just store y in the dipole splitting info everywhere anyway!!!
-  // The only value stored in dInfo.lastSplittingParameters() should be zPrime
-  //assert(split.lastSplittingParameters().size() == 1 );
-  double zPrime = split.lastSplittingParameters()[0];
-
   // Construct mass squared variables
-  double mui2 = sqr(split.emitterData()->mass() / split.scale());
-  double mu2 = mui2;
-  double muj2 = sqr(split.spectatorMass() / split.scale());
-  double bar = 1. - mui2 - mu2 - muj2;
+  Energy2 Qijk = sqr(split.scale());
+  Energy2 mi2 = sqr(split.emitterData()->mass());
+  Energy2 mj2 = mi2;
+  Energy2 mk2 = sqr(split.spectatorMass());
+  Energy2 sbar = Qijk - mi2 - mj2 - mk2;
 
   // Calculate y
-  double y = (sqr(pt)/sqr(split.scale()) 
-             + sqr(1.-zPrime)*mui2 + sqr(zPrime)*mu2) 
-             / (bar*zPrime*(1.-zPrime));
+  double y = (sqr(pt) + sqr(1.-z)*mi2 + sqr(z)*mj2) / sbar / z / (1.-z);
+  
+  // zi, used in dipole splitting kernel
+  double zi = split.lastSplittingParameters()[0];
+  
+  double vijk = sqrt( sqr(2.*mk2 + sbar*(1.-y)) - 4.*mk2*Qijk ) / sbar / (1.-y);
+  double viji = sqrt( sqr(sbar*y) - 4.*sqr(mi2) ) / (sbar*y + 2.*mi2);
 
-  double vijk = sqrt( sqr(2.*muj2+bar*(1.-y))-4.*muj2 ) / (bar*(1.-y)); 
-  double viji = sqrt( sqr(bar*y)-4.*sqr(mui2) ) / (bar*y+2.*mui2);
-
-  double zp = 0.5*(1.+viji*vijk);
-  double zm = 0.5*(1.-viji*vijk);
+  double zip = 0.5*(1.+viji*vijk);
+  double zim = 0.5*(1.-viji*vijk);
 
   // how to choose kappa??
   double kappa = 0.;
 
   ret *= 0.25 / vijk *
-    ( 1. - 2.*( z*(1.-z) - (1.-kappa)*zp*zm 
-                - kappa*mui2/(2.*mui2+(1.-2.*mui2-muj2)*y) ) );
+    ( 1. - 2.*( zi*(1.-zi) - (1.-kappa)*zip*zim 
+                - kappa*mi2 / ( 2.*mi2 + (Qijk - 2.*mi2 - mk2)*y) ) );
     
   return ret > 0. ? ret : 0.;
   
 }
 
+vector< pair<int, Complex> >
+FFMgx2qqxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
+
+  // Need variables for the AP kernels
+  double z = dInfo.lastZ();
+  Energy pt = dInfo.lastPt();
+  Energy2 mi2 = sqr(dInfo.emitterData()->mass());
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double ratio = mi2 / ( mi2 + sqr(pt) );
+  double root = sqrt(1.-ratio);
+  double v_AP_ppp = sqrt(ratio);
+  double v_AP_ppm = z*root;
+  double v_AP_pmp = -(1.-z)*root;
+
+  //double v_AP_mmm = v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = -v_AP_pmp;
+
+  // Initialise variables for the distributions
+  vector< pair<int, Complex> > distPhiDep;
+  double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp)) + 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp);
+  
+  distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp) )/max ) );
+  distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) );
+  distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) );
+
+  return distPhiDep;
+}
+
+DecayMEPtr FFMgx2qqxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
+  
+  // Need variables for the AP kernels
+  double z = dInfo.lastZ();
+  Energy pt = dInfo.lastPt();
+  Energy2 mi2 = sqr(dInfo.emitterData()->mass());
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double ratio = mi2 / ( mi2 + sqr(pt) );
+  double root = sqrt(1.-ratio);
+  double v_AP_ppp = sqrt(ratio);
+  double v_AP_ppm = z*root;
+  double v_AP_pmp = -(1.-z)*root;
+
+  double v_AP_mmm = v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = -v_AP_pmp;
+
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1Half)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -, 2 = +
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm;
+  (*kernelPhiDep)(2,1,1) = v_AP_ppp;
+  (*kernelPhiDep)(0,0,1) = v_AP_mmp/phase;
+  (*kernelPhiDep)(2,1,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,1,0) = v_AP_mpm/phase;
+  (*kernelPhiDep)(2,0,1) = v_AP_pmp*phase;
+  (*kernelPhiDep)(0,1,1) = 0.;
+  (*kernelPhiDep)(2,0,0) = 0.;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FFMgx2qqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void FFMgx2qqxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<FFMgx2qqxDipoleKernel> 
 FFMgx2qqxDipoleKernel::initFFMgx2qqxDipoleKernel;
 // Definition of the static class description member.
 
 void FFMgx2qqxDipoleKernel::Init() {
 
   static ClassDocumentation<FFMgx2qqxDipoleKernel> documentation
     ("FFMgx2qqxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/FFMgx2qqxDipoleKernel.h b/Shower/Dipole/Kernels/FFMgx2qqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FFMgx2qqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FFMgx2qqxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_FFMgx2qqxDipoleKernel_H
 #define HERWIG_FFMgx2qqxDipoleKernel_H
 //
 // This is the declaration of the FFMgx2qqxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer, Martin Stoll, Stephen Webster
  *
  * \brief FFMgx2qqxDipoleKernel implements the g -> qqbar
  * splitting off a final-final dipole
  *
  */
 class FFMgx2qqxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   FFMgx2qqxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~FFMgx2qqxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<FFMgx2qqxDipoleKernel> initFFMgx2qqxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FFMgx2qqxDipoleKernel & operator=(const FFMgx2qqxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of FFMgx2qqxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::FFMgx2qqxDipoleKernel,1> {
   /** Typedef of the first base class of FFMgx2qqxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the FFMgx2qqxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::FFMgx2qqxDipoleKernel>
   : public ClassTraitsBase<Herwig::FFMgx2qqxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::FFMgx2qqxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * FFMgx2qqxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class FFMgx2qqxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_FFMgx2qqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FFMqx2qgxDipoleKernel.cc b/Shower/Dipole/Kernels/FFMqx2qgxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FFMqx2qgxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FFMqx2qgxDipoleKernel.cc
@@ -1,126 +1,169 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FFMqx2qgxDipoleKernel class.
 //
 
 #include "FFMqx2qgxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 FFMqx2qgxDipoleKernel::FFMqx2qgxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 FFMqx2qgxDipoleKernel::~FFMqx2qgxDipoleKernel() {}
 
 IBPtr FFMqx2qgxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FFMqx2qgxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool FFMqx2qgxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     abs(ind.emitterData()->id()) < 7  &&
     // 2012-05-01
     abs(ind.emitterData()->id()) == abs(flavour()->id()) &&
     !( ind.emitterData()->mass() == ZERO &&
        ind.spectatorData()->mass() == ZERO ) &&
     !ind.initialStateEmitter() && !ind.initialStateSpectator() &&
     !ind.incomingDecayEmitter() && !ind.incomingDecaySpectator();
 }
 
 bool FFMqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
   
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     sk.emission(b)->id() == ParticleID::g &&
     abs(sk.emitter(b)->id()) < 7 &&
     abs(sk.emitter(b)->mass()) == abs(emitter(a)->mass()) &&
     abs(sk.spectator(b)->mass()) == abs(spectator(a)->mass());
 
 }
 
 // 2012-05-01
 tcPDPtr FFMqx2qgxDipoleKernel::emitter(const DipoleIndex& ind) const {
   assert(flavour());
   assert(abs(flavour()->id())<7);
   return ind.emitterData()->id() > 0 ?
     (tcPDPtr) flavour() : (tcPDPtr) flavour()->CC();
 }
 
 tcPDPtr FFMqx2qgxDipoleKernel::emission(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr FFMqx2qgxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double FFMqx2qgxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
   
   double ret = alphaPDF(split);
 
-  // These are the physical variables as used in the standard 
-  // form of the kernel (i.e. do not redefine variables or kernel)
+  // Sudakov parameterisation variables,
+  // needed to calculate y.
   double z = split.lastZ();
   Energy pt = split.lastPt();
 
-  // Need zPrime to calculate y, 
-  // TODO: Should just store y in the dipole splitting info everywhere anyway!!!
-  // The only value stored in dInfo.lastSplittingParameters() should be zPrime
-  //assert(split.lastSplittingParameters().size() == 1 );
-  double zPrime = split.lastSplittingParameters()[0];
-
   // Construct mass squared variables
   // Note for q->qg can use the emitterMass
   // (i.e. mass of emitter before splitting = mass of emitter after)
-  double mui2 = sqr(split.emitterMass() / split.scale());
-  double muj2 = sqr(split.spectatorMass() / split.scale());
-  double bar = 1. - mui2 - muj2;
+  Energy2 Qijk = sqr(split.scale());
+  Energy2 mi2 = sqr(split.emitterMass());
+  Energy2 mk2 = sqr(split.spectatorMass());
+  Energy2 sbar = Qijk - mi2 - mk2;
 
   // Calculate y
-  double y = (sqr(pt)/sqr(split.scale()) + sqr(1.-zPrime)*mui2) / (bar*zPrime*(1.-zPrime));
+  double y = (sqr(pt) + sqr(1.-z)*mi2) / sbar / z / (1.-z);
 
-  double vijk = sqrt( sqr(2.*muj2 + bar*(1.-y))-4.*muj2 ) / (bar*(1.-y));
-  double vbar = sqrt( 1.+sqr(mui2)+sqr(muj2)-2.*(mui2+muj2+mui2*muj2) ) / bar;
+  // zi, used in dipole splitting kernel
+  double zi = split.lastSplittingParameters()[0];
 
-  ret *= (!strictLargeN() ? 4./3. : 3./2.)*( 2./(1.-z*(1.-y)) - vbar/vijk*( 1.+z + mui2*2./(y*(1.-mui2-muj2)) ) );
+  double vijk = sqrt( sqr(2.*mk2 + sbar*(1.-y)) - 4.*mk2*Qijk ) / sbar / (1.-y);
+  double vtilde = sqrt( sqr(Qijk) + sqr(mi2) + sqr(mk2)
+                        - 2.*(mi2*Qijk + mk2*Qijk + mi2*mk2) ) / sbar;
+  
+  ret *= (!strictLargeN() ? 4./3. : 3./2.)*
+    ( 2./(1.-zi*(1.-y)) - vtilde/vijk*( 1. + zi + 2.*mi2/sbar/y ) );
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+FFMqx2qgxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
+  
+  // No dependence on the spin density matrix,
+  // dependence on off-diagonal terms cancels.
+  return {{ {0, 1.} }};
+}
+
+DecayMEPtr FFMqx2qgxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
+
+  // Need variables for the AP kernels
+  double z = dInfo.lastZ();
+  Energy pt = dInfo.lastPt();
+  Energy mi = dInfo.emitterMass();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  Energy den = sqrt(sqr(mi)*sqr(1.-z) + sqr(pt));
+  double v_AP_ppp = pt / den / sqrt(1.-z);
+  double v_AP_ppm = - z * v_AP_ppp ;
+  double v_AP_pmp = mi*(1.-z)*sqrt(1.-z) / den ;
+
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = v_AP_pmp;
+
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -1 or -1/2, 1=+1/2, 2 = +1
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
+  (*kernelPhiDep)(1,1,2) = v_AP_ppp/phase;
+  (*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
+  (*kernelPhiDep)(1,1,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,1,0) = v_AP_mpm;
+  (*kernelPhiDep)(1,0,2) = v_AP_pmp;
+  (*kernelPhiDep)(0,1,2) = 0.;
+  (*kernelPhiDep)(1,0,0) = 0.;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FFMqx2qgxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void FFMqx2qgxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<FFMqx2qgxDipoleKernel> FFMqx2qgxDipoleKernel::initFFMqx2qgxDipoleKernel;
 // Definition of the static class description member.
 
 void FFMqx2qgxDipoleKernel::Init() {
 
   static ClassDocumentation<FFMqx2qgxDipoleKernel> documentation
     ("FFMqx2qgxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/FFMqx2qgxDipoleKernel.h b/Shower/Dipole/Kernels/FFMqx2qgxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FFMqx2qgxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FFMqx2qgxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_FFMqx2qgxDipoleKernel_H
 #define HERWIG_FFMqx2qgxDipoleKernel_H
 //
 // This is the declaration of the FFMqx2qgxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer, Martin Stoll, Stephen Webster
  *
  * \brief FFMqx2qgxDipoleKernel implements the q -> qg
  * splitting off a final-final dipole
  *
  */
 class FFMqx2qgxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   FFMqx2qgxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~FFMqx2qgxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<FFMqx2qgxDipoleKernel> initFFMqx2qgxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FFMqx2qgxDipoleKernel & operator=(const FFMqx2qgxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of FFMqx2qgxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::FFMqx2qgxDipoleKernel,1> {
   /** Typedef of the first base class of FFMqx2qgxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the FFMqx2qgxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::FFMqx2qgxDipoleKernel>
   : public ClassTraitsBase<Herwig::FFMqx2qgxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::FFMqx2qgxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * FFMqx2qgxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class FFMqx2qgxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_FFMqx2qgxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.cc b/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.cc
@@ -1,113 +1,169 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FFgx2ggxDipoleKernel class.
 //
 
 #include "FFgx2ggxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Parameter.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 FFgx2ggxDipoleKernel::FFgx2ggxDipoleKernel() 
   : DipoleSplittingKernel(){}
 
 FFgx2ggxDipoleKernel::~FFgx2ggxDipoleKernel() {}
 
 IBPtr FFgx2ggxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FFgx2ggxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool FFgx2ggxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     ind.emitterData()->id() == ParticleID::g &&
     ind.spectatorData()->mass() == ZERO &&
     !ind.initialStateEmitter() && !ind.initialStateSpectator();
 }
 
 bool FFgx2ggxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     sk.emitter(b)->id() == ParticleID::g &&
     sk.emission(b)->id() == ParticleID::g;
        
 
 }
 
 tcPDPtr FFgx2ggxDipoleKernel::emitter(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr FFgx2ggxDipoleKernel::emission(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr FFgx2ggxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double FFgx2ggxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   double z = split.lastZ();
   double y = sqr(split.lastPt() / split.scale()) / (z*(1.-z));
 
   double S1=1./(1.-z*(1.-y));
   double S2=1./(1.-(1.-z)*(1.-y));
   double NS=(-2 + z*(1.-z));
   
   if( theAsymmetryOption == 0 ){
     ret *= 3.*( S1 + 0.5 * NS);
   }else if ( theAsymmetryOption == 1 ){
     ret *= 3.*z*( S1 +S2 + NS );
   }else{
     ret *= 3.*0.5*( S1 + S2 + NS );
   }
   
   return ret > 0. ? ret : 0.;
 }
 
+vector< pair<int, Complex> >
+FFgx2ggxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
+
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
+  double v_AP_ppm = z*sqrt( z / (1.-z) );
+  double v_AP_pmp = (1.-z)*sqrt( (1.-z)/z );
+
+  //double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = -v_AP_pmp;
+
+  // Initialise variables for the distributions
+  vector< pair<int, Complex> > distPhiDep;
+  double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp)) - 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp);
+
+  distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp))/max ) );
+  distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) );
+  distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) );
+
+  return distPhiDep;
+}
+
+DecayMEPtr FFgx2ggxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
+
+  double z = dInfo.lastZ();
+  
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
+  double v_AP_ppm = z*sqrt( z / (1.-z) );
+  double v_AP_pmp = (1.-z)*sqrt( (1.-z)/z );
+
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = -v_AP_pmp;
+
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1,PDT::Spin1)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -, 2 = +
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
+  (*kernelPhiDep)(2,2,2) = v_AP_ppp/phase;
+  (*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
+  (*kernelPhiDep)(2,2,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
+  (*kernelPhiDep)(2,0,2) = v_AP_pmp*phase;
+  (*kernelPhiDep)(0,2,2) = 0;
+  (*kernelPhiDep)(2,0,0) = 0;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FFgx2ggxDipoleKernel::persistentOutput(PersistentOStream & os) const {
   os << theAsymmetryOption;
 }
 
 void FFgx2ggxDipoleKernel::persistentInput(PersistentIStream & is, int) {
   is >> theAsymmetryOption;
 }
 
 ClassDescription<FFgx2ggxDipoleKernel> FFgx2ggxDipoleKernel::initFFgx2ggxDipoleKernel;
 // Definition of the static class description member.
 
 void FFgx2ggxDipoleKernel::Init() {
 
   static ClassDocumentation<FFgx2ggxDipoleKernel> documentation
     ("FFgx2ggxDipoleKernel");
 
   static Parameter<FFgx2ggxDipoleKernel,int> interfacetheAsymmetryOption
     ("AsymmetryOption",
      "The asymmetry option for final state gluon spliitings.",
      &FFgx2ggxDipoleKernel::theAsymmetryOption, 1, 0, 0,
      false, false, Interface::lowerlim);
 }
diff --git a/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.h b/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.h
@@ -1,187 +1,198 @@
 // -*- C++ -*-
 #ifndef HERWIG_FFgx2ggxDipoleKernel_H
 #define HERWIG_FFgx2ggxDipoleKernel_H
 //
 // This is the declaration of the FFgx2ggxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer
  *
  * \brief FFgx2ggxDipoleKernel implements the g -> gg
  * splitting off a final-final dipole
  *
  */
 class FFgx2ggxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   FFgx2ggxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~FFgx2ggxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<FFgx2ggxDipoleKernel> initFFgx2ggxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FFgx2ggxDipoleKernel & operator=(const FFgx2ggxDipoleKernel &) = delete;
 
   /**
    * Asymmetry option for final state gluon splittings.
    */
   
   int theAsymmetryOption=1;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of FFgx2ggxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::FFgx2ggxDipoleKernel,1> {
   /** Typedef of the first base class of FFgx2ggxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the FFgx2ggxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::FFgx2ggxDipoleKernel>
   : public ClassTraitsBase<Herwig::FFgx2ggxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::FFgx2ggxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * FFgx2ggxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class FFgx2ggxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_FFgx2ggxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.cc b/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.cc
@@ -1,102 +1,154 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FFgx2qqxDipoleKernel class.
 //
 
 #include "FFgx2qqxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 FFgx2qqxDipoleKernel::FFgx2qqxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 FFgx2qqxDipoleKernel::~FFgx2qqxDipoleKernel() {}
 
 IBPtr FFgx2qqxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FFgx2qqxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool FFgx2qqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     ind.emitterData()->id() == ParticleID::g &&
     ind.spectatorData()->mass() == ZERO &&
     flavour()->mass() == ZERO &&
     !ind.initialStateEmitter() && !ind.initialStateSpectator();
 }
 
 bool FFgx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     sk.emitter(b)->id() + sk.emission(b)->id() == 0 &&
     abs(sk.emitter(b)->id()) < 6 &&
     sk.emitter(b)->mass() == ZERO;
        
 }
 
 
 tcPDPtr FFgx2qqxDipoleKernel::emitter(const DipoleIndex&) const {
   assert(flavour());
   assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
   return flavour();
 }
 
 tcPDPtr FFgx2qqxDipoleKernel::emission(const DipoleIndex&) const {
   assert(flavour());
   assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
   return flavour()->CC();
 }
 
 tcPDPtr FFgx2qqxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double FFgx2qqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   double z = split.lastZ();
 
   ret *= .25 * ( 1. - 2.*z*(1.-z) );
 
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+FFgx2qqxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
+
+  double z = dInfo.lastZ();
+  
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppm = z;
+  double v_AP_pmp = -(1.-z);
+
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = -v_AP_pmp;
+
+  // Initialise variables for the distributions
+  vector< pair<int, Complex> > distPhiDep;
+  double max = (sqr(v_AP_ppm) + sqr(v_AP_pmp)) + 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp);
+  
+  distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*( sqr(v_AP_ppm) + sqr(v_AP_pmp) )/max ) );
+  distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) );
+  distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) );
+
+  return distPhiDep;
+}
+
+DecayMEPtr FFgx2qqxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
+  
+  double z = dInfo.lastZ();
+  
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppm = z;
+  double v_AP_pmp = -(1.-z);
+
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = -v_AP_pmp;
+
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1Half)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+  
+  // 0 = -, 2 = +
+  (*kernelPhiDep)(0,0,0) = 0.;
+  (*kernelPhiDep)(2,1,1) = 0.;
+  (*kernelPhiDep)(0,0,1) = v_AP_mmp/phase;
+  (*kernelPhiDep)(2,1,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,1,0) = v_AP_mpm/phase;
+  (*kernelPhiDep)(2,0,1) = v_AP_pmp*phase;
+  (*kernelPhiDep)(0,1,1) = 0.;
+  (*kernelPhiDep)(2,0,0) = 0.;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FFgx2qqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void FFgx2qqxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<FFgx2qqxDipoleKernel> FFgx2qqxDipoleKernel::initFFgx2qqxDipoleKernel;
 // Definition of the static class description member.
 
 void FFgx2qqxDipoleKernel::Init() {
 
   static ClassDocumentation<FFgx2qqxDipoleKernel> documentation
     ("FFgx2qqxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.h b/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_FFgx2qqxDipoleKernel_H
 #define HERWIG_FFgx2qqxDipoleKernel_H
 //
 // This is the declaration of the FFgx2qqxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer
  *
  * \brief FFgx2qqxDipoleKernel implements the g -> qqbar
  * splitting off a final-final dipole
  *
  */
 class FFgx2qqxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   FFgx2qqxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~FFgx2qqxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<FFgx2qqxDipoleKernel> initFFgx2qqxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FFgx2qqxDipoleKernel & operator=(const FFgx2qqxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of FFgx2qqxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::FFgx2qqxDipoleKernel,1> {
   /** Typedef of the first base class of FFgx2qqxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the FFgx2qqxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::FFgx2qqxDipoleKernel>
   : public ClassTraitsBase<Herwig::FFgx2qqxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::FFgx2qqxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * FFgx2qqxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class FFgx2qqxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_FFgx2qqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.cc b/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.cc
@@ -1,99 +1,136 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FFqx2qgxDipoleKernel class.
 //
 
 #include "FFqx2qgxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 FFqx2qgxDipoleKernel::FFqx2qgxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 FFqx2qgxDipoleKernel::~FFqx2qgxDipoleKernel() {}
 
 IBPtr FFqx2qgxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FFqx2qgxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool FFqx2qgxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     abs(ind.emitterData()->id()) < 6  &&
     ind.emitterData()->mass() == ZERO &&
     ind.spectatorData()->mass() == ZERO &&
     !ind.initialStateEmitter() && !ind.initialStateSpectator();
 }
 
 bool FFqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     sk.emission(b)->id() == ParticleID::g &&
     abs(sk.emitter(b)->id()) < 6 &&
     sk.emitter(b)->mass() == ZERO;
        
 
 }
 
 tcPDPtr FFqx2qgxDipoleKernel::emitter(const DipoleIndex& ind) const {
   return ind.emitterData();
 }
 
 tcPDPtr FFqx2qgxDipoleKernel::emission(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr FFqx2qgxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double FFqx2qgxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   double z = split.lastZ();
   double y = sqr(split.lastPt() / split.scale()) / (z*(1.-z));
 
   ret *= (!strictLargeN() ? 4./3. : 3./2.)*( 2./(1.-z*(1.-y)) - (1.+z) );
 
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+FFqx2qgxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
+  
+  // No dependence on the spin density matrix,
+  // dependence on off-diagonal terms cancels.
+  return {{ {0, 1.} }};
+}
+
+DecayMEPtr FFqx2qgxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
+
+  double z = dInfo.lastZ();
+  
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = sqrt( 1./(1.-z) );
+  double v_AP_ppm = -z/sqrt(1.-z);
+
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -1 or -1/2, 1=+1/2, 2 = +1
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
+  (*kernelPhiDep)(1,1,2) = v_AP_ppp/phase;
+  (*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
+  (*kernelPhiDep)(1,1,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,1,0) = 0.;
+  (*kernelPhiDep)(1,0,2) = 0.;
+  (*kernelPhiDep)(0,1,2) = 0.;
+  (*kernelPhiDep)(1,0,0) = 0.;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FFqx2qgxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void FFqx2qgxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<FFqx2qgxDipoleKernel> FFqx2qgxDipoleKernel::initFFqx2qgxDipoleKernel;
 // Definition of the static class description member.
 
 void FFqx2qgxDipoleKernel::Init() {
 
   static ClassDocumentation<FFqx2qgxDipoleKernel> documentation
     ("FFqx2qgxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.h b/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_FFqx2qgxDipoleKernel_H
 #define HERWIG_FFqx2qgxDipoleKernel_H
 //
 // This is the declaration of the FFqx2qgxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer
  *
  * \brief FFqx2qgxDipoleKernel implements the q -> qg
  * splitting off a final-final dipole
  *
  */
 class FFqx2qgxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   FFqx2qgxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~FFqx2qgxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<FFqx2qgxDipoleKernel> initFFqx2qgxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FFqx2qgxDipoleKernel & operator=(const FFqx2qgxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of FFqx2qgxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::FFqx2qgxDipoleKernel,1> {
   /** Typedef of the first base class of FFqx2qgxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the FFqx2qgxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::FFqx2qgxDipoleKernel>
   : public ClassTraitsBase<Herwig::FFqx2qgxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::FFqx2qgxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * FFqx2qgxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class FFqx2qgxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_FFqx2qgxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FIMDecaygx2ggxDipoleKernel.cc b/Shower/Dipole/Kernels/FIMDecaygx2ggxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FIMDecaygx2ggxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FIMDecaygx2ggxDipoleKernel.cc
@@ -1,159 +1,220 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FIMDecaygx2ggxDipoleKernel class.
 //
 
 #include "FIMDecaygx2ggxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Parameter.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 FIMDecaygx2ggxDipoleKernel::FIMDecaygx2ggxDipoleKernel() 
   : DipoleSplittingKernel(){}
 
 FIMDecaygx2ggxDipoleKernel::~FIMDecaygx2ggxDipoleKernel() {}
 
 IBPtr FIMDecaygx2ggxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FIMDecaygx2ggxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool FIMDecaygx2ggxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     ind.incomingDecaySpectator() && !ind.incomingDecayEmitter() &&
     ind.emitterData()->id() == ParticleID::g &&
     !(ind.spectatorData()->mass() == ZERO) &&
     // Initial state here refers to the entire event
     !ind.initialStateEmitter() && !ind.initialStateSpectator();
 }
 
 bool FIMDecaygx2ggxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     sk.emission(b)->id() == ParticleID::g &&
     sk.emitter(b)->id() == ParticleID::g &&
     abs(sk.spectator(b)->mass()) == abs(spectator(a)->mass());
 
 }
 
 
 tcPDPtr FIMDecaygx2ggxDipoleKernel::emitter(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr FIMDecaygx2ggxDipoleKernel::emission(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr FIMDecaygx2ggxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double FIMDecaygx2ggxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
+  
+  double ret = alphaPDF(split);
 
-    double ret = alphaPDF(split);
-
-  // These are the physical variables as used in the standard form of the kernel (i.e. do not redefine variables or kernel)
+  // Sudakov parameterisation variables,
+  // needed to calculate y.
   double z = split.lastZ();
   Energy pt = split.lastPt();
 
-  // Need zPrime to calculate y, 
-  // TODO: Should just store y in the dipole splitting info everywhere anyway!!!
-  // The only value stored in dInfo.lastSplittingParameters() should be zPrime
-  //assert(split.lastSplittingParameters().size() == 1 );
-  double zPrime = split.lastSplittingParameters()[0];
+  // Construct mass squared variables
+  // Note for q->qg can use the emitterMass
+  // (i.e. mass of emitter before splitting = mass of emitter after)
+  Energy2 Qijk = sqr(split.scale());
+  Energy2 mk2 = sqr(split.recoilMass());
+  Energy2 sbar = Qijk - mk2;
 
-  // Construct mass squared variables
-  double mua2 = sqr( split.spectatorMass() / split.scale() );
-  // Recoil system mass
-  double muj2 = sqr(split.recoilMass() / split.scale());
-  double bar = 1. - muj2;
+  // Note this should be the same as Qijk
+  Energy2 ma2 = sqr(split.spectatorMass());
 
-// Calculate y
-  double y = (sqr(pt)/sqr(split.scale())) / (bar*zPrime*(1.-zPrime));
 
-  if( sqr(2.*muj2+bar*(1.-y))-4.*muj2 < 0. ){
+  // Calculate y
+  double y = sqr(pt) / sbar / z / (1.-z);
+
+  if( sqr(2.*mk2+sbar*(1.-y)) - 4.*mk2*Qijk < ZERO ){
     generator()->logWarning( Exception()
-                            << "error in FIMDecaygx2ggxDipoleKernel::evaluate -- " <<
-                            "muj2 " << muj2 << "  y " << y << Exception::warning );
-
+    << "error in FIMDecayqx2qgxDipoleKernel::evaluate -- " <<
+    "mk2 " << mk2/GeV2 << "  y " << y << Exception::warning );
     return 0.0;
   }
 
-  double vijk = sqrt( sqr(2.*muj2+bar*(1.-y))-4.*muj2 ) / (bar*(1.-y));
+  // zi, used in dipole splitting kernel
+  double zi = split.lastSplittingParameters()[0];
+  
+  double vijk = sqrt( sqr(2.*mk2 + sbar*(1.-y)) - 4.*mk2*Qijk ) / sbar / (1.-y);
+  double vtilde = 1.;
   double viji = 1.;
-  double vbar = 1.;
 
-  double zp = 0.5*(1.+viji*vijk);
-  double zm = 0.5*(1.-viji*vijk);
+  double zip = 0.5*(1.+viji*vijk);
+  double zim = 0.5*(1.-viji*vijk);
 
   // how to choose kappa?
   double kappa = 0.;
 
-  double S1 = 0.5*3.*(2.*y + 1.)/((1.+y)-z*(1.-y)) +
+  double S1 = 0.5*3.*(2.*y + 1.)/((1.+y)-zi*(1.-y)) +
     (!strictLargeN() ? 4./3. : 3./2.)*
-    y/(1.-z*(1.-y)) * ( 2.*(2.*y + 1.)/((1.+y)-z*(1.-y))
-			- (vbar/vijk)*(2. + 2.*mua2/((1.-z*(1.-y))*bar)) );
-  double S2 = 0.5*3.*(2.*y + 1.)/((1.+y)-(1.-z)*(1.-y)) +
+    y/(1.-zi*(1.-y)) * ( 2.*(2.*y + 1.)/((1.+y)-zi*(1.-y))
+			- (vtilde/vijk)*(2. + 2.*ma2/((1.-zi*(1.-y))*sbar)) );
+  double S2 = 0.5*3.*(2.*y + 1.)/((1.+y)-(1.-zi)*(1.-y)) +
     (!strictLargeN() ? 4./3. : 3./2.)*
-    y/(1.-(1.-z)*(1.-y)) * ( 2.*(2.*y + 1.)/((1.+y)-(1.-z)*(1.-y))
-			     - (vbar/vijk)*(2. + 2.*mua2/((1.-(1.-z)*(1.-y))*bar)) );  
-  double NS = 0.5*3.*(z*(1.-z)-(1.-kappa)*zp*zm - 2.)/vijk;
-
+    y/(1.-(1.-zi)*(1.-y)) * ( 2.*(2.*y + 1.)/((1.+y)-(1.-zi)*(1.-y))
+			     - (vtilde/vijk)*(2. + 2.*ma2/((1.-(1.-zi)*(1.-y))*sbar)) );  
+  double NS = 0.5*3.*(zi*(1.-zi)-(1.-kappa)*zip*zim - 2.)/vijk;
 
   if( theAsymmetryOption == 0 ){
     ret *= 2.*S1 + NS;
   }else if ( theAsymmetryOption == 1 ){
-    ret *= 2.*z*( S1 + S2 + NS );
+    ret *= 2.*zi*( S1 + S2 + NS );
   }else{
     ret *= S1 + S2 + NS;
   }
   
   return ret > 0. ? ret : 0.;
   
 }
 
+vector< pair<int, Complex> >
+FIMDecaygx2ggxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo,
+                                        const RhoDMatrix& rho) const {
+
+  // Need variables for the AP kernels
+  double z = dInfo.lastSplittingParameters()[0];
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
+  double v_AP_ppm = z*sqrt( z / (1.-z) );
+  double v_AP_pmp = (1.-z)*sqrt( (1.-z)/z );
+
+  //double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = -v_AP_pmp;
+
+  // Initialise variables for the distributions
+  vector< pair<int, Complex> > distPhiDep;
+  double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp)) - 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp);
+
+  distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp))/max ) );
+  distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) );
+  distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) );
+  
+  return distPhiDep;
+}
+
+
+DecayMEPtr FIMDecaygx2ggxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
+
+  // Need variables for the AP kernels
+  double z = dInfo.lastSplittingParameters()[0];  
+  
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
+  double v_AP_ppm = z*sqrt( z / (1.-z) );
+  double v_AP_pmp = (1.-z)*sqrt( (1.-z)/z );
+
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = -v_AP_pmp;
+  
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1,PDT::Spin1)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -, 2 = +
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
+  (*kernelPhiDep)(2,2,2) = v_AP_ppp/phase;
+  (*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
+  (*kernelPhiDep)(2,2,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
+  (*kernelPhiDep)(2,0,2) = v_AP_pmp*phase;
+  (*kernelPhiDep)(0,2,2) = 0;
+  (*kernelPhiDep)(2,0,0) = 0;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FIMDecaygx2ggxDipoleKernel::persistentOutput(PersistentOStream & os) const {
   os<<theAsymmetryOption;
 }
 
 void FIMDecaygx2ggxDipoleKernel::persistentInput(PersistentIStream & is, int) {
   is>>theAsymmetryOption;
 }
 
 ClassDescription<FIMDecaygx2ggxDipoleKernel> FIMDecaygx2ggxDipoleKernel::initFIMDecaygx2ggxDipoleKernel;
 // Definition of the static class description member.
 
 void FIMDecaygx2ggxDipoleKernel::Init() {
 
   static ClassDocumentation<FIMDecaygx2ggxDipoleKernel> documentation
     ("FIMDecaygx2ggxDipoleKernel");
 
   static Parameter<FIMDecaygx2ggxDipoleKernel,int> interfacetheAsymmetryOption
     ("AsymmetryOption",
      "The asymmetry option for final state gluon spliitings.",
      &FIMDecaygx2ggxDipoleKernel::theAsymmetryOption, 0, 0, 0,
      false, false, Interface::lowerlim);
 
 }
diff --git a/Shower/Dipole/Kernels/FIMDecaygx2ggxDipoleKernel.h b/Shower/Dipole/Kernels/FIMDecaygx2ggxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FIMDecaygx2ggxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FIMDecaygx2ggxDipoleKernel.h
@@ -1,186 +1,197 @@
 // -*- C++ -*-
 #ifndef HERWIG_FIMDecaygx2ggxDipoleKernel_H
 #define HERWIG_FIMDecaygx2ggxDipoleKernel_H
 //
 // This is the declaration of the FIMDecaygx2ggxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Stephen Webster
  *
  * \brief FIMDecaygx2ggxDipoleKernel implements the g -> gg
  * splitting off a final-initial decay dipole and includes the
  * contribution from the splitting of the intial / decay particle
  *
  */
 class FIMDecaygx2ggxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   FIMDecaygx2ggxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~FIMDecaygx2ggxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
   
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<FIMDecaygx2ggxDipoleKernel> initFIMDecaygx2ggxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FIMDecaygx2ggxDipoleKernel & operator=(const FIMDecaygx2ggxDipoleKernel &) = delete;
 
   /**
    * Asymmetry option for final state gluon splittings.
    */
   int theAsymmetryOption=0;
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of FIMDecaygx2ggxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::FIMDecaygx2ggxDipoleKernel,1> {
   /** Typedef of the first base class of FIMDecaygx2ggxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the FIMDecaygx2ggxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::FIMDecaygx2ggxDipoleKernel>
   : public ClassTraitsBase<Herwig::FIMDecaygx2ggxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::FIMDecaygx2ggxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * FIMDecaygx2ggxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class FIMDecaygx2ggxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_FIMDecaygx2ggxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FIMDecaygx2qqxDipoleKernel.cc b/Shower/Dipole/Kernels/FIMDecaygx2qqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FIMDecaygx2qqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FIMDecaygx2qqxDipoleKernel.cc
@@ -1,142 +1,207 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FIMDecaygx2qqxDipoleKernel class.
 //
 
 #include "FIMDecaygx2qqxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Parameter.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 FIMDecaygx2qqxDipoleKernel::FIMDecaygx2qqxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 FIMDecaygx2qqxDipoleKernel::~FIMDecaygx2qqxDipoleKernel() {}
 
 IBPtr FIMDecaygx2qqxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FIMDecaygx2qqxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool FIMDecaygx2qqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     ind.incomingDecaySpectator() && !ind.incomingDecayEmitter() &&
     ind.emitterData()->id() == ParticleID::g &&
     !(ind.spectatorData()->mass() == ZERO) &&
     // Initial state here refers to the entire event
     !ind.initialStateEmitter() && !ind.initialStateSpectator();
 }
 
 bool FIMDecaygx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     sk.emitter(b)->id() + sk.emission(b)->id() == 0 &&
     abs(sk.emitter(b)->id()) < 6 &&
     emitter(a)->id() == sk.emitter(b)->id() &&
     abs(sk.spectator(b)->mass()) == abs(spectator(a)->mass());
 
 }
 
 
 tcPDPtr FIMDecaygx2qqxDipoleKernel::emitter(const DipoleIndex&) const {
   assert(flavour());
   assert(abs(flavour()->id()) < 6);
   return flavour();
 }
 
 tcPDPtr FIMDecaygx2qqxDipoleKernel::emission(const DipoleIndex&) const {
   assert(flavour());
   assert(abs(flavour()->id()) < 6);
   return flavour()->CC();
 }
 
 tcPDPtr FIMDecaygx2qqxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double FIMDecaygx2qqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
   
   double ret = alphaPDF(split);
 
-  // These are the physical variables as used in the standard form of the kernel (i.e. do not redefine variables or kernel)
+  // Sudakov parameterisation variables,
+  // needed to calculate y.
   double z = split.lastZ();
   Energy pt = split.lastPt();
 
-  // Need zPrime to calculate y, 
-  // TODO: Should just store y in the dipole splitting info everywhere anyway!!!
-  // The only value stored in dInfo.lastSplittingParameters() should be zPrime
-  //assert(split.lastSplittingParameters().size() == 1 );
-  double zPrime = split.lastSplittingParameters()[0];
-
-
   // Construct mass squared variables
-  double mui2 = sqr(split.emitterData()->mass() / split.scale());
-  double mu2 = mui2;
-  //double mua2 = sqr( split.spectatorMass() / split.scale() );
-  // Recoil system mass
-  double muj2 = sqr(split.recoilMass() / split.scale());
-  double bar = 1. - mui2 - mu2 - muj2;
+  // Note for q->qg can use the emitterMass
+  // (i.e. mass of emitter before splitting = mass of emitter after)
+  Energy2 Qijk = sqr(split.scale());
+  Energy2 mi2 = sqr(split.emitterData()->mass());
+  Energy2 mj2 = mi2;
+  Energy2 mk2 = sqr(split.recoilMass());
+  Energy2 sbar = Qijk - mi2 - mj2 - mk2;
 
   // Calculate y
-  double y = (sqr(pt)/sqr(split.scale()) + sqr(1.-zPrime)*mui2 + sqr(zPrime)*mu2) / (bar*zPrime*(1.-zPrime));
+  double y = (sqr(pt) + sqr(1.-z)*mi2 + sqr(z)*mj2) / sbar / z / (1.-z);
 
-  if( sqr(2.*muj2+bar*(1.-y))-4.*muj2 < 0. ){
+  if( sqr(2.*mk2+sbar*(1.-y)) - 4.*mk2*Qijk < ZERO ){
     generator()->logWarning( Exception()
-                            << "error in FIMDecaygx2qqxDipoleKernel::evaluate -- " <<
-                            "muj2 " << muj2 << "  mui2 " << mui2 << "  y " << y << Exception::warning );
-
+    << "error in FIMDecayqx2qgxDipoleKernel::evaluate -- " <<
+    "mk2 " << mk2/GeV2 << "  mi2 " << mi2/GeV2 << "  y " << y << Exception::warning );
     return 0.0;
   }
 
-  double vijk = sqrt( sqr(2.*muj2+bar*(1.-y))-4.*muj2 ) / (bar*(1.-y));
-  double viji = sqrt( sqr(bar*y)-4.*sqr(mui2) ) / (bar*y+2.*mui2);
-  //double vbar = sqrt( 1.+sqr(mui2)+sqr(muj2)-2.*(mui2+muj2+mui2*muj2) ) / bar;
+  // zi, used in dipole splitting kernel
+  double zi = split.lastSplittingParameters()[0];
+
+  double vijk = sqrt( sqr(2.*mk2 + sbar*(1.-y)) - 4.*mk2*Qijk ) / sbar / (1.-y);
+  double viji = sqrt( sqr(sbar*y) - 4.*sqr(mi2) ) / (sbar*y + 2.*mi2);
   
-  double zp = 0.5*(1.+viji*vijk);
-  double zm = 0.5*(1.-viji*vijk);
+  double zip = 0.5*(1.+viji*vijk);
+  double zim = 0.5*(1.-viji*vijk);
 
   // how to choose kappa?
   double kappa = 0.;
 
-  ret *= 0.25 / vijk * ( 1. - 2.*( z*(1.-z) - (1.-kappa)*zp*zm - kappa*mui2/(2*mui2+bar*y) ) );
+  ret *= 0.25 / vijk
+    * ( 1. - 2.*( zi*(1.-zi) - (1.-kappa)*zip*zim - kappa*mi2/(2.*mi2 + sbar*y) ) );
   
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+FIMDecaygx2qqxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo,
+                                        const RhoDMatrix& rho) const {
+
+  // Need variables for the AP kernels
+  double z = dInfo.lastSplittingParameters()[0];
+  Energy pt = dInfo.lastPt();
+  Energy2 mi2 = sqr(dInfo.emitterData()->mass());
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double ratio = mi2 / ( mi2 + sqr(pt) );
+  double root = sqrt(1.-ratio);
+  double v_AP_ppp = sqrt(ratio);
+  double v_AP_ppm = z*root;
+  double v_AP_pmp = -(1.-z)*root;
+
+  //  double v_AP_mmm = v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = -v_AP_pmp;
+
+  // Initialise variables for the distributions
+  vector< pair<int, Complex> > distPhiDep;
+  double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp)) + 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp);
+  
+  distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp) )/max ) );
+  distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) );
+  distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) );
+
+  return distPhiDep;
+}
+
+
+DecayMEPtr FIMDecaygx2qqxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
+  
+  // Need variables for the AP kernels
+  double z = dInfo.lastSplittingParameters()[0];
+  Energy pt = dInfo.lastPt();
+  Energy2 mi2 = sqr(dInfo.emitterData()->mass());
+  
+  // Altarelli-Parisi spin-indexed kernels:
+  double ratio = mi2 / ( mi2 + sqr(pt) );
+  double root = sqrt(1.-ratio);
+  double v_AP_ppp = sqrt(ratio);
+  double v_AP_ppm = z*root;
+  double v_AP_pmp = -(1.-z)*root;
+
+  double v_AP_mmm = v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = -v_AP_pmp;
+
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1Half)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -, 2 = +
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm;
+  (*kernelPhiDep)(2,1,1) = v_AP_ppp;;
+  (*kernelPhiDep)(0,0,1) = v_AP_mmp/phase;
+  (*kernelPhiDep)(2,1,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,1,0) = v_AP_mpm/phase;
+  (*kernelPhiDep)(2,0,1) = v_AP_pmp*phase;
+  (*kernelPhiDep)(0,1,1) = 0.;
+  (*kernelPhiDep)(2,0,0) = 0.;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FIMDecaygx2qqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void FIMDecaygx2qqxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<FIMDecaygx2qqxDipoleKernel> FIMDecaygx2qqxDipoleKernel::initFIMDecaygx2qqxDipoleKernel;
 // Definition of the static class description member.
 
 void FIMDecaygx2qqxDipoleKernel::Init() {
 
   static ClassDocumentation<FIMDecaygx2qqxDipoleKernel> documentation
     ("FIMDecaygx2qqxDipoleKernel");
 
 }
diff --git a/Shower/Dipole/Kernels/FIMDecaygx2qqxDipoleKernel.h b/Shower/Dipole/Kernels/FIMDecaygx2qqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FIMDecaygx2qqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FIMDecaygx2qqxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_FIMDecaygx2qqxDipoleKernel_H
 #define HERWIG_FIMDecaygx2qqxDipoleKernel_H
 //
 // This is the declaration of the FIMDecaygx2qqxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Stephen Webster
  *
  * \brief FIMDecaygx2qqxDipoleKernel implements the g -> qq
  * splitting off a final-initial decay dipole
  *
  */
 class FIMDecaygx2qqxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   FIMDecaygx2qqxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~FIMDecaygx2qqxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<FIMDecaygx2qqxDipoleKernel> initFIMDecaygx2qqxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FIMDecaygx2qqxDipoleKernel & operator=(const FIMDecaygx2qqxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of FIMDecaygx2qqxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::FIMDecaygx2qqxDipoleKernel,1> {
   /** Typedef of the first base class of FIMDecaygx2qqxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the FIMDecaygx2qqxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::FIMDecaygx2qqxDipoleKernel>
   : public ClassTraitsBase<Herwig::FIMDecaygx2qqxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::FIMDecaygx2qqxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * FIMDecaygx2qqxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class FIMDecaygx2qqxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_FIMDecaygx2qqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FIMDecayqx2qgxDipoleKernel.cc b/Shower/Dipole/Kernels/FIMDecayqx2qgxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FIMDecayqx2qgxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FIMDecayqx2qgxDipoleKernel.cc
@@ -1,144 +1,187 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FIMDecayqx2qgxDipoleKernel class.
 //
 
 #include "FIMDecayqx2qgxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 FIMDecayqx2qgxDipoleKernel::FIMDecayqx2qgxDipoleKernel() : DipoleSplittingKernel() {}
 
 FIMDecayqx2qgxDipoleKernel::~FIMDecayqx2qgxDipoleKernel() {}
 
 IBPtr FIMDecayqx2qgxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FIMDecayqx2qgxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool FIMDecayqx2qgxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     ind.incomingDecaySpectator() && !ind.incomingDecayEmitter() &&
     abs(ind.emitterData()->id()) < 7  &&
     // This line matches to the kernel declared in a .in file for the given emitter flavour
     abs(ind.emitterData()->id()) == abs(flavour()->id()) &&
     !(ind.spectatorData()->mass() == ZERO) && 
     // Initial state here refers to the entire event
     !ind.initialStateEmitter() && !ind.initialStateSpectator();
 }
 
 bool FIMDecayqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 						     const DipoleSplittingKernel& sk,
 						     const DipoleIndex& b) const {
   
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     sk.emission(b)->id() == ParticleID::g &&
     abs(sk.emitter(b)->id()) < 7 &&
     abs(sk.emitter(b)->mass()) == abs(emitter(a)->mass()) &&
     abs(sk.spectator(b)->mass()) == abs(spectator(a)->mass());
 
 }
 
 tcPDPtr FIMDecayqx2qgxDipoleKernel::emitter(const DipoleIndex& ind) const {
 
   assert(flavour());
   assert(abs(flavour()->id()) < 7);
 
   return ind.emitterData()->id() > 0 ?
     (tcPDPtr) flavour() : (tcPDPtr) flavour()->CC();
 }
 
 
 tcPDPtr FIMDecayqx2qgxDipoleKernel::emission(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 
 tcPDPtr FIMDecayqx2qgxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 
 double FIMDecayqx2qgxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
   
   double ret = alphaPDF(split);
 
-  // These are the physical variables as used in the standard form of the kernel (i.e. do not redefine variables or kernel)
+  // Sudakov parameterisation variables,
+  // needed to calculate y.
   double z = split.lastZ();
   Energy pt = split.lastPt();
 
-  // Need zPrime to calculate y, 
-  // TODO: Should just store y in the dipole splitting info everywhere anyway!!!
-  // The only value stored in dInfo.lastSplittingParameters() should be zPrime
-  //assert(split.lastSplittingParameters().size() == 1 );
-  double zPrime = split.lastSplittingParameters()[0];
-
   // Construct mass squared variables
   // Note for q->qg can use the emitterMass
   // (i.e. mass of emitter before splitting = mass of emitter after)
-  double mui2 = sqr(split.emitterMass() / split.scale());
-  // Recoil system mass
-  double muj2 = sqr(split.recoilMass() / split.scale());
-  // This should be equal to one
-  double mua2 = sqr( split.spectatorMass() / split.scale() );
-  double bar = 1. - mui2 - muj2;
-  
+  Energy2 Qijk = sqr(split.scale());
+  Energy2 mi2 = sqr(split.emitterMass());
+  Energy2 mk2 = sqr(split.recoilMass());
+  Energy2 sbar = Qijk - mi2 - mk2;
+
+  // Note this should be the same as Qijk
+  Energy2 ma2 = sqr(split.spectatorMass());
+
   // Calculate y
-  double y = (sqr(pt)/sqr(split.scale()) + sqr(1.-zPrime)*mui2) / (bar*zPrime*(1.-zPrime));
+  double y = (sqr(pt) + sqr(1.-z)*mi2) / sbar / z / (1.-z);
 
-  if( sqr(2.*muj2+bar*(1.-y))-4.*muj2 < 0. ){
+  if( sqr(2.*mk2+sbar*(1.-y)) - 4.*mk2*Qijk < ZERO ){
     generator()->logWarning( Exception()
     << "error in FIMDecayqx2qgxDipoleKernel::evaluate -- " <<
-    "muj2 " << muj2 << "  mui2 " << mui2 << "  y " << y << Exception::warning );
+    "mk2 " << mk2/GeV2 << "  mi2 " << mi2/GeV2 << "  y " << y << Exception::warning );
     return 0.0;
   }
 
-  double vijk = sqrt( sqr(2.*muj2 + bar*(1.-y))-4.*muj2 ) / (bar*(1.-y));
-  double vbar = sqrt( 1.+sqr(mui2)+sqr(muj2)-2.*(mui2+muj2+mui2*muj2) ) / bar;
+  // zi, used in dipole splitting kernel
+  double zi = split.lastSplittingParameters()[0];
+
+  double vijk = sqrt( sqr(2.*mk2 + sbar*(1.-y)) - 4.*mk2*Qijk ) / sbar / (1.-y);
+  double vtilde = sqrt( sqr(Qijk) + sqr(mi2) + sqr(mk2)
+                        - 2.*(mi2*Qijk + mk2*Qijk + mi2*mk2) ) / sbar;
 
   ret *=
     (!strictLargeN() ? 4./3. : 3./2.)
-    * ( ( 2.*(2.*mui2/bar + 2.*y + 1.)/((1.+y)-z*(1.-y))
-	  - (vbar/vijk)*((1.+z) + 2.*mui2/(y*bar)) )
-	+ y/(1.-z*(1.-y)) * ( 2.*(2.*mui2/bar + 2.*y + 1.)/((1.+y)-z*(1.-y))
-			      - (vbar/vijk)*(2. + 2.*mua2/((1.-z*(1.-y))*bar)) ) );
+    * ( ( 2.*( 2.*mi2/sbar + 2.*y + 1. ) / ((1.+y) - zi*(1.-y))
+          - (vtilde/vijk) * ( (1.+zi) + 2.*mi2/y/sbar ) )
+	+ y/(1. - zi*(1.-y)) * ( 2.*(2.*mi2/sbar + 2.*y + 1. ) / ((1.+y) - zi*(1.-y))
+                             - (vtilde/vijk) * ( 2. + 2.*ma2/((1. - zi*(1.-y))*sbar) ) ) );
   
   return ret > 0. ? ret : 0.;
   
 }
 
+vector< pair<int, Complex> >
+FIMDecayqx2qgxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
+
+  // No dependence on the spin density matrix,
+  // dependence on off-diagonal terms cancels.  
+  return {{ {0, 1.} }};
+}
+
+DecayMEPtr FIMDecayqx2qgxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
+
+  // Need variables for the AP kernels
+  double z = dInfo.lastSplittingParameters()[0];
+  Energy pt = dInfo.lastPt();
+  Energy mi = dInfo.emitterMass();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  Energy den = sqrt(sqr(mi)*sqr(1.-z) + sqr(pt));
+  double v_AP_ppp = pt / den / sqrt(1.-z);
+  double v_AP_ppm = - z * v_AP_ppp ;
+  double v_AP_pmp = mi*(1.-z)*sqrt(1.-z) / den ;
+
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = v_AP_pmp;
+  
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -1 or -1/2, 1=+1/2, 2 = +1
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
+  (*kernelPhiDep)(1,1,2) = v_AP_ppp/phase;
+  (*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
+  (*kernelPhiDep)(1,1,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,1,0) = v_AP_mpm;
+  (*kernelPhiDep)(1,0,2) = v_AP_pmp;
+  (*kernelPhiDep)(0,1,2) = 0.;
+  (*kernelPhiDep)(1,0,0) = 0.;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FIMDecayqx2qgxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void FIMDecayqx2qgxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<FIMDecayqx2qgxDipoleKernel> FIMDecayqx2qgxDipoleKernel::initFIMDecayqx2qgxDipoleKernel;
 // Definition of the static class description member.
 
 void FIMDecayqx2qgxDipoleKernel::Init() {
 
   static ClassDocumentation<FIMDecayqx2qgxDipoleKernel> documentation
     ("FIMDecayqx2qgxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/FIMDecayqx2qgxDipoleKernel.h b/Shower/Dipole/Kernels/FIMDecayqx2qgxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FIMDecayqx2qgxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FIMDecayqx2qgxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_FIMDecayqx2qgxDipoleKernel_H
 #define HERWIG_FIMDecayqx2qgxDipoleKernel_H
 //
 // This is the declaration of the FIMDecayqx2qgxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Stephen Webster
  *
  * \brief FIMDecayqx2qgxDipoleKernel implements the q -> qg
  * splitting off a final-initial decay dipole and includes the
  * contribution from the splitting of the intial / decay particle
  *
  */
 class FIMDecayqx2qgxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   FIMDecayqx2qgxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~FIMDecayqx2qgxDipoleKernel();
   //@}
 
 public:
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex& ind) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex& ind) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo& split) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<FIMDecayqx2qgxDipoleKernel> initFIMDecayqx2qgxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FIMDecayqx2qgxDipoleKernel & operator=(const FIMDecayqx2qgxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of FIMDecayqx2qgxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::FIMDecayqx2qgxDipoleKernel,1> {
   /** Typedef of the first base class of FIMDecayqx2qgxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the FIMDecayqx2qgxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::FIMDecayqx2qgxDipoleKernel>
   : public ClassTraitsBase<Herwig::FIMDecayqx2qgxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::FIMDecayqx2qgxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * FIMDecayqx2qgxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class FIMDecayqx2qgxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_FIMDecayqx2qgxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FIMgx2qqxDipoleKernel.cc b/Shower/Dipole/Kernels/FIMgx2qqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FIMgx2qqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FIMgx2qqxDipoleKernel.cc
@@ -1,116 +1,180 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FIMgx2qqxDipoleKernel class.
 //
 
 #include "FIMgx2qqxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 FIMgx2qqxDipoleKernel::FIMgx2qqxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 FIMgx2qqxDipoleKernel::~FIMgx2qqxDipoleKernel() {}
 
 IBPtr FIMgx2qqxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FIMgx2qqxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool FIMgx2qqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     ind.emitterData()->id() == ParticleID::g &&
     ind.spectatorData()->mass() == ZERO &&
     flavour()->mass() != ZERO &&
     !ind.initialStateEmitter() && ind.initialStateSpectator();
 }
 
 bool FIMgx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     sk.emitter(b)->id() + sk.emission(b)->id() == 0 &&
     abs(sk.emitter(b)->id()) < 6 &&
     emitter(a)->mass() == sk.emitter(b)->mass() &&
     a.spectatorPDF() == b.spectatorPDF();
 
 }
 
 
 tcPDPtr FIMgx2qqxDipoleKernel::emitter(const DipoleIndex&) const {
   assert(flavour());
   assert(abs(flavour()->id()) < 6 && flavour()->mass() != ZERO);
   return flavour();
 }
 
 tcPDPtr FIMgx2qqxDipoleKernel::emission(const DipoleIndex&) const {
   assert(flavour());
   assert(abs(flavour()->id()) < 6 && flavour()->mass() != ZERO);
   return flavour()->CC();
 }
 
 tcPDPtr FIMgx2qqxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 // TODO
 // assure split.scale() is sqrt(sbar)
 double FIMgx2qqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   // mi=m=mQ, Mi=0, mj=Mj=0
   Energy2 mQ2 = sqr(split.emitterData()->mass());
 
   double z = split.lastZ();
   double x = 1./ ( 1. +
 		   ( sqr(split.lastPt()) + mQ2 ) /
 		   ( z*(1.-z) * sqr(split.scale()) ) );
 
   double muQ2 = x * mQ2/sqr(split.scale());
 
   double zm = .5 * ( 1. - sqrt( 1. - 4.*muQ2/(1.-x) ) );
   double zp = .5 * ( 1. + sqrt( 1. - 4.*muQ2/(1.-x) ) );
 
   ret *= .25 * (1.-2.*(zp-z)*(z-zm));
 
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+FIMgx2qqxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
+
+  double z = dInfo.lastZ();
+  Energy pt = dInfo.lastPt();
+  Energy2 mi2 = sqr(dInfo.emitterData()->mass());
+  
+  // Altarelli-Parisi spin-indexed kernels:
+  double ratio = mi2 / ( mi2 + sqr(pt) );
+  double root = sqrt(1.-ratio);
+  double v_AP_ppp = sqrt(ratio);
+  double v_AP_ppm = z*root;
+  double v_AP_pmp = -(1.-z)*root;
+
+  //double v_AP_mmm = v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = -v_AP_pmp;
+
+  // Initialise variables for the distributions
+  vector< pair<int, Complex> > distPhiDep;
+  double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp)) + 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp);
+  
+  distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp) )/max ) );
+  distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) );
+  distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) );
+
+  return distPhiDep;
+}
+
+DecayMEPtr FIMgx2qqxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
+  
+  double z = dInfo.lastZ();
+  Energy pt = dInfo.lastPt();
+  Energy2 mi2 = sqr(dInfo.emitterData()->mass());
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double ratio = mi2 / ( mi2 + sqr(pt) );
+  double root = sqrt(1.-ratio);
+  double v_AP_ppp = sqrt(ratio);
+  double v_AP_ppm = z*root;
+  double v_AP_pmp = -(1.-z)*root;
+
+  double v_AP_mmm = v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = -v_AP_pmp;
+
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1Half)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -, 2 = +
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm;
+  (*kernelPhiDep)(2,1,1) = v_AP_ppp;
+  (*kernelPhiDep)(0,0,1) = v_AP_mmp/phase;
+  (*kernelPhiDep)(2,1,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,1,0) = v_AP_mpm/phase;
+  (*kernelPhiDep)(2,0,1) = v_AP_pmp*phase;
+  (*kernelPhiDep)(0,1,1) = 0.;
+  (*kernelPhiDep)(2,0,0) = 0.;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FIMgx2qqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void FIMgx2qqxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<FIMgx2qqxDipoleKernel> FIMgx2qqxDipoleKernel::initFIMgx2qqxDipoleKernel;
 // Definition of the static class description member.
 
 void FIMgx2qqxDipoleKernel::Init() {
 
   static ClassDocumentation<FIMgx2qqxDipoleKernel> documentation
     ("FIMgx2qqxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/FIMgx2qqxDipoleKernel.h b/Shower/Dipole/Kernels/FIMgx2qqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FIMgx2qqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FIMgx2qqxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_FIMgx2qqxDipoleKernel_H
 #define HERWIG_FIMgx2qqxDipoleKernel_H
 //
 // This is the declaration of the FIMgx2qqxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer, Martin Stoll
  *
  * \brief FIMgx2qqxDipoleKernel implements the g -> qqbar
  * splitting off a final-initial dipole
  *
  */
 class FIMgx2qqxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   FIMgx2qqxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~FIMgx2qqxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<FIMgx2qqxDipoleKernel> initFIMgx2qqxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FIMgx2qqxDipoleKernel & operator=(const FIMgx2qqxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of FIMgx2qqxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::FIMgx2qqxDipoleKernel,1> {
   /** Typedef of the first base class of FIMgx2qqxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the FIMgx2qqxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::FIMgx2qqxDipoleKernel>
   : public ClassTraitsBase<Herwig::FIMgx2qqxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::FIMgx2qqxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * FIMgx2qqxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class FIMgx2qqxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_FIMgx2qqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FIMqx2qgxDipoleKernel.cc b/Shower/Dipole/Kernels/FIMqx2qgxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FIMqx2qgxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FIMqx2qgxDipoleKernel.cc
@@ -1,113 +1,155 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FIMqx2qgxDipoleKernel class.
 //
 
 #include "FIMqx2qgxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 FIMqx2qgxDipoleKernel::FIMqx2qgxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 FIMqx2qgxDipoleKernel::~FIMqx2qgxDipoleKernel() {}
 
 IBPtr FIMqx2qgxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FIMqx2qgxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool FIMqx2qgxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     abs(ind.emitterData()->id()) < 7 &&
     abs(ind.emitterData()->id())==abs(flavour()->id()) &&
     ind.emitterData()->mass() != ZERO &&
     ind.spectatorData()->mass() == ZERO &&
     !ind.initialStateEmitter() && ind.initialStateSpectator();
 }
 
 bool FIMqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     sk.emission(b)->id() == ParticleID::g &&
     abs(sk.emitter(b)->id()) < 7 &&
     sk.emitter(b)->mass() == emitter(a)->mass() &&
     a.spectatorPDF() == b.spectatorPDF();
 
 }
 
 
 tcPDPtr FIMqx2qgxDipoleKernel::emitter(const DipoleIndex& ind) const {
   assert(flavour());
   assert(abs(flavour()->id())<7 && flavour()->mass() != ZERO);
   return ind.emitterData()->id() > 0 ?
     (tcPDPtr) flavour() : (tcPDPtr) flavour()->CC();
 }
 
 tcPDPtr FIMqx2qgxDipoleKernel::emission(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr FIMqx2qgxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 // TODO
 // split.scale() should be sqrt(sbar) = sqrt( Mi2 - Q2 ) !!!
 double FIMqx2qgxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   // Mi=mi=mQ, m=0, Mj=mj=0
   Energy2 mQ2 = sqr(split.emitterMass());
 
   double z = split.lastZ();
   double x = 1. / ( 1. + 
 		    ( sqr(split.lastPt()) + sqr(1.-z)*mQ2 ) /
 		    ( z*(1.-z) * sqr(split.scale()) ) );
 
   // Simon has extra terms
   ret *= (!strictLargeN() ? 4./3. : 3./2.) *
     ( 2./(1.-z+(1.-x)) -(1.+z) - mQ2/sqr(split.scale()) * 2.*x/(1.-x) );
 
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+FIMqx2qgxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
+
+  // No dependence on the spin density matrix,
+  // dependence on off-diagonal terms cancels.
+  return {{ {0, 1.} }};
+}
+
+DecayMEPtr FIMqx2qgxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
+
+  double z = dInfo.lastZ();
+  Energy pt = dInfo.lastPt();
+  Energy mi = dInfo.emitterMass();
+  
+  // Altarelli-Parisi spin-indexed kernels:
+  Energy den = sqrt(sqr(mi)*sqr(1.-z) + sqr(pt));
+  double v_AP_ppp = pt / den / sqrt(1.-z);
+  double v_AP_ppm = - z * v_AP_ppp ;
+  double v_AP_pmp = mi*(1.-z)*sqrt(1.-z) / den ;
+
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = v_AP_pmp;
+  
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -1 or -1/2, 1=+1/2, 2 = +1
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
+  (*kernelPhiDep)(1,1,2) = v_AP_ppp/phase;
+  (*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
+  (*kernelPhiDep)(1,1,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,1,0) = v_AP_mpm;
+  (*kernelPhiDep)(1,0,2) = v_AP_pmp;
+  (*kernelPhiDep)(0,1,2) = 0.;
+  (*kernelPhiDep)(1,0,0) = 0.;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FIMqx2qgxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void FIMqx2qgxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<FIMqx2qgxDipoleKernel> FIMqx2qgxDipoleKernel::initFIMqx2qgxDipoleKernel;
 // Definition of the static class description member.
 
 void FIMqx2qgxDipoleKernel::Init() {
 
   static ClassDocumentation<FIMqx2qgxDipoleKernel> documentation
     ("FIMqx2qgxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/FIMqx2qgxDipoleKernel.h b/Shower/Dipole/Kernels/FIMqx2qgxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FIMqx2qgxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FIMqx2qgxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_FIMqx2qgxDipoleKernel_H
 #define HERWIG_FIMqx2qgxDipoleKernel_H
 //
 // This is the declaration of the FIMqx2qgxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer, Martin Stoll
  *
  * \brief FIMqx2qgxDipoleKernel implements the q -> qg
  * splitting off a final-initial dipole
  *
  */
 class FIMqx2qgxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   FIMqx2qgxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~FIMqx2qgxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<FIMqx2qgxDipoleKernel> initFIMqx2qgxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FIMqx2qgxDipoleKernel & operator=(const FIMqx2qgxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of FIMqx2qgxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::FIMqx2qgxDipoleKernel,1> {
   /** Typedef of the first base class of FIMqx2qgxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the FIMqx2qgxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::FIMqx2qgxDipoleKernel>
   : public ClassTraitsBase<Herwig::FIMqx2qgxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::FIMqx2qgxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * FIMqx2qgxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class FIMqx2qgxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_FIMqx2qgxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FIgx2ggxDipoleKernel.cc b/Shower/Dipole/Kernels/FIgx2ggxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FIgx2ggxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FIgx2ggxDipoleKernel.cc
@@ -1,116 +1,172 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FIgx2ggxDipoleKernel class.
 //
 
 #include "FIgx2ggxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Parameter.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 FIgx2ggxDipoleKernel::FIgx2ggxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 FIgx2ggxDipoleKernel::~FIgx2ggxDipoleKernel() {}
 
 IBPtr FIgx2ggxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FIgx2ggxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool FIgx2ggxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     ind.emitterData()->id() == ParticleID::g &&
     ind.spectatorData()->mass() == ZERO &&
     !ind.initialStateEmitter() && ind.initialStateSpectator();
 }
 
 bool FIgx2ggxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     sk.emitter(b)->id() == ParticleID::g &&
     sk.emission(b)->id() == ParticleID::g &&
     a.spectatorPDF() == b.spectatorPDF();
 
 }
 
 tcPDPtr FIgx2ggxDipoleKernel::emitter(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr FIgx2ggxDipoleKernel::emission(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr FIgx2ggxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double FIgx2ggxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   double z = split.lastZ();
   double x = 1. / ( 1. + sqr(split.lastPt()/split.scale()) / (z*(1.-z)) );
 
   double S1=1./(1.-z+(1.-x));
   double S2=1./(1.-(1.-z)+(1.-x));
   double NS=(-2 + z*(1.-z)+(1.-x)*(1.+x*z*(1.-z)));
   
   if( theAsymmetryOption == 0 ){
     ret *= 3.*( S1 + 0.5 * NS);
   }else if ( theAsymmetryOption == 1 ){
     ret *= 3.*z*( S1 +S2 + NS );
   }else{
     ret *= 3.*0.5*( S1 + S2 + NS );
   }
   
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+FIgx2ggxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
+
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
+  double v_AP_ppm = z*sqrt( z / (1.-z) );
+  double v_AP_pmp = (1.-z)*sqrt( (1.-z)/z );
+
+  //double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = -v_AP_pmp;
+  
+  // Initialise variables for the distributions
+  vector< pair<int, Complex> > distPhiDep;
+  double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp)) - 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp);
+  
+  distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp))/max ) );
+  distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) );
+  distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) );
+  
+  return distPhiDep;
+}
+
+DecayMEPtr FIgx2ggxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
+
+  double z = dInfo.lastZ();
+  
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
+  double v_AP_ppm = z*sqrt( z / (1.-z) );
+  double v_AP_pmp = (1.-z)*sqrt( (1.-z)/z );
+
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = -v_AP_pmp;
+  
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1,PDT::Spin1)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -, 2 = +
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
+  (*kernelPhiDep)(2,2,2) = v_AP_ppp/phase;
+  (*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
+  (*kernelPhiDep)(2,2,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
+  (*kernelPhiDep)(2,0,2) = v_AP_pmp*phase;
+  (*kernelPhiDep)(0,2,2) = 0;
+  (*kernelPhiDep)(2,0,0) = 0;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FIgx2ggxDipoleKernel::persistentOutput(PersistentOStream & os) const {
 
   os << theAsymmetryOption;
 }
 
 void FIgx2ggxDipoleKernel::persistentInput(PersistentIStream & is, int) {
   is >> theAsymmetryOption;
 }
 
 ClassDescription<FIgx2ggxDipoleKernel> FIgx2ggxDipoleKernel::initFIgx2ggxDipoleKernel;
 // Definition of the static class description member.
 
 void FIgx2ggxDipoleKernel::Init() {
 
   static ClassDocumentation<FIgx2ggxDipoleKernel> documentation
     ("FIgx2ggxDipoleKernel");
 
   static Parameter<FIgx2ggxDipoleKernel,int> interfacetheAsymmetryOption
   ("AsymmetryOption",
    "The asymmetry option for final state gluon spliitings.",
    &FIgx2ggxDipoleKernel::theAsymmetryOption, 1, 0, 0,
    false, false, Interface::lowerlim);
 }
 
diff --git a/Shower/Dipole/Kernels/FIgx2ggxDipoleKernel.h b/Shower/Dipole/Kernels/FIgx2ggxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FIgx2ggxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FIgx2ggxDipoleKernel.h
@@ -1,186 +1,197 @@
 // -*- C++ -*-
 #ifndef HERWIG_FIgx2ggxDipoleKernel_H
 #define HERWIG_FIgx2ggxDipoleKernel_H
 //
 // This is the declaration of the FIgx2ggxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer
  *
  * \brief FIgx2ggxDipoleKernel implements the g -> gg
  * splitting off a final-initial dipole
  *
  */
 class FIgx2ggxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   FIgx2ggxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~FIgx2ggxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
   /**
    * Asymmetry option for final state gluon splittings.
    */
   
   int theAsymmetryOption=1;
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<FIgx2ggxDipoleKernel> initFIgx2ggxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FIgx2ggxDipoleKernel & operator=(const FIgx2ggxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of FIgx2ggxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::FIgx2ggxDipoleKernel,1> {
   /** Typedef of the first base class of FIgx2ggxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the FIgx2ggxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::FIgx2ggxDipoleKernel>
   : public ClassTraitsBase<Herwig::FIgx2ggxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::FIgx2ggxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * FIgx2ggxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class FIgx2ggxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_FIgx2ggxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FIgx2qqxDipoleKernel.cc b/Shower/Dipole/Kernels/FIgx2qqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FIgx2qqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FIgx2qqxDipoleKernel.cc
@@ -1,103 +1,155 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FIgx2qqxDipoleKernel class.
 //
 
 #include "FIgx2qqxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 FIgx2qqxDipoleKernel::FIgx2qqxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 FIgx2qqxDipoleKernel::~FIgx2qqxDipoleKernel() {}
 
 IBPtr FIgx2qqxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FIgx2qqxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool FIgx2qqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     ind.emitterData()->id() == ParticleID::g &&
     ind.spectatorData()->mass() == ZERO &&
     flavour()->mass() == ZERO &&
     !ind.initialStateEmitter() && ind.initialStateSpectator();
 }
 
 bool FIgx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     sk.emitter(b)->id() + sk.emission(b)->id() == 0 &&
     abs(sk.emitter(b)->id()) < 6 &&
     // sk.emitter(b)->mass() == ZERO &&
     a.spectatorPDF() == b.spectatorPDF();
 
 }
 
 
 tcPDPtr FIgx2qqxDipoleKernel::emitter(const DipoleIndex&) const {
   assert(flavour());
   assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
   return flavour();
 }
 
 tcPDPtr FIgx2qqxDipoleKernel::emission(const DipoleIndex&) const {
   assert(flavour());
   assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
   return flavour()->CC();
 }
 
 tcPDPtr FIgx2qqxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double FIgx2qqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   double z = split.lastZ();
 
   ret *= .25 * (1.-2.*z*(1.-z));
 
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+FIgx2qqxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
+
+  double z = dInfo.lastZ();
+  
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppm = z;
+  double v_AP_pmp = -(1.-z);
+
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = -v_AP_pmp;
+
+  // Initialise variables for the distributions
+  vector< pair<int, Complex> > distPhiDep;
+  double max = (sqr(v_AP_ppm) + sqr(v_AP_pmp)) + 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp);
+  
+  distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*( sqr(v_AP_ppm) + sqr(v_AP_pmp) )/max ) );
+  distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) );
+  distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) );
+
+  return distPhiDep;
+}
+
+DecayMEPtr FIgx2qqxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
+  
+  double z = dInfo.lastZ();
+    
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppm = z;
+  double v_AP_pmp = -(1.-z);
+
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_mpm = -v_AP_pmp;
+
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1Half)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -, 2 = +
+  (*kernelPhiDep)(0,0,0) = 0.;
+  (*kernelPhiDep)(2,1,1) = 0.;
+  (*kernelPhiDep)(0,0,1) = v_AP_mmp/phase;
+  (*kernelPhiDep)(2,1,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,1,0) = v_AP_mpm/phase;
+  (*kernelPhiDep)(2,0,1) = v_AP_pmp*phase;
+  (*kernelPhiDep)(0,1,1) = 0.;
+  (*kernelPhiDep)(2,0,0) = 0.;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FIgx2qqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void FIgx2qqxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<FIgx2qqxDipoleKernel> FIgx2qqxDipoleKernel::initFIgx2qqxDipoleKernel;
 // Definition of the static class description member.
 
 void FIgx2qqxDipoleKernel::Init() {
 
   static ClassDocumentation<FIgx2qqxDipoleKernel> documentation
     ("FIgx2qqxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/FIgx2qqxDipoleKernel.h b/Shower/Dipole/Kernels/FIgx2qqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FIgx2qqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FIgx2qqxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_FIgx2qqxDipoleKernel_H
 #define HERWIG_FIgx2qqxDipoleKernel_H
 //
 // This is the declaration of the FIgx2qqxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer
  *
  * \brief FIgx2qqxDipoleKernel implements the g -> qqbar
  * splitting off a final-initial dipole
  *
  */
 class FIgx2qqxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   FIgx2qqxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~FIgx2qqxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<FIgx2qqxDipoleKernel> initFIgx2qqxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FIgx2qqxDipoleKernel & operator=(const FIgx2qqxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of FIgx2qqxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::FIgx2qqxDipoleKernel,1> {
   /** Typedef of the first base class of FIgx2qqxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the FIgx2qqxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::FIgx2qqxDipoleKernel>
   : public ClassTraitsBase<Herwig::FIgx2qqxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::FIgx2qqxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * FIgx2qqxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class FIgx2qqxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_FIgx2qqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FIqx2qgxDipoleKernel.cc b/Shower/Dipole/Kernels/FIqx2qgxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FIqx2qgxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FIqx2qgxDipoleKernel.cc
@@ -1,101 +1,138 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the FIqx2qgxDipoleKernel class.
 //
 
 #include "FIqx2qgxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 FIqx2qgxDipoleKernel::FIqx2qgxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 FIqx2qgxDipoleKernel::~FIqx2qgxDipoleKernel() {}
 
 IBPtr FIqx2qgxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FIqx2qgxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool FIqx2qgxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     abs(ind.emitterData()->id()) < 6 &&
     ind.emitterData()->mass() == ZERO &&
     ind.spectatorData()->mass() == ZERO &&
     !ind.initialStateEmitter() && ind.initialStateSpectator();
 }
 
 bool FIqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     sk.emission(b)->id() == ParticleID::g &&
     abs(sk.emitter(b)->id()) < 6 &&
     sk.emitter(b)->mass() == ZERO &&
     a.spectatorPDF() == b.spectatorPDF();
        
 
 }
 
 
 tcPDPtr FIqx2qgxDipoleKernel::emitter(const DipoleIndex& ind) const {
   return ind.emitterData();
 }
 
 tcPDPtr FIqx2qgxDipoleKernel::emission(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr FIqx2qgxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double FIqx2qgxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   double z = split.lastZ();
   double x = 1. / ( 1. + sqr(split.lastPt()/split.scale()) / (z*(1.-z)) );
 
   ret *= (!strictLargeN() ? 4./3. : 3./2.) * ( 2./(1.-z+(1.-x)) -(1.+z) + (1.-x)*(1.+3.*x*z) );
 
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+FIqx2qgxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
+
+  // No dependence on the spin density matrix,
+  // dependence on off-diagonal terms cancels.
+  return {{ {0, 1.} }};
+}
+
+DecayMEPtr FIqx2qgxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
+
+  double z = dInfo.lastZ();
+  
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = sqrt( 1./(1.-z) );
+  double v_AP_ppm = -z/sqrt(1.-z);
+
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -1 or -1/2, 1=+1/2, 2 = +1
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
+  (*kernelPhiDep)(1,1,2) = v_AP_ppp/phase;
+  (*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
+  (*kernelPhiDep)(1,1,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,1,0) = 0.;
+  (*kernelPhiDep)(1,0,2) = 0.;
+  (*kernelPhiDep)(0,1,2) = 0.;
+  (*kernelPhiDep)(1,0,0) = 0.;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FIqx2qgxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void FIqx2qgxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<FIqx2qgxDipoleKernel> FIqx2qgxDipoleKernel::initFIqx2qgxDipoleKernel;
 // Definition of the static class description member.
 
 void FIqx2qgxDipoleKernel::Init() {
 
   static ClassDocumentation<FIqx2qgxDipoleKernel> documentation
     ("FIqx2qgxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/FIqx2qgxDipoleKernel.h b/Shower/Dipole/Kernels/FIqx2qgxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FIqx2qgxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FIqx2qgxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_FIqx2qgxDipoleKernel_H
 #define HERWIG_FIqx2qgxDipoleKernel_H
 //
 // This is the declaration of the FIqx2qgxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer
  *
  * \brief FIqx2qgxDipoleKernel implements the q -> qg
  * splitting off a final-initial dipole
  *
  */
 class FIqx2qgxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   FIqx2qgxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~FIqx2qgxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<FIqx2qgxDipoleKernel> initFIqx2qgxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FIqx2qgxDipoleKernel & operator=(const FIqx2qgxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of FIqx2qgxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::FIqx2qgxDipoleKernel,1> {
   /** Typedef of the first base class of FIqx2qgxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the FIqx2qgxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::FIqx2qgxDipoleKernel>
   : public ClassTraitsBase<Herwig::FIqx2qgxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::FIqx2qgxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * FIqx2qgxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class FIqx2qgxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_FIqx2qgxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IFMgx2ggxDipoleKernel.cc b/Shower/Dipole/Kernels/IFMgx2ggxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IFMgx2ggxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IFMgx2ggxDipoleKernel.cc
@@ -1,109 +1,165 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the IFMgx2ggxDipoleKernel class.
 //
 
 #include "IFMgx2ggxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 IFMgx2ggxDipoleKernel::IFMgx2ggxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 IFMgx2ggxDipoleKernel::~IFMgx2ggxDipoleKernel() {}
 
 IBPtr IFMgx2ggxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr IFMgx2ggxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool IFMgx2ggxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     ind.emitterData()->id() == ParticleID::g &&
     ind.spectatorData()->mass() != ZERO &&
     ind.initialStateEmitter() && !ind.initialStateSpectator();
 }
 
 bool IFMgx2ggxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     sk.emitter(b)->id() == ParticleID::g &&
     sk.emission(b)->id() == ParticleID::g &&
     a.emitterPDF() == b.emitterPDF() &&
     sk.spectator(b)->mass() == spectator(a)->mass();
 
 }
 
 
 tcPDPtr IFMgx2ggxDipoleKernel::emitter(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr IFMgx2ggxDipoleKernel::emission(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr IFMgx2ggxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double IFMgx2ggxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   double z = split.lastZ();
   Energy pt = split.lastPt();
   double ratio = sqr(pt/split.scale());
   double muk2 = sqr(split.spectatorMass()/split.scale());
 
 	// Calculate x and u
     double rho = 1. - 4.*ratio*(1.-muk2)*z*(1.-z)/sqr(1.-z+ratio);
     double x = 0.5*((1.-z+ratio)/(ratio*(1.-muk2))) * (1. - sqrt(rho));
     double u = x*ratio / (1.-z);
 
 // NOTE - The definition of muk used in the kinematics differs from that in CS
 
     double muk2CS = x*muk2;
     ret *= 3. * ( 1./(1.-x+u) - 1. + x*(1.-x) + (1.-x)/x - muk2CS*u/(x*(1.-u)) );
 
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+IFMgx2ggxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
+
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
+  double v_AP_ppm = z*sqrt( z / (1.-z) );
+  double v_AP_mpm = -(1.-z)*sqrt( (1.-z)/z );
+
+  double v_AP_mmm = -v_AP_ppp;
+  //double v_AP_mmp = -v_AP_ppm;
+  double v_AP_pmp = -v_AP_mpm;
+
+  // Initialise variables for the distributions
+  vector< pair<int, Complex> > distPhiDep;
+  double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_mpm)) - 2.*abs(rho(0,2))*(v_AP_ppp*v_AP_pmp + v_AP_mmm*v_AP_mpm);
+
+  distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_mpm))/max ) );
+  distPhiDep.push_back( make_pair(2, rho(0,2)*(v_AP_mmm*v_AP_mpm + v_AP_pmp*v_AP_ppp)/max ) );
+  distPhiDep.push_back( make_pair(-2, rho(2,0)*(v_AP_ppp*v_AP_pmp + v_AP_mpm*v_AP_mmm)/max) );
+  
+  return distPhiDep;
+}
+
+DecayMEPtr IFMgx2ggxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
+
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
+  double v_AP_ppm = z*sqrt( z / (1.-z) );
+  double v_AP_mpm = -(1.-z)*sqrt( (1.-z)/z );
+
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_pmp = -v_AP_mpm;
+    
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1, PDT::Spin1, PDT::Spin1)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -, 2 = +
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
+  (*kernelPhiDep)(2,2,2) = v_AP_ppp/phase;
+  (*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
+  (*kernelPhiDep)(2,2,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
+  (*kernelPhiDep)(2,0,2) = v_AP_pmp*phase;
+  (*kernelPhiDep)(0,2,2) = 0;
+  (*kernelPhiDep)(2,0,0) = 0;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void IFMgx2ggxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void IFMgx2ggxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<IFMgx2ggxDipoleKernel> IFMgx2ggxDipoleKernel::initIFMgx2ggxDipoleKernel;
 // Definition of the static class description member.
 
 void IFMgx2ggxDipoleKernel::Init() {
 
   static ClassDocumentation<IFMgx2ggxDipoleKernel> documentation
     ("IFMgx2ggxDipoleKernelv");
 
 }
 
diff --git a/Shower/Dipole/Kernels/IFMgx2ggxDipoleKernel.h b/Shower/Dipole/Kernels/IFMgx2ggxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IFMgx2ggxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IFMgx2ggxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_IFMgx2ggxDipoleKernel_H
 #define HERWIG_IFMgx2ggxDipoleKernel_H
 //
 // This is the declaration of the IFMgx2ggxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer, Martin Stoll
  *
  * \brief IFMgx2ggxDipoleKernel implements the g -> gg
  * splitting off an initial-final dipole
  *
  */
 class IFMgx2ggxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   IFMgx2ggxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~IFMgx2ggxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<IFMgx2ggxDipoleKernel> initIFMgx2ggxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   IFMgx2ggxDipoleKernel & operator=(const IFMgx2ggxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of IFMgx2ggxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::IFMgx2ggxDipoleKernel,1> {
   /** Typedef of the first base class of IFMgx2ggxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the IFMgx2ggxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::IFMgx2ggxDipoleKernel>
   : public ClassTraitsBase<Herwig::IFMgx2ggxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::IFMgx2ggxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * IFMgx2ggxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class IFMgx2ggxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_IFMgx2ggxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IFMgx2qqxDipoleKernel.cc b/Shower/Dipole/Kernels/IFMgx2qqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IFMgx2qqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IFMgx2qqxDipoleKernel.cc
@@ -1,115 +1,168 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the IFMgx2qqxDipoleKernel class.
 //
 
 #include "IFMgx2qqxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 IFMgx2qqxDipoleKernel::IFMgx2qqxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 IFMgx2qqxDipoleKernel::~IFMgx2qqxDipoleKernel() {}
 
 IBPtr IFMgx2qqxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr IFMgx2qqxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool IFMgx2qqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     ind.emitterData()->id() == ParticleID::g &&
     ind.spectatorData()->mass() != ZERO &&
     flavour()->mass() == ZERO &&
     ind.initialStateEmitter() && !ind.initialStateSpectator();
 }
 
 bool IFMgx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     flavour() == sk.flavour() &&
     abs(flavour()->id()) < 6 &&
     flavour()->mass() == ZERO &&
     spectator(a)->mass() == sk.spectator(b)->mass() &&
     a.emitterPDF() == b.emitterPDF();
 
 }
 
 
 tcPDPtr IFMgx2qqxDipoleKernel::emitter(const DipoleIndex&) const {
   assert(flavour());
   assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
   return flavour();
 }
 
 tcPDPtr IFMgx2qqxDipoleKernel::emission(const DipoleIndex&) const {
   assert(flavour());
   assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
   return flavour();
 }
 
 tcPDPtr IFMgx2qqxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double IFMgx2qqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   double z = split.lastZ();
   Energy pt = split.lastPt();
   double ratio = sqr(pt/split.scale());
   double muk2 = sqr(split.spectatorMass()/split.scale());
   
 // Calculate x and u
   double rho = 1. - 4.*ratio*(1.-muk2)*z*(1.-z)/sqr(1.-z+ratio);
   double x = 0.5*((1.-z+ratio)/(ratio*(1.-muk2))) * (1. - sqrt(rho));
   double u = x*ratio / (1.-z);
 
   // NOTE - The definition of muk used in the kinematics differs from that in CS
     double muk2CS = x*muk2;
     ret *= 0.5 * (!strictLargeN() ? 4./3. : 3./2.) *
       ( x + 2.*(1.-x)/x - 2.*muk2CS/x*u/(1.-u) );
 
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+IFMgx2qqxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
+
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = sqrt(1./z);
+  double v_AP_mpm = (1.-z)/sqrt(z);
+
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_pmp = -v_AP_mpm;
+
+  // Initialise variables for the distributions
+  vector< pair<int, Complex> > distPhiDep;
+  double max = sqr(v_AP_ppp) + sqr(v_AP_mpm)
+    - 2.*abs(rho(0,2))*(v_AP_pmp*v_AP_ppp + v_AP_mmm*v_AP_mpm);
+
+  distPhiDep.push_back(make_pair( 0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_mpm))/max ) );
+  distPhiDep.push_back(make_pair( 2, rho(0,2)*(v_AP_pmp*v_AP_ppp + v_AP_mmm*v_AP_mpm )/max ) );
+  distPhiDep.push_back(make_pair( -2, rho(2,0)*(v_AP_ppp*v_AP_pmp + v_AP_mpm*v_AP_mmm )/max ) );
+
+  return distPhiDep;
+}
+
+DecayMEPtr IFMgx2qqxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
+
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = sqrt(1./z);
+  double v_AP_mpm = (1.-z)/sqrt(z);
+  
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_pmp = -v_AP_mpm;
+  
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half, PDT::Spin1, PDT::Spin1Half)));  
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -1 or -1/2, 1=+1/2, 2 = +1
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
+  (*kernelPhiDep)(1,2,1) = v_AP_ppp/phase;
+  (*kernelPhiDep)(0,0,1) = 0.;
+  (*kernelPhiDep)(1,2,0) = 0.;
+  (*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
+  (*kernelPhiDep)(1,0,1) = v_AP_pmp*phase;
+  (*kernelPhiDep)(0,2,1) = 0.;
+  (*kernelPhiDep)(1,0,0) = 0.;            
+  
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void IFMgx2qqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void IFMgx2qqxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<IFMgx2qqxDipoleKernel> IFMgx2qqxDipoleKernel::initIFMgx2qqxDipoleKernel;
 // Definition of the static class description member.
 
 void IFMgx2qqxDipoleKernel::Init() {
 
   static ClassDocumentation<IFMgx2qqxDipoleKernel> documentation
     ("IFMgx2qqxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/IFMgx2qqxDipoleKernel.h b/Shower/Dipole/Kernels/IFMgx2qqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IFMgx2qqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IFMgx2qqxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_IFMgx2qqxDipoleKernel_H
 #define HERWIG_IFMgx2qqxDipoleKernel_H
 //
 // This is the declaration of the IFgx2qqxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer, Martin Stoll
  *
  * \brief IFMgx2qqxDipoleKernel implements the g -> qq
  * splitting off an initial-final dipole
  *
  */
 class IFMgx2qqxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   IFMgx2qqxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~IFMgx2qqxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<IFMgx2qqxDipoleKernel> initIFMgx2qqxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   IFMgx2qqxDipoleKernel & operator=(const IFMgx2qqxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of IFMgx2qqxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::IFMgx2qqxDipoleKernel,1> {
   /** Typedef of the first base class of IFMgx2qqxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the IFMgx2qqxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::IFMgx2qqxDipoleKernel>
   : public ClassTraitsBase<Herwig::IFMgx2qqxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::IFMgx2qqxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * IFMgx2qqxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class IFMgx2qqxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_IFMgx2qqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IFMqx2gqxDipoleKernel.cc b/Shower/Dipole/Kernels/IFMqx2gqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IFMqx2gqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IFMqx2gqxDipoleKernel.cc
@@ -1,107 +1,144 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the IFMqx2gqxDipoleKernel class.
 //
 
 #include "IFMqx2gqxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 IFMqx2gqxDipoleKernel::IFMqx2gqxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 IFMqx2gqxDipoleKernel::~IFMqx2gqxDipoleKernel() {}
 
 IBPtr IFMqx2gqxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr IFMqx2gqxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool IFMqx2gqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     abs(ind.emitterData()->id()) < 6  &&
     ind.emitterData()->mass() == ZERO &&
     ind.spectatorData()->mass() != ZERO &&
     ind.initialStateEmitter() && !ind.initialStateSpectator();
 }
 
 bool IFMqx2gqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     a.emitterData() == b.emitterData() &&
     emitter(a) == sk.emitter(b) &&
     spectator(a)->mass() == sk.spectator(b)->mass() &&
     a.emitterPDF() == b.emitterPDF();
 
 }
 
 
 tcPDPtr IFMqx2gqxDipoleKernel::emitter(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr IFMqx2gqxDipoleKernel::emission(const DipoleIndex& ind) const {
   return ind.emitterData()->CC();
 }
 
 tcPDPtr IFMqx2gqxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double IFMqx2gqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   double z = split.lastZ();
   Energy pt = split.lastPt();
   double ratio = sqr(pt/split.scale());
   double muk2 = sqr(split.spectatorMass()/split.scale());
   
-// Calculate x
-    double rho = 1. - 4.*ratio*(1.-muk2)*z*(1.-z)/sqr(1.-z+ratio);
-    double x = 0.5*((1.-z+ratio)/(ratio*(1.-muk2))) * (1. - sqrt(rho));
-
+  // Calculate x
+  double rho = 1. - 4.*ratio*(1.-muk2)*z*(1.-z)/sqr(1.-z+ratio);
+  double x = 0.5*((1.-z+ratio)/(ratio*(1.-muk2))) * (1. - sqrt(rho));
 
   ret *= .5 * ( 1.-2.*x*(1.-x)  );
 
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+IFMqx2gqxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
+
+  // No dependence on the spin density matrix,
+  // dependence on off-diagonal terms cancels.
+  return {{ {0, 1.} }};
+}
+
+DecayMEPtr IFMqx2gqxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
+
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppm = z;
+  double v_AP_mpm = (1.-z);
+
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_pmp = -v_AP_mpm;
+    
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1, PDT::Spin1Half, PDT::Spin1Half)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -, 2 = +
+  (*kernelPhiDep)(0,0,0) = 0.;
+  (*kernelPhiDep)(2,1,1) = 0.;
+  (*kernelPhiDep)(0,0,1) = v_AP_mmp/phase;
+  (*kernelPhiDep)(2,1,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,1,0) = v_AP_mpm/phase;
+  (*kernelPhiDep)(2,0,1) = v_AP_pmp*phase;
+  (*kernelPhiDep)(0,1,1) = 0.;
+  (*kernelPhiDep)(2,0,0) = 0.;
+
+  return kernelPhiDep;
+}
+
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void IFMqx2gqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void IFMqx2gqxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<IFMqx2gqxDipoleKernel> IFMqx2gqxDipoleKernel::initIFMqx2gqxDipoleKernel;
 // Definition of the static class description member.
 
 void IFMqx2gqxDipoleKernel::Init() {
 
   static ClassDocumentation<IFMqx2gqxDipoleKernel> documentation
     ("IFMqx2gqxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/IFMqx2gqxDipoleKernel.h b/Shower/Dipole/Kernels/IFMqx2gqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IFMqx2gqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IFMqx2gqxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_IFMqx2gqxDipoleKernel_H
 #define HERWIG_IFMqx2gqxDipoleKernel_H
 //
 // This is the declaration of the IFqx2gqxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer, Martin Stoll
  *
  * \brief IFMqx2gqxDipoleKernel implements the q -> gqbar
  * splitting off an initial-final dipole
  *
  */
 class IFMqx2gqxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   IFMqx2gqxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~IFMqx2gqxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<IFMqx2gqxDipoleKernel> initIFMqx2gqxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   IFMqx2gqxDipoleKernel & operator=(const IFMqx2gqxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of IFMqx2gqxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::IFMqx2gqxDipoleKernel,1> {
   /** Typedef of the first base class of IFMqx2gqxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the IFMqx2gqxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::IFMqx2gqxDipoleKernel>
   : public ClassTraitsBase<Herwig::IFMqx2gqxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::IFMqx2gqxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * IFMqx2gqxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class IFMqx2gqxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_IFMqx2gqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IFMqx2qgxDipoleKernel.cc b/Shower/Dipole/Kernels/IFMqx2qgxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IFMqx2qgxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IFMqx2qgxDipoleKernel.cc
@@ -1,109 +1,147 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the IFMqx2qgxDipoleKernel class.
 //
 
 #include "IFMqx2qgxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 IFMqx2qgxDipoleKernel::IFMqx2qgxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 IFMqx2qgxDipoleKernel::~IFMqx2qgxDipoleKernel() {}
 
 IBPtr IFMqx2qgxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr IFMqx2qgxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool IFMqx2qgxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     abs(ind.emitterData()->id()) < 6  &&
     ind.emitterData()->mass() == ZERO &&
     ind.spectatorData()->mass() != ZERO &&
     ind.initialStateEmitter() && !ind.initialStateSpectator();
 }
 
 bool IFMqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     emitter(a) == sk.emitter(b) &&
     emission(a) == sk.emission(b) &&
     spectator(a)->mass() == sk.spectator(b)->mass() &&
     a.emitterPDF() == b.emitterPDF();
 
 }
 
 
 tcPDPtr IFMqx2qgxDipoleKernel::emitter(const DipoleIndex& ind) const {
   return ind.emitterData();
 }
 
 tcPDPtr IFMqx2qgxDipoleKernel::emission(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr IFMqx2qgxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double IFMqx2qgxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   double z = split.lastZ();
   Energy pt = split.lastPt();
   double ratio = sqr(pt/split.scale());
   double muk2 = sqr(split.spectatorMass()/split.scale());
 
 // Calculate x and u
     double rho = 1. - 4.*ratio*(1.-muk2)*z*(1.-z)/sqr(1.-z+ratio);
     double x = 0.5*((1.-z+ratio)/(ratio*(1.-muk2))) * (1. - sqrt(rho));
     double u = x*ratio / (1.-z);
   
 // 19/01/2017 - SW: Removed finite term as its effect on
 // the ratio of -ve/+ve kernels is small
     ret *= (!strictLargeN() ? 4./3. : 3./2.) * ( 2./(1.-x+u) - (1.+x) );
 
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+IFMqx2qgxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
+
+  // No dependence on the spin density matrix,
+  // dependence on off-diagonal terms cancels.
+  return {{ {0, 1.} }};
+}
+
+DecayMEPtr IFMqx2qgxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
+
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = sqrt( 1./(1.-z) );
+  double v_AP_ppm = -z/sqrt(1.-z);
+
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half, PDT::Spin1Half, PDT::Spin1)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -, 2 = +
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
+  (*kernelPhiDep)(1,1,2) = v_AP_ppp/phase;
+  (*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
+  (*kernelPhiDep)(1,1,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,1,0) = 0.;
+  (*kernelPhiDep)(1,0,2) = 0.;
+  (*kernelPhiDep)(0,1,2) = 0.;
+  (*kernelPhiDep)(1,0,0) = 0.;
+  
+  return kernelPhiDep;
+}
+
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void IFMqx2qgxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void IFMqx2qgxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<IFMqx2qgxDipoleKernel> IFMqx2qgxDipoleKernel::initIFMqx2qgxDipoleKernel;
 // Definition of the static class description member.
 
 void IFMqx2qgxDipoleKernel::Init() {
 
   static ClassDocumentation<IFMqx2qgxDipoleKernel> documentation
     ("IFMqx2qgxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/IFMqx2qgxDipoleKernel.h b/Shower/Dipole/Kernels/IFMqx2qgxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IFMqx2qgxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IFMqx2qgxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_IFMqx2qgxDipoleKernel_H
 #define HERWIG_IFMqx2qgxDipoleKernel_H
 //
 // This is the declaration of the IFqx2qgxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer, Martin Stoll
  *
  * \brief IFMqx2qgxDipoleKernel implements the q -> qg
  * splitting off an initial-final dipole
  *
  */
 class IFMqx2qgxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   IFMqx2qgxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~IFMqx2qgxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<IFMqx2qgxDipoleKernel> initIFMqx2qgxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   IFMqx2qgxDipoleKernel & operator=(const IFMqx2qgxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of IFMqx2qgxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::IFMqx2qgxDipoleKernel,1> {
   /** Typedef of the first base class of IFMqx2qgxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the IFMqx2qgxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::IFMqx2qgxDipoleKernel>
   : public ClassTraitsBase<Herwig::IFMqx2qgxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::IFMqx2qgxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * IFMqx2qgxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class IFMqx2qgxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_IFMqx2qgxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IFgx2ggxDipoleKernel.cc b/Shower/Dipole/Kernels/IFgx2ggxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IFgx2ggxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IFgx2ggxDipoleKernel.cc
@@ -1,102 +1,158 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the IFgx2ggxDipoleKernel class.
 //
 
 #include "IFgx2ggxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 IFgx2ggxDipoleKernel::IFgx2ggxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 IFgx2ggxDipoleKernel::~IFgx2ggxDipoleKernel() {}
 
 IBPtr IFgx2ggxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr IFgx2ggxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool IFgx2ggxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     ind.emitterData()->id() == ParticleID::g &&
     ind.spectatorData()->mass() == ZERO &&
     ind.initialStateEmitter() && !ind.initialStateSpectator();
 }
 
 bool IFgx2ggxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     sk.emitter(b)->id() == ParticleID::g &&
     sk.emission(b)->id() == ParticleID::g &&
     a.emitterPDF() == b.emitterPDF();
 
 }
 
 
 tcPDPtr IFgx2ggxDipoleKernel::emitter(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr IFgx2ggxDipoleKernel::emission(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr IFgx2ggxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double IFgx2ggxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   double z = split.lastZ();
   double ratio = sqr(split.lastPt()/split.scale());
 
   double rho = 1. - 4.*ratio*z*(1.-z)/sqr(1.-z+ratio);
   double x = 0.5*((1.-z+ratio)/ratio)*(1.-sqrt(rho));
   double u = 0.5*((1.-z+ratio)/(1.-z))*(1.-sqrt(rho));
 
   ret *= 3. * ( 1./(1.-x+u) + (1.-x)/x - 1. + x*(1.-x) );
 
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+IFgx2ggxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
+
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
+  double v_AP_ppm = z*sqrt( z / (1.-z) );
+  double v_AP_mpm = -(1.-z)*sqrt( (1.-z)/z );
+
+  double v_AP_mmm = -v_AP_ppp;
+  //double v_AP_mmp = -v_AP_ppm;
+  double v_AP_pmp = -v_AP_mpm;
+
+  // Initialise variables for the distributions
+  vector< pair<int, Complex> > distPhiDep;
+  double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_mpm)) - 2.*abs(rho(0,2))*(v_AP_ppp*v_AP_pmp + v_AP_mmm*v_AP_mpm);
+
+  distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_mpm))/max ) );
+  distPhiDep.push_back( make_pair(2, rho(0,2)*(v_AP_mmm*v_AP_mpm + v_AP_pmp*v_AP_ppp)/max ) );
+  distPhiDep.push_back( make_pair(-2, rho(2,0)*(v_AP_ppp*v_AP_pmp + v_AP_mpm*v_AP_mmm)/max) );
+  
+  return distPhiDep;
+}
+
+DecayMEPtr IFgx2ggxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
+
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
+  double v_AP_ppm = z*sqrt( z / (1.-z) );
+  double v_AP_mpm = -(1.-z)*sqrt( (1.-z)/z );
+
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_pmp = -v_AP_mpm;
+    
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1, PDT::Spin1, PDT::Spin1)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -, 2 = +
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
+  (*kernelPhiDep)(2,2,2) = v_AP_ppp/phase;
+  (*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
+  (*kernelPhiDep)(2,2,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
+  (*kernelPhiDep)(2,0,2) = v_AP_pmp*phase;
+  (*kernelPhiDep)(0,2,2) = 0;
+  (*kernelPhiDep)(2,0,0) = 0;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void IFgx2ggxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void IFgx2ggxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<IFgx2ggxDipoleKernel> IFgx2ggxDipoleKernel::initIFgx2ggxDipoleKernel;
 // Definition of the static class description member.
 
 void IFgx2ggxDipoleKernel::Init() {
 
   static ClassDocumentation<IFgx2ggxDipoleKernel> documentation
     ("IFgx2ggxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/IFgx2ggxDipoleKernel.h b/Shower/Dipole/Kernels/IFgx2ggxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IFgx2ggxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IFgx2ggxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_IFgx2ggxDipoleKernel_H
 #define HERWIG_IFgx2ggxDipoleKernel_H
 //
 // This is the declaration of the IFgx2ggxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer
  *
  * \brief IFgx2ggxDipoleKernel implements the g -> gg
  * splitting off an initial-final dipole
  *
  */
 class IFgx2ggxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   IFgx2ggxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~IFgx2ggxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<IFgx2ggxDipoleKernel> initIFgx2ggxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   IFgx2ggxDipoleKernel & operator=(const IFgx2ggxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of IFgx2ggxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::IFgx2ggxDipoleKernel,1> {
   /** Typedef of the first base class of IFgx2ggxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the IFgx2ggxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::IFgx2ggxDipoleKernel>
   : public ClassTraitsBase<Herwig::IFgx2ggxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::IFgx2ggxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * IFgx2ggxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class IFgx2ggxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_IFgx2ggxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IFgx2qqxDipoleKernel.cc b/Shower/Dipole/Kernels/IFgx2qqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IFgx2qqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IFgx2qqxDipoleKernel.cc
@@ -1,107 +1,160 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the IFgx2qqxDipoleKernel class.
 //
 
 #include "IFgx2qqxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 IFgx2qqxDipoleKernel::IFgx2qqxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 IFgx2qqxDipoleKernel::~IFgx2qqxDipoleKernel() {}
 
 IBPtr IFgx2qqxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr IFgx2qqxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool IFgx2qqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     ind.emitterData()->id() == ParticleID::g &&
     ind.spectatorData()->mass() == ZERO &&
     flavour()->mass() == ZERO &&
     ind.initialStateEmitter() && !ind.initialStateSpectator();
 }
 
 bool IFgx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     flavour() == sk.flavour() &&
     abs(flavour()->id()) < 6 &&
     flavour()->mass() == ZERO &&
     a.emitterPDF() == b.emitterPDF();
 
 }
 
 
 tcPDPtr IFgx2qqxDipoleKernel::emitter(const DipoleIndex&) const {
   assert(flavour());
   assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
   return flavour();
 }
 
 tcPDPtr IFgx2qqxDipoleKernel::emission(const DipoleIndex&) const {
   assert(flavour());
   assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
   return flavour();
 }
 
 tcPDPtr IFgx2qqxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double IFgx2qqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   double z = split.lastZ();
   double ratio = sqr(split.lastPt()/split.scale());
 
   double rho = 1. - 4.*ratio*z*(1.-z)/sqr(1.-z+ratio);
   double x = 0.5*((1.-z+ratio)/ratio)*(1.-sqrt(rho));
 
   ret *= 0.5 * (!strictLargeN() ? 4./3. : 3./2.) * ( x + 2.*(1.-x)/x );
 
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+IFgx2qqxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
+
+  double z = dInfo.lastZ();
+  
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = sqrt(1./z);
+  double v_AP_mpm = (1.-z)/sqrt(z);
+
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_pmp = -v_AP_mpm;
+
+  // Initialise variables for the distributions
+  vector< pair<int, Complex> > distPhiDep;
+  double max = sqr(v_AP_ppp) + sqr(v_AP_mpm)
+    - 2.*abs(rho(0,2))*(v_AP_pmp*v_AP_ppp + v_AP_mmm*v_AP_mpm);
+
+  distPhiDep.push_back(make_pair( 0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_mpm))/max ) );
+  distPhiDep.push_back(make_pair( 2, rho(0,2)*(v_AP_pmp*v_AP_ppp + v_AP_mmm*v_AP_mpm )/max ) );
+  distPhiDep.push_back(make_pair( -2, rho(2,0)*(v_AP_ppp*v_AP_pmp + v_AP_mpm*v_AP_mmm )/max ) );
+
+  return distPhiDep;
+}
+
+DecayMEPtr IFgx2qqxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
+
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = sqrt(1./z);
+  double v_AP_mpm = (1.-z)/sqrt(z);
+  
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_pmp = -v_AP_mpm;
+  
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half, PDT::Spin1, PDT::Spin1Half)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -1 or -1/2, 1=+1/2, 2 = +1
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
+  (*kernelPhiDep)(1,2,1) = v_AP_ppp/phase;
+  (*kernelPhiDep)(0,0,1) = 0.;
+  (*kernelPhiDep)(1,2,0) = 0.;
+  (*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
+  (*kernelPhiDep)(1,0,1) = v_AP_pmp*phase;
+  (*kernelPhiDep)(0,2,1) = 0.;
+  (*kernelPhiDep)(1,0,0) = 0.;            
+  
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void IFgx2qqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void IFgx2qqxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<IFgx2qqxDipoleKernel> IFgx2qqxDipoleKernel::initIFgx2qqxDipoleKernel;
 // Definition of the static class description member.
 
 void IFgx2qqxDipoleKernel::Init() {
 
   static ClassDocumentation<IFgx2qqxDipoleKernel> documentation
     ("IFgx2qqxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/IFgx2qqxDipoleKernel.h b/Shower/Dipole/Kernels/IFgx2qqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IFgx2qqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IFgx2qqxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_IFgx2qqxDipoleKernel_H
 #define HERWIG_IFgx2qqxDipoleKernel_H
 //
 // This is the declaration of the IFgx2qqxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer
  *
  * \brief IFgx2qqxDipoleKernel implements the g -> qq
  * splitting off an initial-final dipole
  *
  */
 class IFgx2qqxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   IFgx2qqxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~IFgx2qqxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<IFgx2qqxDipoleKernel> initIFgx2qqxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   IFgx2qqxDipoleKernel & operator=(const IFgx2qqxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of IFgx2qqxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::IFgx2qqxDipoleKernel,1> {
   /** Typedef of the first base class of IFgx2qqxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the IFgx2qqxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::IFgx2qqxDipoleKernel>
   : public ClassTraitsBase<Herwig::IFgx2qqxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::IFgx2qqxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * IFgx2qqxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class IFgx2qqxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_IFgx2qqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IFqx2gqxDipoleKernel.cc b/Shower/Dipole/Kernels/IFqx2gqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IFqx2gqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IFqx2gqxDipoleKernel.cc
@@ -1,102 +1,139 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the IFqx2gqxDipoleKernel class.
 //
 
 #include "IFqx2gqxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 IFqx2gqxDipoleKernel::IFqx2gqxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 IFqx2gqxDipoleKernel::~IFqx2gqxDipoleKernel() {}
 
 IBPtr IFqx2gqxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr IFqx2gqxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool IFqx2gqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     abs(ind.emitterData()->id()) < 6  &&
     ind.emitterData()->mass() == ZERO &&
     ind.spectatorData()->mass() == ZERO &&
     ind.initialStateEmitter() && !ind.initialStateSpectator();
 }
 
 bool IFqx2gqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     a.emitterData() == b.emitterData() &&
     emitter(a) == sk.emitter(b) &&
     a.emitterPDF() == b.emitterPDF();
 
 }
 
 
 tcPDPtr IFqx2gqxDipoleKernel::emitter(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr IFqx2gqxDipoleKernel::emission(const DipoleIndex& ind) const {
   return ind.emitterData()->CC();
 }
 
 tcPDPtr IFqx2gqxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double IFqx2gqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   double z = split.lastZ();
   double ratio = sqr(split.lastPt()/split.scale());
 
   double rho = 1. - 4.*ratio*z*(1.-z)/sqr(1.-z+ratio);
   double x = 0.5*((1.-z+ratio)/ratio)*(1.-sqrt(rho));
 
   ret *= .5 * ( 1.-2.*x*(1.-x)  );
 
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+IFqx2gqxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
+
+  // No dependence on the spin density matrix,
+  // dependence on off-diagonal terms cancels.
+  return {{ {0, 1.} }};
+}
+
+DecayMEPtr IFqx2gqxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
+
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppm = z;
+  double v_AP_mpm = (1.-z);
+  
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_pmp = -v_AP_mpm;
+    
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1, PDT::Spin1Half, PDT::Spin1Half)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -, 2 = +
+  (*kernelPhiDep)(0,0,0) = 0.;
+  (*kernelPhiDep)(2,1,1) = 0.;
+  (*kernelPhiDep)(0,0,1) = v_AP_mmp/phase;
+  (*kernelPhiDep)(2,1,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,1,0) = v_AP_mpm/phase;
+  (*kernelPhiDep)(2,0,1) = v_AP_pmp*phase;
+  (*kernelPhiDep)(0,1,1) = 0.;
+  (*kernelPhiDep)(2,0,0) = 0.;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void IFqx2gqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void IFqx2gqxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<IFqx2gqxDipoleKernel> IFqx2gqxDipoleKernel::initIFqx2gqxDipoleKernel;
 // Definition of the static class description member.
 
 void IFqx2gqxDipoleKernel::Init() {
 
   static ClassDocumentation<IFqx2gqxDipoleKernel> documentation
     ("IFqx2gqxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/IFqx2gqxDipoleKernel.h b/Shower/Dipole/Kernels/IFqx2gqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IFqx2gqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IFqx2gqxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_IFqx2gqxDipoleKernel_H
 #define HERWIG_IFqx2gqxDipoleKernel_H
 //
 // This is the declaration of the IFqx2gqxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer
  *
  * \brief IFqx2gqxDipoleKernel implements the q -> gqbar
  * splitting off an initial-final dipole
  *
  */
 class IFqx2gqxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   IFqx2gqxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~IFqx2gqxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<IFqx2gqxDipoleKernel> initIFqx2gqxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   IFqx2gqxDipoleKernel & operator=(const IFqx2gqxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of IFqx2gqxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::IFqx2gqxDipoleKernel,1> {
   /** Typedef of the first base class of IFqx2gqxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the IFqx2gqxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::IFqx2gqxDipoleKernel>
   : public ClassTraitsBase<Herwig::IFqx2gqxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::IFqx2gqxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * IFqx2gqxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class IFqx2gqxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_IFqx2gqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IFqx2qgxDipoleKernel.cc b/Shower/Dipole/Kernels/IFqx2qgxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IFqx2qgxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IFqx2qgxDipoleKernel.cc
@@ -1,103 +1,140 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the IFqx2qgxDipoleKernel class.
 //
 
 #include "IFqx2qgxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 IFqx2qgxDipoleKernel::IFqx2qgxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 IFqx2qgxDipoleKernel::~IFqx2qgxDipoleKernel() {}
 
 IBPtr IFqx2qgxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr IFqx2qgxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool IFqx2qgxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     abs(ind.emitterData()->id()) < 6  &&
     ind.emitterData()->mass() == ZERO &&
     ind.spectatorData()->mass() == ZERO &&
     ind.initialStateEmitter() && !ind.initialStateSpectator();
 }
 
 bool IFqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     emitter(a) == sk.emitter(b) &&
     emission(a) == sk.emission(b) &&
     a.emitterPDF() == b.emitterPDF();
 
 }
 
 
 tcPDPtr IFqx2qgxDipoleKernel::emitter(const DipoleIndex& ind) const {
   return ind.emitterData();
 }
 
 tcPDPtr IFqx2qgxDipoleKernel::emission(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr IFqx2qgxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double IFqx2qgxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   double z = split.lastZ();
   double ratio = sqr(split.lastPt()/split.scale());
 
   double rho = 1. - 4.*ratio*z*(1.-z)/sqr(1.-z+ratio);
   double x = 0.5*((1.-z+ratio)/ratio)*(1.-sqrt(rho));
   double u = 0.5*((1.-z+ratio)/(1.-z))*(1.-sqrt(rho));
 
   ret *= (!strictLargeN() ? 4./3. : 3./2.) * ( 2./(1.-x+u) - (1.+x) + u*(1.+3.*x*(1.-u) ) );
 
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+IFqx2qgxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
+
+  // No dependence on the spin density matrix,
+  // dependence on off-diagonal terms cancels.
+  return {{ {0, 1.} }};
+}
+
+DecayMEPtr IFqx2qgxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
+
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = sqrt( 1./(1.-z) );
+  double v_AP_ppm = -z/sqrt(1.-z);
+
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half, PDT::Spin1Half, PDT::Spin1)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -, 2 = +
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
+  (*kernelPhiDep)(1,1,2) = v_AP_ppp/phase;
+  (*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
+  (*kernelPhiDep)(1,1,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,1,0) = 0.;
+  (*kernelPhiDep)(1,0,2) = 0.;
+  (*kernelPhiDep)(0,1,2) = 0.;
+  (*kernelPhiDep)(1,0,0) = 0.;
+  
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void IFqx2qgxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void IFqx2qgxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<IFqx2qgxDipoleKernel> IFqx2qgxDipoleKernel::initIFqx2qgxDipoleKernel;
 // Definition of the static class description member.
 
 void IFqx2qgxDipoleKernel::Init() {
 
   static ClassDocumentation<IFqx2qgxDipoleKernel> documentation
     ("IFqx2qgxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/IFqx2qgxDipoleKernel.h b/Shower/Dipole/Kernels/IFqx2qgxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IFqx2qgxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IFqx2qgxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_IFqx2qgxDipoleKernel_H
 #define HERWIG_IFqx2qgxDipoleKernel_H
 //
 // This is the declaration of the IFqx2qgxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer
  *
  * \brief IFqx2qgxDipoleKernel implements the q -> qg
  * splitting off an initial-final dipole
  *
  */
 class IFqx2qgxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   IFqx2qgxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~IFqx2qgxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<IFqx2qgxDipoleKernel> initIFqx2qgxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   IFqx2qgxDipoleKernel & operator=(const IFqx2qgxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of IFqx2qgxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::IFqx2qgxDipoleKernel,1> {
   /** Typedef of the first base class of IFqx2qgxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the IFqx2qgxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::IFqx2qgxDipoleKernel>
   : public ClassTraitsBase<Herwig::IFqx2qgxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::IFqx2qgxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * IFqx2qgxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class IFqx2qgxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_IFqx2qgxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IIgx2ggxDipoleKernel.cc b/Shower/Dipole/Kernels/IIgx2ggxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IIgx2ggxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IIgx2ggxDipoleKernel.cc
@@ -1,101 +1,160 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the IIgx2ggxDipoleKernel class.
 //
 
 #include "IIgx2ggxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 IIgx2ggxDipoleKernel::IIgx2ggxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 IIgx2ggxDipoleKernel::~IIgx2ggxDipoleKernel() {}
 
 IBPtr IIgx2ggxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr IIgx2ggxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool IIgx2ggxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     ind.emitterData()->id() == ParticleID::g &&
     ind.spectatorData()->mass() == ZERO &&
     ind.initialStateEmitter() && ind.initialStateSpectator();
 }
 
 bool IIgx2ggxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     sk.emitter(b)->id() == ParticleID::g &&
     sk.emission(b)->id() == ParticleID::g &&
     a.emitterPDF() == b.emitterPDF() &&
     a.spectatorData() == b.spectatorData() &&
     a.spectatorPDF() == b.spectatorPDF();
 
 }
 
 
 tcPDPtr IIgx2ggxDipoleKernel::emitter(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr IIgx2ggxDipoleKernel::emission(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr IIgx2ggxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double IIgx2ggxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   double z = split.lastZ();
   double ratio = sqr(split.lastPt()/split.scale());
+
   double x = z*(1.-z)/(1.-z+ratio);
 
   ret *= 3. * ( x/(1.-x) + (1.-x)/x +x*(1.-x) );
 
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+IIgx2ggxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
+
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
+  double v_AP_ppm = z*sqrt( z / (1.-z) );
+  double v_AP_mpm = -(1.-z)*sqrt( (1.-z)/z );
+
+  double v_AP_mmm = -v_AP_ppp;
+  //double v_AP_mmp = -v_AP_ppm;
+  double v_AP_pmp = -v_AP_mpm;
+  
+  // Initialise variables for the distributions
+  vector< pair<int, Complex> > distPhiDep;
+  double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_mpm))
+    - 2.*abs(rho(0,2))*(v_AP_ppp*v_AP_pmp + v_AP_mmm*v_AP_mpm);
+
+  distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*
+                                  (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_mpm))/max ) );
+  distPhiDep.push_back( make_pair(2, rho(0,2)*(v_AP_mmm*v_AP_mpm + v_AP_pmp*v_AP_ppp)/max ) );
+  distPhiDep.push_back( make_pair(-2, rho(2,0)*(v_AP_ppp*v_AP_pmp + v_AP_mpm*v_AP_mmm)/max) );
+
+  return distPhiDep;
+}
+
+DecayMEPtr IIgx2ggxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
+
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
+  double v_AP_ppm = z*sqrt( z / (1.-z) );
+  double v_AP_mpm = -(1.-z)*sqrt( (1.-z)/z );
+
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_pmp = -v_AP_mpm;
+    
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1, PDT::Spin1, PDT::Spin1)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -, 2 = +
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
+  (*kernelPhiDep)(2,2,2) = v_AP_ppp/phase;
+  (*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
+  (*kernelPhiDep)(2,2,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
+  (*kernelPhiDep)(2,0,2) = v_AP_pmp*phase;
+  (*kernelPhiDep)(0,2,2) = 0;
+  (*kernelPhiDep)(2,0,0) = 0;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void IIgx2ggxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void IIgx2ggxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<IIgx2ggxDipoleKernel> IIgx2ggxDipoleKernel::initIIgx2ggxDipoleKernel;
 // Definition of the static class description member.
 
 void IIgx2ggxDipoleKernel::Init() {
 
   static ClassDocumentation<IIgx2ggxDipoleKernel> documentation
     ("IIgx2ggxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/IIgx2ggxDipoleKernel.h b/Shower/Dipole/Kernels/IIgx2ggxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IIgx2ggxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IIgx2ggxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_IIgx2ggxDipoleKernel_H
 #define HERWIG_IIgx2ggxDipoleKernel_H
 //
 // This is the declaration of the IIgx2ggxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer
  *
  * \brief IIgx2ggxDipoleKernel implements the g -> gg
  * splitting off an initial-initial dipole
  *
  */
 class IIgx2ggxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   IIgx2ggxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~IIgx2ggxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
-
+  
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<IIgx2ggxDipoleKernel> initIIgx2ggxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   IIgx2ggxDipoleKernel & operator=(const IIgx2ggxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of IIgx2ggxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::IIgx2ggxDipoleKernel,1> {
   /** Typedef of the first base class of IIgx2ggxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the IIgx2ggxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::IIgx2ggxDipoleKernel>
   : public ClassTraitsBase<Herwig::IIgx2ggxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::IIgx2ggxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * IIgx2ggxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class IIgx2ggxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_IIgx2ggxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IIgx2qqxDipoleKernel.cc b/Shower/Dipole/Kernels/IIgx2qqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IIgx2qqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IIgx2qqxDipoleKernel.cc
@@ -1,107 +1,161 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the IIgx2qqxDipoleKernel class.
 //
 
 #include "IIgx2qqxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 IIgx2qqxDipoleKernel::IIgx2qqxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 IIgx2qqxDipoleKernel::~IIgx2qqxDipoleKernel() {}
 
 IBPtr IIgx2qqxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr IIgx2qqxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool IIgx2qqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     ind.emitterData()->id() == ParticleID::g &&
     ind.spectatorData()->mass() == ZERO &&
     flavour()->mass() == ZERO &&
     ind.initialStateEmitter() && ind.initialStateSpectator();
 }
 
 bool IIgx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     flavour() == sk.flavour() &&
     abs(flavour()->id()) < 6 &&
     flavour()->mass() == ZERO &&
     a.emitterPDF() == b.emitterPDF() &&
     a.spectatorData() == b.spectatorData() &&
     a.spectatorPDF() == b.spectatorPDF();
 
 }
 
 
 tcPDPtr IIgx2qqxDipoleKernel::emitter(const DipoleIndex&) const {
   assert(flavour());
   assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
   return flavour();
 }
 
 tcPDPtr IIgx2qqxDipoleKernel::emission(const DipoleIndex&) const {
   assert(flavour());
   assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
   return flavour();
 }
 
 tcPDPtr IIgx2qqxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double IIgx2qqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   double z = split.lastZ();
   double ratio = sqr(split.lastPt()/split.scale());
+
   double x = z*(1.-z)/(1.-z+ratio);
 
   ret *= 0.5 * (!strictLargeN() ? 4./3. : 3./2.) * ( 1./x +sqr(1.-x)/x );
 
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+IIgx2qqxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
+  
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = sqrt(1./z);
+  double v_AP_mpm = (1.-z)/sqrt(z);
+
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_pmp = -v_AP_mpm;
+    
+  // Initialise variables for the distributions
+  vector< pair<int, Complex> > distPhiDep;  
+  double max = sqr(v_AP_ppp) + sqr(v_AP_mpm)
+    - 2.*abs(rho(0,2))*(v_AP_pmp*v_AP_ppp + v_AP_mmm*v_AP_mpm);
+
+  distPhiDep.push_back(make_pair( 0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_mpm))/max ) );
+  distPhiDep.push_back(make_pair( 2, rho(0,2)*(v_AP_pmp*v_AP_ppp + v_AP_mmm*v_AP_mpm )/max ) );
+  distPhiDep.push_back(make_pair( -2, rho(2,0)*(v_AP_ppp*v_AP_pmp + v_AP_mpm*v_AP_mmm )/max ) );
+
+  return distPhiDep;
+}
+
+DecayMEPtr IIgx2qqxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
+
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = sqrt(1./z);
+  double v_AP_mpm = (1.-z)/sqrt(z);
+  
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_pmp = -v_AP_mpm;
+  
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half, PDT::Spin1, PDT::Spin1Half)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -1 or -1/2, 1=+1/2, 2 = +1
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
+  (*kernelPhiDep)(1,2,1) = v_AP_ppp/phase;
+  (*kernelPhiDep)(0,0,1) = 0.;
+  (*kernelPhiDep)(1,2,0) = 0.;
+  (*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
+  (*kernelPhiDep)(1,0,1) = v_AP_pmp*phase;
+  (*kernelPhiDep)(0,2,1) = 0.;
+  (*kernelPhiDep)(1,0,0) = 0.;            
+  
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void IIgx2qqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void IIgx2qqxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<IIgx2qqxDipoleKernel> IIgx2qqxDipoleKernel::initIIgx2qqxDipoleKernel;
 // Definition of the static class description member.
 
 void IIgx2qqxDipoleKernel::Init() {
 
   static ClassDocumentation<IIgx2qqxDipoleKernel> documentation
     ("IIgx2qqxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/IIgx2qqxDipoleKernel.h b/Shower/Dipole/Kernels/IIgx2qqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IIgx2qqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IIgx2qqxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_IIgx2qqxDipoleKernel_H
 #define HERWIG_IIgx2qqxDipoleKernel_H
 //
 // This is the declaration of the IIgx2qqxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer
  *
  * \brief IIgx2qqxDipoleKernel implements the g -> qq
  * splitting off an initial-initial dipole
  *
  */
 class IIgx2qqxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   IIgx2qqxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~IIgx2qqxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<IIgx2qqxDipoleKernel> initIIgx2qqxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   IIgx2qqxDipoleKernel & operator=(const IIgx2qqxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of IIgx2qqxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::IIgx2qqxDipoleKernel,1> {
   /** Typedef of the first base class of IIgx2qqxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the IIgx2qqxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::IIgx2qqxDipoleKernel>
   : public ClassTraitsBase<Herwig::IIgx2qqxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::IIgx2qqxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * IIgx2qqxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class IIgx2qqxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_IIgx2qqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IIqx2gqxDipoleKernel.cc b/Shower/Dipole/Kernels/IIqx2gqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IIqx2gqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IIqx2gqxDipoleKernel.cc
@@ -1,102 +1,140 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the IIqx2gqxDipoleKernel class.
 //
 
 #include "IIqx2gqxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 IIqx2gqxDipoleKernel::IIqx2gqxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 IIqx2gqxDipoleKernel::~IIqx2gqxDipoleKernel() {}
 
 IBPtr IIqx2gqxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr IIqx2gqxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool IIqx2gqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     abs(ind.emitterData()->id()) < 6  &&
     ind.emitterData()->mass() == ZERO &&
     ind.spectatorData()->mass() == ZERO &&
     ind.initialStateEmitter() && ind.initialStateSpectator();
 }
 
 bool IIqx2gqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     a.emitterData() == b.emitterData() &&
     emitter(a) == sk.emitter(b) &&
     a.emitterPDF() == b.emitterPDF() &&
     a.spectatorData() == b.spectatorData() &&
     a.spectatorPDF() == b.spectatorPDF();
 
 }
 
-
+  
 tcPDPtr IIqx2gqxDipoleKernel::emitter(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr IIqx2gqxDipoleKernel::emission(const DipoleIndex& ind) const {
   return ind.emitterData()->CC();
 }
 
 tcPDPtr IIqx2gqxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double IIqx2gqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   double z = split.lastZ();
   double ratio = sqr(split.lastPt()/split.scale());
+
   double x = z*(1.-z)/(1.-z+ratio);
 
   ret *= .5 * ( 1.-2.*x*(1.-x) );
 
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+IIqx2gqxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
+
+  // No dependence on the spin density matrix,
+  // dependence on off-diagonal terms cancels.
+  return {{ {0, 1.} }};
+}
+
+DecayMEPtr IIqx2gqxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
+
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppm = z;
+  double v_AP_mpm = (1.-z);
+  
+  double v_AP_mmp = -v_AP_ppm;
+  double v_AP_pmp = -v_AP_mpm;
+  
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1, PDT::Spin1Half, PDT::Spin1Half)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -, 2 = +
+  (*kernelPhiDep)(0,0,0) = 0.;
+  (*kernelPhiDep)(2,1,1) = 0.;
+  (*kernelPhiDep)(0,0,1) = v_AP_mmp/phase;
+  (*kernelPhiDep)(2,1,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,1,0) = v_AP_mpm/phase;
+  (*kernelPhiDep)(2,0,1) = v_AP_pmp*phase;
+  (*kernelPhiDep)(0,1,1) = 0.;
+  (*kernelPhiDep)(2,0,0) = 0.;
+
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void IIqx2gqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void IIqx2gqxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<IIqx2gqxDipoleKernel> IIqx2gqxDipoleKernel::initIIqx2gqxDipoleKernel;
 // Definition of the static class description member.
 
 void IIqx2gqxDipoleKernel::Init() {
 
   static ClassDocumentation<IIqx2gqxDipoleKernel> documentation
     ("IIqx2gqxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/IIqx2gqxDipoleKernel.h b/Shower/Dipole/Kernels/IIqx2gqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IIqx2gqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IIqx2gqxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_IIqx2gqxDipoleKernel_H
 #define HERWIG_IIqx2gqxDipoleKernel_H
 //
 // This is the declaration of the IIqx2gqxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer
  *
  * \brief IIqx2gqxDipoleKernel implements the q -> gqbar
  * splitting off an initial-initial dipole
  *
  */
 class IIqx2gqxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   IIqx2gqxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~IIqx2gqxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<IIqx2gqxDipoleKernel> initIIqx2gqxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   IIqx2gqxDipoleKernel & operator=(const IIqx2gqxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of IIqx2gqxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::IIqx2gqxDipoleKernel,1> {
   /** Typedef of the first base class of IIqx2gqxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the IIqx2gqxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::IIqx2gqxDipoleKernel>
   : public ClassTraitsBase<Herwig::IIqx2gqxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::IIqx2gqxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * IIqx2gqxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class IIqx2gqxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_IIqx2gqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IIqx2qgxDipoleKernel.cc b/Shower/Dipole/Kernels/IIqx2qgxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IIqx2qgxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IIqx2qgxDipoleKernel.cc
@@ -1,102 +1,139 @@
 // -*- C++ -*-
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the IIqx2qgxDipoleKernel class.
 //
 
 #include "IIqx2qgxDipoleKernel.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 using namespace Herwig;
 
 IIqx2qgxDipoleKernel::IIqx2qgxDipoleKernel() 
   : DipoleSplittingKernel() {}
 
 IIqx2qgxDipoleKernel::~IIqx2qgxDipoleKernel() {}
 
 IBPtr IIqx2qgxDipoleKernel::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr IIqx2qgxDipoleKernel::fullclone() const {
   return new_ptr(*this);
 }
 
 bool IIqx2qgxDipoleKernel::canHandle(const DipoleIndex& ind) const {
   return
   useThisKernel() &&
     abs(ind.emitterData()->id()) < 6  &&
     ind.emitterData()->mass() == ZERO &&
     ind.spectatorData()->mass() == ZERO &&
     ind.initialStateEmitter() && ind.initialStateSpectator();
 }
 
 bool IIqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
 					       const DipoleSplittingKernel& sk,
 					       const DipoleIndex& b) const {
 
   assert(canHandle(a));
 
   if ( !canHandle(b) )
     return false;
 
   return
     emitter(a) == sk.emitter(b) &&
     emission(a) == sk.emission(b) &&
     a.emitterPDF() == b.emitterPDF() &&
     a.spectatorData() == b.spectatorData() &&
     a.spectatorPDF() == b.spectatorPDF();
 
 }
 
 
 tcPDPtr IIqx2qgxDipoleKernel::emitter(const DipoleIndex& ind) const {
   return ind.emitterData();
 }
 
 tcPDPtr IIqx2qgxDipoleKernel::emission(const DipoleIndex&) const {
   return getParticleData(ParticleID::g);
 }
 
 tcPDPtr IIqx2qgxDipoleKernel::spectator(const DipoleIndex& ind) const {
   return ind.spectatorData();
 }
 
 double IIqx2qgxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
 
   double ret = alphaPDF(split);
 
   double z = split.lastZ();
   double ratio = sqr(split.lastPt()/split.scale());
   double x = z*(1.-z)/(1.-z+ratio);
 
   ret *= (!strictLargeN() ? 4./3. : 3./2.) * ( (1.+sqr(x))/(1.-x) );
 
   return ret > 0. ? ret : 0.;
 
 }
 
+vector< pair<int, Complex> >
+IIqx2qgxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
+
+  // No dependence on the spin density matrix,
+  // dependence on off-diagonal terms cancels.
+  return {{ {0, 1.} }};
+}
+
+DecayMEPtr IIqx2qgxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
+
+  double z = dInfo.lastZ();
+
+  // Altarelli-Parisi spin-indexed kernels:
+  double v_AP_ppp = sqrt( 1./(1.-z) );
+  double v_AP_ppm = -z/sqrt(1.-z);
+
+  double v_AP_mmm = -v_AP_ppp;
+  double v_AP_mmp = -v_AP_ppm;
+  
+  // Construct the (phi-dependent) spin-unaveraged splitting kernel
+  DecayMEPtr kernelPhiDep
+    (new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half, PDT::Spin1Half, PDT::Spin1)));
+  Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
+
+  // 0 = -, 2 = +
+  (*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
+  (*kernelPhiDep)(1,1,2) = v_AP_ppp/phase;
+  (*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
+  (*kernelPhiDep)(1,1,0) = v_AP_ppm*phase;
+  (*kernelPhiDep)(0,1,0) = 0.;
+  (*kernelPhiDep)(1,0,2) = 0.;
+  (*kernelPhiDep)(0,1,2) = 0.;
+  (*kernelPhiDep)(1,0,0) = 0.;
+  
+  return kernelPhiDep;
+}
+
 // If needed, insert default implementations of  function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void IIqx2qgxDipoleKernel::persistentOutput(PersistentOStream & ) const {
 }
 
 void IIqx2qgxDipoleKernel::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<IIqx2qgxDipoleKernel> IIqx2qgxDipoleKernel::initIIqx2qgxDipoleKernel;
 // Definition of the static class description member.
 
 void IIqx2qgxDipoleKernel::Init() {
 
   static ClassDocumentation<IIqx2qgxDipoleKernel> documentation
     ("IIqx2qgxDipoleKernel");
 
 }
 
diff --git a/Shower/Dipole/Kernels/IIqx2qgxDipoleKernel.h b/Shower/Dipole/Kernels/IIqx2qgxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IIqx2qgxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IIqx2qgxDipoleKernel.h
@@ -1,181 +1,192 @@
 // -*- C++ -*-
 #ifndef HERWIG_IIqx2qgxDipoleKernel_H
 #define HERWIG_IIqx2qgxDipoleKernel_H
 //
 // This is the declaration of the IIqx2qgxDipoleKernel class.
 //
 
 #include "DipoleSplittingKernel.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer
  *
  * \brief IIqx2qgxDipoleKernel implements the q -> qg
  * splitting off an initial-initial dipole
  *
  */
 class IIqx2qgxDipoleKernel: public DipoleSplittingKernel {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   IIqx2qgxDipoleKernel();
 
   /**
    * The destructor.
    */
   virtual ~IIqx2qgxDipoleKernel();
   //@}
 
 public:
 
   /**
    * Return true, if this splitting kernel
    * applies to the given dipole index.
    */
   virtual bool canHandle(const DipoleIndex&) const;
 
   /**
    * Return true, if this splitting kernel is
    * the same for the given index a, as the given
    * splitting kernel for index b.
    */
   virtual bool canHandleEquivalent(const DipoleIndex& a,
 				   const DipoleSplittingKernel& sk,
 				   const DipoleIndex& b) const;
 
   /**
    * Return the emitter data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emitter(const DipoleIndex&) const;
 
   /**
    * Return the emission data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr emission(const DipoleIndex&) const;
 
   /**
    * Return the spectator data after splitting, given
    * a dipole index.
    */
   virtual tcPDPtr spectator(const DipoleIndex&) const;
 
   /**
    * Evaluate this splitting kernel for the given
    * dipole splitting.
    */
   virtual double evaluate(const DipoleSplittingInfo&) const;
 
+  /**
+   * Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
+   * required for generating spin-correlated azimuthal angles.
+   **/
+  virtual vector< pair<int, Complex> >  generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
+   
+  /**
+   * Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
+   **/
+  virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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;
 
   /** 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<IIqx2qgxDipoleKernel> initIIqx2qgxDipoleKernel;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   IIqx2qgxDipoleKernel & operator=(const IIqx2qgxDipoleKernel &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of IIqx2qgxDipoleKernel. */
 template <>
 struct BaseClassTrait<Herwig::IIqx2qgxDipoleKernel,1> {
   /** Typedef of the first base class of IIqx2qgxDipoleKernel. */
   typedef Herwig::DipoleSplittingKernel NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the IIqx2qgxDipoleKernel class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::IIqx2qgxDipoleKernel>
   : public ClassTraitsBase<Herwig::IIqx2qgxDipoleKernel> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::IIqx2qgxDipoleKernel"; }
   /**
    * The name of a file containing the dynamic library where the class
    * IIqx2qgxDipoleKernel is implemented. It may also include several, space-separated,
    * libraries if the class IIqx2qgxDipoleKernel depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_IIqx2qgxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/Makefile.am b/Shower/Dipole/Kernels/Makefile.am
--- a/Shower/Dipole/Kernels/Makefile.am
+++ b/Shower/Dipole/Kernels/Makefile.am
@@ -1,74 +1,76 @@
 noinst_LTLIBRARIES = libHwDipoleShowerKernels.la
 
 nodist_libHwDipoleShowerKernels_la_SOURCES = \
 DipoleKernels__all.cc
 
 BUILT_SOURCES  = DipoleKernels__all.cc
 CLEANFILES = DipoleKernels__all.cc
 
 DipoleKernels__all.cc : $(DIR_H_FILES) $(DIR_CC_FILES) Makefile
 	@echo "Concatenating .cc files into $@"
 	@$(top_srcdir)/cat_with_cpplines $(DIR_CC_FILES) > $@
 
 EXTRA_DIST = $(ALL_H_FILES) $(ALL_CC_FILES)
 
 DIR_H_FILES = $(addprefix $(srcdir)/,$(ALL_H_FILES))
 ALL_H_FILES = \
 	DipoleSplittingKernel.h \
+	ColourMatrixElementCorrection.h \
 	FFMqx2qgxDipoleKernel.h \
 	FFMgx2ggxDipoleKernel.h \
 	FFMgx2qqxDipoleKernel.h \
 	FFqx2qgxDipoleKernel.h  \
 	FFgx2ggxDipoleKernel.h  \
 	FFgx2qqxDipoleKernel.h  \
 	FIqx2qgxDipoleKernel.h  \
 	FIgx2ggxDipoleKernel.h  \
 	FIgx2qqxDipoleKernel.h  \
 	IFqx2qgxDipoleKernel.h  \
 	IFqx2gqxDipoleKernel.h  \
 	IFgx2ggxDipoleKernel.h  \
 	IFgx2qqxDipoleKernel.h  \
 	IIqx2qgxDipoleKernel.h  \
 	IIqx2gqxDipoleKernel.h  \
 	IIgx2ggxDipoleKernel.h  \
 	IIgx2qqxDipoleKernel.h  \
 	FIMqx2qgxDipoleKernel.h \
 	FIMgx2qqxDipoleKernel.h \
 	IFMqx2qgxDipoleKernel.h \
 	IFMqx2gqxDipoleKernel.h \
 	IFMgx2ggxDipoleKernel.h \
 	IFMgx2qqxDipoleKernel.h \
 	FIMDecaygx2qqxDipoleKernel.h \
 	FIMDecayqx2qgxDipoleKernel.h \
 	FIMDecaygx2ggxDipoleKernel.h
 
 DIR_CC_FILES = $(addprefix $(srcdir)/,$(ALL_CC_FILES))
 ALL_CC_FILES = \
 	DipoleSplittingKernel.cc \
+	ColourMatrixElementCorrection.cc \
 	FFMqx2qgxDipoleKernel.cc \
 	FFMgx2ggxDipoleKernel.cc \
 	FFMgx2qqxDipoleKernel.cc \
 	FFqx2qgxDipoleKernel.cc  \
 	FFgx2ggxDipoleKernel.cc  \
 	FFgx2qqxDipoleKernel.cc  \
 	FIqx2qgxDipoleKernel.cc  \
 	FIgx2ggxDipoleKernel.cc  \
 	FIgx2qqxDipoleKernel.cc  \
 	IFqx2qgxDipoleKernel.cc  \
 	IFqx2gqxDipoleKernel.cc  \
 	IFgx2ggxDipoleKernel.cc  \
 	IFgx2qqxDipoleKernel.cc  \
 	IIqx2qgxDipoleKernel.cc  \
 	IIqx2gqxDipoleKernel.cc  \
 	IIgx2ggxDipoleKernel.cc  \
 	IIgx2qqxDipoleKernel.cc  \
 	FIMqx2qgxDipoleKernel.cc \
 	FIMgx2qqxDipoleKernel.cc \
 	IFMqx2qgxDipoleKernel.cc \
 	IFMqx2gqxDipoleKernel.cc \
 	IFMgx2ggxDipoleKernel.cc \
 	IFMgx2qqxDipoleKernel.cc \
 	FIMDecaygx2qqxDipoleKernel.cc \
 	FIMDecayqx2qgxDipoleKernel.cc \
 	FIMDecaygx2ggxDipoleKernel.cc
 
diff --git a/Shower/Dipole/Kinematics/DipoleSplittingKinematics.cc b/Shower/Dipole/Kinematics/DipoleSplittingKinematics.cc
--- a/Shower/Dipole/Kinematics/DipoleSplittingKinematics.cc
+++ b/Shower/Dipole/Kinematics/DipoleSplittingKinematics.cc
@@ -1,327 +1,389 @@
 // -*- C++ -*-
 //
 // DipoleSplittingKinematics.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.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the DipoleSplittingKinematics class.
 //
 
 #include "DipoleSplittingKinematics.h"
 #include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Reference.h"
 #include "ThePEG/Interface/Parameter.h"
 #include "ThePEG/Interface/Switch.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 #include "Herwig/MatrixElement/Matchbox/Phasespace/RandomHelpers.h"
 
 #include <limits>
 
 using namespace Herwig;
 
 DipoleSplittingKinematics::DipoleSplittingKinematics()
   : HandlerBase(), theIRCutoff(1.0*GeV), 
     theXMin(1.e-5), theJacobian(0.0),
     theLastPt(0.0*GeV), theLastZ(0.0), theLastPhi(0.0),
     theLastEmitterZ(1.0), theLastSpectatorZ(1.0),
     theLastSplittingParameters(),theOpenZBoundaries(1) {}
 
 DipoleSplittingKinematics::~DipoleSplittingKinematics() {}
 
 void DipoleSplittingKinematics::persistentOutput(PersistentOStream & os) const {
   os << ounit(theIRCutoff,GeV) << theXMin << theMCCheck<<theOpenZBoundaries;
 }
 
 void DipoleSplittingKinematics::persistentInput(PersistentIStream & is, int) {
   is >> iunit(theIRCutoff,GeV) >> theXMin >> theMCCheck>>theOpenZBoundaries;
 }
 
 void DipoleSplittingKinematics::prepareSplitting(DipoleSplittingInfo& dInfo) {
 
   dInfo.splittingKinematics(this);
 
   if ( lastPt() > IRCutoff() )
     dInfo.lastPt(lastPt());
   else {
     dInfo.lastPt(0.0*GeV);
     dInfo.didStopEvolving();
   }
 
   dInfo.lastZ(lastZ());
   dInfo.lastPhi(lastPhi());
   dInfo.lastEmitterZ(lastEmitterZ());
   dInfo.lastSpectatorZ(lastSpectatorZ());
   dInfo.splittingParameters().resize(lastSplittingParameters().size());
   copy(lastSplittingParameters().begin(),lastSplittingParameters().end(),
        dInfo.splittingParameters().begin());  
 }
 
 
 Energy DipoleSplittingKinematics::ptMax(Energy dScale, 
-					double emX, double specX,
-					const DipoleSplittingInfo& dInfo,
-					const DipoleSplittingKernel& split) const {
+                                        double emX, double specX,
+                                        const DipoleSplittingInfo& dInfo,
+                                        const DipoleSplittingKernel& split) const {
   return ptMax(dScale, emX, specX, dInfo.index(), split);
 } 
 
 
 Energy DipoleSplittingKinematics::ptMax(Energy dScale, 
-					double emX, double specX,
-					const DipoleIndex& dIndex,
-					const DipoleSplittingKernel& split,
-					tPPtr, tPPtr) const {
+                                        double emX, double specX,
+                                        const DipoleIndex& dIndex,
+                                        const DipoleSplittingKernel& split,
+                                        tPPtr, tPPtr) const {
   return ptMax(dScale, emX, specX, dIndex, split);
 } 
 
 Energy DipoleSplittingKinematics::QMax(Energy dScale, 
-				       double emX, double specX,
-				       const DipoleSplittingInfo& dInfo,
-				       const DipoleSplittingKernel& split) const {
+                                       double emX, double specX,
+                                       const DipoleSplittingInfo& dInfo,
+                                       const DipoleSplittingKernel& split) const {
   return QMax(dScale, emX, specX, dInfo.index(), split);
 }
 
 Energy DipoleSplittingKinematics::QMax(Energy dScale, 
-				       double emX, double specX,
-					const DipoleIndex& dIndex,
-					const DipoleSplittingKernel& split,
-					tPPtr, tPPtr) const {
+                                       double emX, double specX,
+                                       const DipoleIndex& dIndex,
+                                       const DipoleSplittingKernel& split,
+                                       tPPtr, tPPtr) const {
   return QMax(dScale, emX, specX, dIndex, split);
 }
 
 Energy DipoleSplittingKinematics::generatePt(double r, Energy dScale,
-					     double emX, double specX,
-					     const DipoleIndex& dIndex,
-					     const DipoleSplittingKernel& split,
-					     double& weight) const {
+                                             double emX, double specX,
+                                             const DipoleIndex& dIndex,
+                                             const DipoleSplittingKernel& split,
+                                             double& weight) const {
 
   Energy maxPt = ptMax(dScale,emX,specX,dIndex,split);
   if ( maxPt <= IRCutoff() ) {
     weight = 0.0;
     return ZERO;
   }
 
   weight *= log(sqr(maxPt/IRCutoff()));
 
   return IRCutoff()*pow(maxPt/IRCutoff(),r);
 
 }
 
 double DipoleSplittingKinematics::ptToRandom(Energy pt, Energy dScale,
-					     double emX, double specX,
-					     const DipoleIndex& dIndex,
-					     const DipoleSplittingKernel& split) const {
+                                             double emX, double specX,
+                                             const DipoleIndex& dIndex,
+                                             const DipoleSplittingKernel& split) const {
 
   Energy maxPt = ptMax(dScale,emX,specX,dIndex,split);
   assert(pt >= IRCutoff() && pt <= maxPt);
 
   return log(pt/IRCutoff())/log(maxPt/IRCutoff());
 
 }
 
 double DipoleSplittingKinematics::generateZ(double r, Energy pt, int sampling,
-					    const DipoleSplittingInfo& dInfo,
-					    const DipoleSplittingKernel& split,
-					    double& weight) const {
+                                            const DipoleSplittingInfo& dInfo,
+                                            const DipoleSplittingKernel& split,
+                                            double& weight) const {
 
   pair<double,double> zLims = zBoundaries(pt,dInfo,split);
 
   if(zLims.first==zLims.second){  
 	weight = 0.0;
-      	return 0.0;
+    return 0.0;
   }
 
   using namespace RandomHelpers;
 
   if ( sampling == FlatZ ) {
     pair<double,double> kw = generate(flat(zLims.first,zLims.second),r);
 
     if ( kw.second != 0. ) {
       weight *= kw.second;
       return kw.first;
     }
     else {
       assert( kw.first < zLims.first || kw.first > zLims.second );
       weight *= kw.second;
       return -1.;
     }
 
   }
 
   if ( sampling == OneOverZ ) {
     pair<double,double> kw = generate(inverse(0.0,zLims.first,zLims.second),r);
 
     if ( kw.second != 0. ) {
       weight *= kw.second;
       return kw.first;
     }
     else {
       assert( kw.first < zLims.first || kw.first > zLims.second );
       weight *= kw.second;
       return -1.;
     }
 
   }
 
   if ( sampling == OneOverOneMinusZ ) {
     pair<double,double> kw = generate(inverse(1.0,zLims.first,zLims.second),r);
 
     if ( kw.second != 0. ) {
       weight *= kw.second;
       return kw.first;
     }
     else {
       assert( kw.first < zLims.first || kw.first > zLims.second );
       weight *= kw.second;
       return -1.;
     }
 
   }
 
   if ( sampling == OneOverZOneMinusZ ) {
     pair<double,double> kw = generate(inverse(0.0,zLims.first,zLims.second) + 
-				      inverse(1.0,zLims.first,zLims.second),r);
+                                      inverse(1.0,zLims.first,zLims.second),r);
 
     if ( kw.second != 0. ) {
       weight *= kw.second;
       return kw.first;
     }
     else {
       assert( kw.first < zLims.first || kw.first > zLims.second );
       weight *= kw.second;
       return -1.;
     }
   }
 
   weight = 0.0;
   return 0.0;
 
 }
 
 Lorentz5Momentum DipoleSplittingKinematics::getKt(const Lorentz5Momentum& p1,
-						  const Lorentz5Momentum& p2,
-						  Energy pt,
-						  double phi,
-						  bool spacelike) const {
+                                                  const Lorentz5Momentum& p2,
+                                                  Energy pt,
+                                                  double phi,
+                                                  bool spacelike) const {
 
   Lorentz5Momentum P;
+  // CoM frame
   if ( !spacelike )
     P = p1 + p2;
+  // Breit frame
   else
     P = p1 - p2;
+  
+  Energy mag = sqrt(abs(P.m2()));
 
-  Energy2 Q2 = abs(P.m2());
-
+  // Define Q. The 'boost' part of this transforms from the current
+  // frame into a frame (') in which P' = Q
   Lorentz5Momentum Q = 
     !spacelike ? 
-    Lorentz5Momentum(ZERO,ZERO,ZERO,sqrt(Q2),sqrt(Q2)) :
-    Lorentz5Momentum(ZERO,ZERO,sqrt(Q2),ZERO,-sqrt(Q2));
+    Lorentz5Momentum(ZERO,ZERO,ZERO,mag,mag) :
+    Lorentz5Momentum(ZERO,ZERO,mag,ZERO,-mag);
 
-  if ( spacelike && Q.z() < P.z() )
+  // This is required to make the boost parameter
+  // gamma positive (construct the 00 term of the
+  // transformtion below to see this)
+  //if ( spacelike && P.z() < -mag )
+  //Q.setZ(-Q.z());
+  // Below is safer than above as it avoids
+  // cases of very small positive (P*Q + Q2)
+  if ( spacelike && P.z() < ZERO )
     Q.setZ(-Q.z());
 
+  Energy2 Q2 = Q.m2();
+
+  // Establish if we need to boost
   bool boost =
     abs((P-Q).vect().mag2()/GeV2) > 1e-10 ||
     abs((P-Q).t()/GeV) > 1e-5;
-  boost &= (P*Q-Q.mass2())/GeV2 > 1e-8;
+  
+  // Initialise copy of p1 to transform in the following
+  Lorentz5Momentum inFrame1(p1);
+  if ( boost )
+    inFrame1 = inFrame1 - ((P*inFrame1+Q*inFrame1)/(Q2+P*Q))*(P+Q) + 2.*((P*inFrame1)/Q2)*Q; 
 
-  Lorentz5Momentum inFrame1;
-  if ( boost )
-    inFrame1 = p1 + ((P*p1-Q*p1)/(P*Q-Q.mass2()))*(P-Q);
-  else
-    inFrame1 = p1;
-
-  Energy ptx = inFrame1.x();
-  Energy pty = inFrame1.y();
-  Energy q = 2.*inFrame1.z();
-
-  Energy Qp = sqrt(4.*(sqr(ptx)+sqr(pty))+sqr(q));
-  Energy Qy = sqrt(4.*sqr(pty)+sqr(q));
-
+  // Compute components of kt
   double cPhi = cos(phi);
   double sPhi = sqrt(1.-sqr(cPhi));
   if ( phi > Constants::pi )
     sPhi = -sPhi;
+  
+  // Initialise kt
+  Lorentz5Momentum kt;
+  
+  // By 'timelike' case we mean we work in the centre-of-momentum frame
+  // The boost to the com frame is defined upto some rotation,
+  // here we do the rotation to/from the frame with boosted p1 along the +ve z-axis
+  if ( !spacelike ) {
 
-  Lorentz5Momentum kt;
+    Axis inFrame1Unit = inFrame1.vect().unit();
+    if ( inFrame1Unit.perp2() > 1e-12 ) {
+      // 'n' indicates normalised momenta components
+      double pxn = inFrame1Unit.x();
+      double pyn = inFrame1Unit.y();
+      double pzn = inFrame1Unit.z();
+      double den = 1./(1.+pzn);
+      
+      kt.setT(ZERO);
+      kt.setX( pt * ( (sqr(pyn)*den + pzn)*cPhi - pxn*pyn*den*sPhi ) );
+      kt.setY( pt * ( -pxn*pyn*den*cPhi + (sqr(pxn)*den + pzn)*sPhi) );
+      kt.setZ( -pt * ( pxn*cPhi + pyn*sPhi ) );
+    }
 
-  if ( !spacelike ) {
-    kt.setT(ZERO);
-    kt.setX(pt*Qy*cPhi/Qp);
-    kt.setY(-pt*(4*ptx*pty*cPhi/Qp+q*sPhi)/Qy);
-    kt.setZ(2.*pt*(-ptx*q*cPhi/Qp + pty*sPhi)/Qy);
-  } else {
-    kt.setT(2.*pt*(ptx*q*cPhi+pty*Qp*sPhi)/(q*Qy));
-    kt.setX(pt*(Qp*q*cPhi+4.*ptx*pty*sPhi)/(q*Qy));
-    kt.setY(pt*Qy*sPhi/q);
+    // If boosted p1 already lies along the z-axis, construct the pt
+    // in this frame, rotating to put boosted p1 along the *+ve* z-axis
+    // if required
+    else {
+      
+      // Note pzn will simply be +1 or -1 in this case
+      double pzn = inFrame1Unit.z();
+      
+      // Multiply y component by pzn:
+      // In the case of pzn = -1, this corresponds to a rotation
+      // about the x-axis as done in boostToSplitting
+      kt.setT(ZERO);
+      kt.setX( pt * cPhi );
+      kt.setY( pt * pzn*sPhi );
+      kt.setZ(ZERO);
+    }
+  }
+
+  // By 'spacelike' we mean we work in the Breit frame.
+  // The transformation to the breit frame above is
+  // defined up to boosts in the x- and y-directions,
+  // here we do the boosts to put the momenta along the z-axis
+  else {
+    Energy ptx = inFrame1.x();
+    Energy pty = inFrame1.y();
+
+    // q/2 = energy component of inFrame1 AFTER applying
+    // boosts to eliminate the x and y components. Therefore
+    // we calculate q from the mass and the z-component as
+    // these will not change due to these boosts.
+    Energy q = 2.*sqrt(sqr(inFrame1) + sqr(inFrame1.z()));
+  
+    Energy Qp = sqrt(4.*(sqr(ptx)+sqr(pty))+sqr(q));
+    Energy Qy = sqrt(4.*sqr(pty)+sqr(q));
+    
+    // Most straightforward way to construct kt in frame
+    // where p1 lies along the positive z-axis
+    double pzn = inFrame1.z()/abs(inFrame1.z());
+
+    kt.setT(2.*pt*(ptx*q*cPhi+pty*Qp*pzn*sPhi)/(q*Qy));
+    kt.setX(pt*(Qp*q*cPhi+4.*ptx*pty*pzn*sPhi)/(q*Qy));
+    kt.setY(pt*Qy*pzn*sPhi/q);      
     kt.setZ(ZERO);
   }
 
+  // Transform back to the lab frame
+  // Note Q*kt = 0
   if ( boost )
-    kt = kt + ((P*kt-Q*kt)/(P*Q-Q.mass2()))*(P-Q);
+    kt = kt - ((P*kt+Q*kt)/(Q2+P*Q))*(P+Q);// + 2.*((Q*kt)/Q2)*P;
+  
   kt.setMass(-pt);
   kt.rescaleRho();
 
-  return kt;
+  return kt;  
+}
 
-}
 
 // If needed, insert default implementations of virtual function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 AbstractClassDescription<DipoleSplittingKinematics> DipoleSplittingKinematics::initDipoleSplittingKinematics;
 // Definition of the static class description member.
 
 void DipoleSplittingKinematics::Init() {
 
   static ClassDocumentation<DipoleSplittingKinematics> documentation
     ("DipoleSplittingKinematics is the base class for dipole splittings "
      "as performed in the dipole shower.");
 
 
   static Parameter<DipoleSplittingKinematics,Energy> interfaceIRCutoff
     ("IRCutoff",
      "The IR cutoff to be used by this splitting kinematics.",
      &DipoleSplittingKinematics::theIRCutoff, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
      false, false, Interface::lowerlim);
 
 
   static Parameter<DipoleSplittingKinematics,double> interfaceXMin
     ("XMin",
      "The minimum momentum fraction for incoming partons",
      &DipoleSplittingKinematics::theXMin, 1.0e-5, 0.0, 1.0,
      false, false, Interface::limited);
 
 
   static Reference<DipoleSplittingKinematics,DipoleMCCheck> interfaceMCCheck
     ("MCCheck",
      "[debug option] MCCheck",
      &DipoleSplittingKinematics::theMCCheck, false, false, true, true, false);
 
   interfaceMCCheck.rank(-1);
   
   
   static Switch<DipoleSplittingKinematics,int> interfaceOpenZBoundaries
-  ("OpenZBoundaries", "",
-   &DipoleSplittingKinematics::theOpenZBoundaries, 0, false, false);
+    ("OpenZBoundaries", "",
+     &DipoleSplittingKinematics::theOpenZBoundaries, 0, false, false);
   static SwitchOption interfaceOpenZBoundarieshardScale
-  (interfaceOpenZBoundaries,   "Hard",   "",   0);
+    (interfaceOpenZBoundaries,   "Hard",   "",   0);
   static SwitchOption interfaceOpenZBoundariesfull
-  (interfaceOpenZBoundaries,   "Full",   "",   1);
+    (interfaceOpenZBoundaries,   "Full",   "",   1);
   static SwitchOption interfaceOpenZBoundariesDipoleScale
-  (interfaceOpenZBoundaries,   "DipoleScale",   "",   2);
+    (interfaceOpenZBoundaries,   "DipoleScale",   "",   2);
   
   
   
   
   
 
 }
 
diff --git a/Shower/Dipole/Kinematics/DipoleSplittingKinematics.h b/Shower/Dipole/Kinematics/DipoleSplittingKinematics.h
--- a/Shower/Dipole/Kinematics/DipoleSplittingKinematics.h
+++ b/Shower/Dipole/Kinematics/DipoleSplittingKinematics.h
@@ -1,643 +1,672 @@
 // -*- C++ -*-
 //
 // DipoleSplittingKinematics.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_DipoleSplittingKinematics_H
 #define HERWIG_DipoleSplittingKinematics_H
 //
 // This is the declaration of the DipoleSplittingKinematics class.
 //
 
 #include "ThePEG/Handlers/HandlerBase.h"
 #include "ThePEG/Vectors/Lorentz5Vector.h"
 
 #include "ThePEG/EventRecord/Particle.h"
 #include "ThePEG/Utilities/UtilityBase.h"
 
 #include "Herwig/Shower/Dipole/Utility/DipoleMCCheck.h"
 
 namespace Herwig {
 
   using namespace ThePEG;
 
   class DipoleIndex;
   class DipoleSplittingInfo;
   class DipoleSplittingKernel;
 
   /**
    * \ingroup DipoleShower
    * \author Simon Platzer
    *
    * \brief DipoleSplittingKinematics is the base class for dipole splittings
    * as performed in the dipole shower.
    *
    * @see \ref DipoleSplittingKinematicsInterfaces "The interfaces"
    * defined for DipoleSplittingKinematics.
    */
   class DipoleSplittingKinematics: public HandlerBase {
 
   public:
 
     /** @name Standard constructors and destructors. */
     //@{
     /**
      * The default constructor.
      */
     DipoleSplittingKinematics();
 
     /**
      * The destructor.
      */
     virtual ~DipoleSplittingKinematics();
     //@}
 
   public:
 
     /**
      * Return the boundaries in between the evolution
      * variable random number is to be sampled; the lower
      * cuoff is assumed to correspond to the infrared cutoff.
      */
     virtual pair<double,double> kappaSupport(const DipoleSplittingInfo&) const {
       return {0.0,1.0};
     }
 
     /**
      * Return the boundaries in between the momentum
      * fraction random number is to be sampled.
      */
     virtual pair<double,double> xiSupport(const DipoleSplittingInfo&) const {
       return {0.0,1.0};
     }
 
     /**
      * Return the dipole scale associated to the
      * given pair of emitter and spectator. This
      * should be the invariant mass or absolute value
      * final/final or initial/initial and the absolute
      * value of the momentum transfer for intial/final or
      * final/initial dipoles.
      */
     virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
 			       const Lorentz5Momentum& pSpectator) const {
 	// MEMinBias produces non-zero zeros.
       if(abs(pEmitter*pSpectator)<0.0000001*GeV2)return ZERO;
       assert(pEmitter*pSpectator >= ZERO);
       return sqrt(2.*pEmitter*pSpectator);
     }
 
     /**
      * Return the mass of the system absorbing 
      * the recoil in the dipole splitting. 
      * This is overloaded in the decay dipoles.
      */
     virtual Energy recoilMassKin(const Lorentz5Momentum&,
 			      const Lorentz5Momentum& pSpectator) const {
       return pSpectator.m();
     }
 
     /**
      * Return the maximum pt for the given dipole scale.
      */
     virtual Energy ptMax(Energy dScale, 
 			 double emX, double specX,
 			 const DipoleIndex& dIndex,
 			 const DipoleSplittingKernel& split) const =0;
 
     /**
      * Return the maximum pt for the given dipole scale.
      */
     virtual Energy ptMax(Energy dScale, 
 			 double emX, double specX,
 			 const DipoleSplittingInfo& dInfo,
 			 const DipoleSplittingKernel& split) const;
     
     /**
      * Return the maximum pt for the given dipole scale.
      */
     virtual Energy ptMax(Energy dScale, 
 			 double emX, double specX,
 			 const DipoleIndex& dIndex,
 			 const DipoleSplittingKernel& split,
 			 tPPtr emitter, tPPtr spectator) const; 
 
     /**
      * Return the maximum virtuality for the given dipole scale.
      */
     virtual Energy QMax(Energy dScale, 
 			double emX, double specX,
 			const DipoleIndex& dIndex,
 			const DipoleSplittingKernel& split) const =0;
 
     /**
      * Return the maximum virtuality for the given dipole scale.
      */
     virtual Energy QMax(Energy dScale, 
 			double emX, double specX,
 			const DipoleSplittingInfo& dInfo,
 			const DipoleSplittingKernel& split) const;
 
     /**
      * Return the maximum virtuality for the given dipole scale.
      */
     virtual Energy QMax(Energy dScale, 
 			double emX, double specX,
 			const DipoleIndex& dIndex,
 			const DipoleSplittingKernel& split,
 			tPPtr emitter, tPPtr spectator) const;
   
     /**
      * Return the pt given a virtuality.
      */
     virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const = 0;
 
     /**
      * Return the virtuality given a pt.
      */
     virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const = 0;
 
     /**
      * Return the infrared cutoff.
      */
     virtual Energy IRCutoff() const { return theIRCutoff; }
 
     /**
      * Return the minimum momentum fraction for
      * incoming partons
      */
     double xMin() const { return theXMin; }
 
     /**
      * Generate a pt
      */
     Energy generatePt(double r, Energy dScale,
 		      double emX, double specX,
 		      const DipoleIndex& dIndex,
 		      const DipoleSplittingKernel& split,
 		      double& weight) const;
 
     /**
      * Return the random number associated to
      * the given pt.
      */
     virtual double ptToRandom(Energy pt, Energy dScale,
 			      double emX, double specX,
 			      const DipoleIndex& dIndex,
 			      const DipoleSplittingKernel& split) const;
 
     /**
      * Return the boundaries on the momentum fraction
      */
     virtual pair<double,double> zBoundaries(Energy pt,
 					    const DipoleSplittingInfo& dInfo,
 					    const DipoleSplittingKernel& split) const = 0;
 
     /**
      * Enumerate the variants of sampling z
      */
     enum ZSamplingOptions {
 
       FlatZ = 0,
       OneOverZ,
       OneOverOneMinusZ,
       OneOverZOneMinusZ
 
     };
 
     /**
      * Generate a z value flat
      */
     double generateZ(double r, Energy pt, int sampling,
 		     const DipoleSplittingInfo& dInfo,
 		     const DipoleSplittingKernel& split,
 		     double& weight) const;
 
     /**
      * Generate splitting variables given three random numbers
      * and the momentum fractions of the emitter and spectator.
      * Return true on success.
      */
     virtual bool generateSplitting(double kappa, double xi, double phi,
 				   DipoleSplittingInfo& info,
 				   const DipoleSplittingKernel&) = 0;
 
     /**
      * Get the splitting phasespace weight associated to
      * the last call to generateSplitting. This is taken to
      * be the single particle phasespace times 16 \pi^2 divided
      * by the relevant propagator invariant.
      */
     double jacobian() const { return theJacobian; }
 
     /**
      * Return true, if this splitting kinematics
      * class is capable of delivering an overestimate
      * to the jacobian.
      */
     virtual bool haveOverestimate() const { return false; }
 
     /**
      * Return the overestimated jacobian for the
      * last generated parameters.
      */
     virtual double jacobianOverestimate() const { return -1.; }
 
     /**
      * Return the last generated pt
      */
     Energy lastPt() const { return theLastPt; }
 
     /**
      * Return the last generated momentum fraction.
      */
     double lastZ() const { return theLastZ; }
 
     /**
      * Return the last calculated zPrime for massive FF and decay dipoles.
      */
     
     // Do not need in current implementation,
     // using lastSplittingParameters instead.
     //double lastZPrime() const { return theLastZPrime; }
 
     /**
      * Return the last generated azimuthal angle.
      */
     double lastPhi() const { return theLastPhi; }
 
     /**
      * Return the momentum fraction, by which the emitter's
      * momentum fraction should be divided after the splitting.
      */
     double lastEmitterZ() const { return theLastEmitterZ; }
 
     /**
      * Return the momentum fraction, by which the spectator's
      * momentum fraction should be divided after the splitting.
      */
     double lastSpectatorZ() const { return theLastSpectatorZ; }
 
     /**
      * Return any additional parameters needed to
      * evaluate the splitting kernel or to generate the 
      * full splitting.
      */
     const vector<double>& lastSplittingParameters() const { return theLastSplittingParameters; }
 
     /**
      * Complete a DipoleSplittingInfo object with
      * the parameters generated by the last call to
      * generateSplitting()
      */
     void prepareSplitting(DipoleSplittingInfo& dInfo);
 
   public:
 
     /**
      * Generate the full kinematics given emitter and
      * spectator momentum and a previously completeted
      * DipoleSplittingInfo object.
      */
     virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
 				    const Lorentz5Momentum& pSpectator,
 				    const DipoleSplittingInfo& dInfo) = 0;
 
 
 
     /**
      * Return the emitter's momentum after the splitting.
      */
     const Lorentz5Momentum& lastEmitterMomentum() const { return theEmitterMomentum; }
 
     /**
      * Return the spectator's momentum after the splitting.
      */
     const Lorentz5Momentum& lastSpectatorMomentum() const { return theSpectatorMomentum; }
 
     /**
      * Return the emission's momentum.
      */
     const Lorentz5Momentum& lastEmissionMomentum() const { return theEmissionMomentum; }
 
     /*
      * Return true, if there is a transformation which should
      * be applied to all other final state particles except the ones
      * involved in the splitting after having performed the splitting.
      */
     virtual bool doesTransform () const { return false; }
 
+    /**
+     * Calculate and store a required Lorentz transformation
+     **/
+    virtual void setTransformation () {};
+
     /*
      * Use the Dipole scale instead of hardpt for z-boundaries.
      */
     int openZBoundaries() const { return theOpenZBoundaries; }
 
     /*
      * perform the transformation if required.
      */
-    virtual Lorentz5Momentum transform (const Lorentz5Momentum& p) const { return p; }
+    virtual void transform (PPtr&) {};
 
     /*
+     * SW 30/01/2019: Test feature only, not for release.
+     * Return true to only apply the transformation to non-coloured particles.
+     * Note this requires careful handling in DipoleEventRecord
+     */
+    //virtual bool transformHardOnly() const { return false; }
+    
+    /**
+     * SW 30/01/2019: Test feature only, not for release.
+     * In II case use colourless particles only to absorb recoil
+     */   
+    //virtual void transformHard ( PPtr& ) {};
+
+    /**
+     * SW 30/01/2019: Used in DipoleEventRecord to prepare for 
+     * transformHard, test feature only, not for release.
+     * Add to splitRecoilMomentum for transformation
+     */
+    // void addToRecoilMom( const Lorentz5Momentum& mom ) {    
+    //   Lorentz5Momentum newRecoilMom = splitRecoilMomentum() + mom;
+    //   splitRecoilMomentum(newRecoilMom);
+    // }
+    
+    /*
      * Return true if this splitting is of a dipole which contains
      * a decayed parton and requires the remnant to absorb the recoil.
      */
     virtual bool isDecay() const { return false; }
 
     /**
      * Perform the recoil in the case of a decayed parton
      */
     //virtual Lorentz5Momentum decayRecoil ( const Lorentz5Momentum& p, const int) { return p; }
 
     /**
      * Perform the recoil in the case of a decayed parton
      */
     virtual void decayRecoil ( PList& ) {};
 
+    /**
+     * Return the pVector, required for spin correlations.
+     */
+    virtual Lorentz5Momentum pVector(const Lorentz5Momentum& pEmitter,
+                                     const Lorentz5Momentum&,
+                                     const DipoleSplittingInfo&) const {
+      return pEmitter;
+    }
+
+    /**
+     * Return the nVector, required for spin correlations.
+     */
+    virtual Lorentz5Momentum nVector(const Lorentz5Momentum&,
+                                     const Lorentz5Momentum& pSpectator,
+                                     const DipoleSplittingInfo&) const {
+      return pSpectator;
+    }
+
  // {;}
 
   protected:
 
     /**
      * Calculate a transverse momentum for the given momenta,
      * invariant pt and azimuth.
      */
     Lorentz5Momentum getKt(const Lorentz5Momentum& p1,
 			   const Lorentz5Momentum& p2,
 			   Energy pt,
 			   double phi,
 			   bool spacelike = false) const;
 
     /**
      * Set the splitting phasespace weight associated to
      * the last call to generateSplitting. This is taken to
      * be the single particle phasespace times 16 \pi^2 divided
      * by the relevant propagator invariant.
      */
     void jacobian(double w) { theJacobian = w; }
 
     /**
      * Set the last generated pt
      */
     void lastPt(Energy p) { theLastPt = p; }
 
     /**
      * Set the last generated momentum fraction.
      */
     void lastZ(double z) { theLastZ = z; }
 
     /**
      * Set the last calculated zPrime for massive FF and decay dipoles.
      */
     // Do not need in current implementation,
     // using lastSplittingParameters instead.
     //void lastZPrime(double zPrime) { theLastZPrime = zPrime; }
 
     /**
      * Set the last generated azimuthal angle.
      */
     void lastPhi(double p) { theLastPhi = p; }
 
     /**
      * Set the momentum fraction, by which the emitter's
      * momentum fraction should be divided after the splitting.
      */
     void lastEmitterZ(double z) { theLastEmitterZ = z; }
 
     /**
      * Set the momentum fraction, by which the spectator's
      * momentum fraction should be divided after the splitting.
      */
     void lastSpectatorZ(double z) { theLastSpectatorZ = z; }
 
     /**
      * Access any additional parameters needed to
      * evaluate the splitting kernel or to generate the 
      * full splitting.
      */
     vector<double>& splittingParameters() { return theLastSplittingParameters; }
 
     /**
      * Set the emitter's momentum after the splitting.
      */
     void emitterMomentum(const Lorentz5Momentum& p) { theEmitterMomentum = p; }
 
     /**
      * Set the spectator's momentum after the splitting.
      */
     void spectatorMomentum(const Lorentz5Momentum& p) { theSpectatorMomentum = p; }
 
     /**
      * Set the emission's momentum.
      */
     void emissionMomentum(const Lorentz5Momentum& p) { theEmissionMomentum = p; }
 
     /**
-     * Set the momentum of the recoil system before the splitting.
-     * 25/05/2016 - Not currently used.
-     */
-    //void recoilMomentum( const Lorentz5Momentum& mom ) { theRecoilMomentum = mom; }
-
-    /**
      * Set the momentum of the recoil system after the splitting.
      */
     void splitRecoilMomentum( const Lorentz5Momentum& mom ) { theSplitRecoilMomentum = mom; }
-
-    /**
-     * Return the momentum of the recoil system before splitting.
-     * 25/05/2016 - Not currently used.
-     */
-    //const Lorentz5Momentum& recoilMomentum() const { return theRecoilMomentum; }
-
+    
     /**
      * Return the momentum of the recoil system after splitting.
      */
     const Lorentz5Momentum& splitRecoilMomentum() const { return theSplitRecoilMomentum; }
 
   public:
 
     /**
      * 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();
 
   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);
     //@}
 
 
     // If needed, insert declarations of virtual function defined in the
     // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
   private:
 
     /**
      * The infrared cutoff associated to this
      * splitting kinematics.
      */
     Energy theIRCutoff;
 
     /**
      * The minimum momentum fraction for
      * incoming partons
      */
     double theXMin;
 
     /**
      * The last calculated splitting phase space weight.
      */
     double theJacobian;
 
     /**
      * The last generated pt
      */
     Energy theLastPt;
 
     /**
      * The last generated momentum fraction.
      */
     double theLastZ;
 
     /**
      * The last calculated zPrime required for massive FF
      * and decay kinematics dipoles.
      * zPrime := qi.nk / (qi+qj).nk (qj = emission momentum)
      */
     // Do not need in current implementation,
     // using lastSplittingParameters instead.
     //double theLastZPrime;
 
     /**
      * The last generated azimuthal angle.
      */
     double theLastPhi;
 
     /**
      * The momentum fraction, by which the emitter's
      * momentum fraction should be divided after the splitting.
      */
     double theLastEmitterZ;
 
     /**
      * The momentum fraction, by which the spectator's
      * momentum fraction should be divided after the splitting.
      */
     double theLastSpectatorZ;
 
     /**
      * Any additional parameters needed to
      * evaluate the splitting kernel or to generate the 
      * full splitting.
      */
     vector<double> theLastSplittingParameters;
 
     /**
      * The emitter's momentum after the splitting.
      */
     Lorentz5Momentum theEmitterMomentum;
 
     /**
      * The emission's momentum after the splitting.
      */
     Lorentz5Momentum theEmissionMomentum;
 
     /**
      * The spectator's momentum after the splitting.
      */
     Lorentz5Momentum theSpectatorMomentum;
 
     /**
-     * The momentum of the recoil system used in decay dipole kinematics.
-     * 25/05/2016 - Not currently used
-     */
-    //Lorentz5Momentum theRecoilMomentum;
-
-    /**
-     * The momentum of the recoil system after the splitting, used in decay dipole kinematics.
+     * The momentum of the recoil system after the splitting, 
+     * used in decay dipole kinematics.
      */
     Lorentz5Momentum theSplitRecoilMomentum;
 
 
 
     int theOpenZBoundaries;
 
   protected:
 
     /**
      * Pointer to a check histogram object
      */
     Ptr<DipoleMCCheck>::ptr theMCCheck;
 
   private:
 
     /**
      * The static object used to initialize the description of this class.
      * Indicates that this is an abstract class.
      */
     static AbstractClassDescription<DipoleSplittingKinematics> initDipoleSplittingKinematics;
 
     /**
      * The assignment operator is private and must never be called.
      * In fact, it should not even be implemented.
      */
     DipoleSplittingKinematics & operator=(const DipoleSplittingKinematics &) = delete;
 
   };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
   /** @cond TRAITSPECIALIZATIONS */
 
   /** This template specialization informs ThePEG about the
    *  base classes of DipoleSplittingKinematics. */
   template <>
   struct BaseClassTrait<Herwig::DipoleSplittingKinematics,1> {
     /** Typedef of the first base class of DipoleSplittingKinematics. */
     typedef HandlerBase NthBase;
   };
 
   /** This template specialization informs ThePEG about the name of
    *  the DipoleSplittingKinematics class and the shared object where it is defined. */
   template <>
   struct ClassTraits<Herwig::DipoleSplittingKinematics>
     : public ClassTraitsBase<Herwig::DipoleSplittingKinematics> {
     /** Return a platform-independent class name */
     static string className() { return "Herwig::DipoleSplittingKinematics"; }
     /**
      * The name of a file containing the dynamic library where the class
      * DipoleSplittingKinematics is implemented. It may also include several, space-separated,
      * libraries if the class DipoleSplittingKinematics depends on other classes (base classes
      * excepted). In this case the listed libraries will be dynamically
      * linked in the order they are specified.
      */
     static string library() { return "HwDipoleShower.so"; }
   };
 
   /** @endcond */
 
 }
 
 #endif /* HERWIG_DipoleSplittingKinematics_H */
diff --git a/Shower/Dipole/Kinematics/FFLightKinematics.cc b/Shower/Dipole/Kinematics/FFLightKinematics.cc
--- a/Shower/Dipole/Kinematics/FFLightKinematics.cc
+++ b/Shower/Dipole/Kinematics/FFLightKinematics.cc
@@ -1,176 +1,175 @@
 // -*- C++ -*-
 //
 // FFLightKinematics.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 FFLightKinematics class.
 //
 
 #include "FFLightKinematics.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 #include "ThePEG/Repository/UseRandom.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
 
 using namespace Herwig;
 
 FFLightKinematics::FFLightKinematics() 
   : DipoleSplittingKinematics() {}
 
 FFLightKinematics::~FFLightKinematics() {}
 
 IBPtr FFLightKinematics::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FFLightKinematics::fullclone() const {
   return new_ptr(*this);
 }
 
 Energy FFLightKinematics::ptMax(Energy dScale, 
 				double, double,
 				const DipoleIndex&,
 				const DipoleSplittingKernel&) const {
   return dScale/2.;
 }
 
 Energy FFLightKinematics::QMax(Energy dScale, 
 			       double, double,
 			       const DipoleIndex&,
 			       const DipoleSplittingKernel&) const {
   return dScale;
 }
 
 Energy FFLightKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
   double z = split.lastZ();
   return scale*sqrt(z*(1.-z));
 }
 
 Energy FFLightKinematics::QFromPt(Energy scale, const DipoleSplittingInfo& split) const {
   double z = split.lastZ();
   return scale/sqrt(z*(1.-z));
 }
 
 pair<double,double> FFLightKinematics::zBoundaries(Energy pt,
 						   const DipoleSplittingInfo& dInfo,
 						   const DipoleSplittingKernel&) const {
   Energy hard=dInfo.hardPt();
   if(openZBoundaries()>0)hard=dInfo.scale()/2.;
   const double s = sqrt(1.-sqr(pt/hard));
   return {0.5*(1.-s),0.5*(1.+s)};
 }
 
 bool FFLightKinematics::generateSplitting(double kappa, double xi, double rphi,
 					  DipoleSplittingInfo& info,
 					  const DipoleSplittingKernel& split) {
 
   double weight = 1.0;
 
   Energy pt = generatePt(kappa,info.scale(),
 			 info.emitterX(),info.spectatorX(),
 			 info.index(),split,
 			 weight);
 
   if ( pt < IRCutoff() || pt > info.hardPt() ) {
     jacobian(0.0);
     return false;
   }
 
   double z = 0.0;
 
   if ( info.index().emitterData()->id() == ParticleID::g ) {
     if ( info.emissionData()->id() != ParticleID::g ) {
       z = generateZ(xi,pt,FlatZ,
 		    info,split,weight);
     } else {
       z = generateZ(xi,pt,OneOverZOneMinusZ,
 		    info,split,weight);
     }
   } else {
     z = generateZ(xi,pt,OneOverOneMinusZ,
 		  info,split,weight);
   }
 
   double y = sqr(pt/info.scale())/(z*(1.-z));
 
   if ( z < 0.0 || z > 1.0 ||
        y < 0.0 || y > 1.0 ) {
     jacobian(0.0);
     return false;
   }
 
   double phi = 2.*Constants::pi*rphi;
 
   jacobian(weight*(1.-y));
 
   lastPt(pt);
   lastZ(z);
   lastPhi(phi);
 
   if ( theMCCheck )
     theMCCheck->book(1.,1.,info.scale(),info.hardPt(),pt,z,jacobian());
 
   return true;
-
 }
 
 void FFLightKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
 					   const Lorentz5Momentum& pSpectator,
 					   const DipoleSplittingInfo& dInfo) {
 
   double z = dInfo.lastZ();
   Energy pt = dInfo.lastPt();
   double y = sqr(pt / (pEmitter+pSpectator).m()) / (z*(1.-z));
-
+ 
   Lorentz5Momentum kt =
     getKt(pEmitter, pSpectator, pt, dInfo.lastPhi());
-
+  
   Lorentz5Momentum em = z*pEmitter + y*(1.-z)*pSpectator + kt;
   Lorentz5Momentum emm = (1.-z)*pEmitter + z*y*pSpectator - kt;
   Lorentz5Momentum spe = (1.-y)*pSpectator;
   
   em.setMass(ZERO);
   em.rescaleEnergy();
 
   emm.setMass(ZERO);
   emm.rescaleEnergy();
   
   spe.setMass(ZERO);
   spe.rescaleEnergy();
 
   emitterMomentum(em);
   emissionMomentum(emm);
   spectatorMomentum(spe);
-
+  
 }
 
 // If needed, insert default implementations of function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FFLightKinematics::persistentOutput(PersistentOStream & ) const {
 }
 
 void FFLightKinematics::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<FFLightKinematics> FFLightKinematics::initFFLightKinematics;
 // Definition of the static class description member.
 
 void FFLightKinematics::Init() {
 
   static ClassDocumentation<FFLightKinematics> documentation
     ("FFLightKinematics implements massless splittings "
      "off a final-final dipole.");
 
 }
 
diff --git a/Shower/Dipole/Kinematics/FFMassiveKinematics.cc b/Shower/Dipole/Kinematics/FFMassiveKinematics.cc
--- a/Shower/Dipole/Kinematics/FFMassiveKinematics.cc
+++ b/Shower/Dipole/Kinematics/FFMassiveKinematics.cc
@@ -1,503 +1,436 @@
 // -*- C++ -*-
 //
 // FFMassiveKinematics.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 FFMassiveKinematics class.
 //
 
 #include "FFMassiveKinematics.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 #include "ThePEG/Repository/UseRandom.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
 #include "Herwig/Shower/Dipole/Kernels/DipoleSplittingKernel.h"
 
 #include "ThePEG/Interface/Switch.h"
 
 // TODO: remove after verification
 // only for checking for NaN or inf
 #include <gsl/gsl_math.h>
 
 using namespace Herwig;
 
 FFMassiveKinematics::FFMassiveKinematics() 
-  : DipoleSplittingKinematics(),
-    theFullJacobian(true) {}
+  : DipoleSplittingKinematics() {}
 
 FFMassiveKinematics::~FFMassiveKinematics() {}
 
 IBPtr FFMassiveKinematics::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FFMassiveKinematics::fullclone() const {
   return new_ptr(*this);
 }
 
 pair<double,double> FFMassiveKinematics::kappaSupport(const DipoleSplittingInfo&) const {
   return {0.0,1.0};
 }
 
 pair<double,double> FFMassiveKinematics::xiSupport(const DipoleSplittingInfo& split) const {
 
   double c = sqrt(1.-4.*sqr(IRCutoff()/generator()->maximumCMEnergy()));
   if ( split.index().emitterData()->id() == ParticleID::g ) {
     if ( split.emissionData()->id() != ParticleID::g )
       return {0.5*(1.-c),0.5*(1.+c)};
     double b = log((1.+c)/(1.-c));
     return {-b,b};
   }
   return {-log(0.5*(1.+c)),-log(0.5*(1.-c))};
 }
 
 Energy FFMassiveKinematics::dipoleScale(const Lorentz5Momentum& pEmitter,
 					const Lorentz5Momentum& pSpectator) const {
   return (pEmitter+pSpectator).m();
 }
 
 Energy FFMassiveKinematics::ptMax(Energy dScale, 
 				  double, double,
 				  const DipoleSplittingInfo& dInfo,
 				  const DipoleSplittingKernel& split) const {
 
   DipoleIndex ind = dInfo.index();
   double mui2 = 0.;
   
   // g->gg and g->qqbar
   if ( abs(split.emitter(ind)->id()) == abs(split.emission(ind)->id()) ) {
     mui2 = sqr(split.emitter(ind)->mass() / dScale);
   }
   // Otherwise have X->Xg (should work for SUSY)
   else {
     mui2 = sqr(dInfo.emitterMass()/dScale);
   }
   
-  double mu2  = sqr(split.emission(ind)->mass() / dScale);
-  double muj = dInfo.spectatorMass()/dScale;  
+  double muj2  = sqr(split.emission(ind)->mass() / dScale);
+  double muk = dInfo.spectatorMass()/dScale;  
   
-  return rootOfKallen( mui2, mu2, sqr(1.-muj) ) / ( 2.-2.*muj ) * dScale;
+  return rootOfKallen(mui2, muj2, sqr(1.-muk)) / ( 2.-2.*muk ) * dScale;
 }
 
 
 Energy FFMassiveKinematics::ptMax(Energy dScale, 
 				  double, double,
 				  const DipoleIndex& ind,
 				  const DipoleSplittingKernel& split,
 				  tPPtr emitter, tPPtr spectator) const {
   double mui2 = 0.;  
   // g->gg and g->qqbar
   if ( abs(split.emitter(ind)->id()) == abs(split.emission(ind)->id()) ) {
     mui2 = sqr(split.emitter(ind)->mass() / dScale);
   }
   // Otherwise have X->Xg (should work for SUSY)
   else {
     mui2 = sqr(emitter->mass()/dScale);
   }
-  double mu2 = sqr(split.emission(ind)->mass() / dScale);
-  double muj = spectator->mass()/dScale;
+  double muj2 = sqr(split.emission(ind)->mass() / dScale);
+  double muk = spectator->mass()/dScale;
   
-  return rootOfKallen( mui2, mu2, sqr(1.-muj) ) / ( 2.-2.*muj ) * dScale;
+  return rootOfKallen(mui2, muj2, sqr(1.-muk)) / ( 2.-2.*muk ) * dScale;
 }
 
 
 Energy FFMassiveKinematics::QMax(Energy dScale, 
 				 double, double,
 				 const DipoleSplittingInfo& dInfo,
 				 const DipoleSplittingKernel&) const {
   assert(false && "implementation missing");
-  double Muj = dInfo.spectatorMass() / dScale;
-  return dScale * ( 1.-2.*Muj+sqr(Muj) );
+  double Muk = dInfo.spectatorMass() / dScale;
+  return dScale * ( 1.-2.*Muk+sqr(Muk) );
 }
 
 // The name of this function is misleading
 // scale here is defined as sqr(scale) = sqr(qi+qj)
 // Here, scale is Q
 Energy FFMassiveKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
-  double zPrime=split.lastSplittingParameters()[0];
+  double z=split.lastSplittingParameters()[0];
 
   // masses
   Energy2 mi2 = ZERO;
   // g->gg and g->qqbar
   if ( abs(split.emitterData()->id()) == abs(split.emissionData()->id()) ) {
     mi2 = sqr(split.emitterData()->mass());
   }
   // Otherwise have X->Xg (should work for SUSY)
   else {
     mi2 = sqr(split.emitterMass());
   }
   Energy2 m2 = sqr(split.emissionData()->mass());
 
-  Energy2 pt2 = zPrime*(1.-zPrime)*sqr(scale) - (1-zPrime)*mi2 - zPrime*m2;  
+  Energy2 pt2 = z*(1.-z)*sqr(scale) - (1.-z)*mi2 - z*m2;  
   assert(pt2 >= ZERO);
   return sqrt(pt2);
 }
 
 // This is simply the inverse of PtFromQ
 Energy FFMassiveKinematics::QFromPt(Energy pt, const DipoleSplittingInfo& split) const {
-  double zPrime=split.lastSplittingParameters()[0];
+  double z=split.lastSplittingParameters()[0];
 
   
   // masses
   Energy2 mi2 = ZERO;
   // g->gg and g->qqbar
   if ( abs(split.emitterData()->id()) == abs(split.emissionData()->id()) ) {
     mi2 = sqr( split.emitterData()->mass());
   }
   // Otherwise have X->Xg (should work for SUSY)
   else {
     mi2 = sqr(split.emitterMass());
   }
   Energy2 m2  = sqr(split.emissionData()->mass());
 
-  Energy2 Q2 = (sqr(pt) + (1-zPrime)*mi2 + zPrime*m2)/(zPrime*(1.-zPrime));
+  Energy2 Q2 = (sqr(pt) + (1.-z)*mi2 + z*m2)/(z*(1.-z));
   return sqrt(Q2);
 }
 
 double FFMassiveKinematics::ptToRandom(Energy pt, Energy,
 				       double,double,
 				       const DipoleIndex&,
 				       const DipoleSplittingKernel&) const {
   return log(pt/IRCutoff()) / log(0.5 * generator()->maximumCMEnergy()/IRCutoff());
 }
 
-// TODO - SW: Implement if statement to check 
-// for spectator mass when tidying up the notation.
+// SW, 14/02/2019: Tidied to match thesis
 bool FFMassiveKinematics::generateSplitting(double kappa, double xi, double rphi,
 					    DipoleSplittingInfo& info,
 					    const DipoleSplittingKernel&) {
   
-  // scaled masses
-  double Mui2 = sqr(info.emitterMass() / info.scale());
-  double Muj2 = sqr(info.spectatorMass() / info.scale());
-  double muj2 = Muj2;
+  // Scale 's' and masses
+  Energy2 Qijk = sqr(info.scale());
+  Energy2 mij2 = sqr(info.emitterMass());
+  Energy2 Mk2 = sqr(info.spectatorMass());
   
-  double mui2 = 0.;
-  // g->gg and g->qqbar
-  if ( abs(info.emitterData()->id()) == abs(info.emissionData()->id()) ) {
-    mui2 = sqr(info.emitterData()->mass()/info.scale());
-  }
-  // Otherwise have X->Xg (should work for SUSY)
-  else {
-    mui2 = Mui2;
-  }
-  double mu2 = sqr(info.emissionData()->mass()/info.scale() );
-
   // To solve issue with scale during presampling
-  // need to enforce that Qijk-mij2-mk2 = 2*pij.pk > 0,
-  // so combine checks by comparing against square root.
-  if ( 1.-Mui2-Muj2 < sqrt(4.*Mui2*Muj2) ) {
+  // need to enforce that Qijk-mij2-mk2 = 2*pij.pk > 0.
+  // Combine checks by comparing against square root
+  if ( Qijk-mij2-Mk2 < sqrt(4.*mij2*Mk2) ) {
     jacobian(0.0);
     return false;
   }
 
-  Energy2 Qijk = sqr(info.scale());
-  double suijk = 0.5*( 1. - Mui2 - Muj2 + sqrt( sqr(1.-Mui2-Muj2) - 4.*Mui2*Muj2 ) );
-
+  Energy2 mk2 = Mk2;  
+  Energy2 mi2 = ZERO;
+  // g->gg and g->qqbar
+  if ( abs(info.emitterData()->id()) == abs(info.emissionData()->id()) ) {
+    mi2 = sqr(info.emitterData()->mass());
+  }
+  // Otherwise have X->Xg (should work for SUSY)
+  else {
+    mi2 = mij2;
+  }
+  Energy2 mj2 = sqr(info.emissionData()->mass());
+  
   // Calculate pt 
   Energy pt = IRCutoff() * pow(0.5 * generator()->maximumCMEnergy()/IRCutoff(),kappa);
   Energy2 pt2 = sqr(pt);
-
+  
   if ( pt > info.hardPt() || pt < IRCutoff() ) {
     jacobian(0.0);
     return false;
   }
 
-  // Generate zPrime (i.e. the new definition of z specific to massive FF)
-  double zPrime;
+  // Generate z
+  double z;
   if ( info.index().emitterData()->id() == ParticleID::g ) {
     if ( info.emissionData()->id() != ParticleID::g ) {
-      zPrime = xi;
+      z = xi;
     } 
     else {
-      zPrime = exp(xi)/(1.+exp(xi));
+      z = exp(xi)/(1.+exp(xi));
     }
   } 
   else {
-    zPrime = 1.-exp(-xi);
+    z = 1.-exp(-xi);
   }
 
   // new: 2011-08-31
   // 2011-11-08: this does happen
-  if( sqrt(mui2)+sqrt(mu2)+sqrt(muj2) > 1. ){
+  if( (sqrt(mi2)+sqrt(mj2)+sqrt(mk2))/ sqrt(Qijk) > 1. ){
     jacobian(0.0);
     return false;
   }
 
-  // These apply to zPrime
-  // phasespace constraint to incorporate ptMax
+  // Limits on z.
+  // Phasespace constraint to incorporate ptMax.
   Energy hard = info.hardPt();
+  Energy2 sqrRootQijkMk = sqr(sqrt(Qijk)-sqrt(mk2));
 
   if(openZBoundaries()>0){
 	// From ptMax(..)
-	hard = rootOfKallen( mui2, mu2, sqr(1.-sqrt(muj2)) ) /
-	       ( 2.-2.*sqrt(muj2) ) * info.scale();
+	hard = rootOfKallen(mi2, mj2, sqrRootQijkMk) / ( 2.*sqrt(sqrRootQijkMk) );
 	assert(pt<=hard);
   }
 
   double ptRatio = sqrt(1.-sqr(pt/hard));  
-  double zp1 = ( 1.+mui2-mu2+muj2-2.*sqrt(muj2) +
-		 rootOfKallen(mui2,mu2,sqr(1-sqrt(muj2))) * ptRatio) /
-    ( 2.*sqr(1.-sqrt(muj2)) );
-  double zm1 = ( 1.+mui2-mu2+muj2-2.*sqrt(muj2) -
-		 rootOfKallen(mui2,mu2,sqr(1-sqrt(muj2))) * ptRatio) /
-    ( 2.*sqr(1.-sqrt(muj2)) );
-
-  if ( zPrime > zp1 || zPrime < zm1 ) {
+  double zp1 = ( mi2 - mj2 + sqrRootQijkMk +
+                 rootOfKallen(mi2,mj2,sqrRootQijkMk) * ptRatio )
+    / 2. / sqrRootQijkMk ;
+  double zm1 = ( mi2 - mj2 + sqrRootQijkMk -
+                 rootOfKallen(mi2,mj2,sqrRootQijkMk) * ptRatio )
+    / 2. / sqrRootQijkMk ;
+  
+  if ( z > zp1 || z < zm1 ) {
     jacobian(0.0);
     return false;
   }
-    
-  // Calculate A:=xij*w
-  double A = (1./(suijk*zPrime*(1.-zPrime))) * ( pt2/Qijk + zPrime*mu2 + (1.-zPrime)*mui2 - zPrime*(1.-zPrime)*Mui2 );
 
-  // Calculate y from A (can also write explicitly in terms of qt, zPrime and masses however we need A anyway)
-  double bar = 1.-mui2-mu2-muj2;
-  double y = (1./bar) * (A*suijk + Mui2 - mui2 - mu2 );
+  // Calculate y
+  Energy2 sbar = Qijk - mi2 - mj2 - mk2;
+  double y = (pt2 + sqr(1.-z)*mi2 + sqr(z)*mj2)
+    / sbar / z / (1.-z);
 
-  // kinematic phasespace boundaries for y
-  // same as in Dittmaier hep-ph/9904440v2 (equivalent to CS)
-  double ym = 2.*sqrt(mui2)*sqrt(mu2)/bar;
-  double yp = 1. - 2.*sqrt(muj2)*(1.-sqrt(muj2))/bar;
+  // Kinematic phasespace boundaries for y.
+  // Same as in Dittmaier hep-ph/9904440v2 (equivalent to CS).
+  double ym = 2.*sqrt(mi2)*sqrt(mj2)/sbar;
+  double yp = 1. - 2.*sqrt(mk2)*sqrt(sqrRootQijkMk) / sbar;
   if ( y < ym || y > yp ) {
     jacobian(0.0);
     return false;
   }
 
+  // Virtuality of emitted pair and other invariant scale
+  Energy2 Qij2 = (pt2 + (1.-z)*mi2 + z*mj2)
+    / z / (1.-z);
+  Energy2 sijk = 0.5*( Qijk - mij2 - Mk2 + rootOfKallen(Qijk,mij2,mk2) );
+  
   // Calculate xk and xij
-  double lambdaK = 1. + (Muj2/suijk);
-  double lambdaIJ = 1. + (Mui2/suijk);
-  double xk = (1./(2.*lambdaK)) * ( (lambdaK + (Muj2/suijk)*lambdaIJ - A) + sqrt( sqr(lambdaK + (Muj2/suijk)*lambdaIJ - A) - 4.*lambdaK*lambdaIJ*Muj2/suijk) );
-  double xij = 1. - ( (Muj2/suijk) * (1.-xk) / xk );
+  double lambdaIJ = 1. + (mij2/sijk);
+  double lambdaK = 1. + (mk2/sijk);
+  double fac1 = lambdaIJ*lambdaK + (mk2 - Qij2)/sijk;
+  double xk =
+    ( fac1 + sqrt( sqr(fac1) - 4.*lambdaIJ*lambdaK*mk2/sijk ) )
+    / 2. / lambdaK ;
+  double xij = 1. - mk2*(1.-xk) / xk / sijk;
 
-  // Transform to standard z definition as used in the kernels (i.e. that used in CS and standard sudakov parametrisations)
-  double z = ( (zPrime*xij*xk*suijk/2.) + (Muj2/ ( 2.*xk*xij*suijk*zPrime))*(pt2/Qijk + mui2) ) /
-    ( (xij*xk*suijk/2.) + (Muj2/(2.*xk*xij))*(Mui2/suijk + A) );
+  // Calculate zi
+  double zi =
+    ( z*xij*xk*sijk + mk2*(pt2+mi2) / (z*xij*xk*sijk) )
+    / (1.-y) / sbar;
 
-  // These apply to z, not zPrime
-  double zm = ( (2.*mui2+bar*y)*(1.-y) - sqrt(y*y-ym*ym)*sqrt(sqr(2.*muj2+bar-bar*y)-4.*muj2) ) /
-    ( 2.*(1.-y)*(mui2+mu2+bar*y) );
-  double zp = ( (2.*mui2+bar*y)*(1.-y) + sqrt(y*y-ym*ym)*sqrt(sqr(2.*muj2+bar-bar*y)-4.*muj2) ) /
-    ( 2.*(1.-y)*(mui2+mu2+bar*y) );
+  // Limits on zi
+  double facA = (2.*mi2 + sbar*y) / 2. / (mi2 + mj2 + sbar*y);
+  // viji*vijk
+  double facB =
+    sqrt( (sqr(2.*mk2 + sbar*(1.-y)) - 4.*mk2*Qijk) *
+          (sqr(sbar)*sqr(y) - 4.*mi2*mj2))
+    / sbar / (1.-y) / (sbar*y + 2.*mi2);
+  double zim = facA * (1. - facB);
+  double zip = facA * (1. + facB);
 
-  if ( z < zm || z > zp ) {
+  if ( zi < zim || zi > zip ) {
     jacobian(0.0);
     return false;
   }
 
-  double phi = 2.*Constants::pi*rphi;
-
   double mapZJacobian;
   if ( info.index().emitterData()->id() == ParticleID::g ) {
     if ( info.emissionData()->id() != ParticleID::g ) {
       mapZJacobian = 1.;
     } 
     else {
       mapZJacobian = z*(1.-z);
     }
   } 
   else {
     mapZJacobian = 1.-z;
   }
 
   // Compute and store the jacobian
   double jac = 0.0;
-  double propCntrb = 1./ ( 1. + (mui2+mu2-Mui2)/(bar*y) );  
-
-  // TODO - SW - Tidy up notation everywhere alongside writing for the manual
-  // The full jacobian including the z->zprime jacobian  
-  if ( theFullJacobian && info.spectatorData()->mass() != ZERO ) {
-
-    // Sort out variables
-    Energy2 sbar = Qijk*bar;
-    Energy2 sijk = Qijk*suijk;
-    Energy2 mi2 = Qijk*mui2;
-    Energy2 mj2 = Qijk*mu2;
-    Energy2 mk2 = Qijk*muj2;    
-    
-    // Compute dy/dzPrime and pt2* dy/dpt2
-    double dyBydzPrime = (1./sbar) * ( -pt2*(1.-2.*zPrime)/sqr(zPrime*(1.-zPrime)) - mi2/sqr(zPrime) + mj2/sqr(1.-zPrime) );
-    InvEnergy2 dyBydpt2 = 1./(sbar*zPrime*(1.-zPrime));
-
-    // Compute dA/dzPrime and dA/dpt2
-    double dABydzPrime = (sbar/sijk) * dyBydzPrime;
-    InvEnergy2 dABydpt2 = (sbar/sijk) * dyBydpt2;
-
-    // Compute dxk/dzPrime, dxk/dpt2, dxij/dzPrime and dxij/dpt2
-    double factor = (0.5/lambdaK) * (-1. - (1./sqrt( sqr(lambdaK + (mk2/sijk)*lambdaIJ - A) - 4.*lambdaK*lambdaIJ*mk2/sijk)) * (lambdaK + (mk2/sijk)*lambdaIJ - A));
-    
-    double dxkBydzPrime = factor * dABydzPrime;
-    InvEnergy2 dxkBydpt2 = factor * dABydpt2;
-
-    double dxijBydzPrime = (mk2/sijk) * (1./sqr(xk)) * dxkBydzPrime;
-    InvEnergy2 dxijBydpt2 = (mk2/sijk) * (1./sqr(xk)) * dxkBydpt2;
-
-    Energy2 dqiDotqkBydzPrime = xij*xk*0.5*sijk + zPrime*dxijBydzPrime*xk*0.5*sijk + zPrime*xij*dxkBydzPrime*0.5*sijk
-      + 0.5*(mk2/sijk)*(pt2 + mi2) * (-1./(xk*xij*sqr(zPrime)) - dxkBydzPrime/(zPrime*xij*sqr(xk)) - dxijBydzPrime/(zPrime*xk*sqr(xij)));
-
-    double dqiDotqkBydpt2 =  dxijBydpt2*zPrime*xk*0.5*sijk + zPrime*xij*dxkBydpt2*0.5*sijk
-      + (0.5*mk2/sijk) * (1./(zPrime*xk*xij)) * (1. + (pt2+mi2)*(-dxkBydpt2/xk - dxijBydpt2/xij) );
-
-    
-    // Compute dzBydzPrime and dzBydpt2
-    Energy2 qiDotqk = (zPrime*xij*xk*sijk*0.5) + (mk2/ ( 2.*xk*xij*sijk*zPrime))*(pt2 + mi2);
-
-    double dzBydzPrime = (1./sbar) * ( 2.*qiDotqk*dyBydzPrime/sqr(1.-y) + (1./(1.-y)) * 2.*dqiDotqkBydzPrime );
-    InvEnergy2 dzBydpt2    = (1./sbar) * ( 2.*qiDotqk*dyBydpt2/sqr(1.-y) + (1./(1.-y)) * 2.*dqiDotqkBydpt2 );
-
-    double pt2Jac = pt2*abs(dzBydpt2*dyBydzPrime - dzBydzPrime*dyBydpt2);
-
-    // Include the other terms and calculate the jacobian
-    jac = propCntrb * bar / rootOfKallen(1.,Mui2,Muj2) * (1.-y)/y * pt2Jac;
-  }
-
-
-  // the exact result when the spectator is massless.
-  else {
-    double jacPt2 = 1. / ( 1. + sqr(1.-zPrime)*Qijk*mui2/pt2 + zPrime*zPrime*Qijk*mu2/pt2 );
-    jac = propCntrb * bar / rootOfKallen(1.,Mui2,Muj2) * (1.-y) * jacPt2;    
-  }
+  jac = sbar / rootOfKallen(Qijk,mij2,mk2) * (1.-y) / ( 1. + (mi2 + mj2 - mij2)/sbar/y )
+    * (pt2 / (pt2 + sqr(1.-z)*mi2+sqr(z)*mj2))
+    * abs(1. - 2.*mk2*Qij2 / (sbar*(1.-y)*xij*xk*sijk));
 
   jacobian(jac * mapZJacobian * 2. * log(0.5 * generator()->maximumCMEnergy()/IRCutoff()) );
 
   // Record the physical variables, as used by the CS kernel definitions
+  double phi = 2.*Constants::pi*rphi;
   lastPt(pt);
   lastZ(z);
   lastPhi(phi);
 
-  // Record zPrime for use in kinematics generation and kernel evaluation
+  // Record zi for use in kinematics generation and kernel evaluation
   splittingParameters().clear();
-  splittingParameters().push_back(zPrime);
-
+  splittingParameters().push_back(zi);
+  
   if ( theMCCheck ) {
     theMCCheck->book(1.,1.,info.scale(),info.hardPt(),pt,z,jacobian());
   }
   return true;
 
 }
 
 // revised 2011-08-22
 // revised 2011-11-06
 // revised with new FF kinematics in 2016 - SW
+// SW, 14/02/2019: Tidied to match thesis
 void FFMassiveKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
 					     const Lorentz5Momentum& pSpectator,
 					     const DipoleSplittingInfo& dInfo) {
 
-  // The only value stored in dInfo.lastSplittingParameters() should be zPrime
-  assert(dInfo.lastSplittingParameters().size() == 1 );
-  double zPrime = dInfo.lastSplittingParameters()[0];
+  double z = dInfo.lastZ();
   Energy pt = dInfo.lastPt();
   Energy2 pt2 = sqr(pt);
 
-  // scaled masses
-  double Mui2 = sqr(dInfo.emitterMass() / dInfo.scale());
-  double Muk2 = sqr(dInfo.spectatorMass() / dInfo.scale());
-  //double muk2 = Muk2;
-
-  Energy mi = ZERO;
+  // Masses
+  Energy2 mij2 = sqr(dInfo.emitterMass());
+  Energy2 Mk2 = sqr(dInfo.spectatorMass());
+  Energy2 mk2 = Mk2;
+  
+  Energy2 mi2 = ZERO;
   // g->gg and g->qqbar
   if ( abs(dInfo.emitterData()->id()) == abs(dInfo.emissionData()->id()) ) {
-    mi = dInfo.emitterData()->mass();
+    mi2 = sqr(dInfo.emitterData()->mass());
   }
   // Otherwise have X->Xg (should work for SUSY)
   else {
-    mi = dInfo.emitterMass();
+    mi2 = mij2;
   }
-  double mui2 = sqr(mi/dInfo.scale());
-  double mu2  = sqr(dInfo.emissionData()->mass() / dInfo.scale() );
+  Energy2 mj2 = sqr(dInfo.emissionData()->mass());
 
+  // Scales
   Energy2 Qijk = sqr(dInfo.scale());
-  double suijk = 0.5*( 1. - Mui2 - Muk2 + sqrt( sqr(1.-Mui2-Muk2) - 4.*Mui2*Muk2 ) );
-  double suijk2 = sqr(suijk);
+  Energy2 Qij2 = (pt2 + (1.-z)*mi2 + z*mj2) / z / (1.-z);
+  Energy2 sijk = 0.5*( Qijk - mij2 - Mk2 + rootOfKallen(Qijk,mij2,Mk2) );
+  Energy4 sijk2 = sqr(sijk);
+  
+  // Calculate xk and xij
+  double lambdaIJ = 1. + (mij2/sijk);
+  double lambdaK = 1. + (mk2/sijk);
+  double fac1 = lambdaIJ*lambdaK + (mk2 - Qij2)/sijk;
+  double xk =
+    ( fac1 + sqrt( sqr(fac1) - 4.*lambdaIJ*lambdaK*mk2/sijk ) )
+    / 2. / lambdaK ;
+  double xij = 1. - mk2*(1.-xk) / xk / sijk;
 
-  // Calculate A:=xij*w
-  double A = (1./(suijk*zPrime*(1.-zPrime))) * ( pt2/Qijk + zPrime*mu2 + (1.-zPrime)*mui2 - zPrime*(1.-zPrime)*Mui2 );
-
-  // Calculate the scaling factors, xk and xij
-  double lambdaK = 1. + (Muk2/suijk);
-  double lambdaIJ = 1. + (Mui2/suijk);
-  double xk = (1./(2.*lambdaK)) * ( (lambdaK + (Muk2/suijk)*lambdaIJ - A) + sqrt( sqr(lambdaK + (Muk2/suijk)*lambdaIJ - A) - 4.*lambdaK*lambdaIJ*Muk2/suijk) );
-  double xij = 1. - ( (Muk2/suijk) * (1.-xk) / xk );
-
-  // Construct reference momenta nk, nij, nt
-  Lorentz5Momentum nij = ( suijk2 / (suijk2-Mui2*Muk2) ) * (pEmitter - (Mui2/suijk)*pSpectator);
-  Lorentz5Momentum nk = ( suijk2 / (suijk2-Mui2*Muk2) ) * (pSpectator - (Muk2/suijk)*pEmitter);
-
-  // Following notation in notes, qt = sqrt(wt)*nt
-  Lorentz5Momentum qt = getKt(nij,nk,pt,dInfo.lastPhi());
+  // Construct reference momenta nk and nij
+  Lorentz5Momentum nij = ( sijk2 / (sijk2-mij2*Mk2) ) * (pEmitter - (mij2/sijk)*pSpectator);
+  Lorentz5Momentum nk = ( sijk2 / (sijk2-mij2*Mk2) ) * (pSpectator - (Mk2/sijk)*pEmitter);
 
   // Construct qij, qk, qi and qj
-  Lorentz5Momentum qij = xij*nij + (Mui2/(xij*suijk))*nk;
-  Lorentz5Momentum qk = xk*nk + (Muk2/(xk*suijk))*nij;
+  Lorentz5Momentum qij = xij*nij + (mij2/(xij*sijk))*nk;
+  Lorentz5Momentum qk = xk*nk + (Mk2/(xk*sijk))*nij;
+
+  Lorentz5Momentum qt = getKt(pEmitter, pSpectator, pt, dInfo.lastPhi());
 
   // For clarity, following notation in notes:
-  //Lorentz5Momentum qi = zPrime*qij + ((pt2 + mi2 - zPrime*zPrime*mij2)/(xij*sijk*zPrime))*nk + sqrt(wt)*nt;
-  //Lorentz5Momentum qj = (1.-zPrime)*qij + ((pt2 + mj2 - sqr(1.-zPrime)*mij2)/(xij*sijk*(1.-zPrime)))*nk - sqrt(wt)*nt;
+  Lorentz5Momentum qi = z*qij + ((pt2 + mi2 - z*z*mij2)/(xij*sijk*z))*nk + qt;
+  Lorentz5Momentum qj = (1.-z)*qij + ((pt2 + mj2 - sqr(1.-z)*mij2)/(xij*sijk*(1.-z)))*nk - qt;
 
-  // No need to actually calculate nt and wt:
-  Lorentz5Momentum qi = zPrime*qij + ((pt2/Qijk + mui2 - zPrime*zPrime*Mui2)/(xij*suijk*zPrime))*nk + qt;
-  Lorentz5Momentum qj = (1.-zPrime)*qij + ((pt2/Qijk + mu2 - sqr(1.-zPrime)*Mui2)/(xij*suijk*(1.-zPrime)))*nk - qt;
-
-  qi.setMass(mi);
+  qi.setMass(sqrt(mi2));
   qi.rescaleEnergy();
   
-  qj.setMass(dInfo.emissionData()->mass());
+  qj.setMass(sqrt(mj2));
   qj.rescaleEnergy();
   
-  qk.setMass(dInfo.spectatorMass());
+  qk.setMass(sqrt(mk2));
   qk.rescaleEnergy();
   
   emitterMomentum(qi);
   emissionMomentum(qj);
   spectatorMomentum(qk);
   
 }
 
 
 // If needed, insert default implementations of function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
-void FFMassiveKinematics::persistentOutput(PersistentOStream & os) const {
-  os << theFullJacobian;
+void FFMassiveKinematics::persistentOutput(PersistentOStream &) const {
+  //os << ;
 }
 
-void FFMassiveKinematics::persistentInput(PersistentIStream & is, int) {
-  is >> theFullJacobian;
+void FFMassiveKinematics::persistentInput(PersistentIStream &, int) {
+  //is >> ;
 }
 
 ClassDescription<FFMassiveKinematics> FFMassiveKinematics::initFFMassiveKinematics;
 // Definition of the static class description member.
 
 void FFMassiveKinematics::Init() {
 
   static ClassDocumentation<FFMassiveKinematics> documentation
     ("FFMassiveKinematics implements massive splittings "
      "off a final-final dipole.");
-
   
-  static Switch<FFMassiveKinematics,bool> interfaceFullJacobian
-    ("FullJacobian",
-     "Use the full jacobian expression for the FF kinematics.",
-     &FFMassiveKinematics::theFullJacobian, true, false, false);
-  static SwitchOption interfaceFullJacobianYes
-    (interfaceFullJacobian,
-     "Yes",
-     "Use the full jacobian.",
-     true);
-  static SwitchOption interfaceFullJacobianNo
-    (interfaceFullJacobian,
-     "No",
-     "Do not use the full jacobian.",
-     false);
-  interfaceFullJacobian.rank(-1);
 }
 
diff --git a/Shower/Dipole/Kinematics/FFMassiveKinematics.h b/Shower/Dipole/Kinematics/FFMassiveKinematics.h
--- a/Shower/Dipole/Kinematics/FFMassiveKinematics.h
+++ b/Shower/Dipole/Kinematics/FFMassiveKinematics.h
@@ -1,303 +1,305 @@
 // -*- C++ -*-
 //
 // FFMassiveKinematics.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_FFMassiveKinematics_H
 #define HERWIG_FFMassiveKinematics_H
 //
 // This is the declaration of the FFMassiveKinematics class.
 //
 
 #include "DipoleSplittingKinematics.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer, Stephen Webster
  *
  * \brief FFMassiveKinematics implements massive splittings
  * off a final-final dipole.
  *
  */
 class FFMassiveKinematics: public DipoleSplittingKinematics {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   FFMassiveKinematics();
 
   /**
    * The destructor.
    */
   virtual ~FFMassiveKinematics();
   //@}
 
 public:
 
   /**
    * Return the boundaries in between the evolution
    * variable random number is to be sampled; the lower
    * cuoff is assumed to correspond to the infrared cutoff.
    */
   virtual pair<double,double> kappaSupport(const DipoleSplittingInfo& dIndex) const;
 
   /**
    * Return the boundaries in between the momentum
    * fraction random number is to be sampled.
    */
   virtual pair<double,double> xiSupport(const DipoleSplittingInfo& dIndex) const;
 
   /**
    * Return the boundaries on the momentum fraction
    */
   virtual pair<double,double> zBoundaries(Energy,
 					  const DipoleSplittingInfo&,
 					  const DipoleSplittingKernel&) const {
     return {0.0,1.0};
   }
 
   /**
    * Return the dipole scale associated to the
    * given pair of emitter and spectator. This
    * should be the invariant mass or absolute value
    * final/final or initial/initial and the absolute
    * value of the momentum transfer for intial/final or
    * final/initial dipoles.
    */
   virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
 			     const Lorentz5Momentum& pSpectator) const;
 
     /**
      * Return the maximum pt for the given dipole scale.
      */
     virtual Energy ptMax(Energy dScale, 
 			 double emX, double specX,
 			 const DipoleSplittingInfo& dInfo,
 			 const DipoleSplittingKernel& split) const;
 
     /**
      * Return the maximum pt for the given dipole scale.
      */
     virtual Energy ptMax(Energy dScale, 
 			 double, double,
 			 const DipoleIndex& dIndex,
 			 const DipoleSplittingKernel& split,
 			 tPPtr emitter, tPPtr spectator) const;
   
     /**
      * Return the maximum pt for the given dipole scale.
      */
     virtual Energy ptMax(Energy, 
 			 double, double,
 			 const DipoleIndex&,
 			 const DipoleSplittingKernel&) const {
       // Only the DipoleSplittingInfo version should be used for massive
       // dipoles, for now anyway.
       assert(false);
       return ZERO;
     }
   
     /**
      * Return the maximum virtuality for the given dipole scale.
      */
     virtual Energy QMax(Energy dScale, 
 			double emX, double specX,
 			const DipoleSplittingInfo& dInfo,
 			const DipoleSplittingKernel& split) const;
   
     /**
      * Return the maximum virtuality for the given dipole scale.
      */
     virtual Energy QMax(Energy, 
     			double, double,
     			const DipoleIndex&,
     			const DipoleSplittingKernel&) const { 
       // Only the DipoleSplittingInfo version should be used for massive
       // dipoles, for now anyway.
       assert(false);
       return ZERO;
     }
 
   /**
    * Return the pt given a virtuality.
    */
   virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
 
   /**
    * Return the virtuality given a pt.
    */
   virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
 
   /**
    * Return the random number associated to
    * the given pt.
    */
   virtual double ptToRandom(Energy pt, Energy dScale,
 			    double emX, double specX,
 			    const DipoleIndex& dIndex,
 			    const DipoleSplittingKernel& split) const;
 
   /**
    * Generate splitting variables given three random numbers
    * and the momentum fractions of the emitter and spectator.
    * Return true on success.
    */
   virtual bool generateSplitting(double kappa, double xi, double phi,
 				 DipoleSplittingInfo& dIndex,
 				 const DipoleSplittingKernel& split);
 
   /**
    * Generate the full kinematics given emitter and
    * spectator momentum and a previously completeted
    * DipoleSplittingInfo object.
    */
   virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
 				  const Lorentz5Momentum& pSpectator,
 				  const DipoleSplittingInfo& dInfo);
 
 public:
   
   /**
    * Triangular / Kallen function
    */
   template <class T>
-  inline double rootOfKallen (T a, T b, T c) const {
-    double sres=a*a + b*b + c*c - 2.*( a*b+a*c+b*c );
-    return sres>0.?sqrt( sres ):0.; }
+  inline T rootOfKallen (T a, T b, T c) const {
+    if ( a*a + b*b + c*c - 2.*(a*b + a*c + b*c) > ZERO )
+      return sqrt(a*a + b*b + c*c - 2.*(a*b + a*c + b*c) ) ;
+    else
+      return ZERO; }
   
   /**
    * Perform a rotation on both momenta such that the first one will
    * point along the (positive) z axis. Rotate back to the original
    * reference frame by applying rotateUz(returnedVector) to each momentum.
    */
   ThreeVector<double> rotateToZ (Lorentz5Momentum& pTarget, Lorentz5Momentum& p1){
     ThreeVector<double> oldAxis = pTarget.vect().unit();
     double ct = oldAxis.z(); double st = sqrt( 1.-sqr(ct) ); // cos,sin(theta)
     double cp = oldAxis.x()/st; double sp = oldAxis.y()/st; // cos,sin(phi)
     pTarget.setZ( pTarget.vect().mag() ); pTarget.setX( 0.*GeV ); pTarget.setY( 0.*GeV );
     Lorentz5Momentum p1old = p1;
     p1.setX(    sp*p1old.x() -    cp*p1old.y()                );
     p1.setY( ct*cp*p1old.x() + ct*sp*p1old.y() - st*p1old.z() );
     p1.setZ( st*cp*p1old.x() + st*sp*p1old.y() + ct*p1old.z() );
     return oldAxis;
   }
 
 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<FFMassiveKinematics> initFFMassiveKinematics;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   FFMassiveKinematics & operator=(const FFMassiveKinematics &) = delete;
 
   /**
    * Option to use the full jacobian, including the z->zprime jacobian.
    **/
   bool  theFullJacobian;
 
   
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of FFMassiveKinematics. */
 template <>
 struct BaseClassTrait<Herwig::FFMassiveKinematics,1> {
   /** Typedef of the first base class of FFMassiveKinematics. */
   typedef Herwig::DipoleSplittingKinematics NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the FFMassiveKinematics class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::FFMassiveKinematics>
   : public ClassTraitsBase<Herwig::FFMassiveKinematics> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::FFMassiveKinematics"; }
   /**
    * The name of a file containing the dynamic library where the class
    * FFMassiveKinematics is implemented. It may also include several, space-separated,
    * libraries if the class FFMassiveKinematics depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_FFMassiveKinematics_H */
diff --git a/Shower/Dipole/Kinematics/FILightKinematics.cc b/Shower/Dipole/Kinematics/FILightKinematics.cc
--- a/Shower/Dipole/Kinematics/FILightKinematics.cc
+++ b/Shower/Dipole/Kinematics/FILightKinematics.cc
@@ -1,187 +1,187 @@
 // -*- C++ -*-
 //
 // FILightKinematics.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 FILightKinematics class.
 //
 
 #include "FILightKinematics.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 #include "ThePEG/Repository/UseRandom.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
 
 using namespace Herwig;
 
 FILightKinematics::FILightKinematics() 
   : DipoleSplittingKinematics() {}
 
 FILightKinematics::~FILightKinematics() {}
 
 IBPtr FILightKinematics::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FILightKinematics::fullclone() const {
   return new_ptr(*this);
 }
 
 Energy FILightKinematics::ptMax(Energy dScale, 
 				double, double specX,
 				const DipoleIndex&,
 				const DipoleSplittingKernel&) const {
   return dScale * sqrt((1.-specX)/specX) /2.;
 }
 
 Energy FILightKinematics::QMax(Energy dScale, 
 			       double, double specX,
 			       const DipoleIndex&,
 			       const DipoleSplittingKernel&) const {
   return dScale * sqrt((1.-specX)/specX);
 }
 
 Energy FILightKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
   double z = split.lastZ();
   return scale*sqrt(z*(1.-z));
 }
 
 Energy FILightKinematics::QFromPt(Energy scale, const DipoleSplittingInfo& split) const {
   double z = split.lastZ();
   return scale/sqrt(z*(1.-z));
 }
 
 pair<double,double> FILightKinematics::zBoundaries(Energy pt,
 						   const DipoleSplittingInfo& dInfo,
 						   const DipoleSplittingKernel&) const {
   Energy hard=dInfo.hardPt();
   if(openZBoundaries()==1)
 	hard=dInfo.scale()*sqrt((1.-dInfo.spectatorX())/dInfo.spectatorX())/2.;
   if(openZBoundaries()==2)
     hard=dInfo.scale()*min(1.,sqrt((1.-dInfo.spectatorX())/dInfo.spectatorX())/2.);
   if(hard<pt)return {0.5,0.5};
   double s = sqrt(1.-sqr(pt/hard));
   return {0.5*(1.-s),0.5*(1.+s)};
 }
 
 bool FILightKinematics::generateSplitting(double kappa, double xi, double rphi,
 					  DipoleSplittingInfo& info,
 					  const DipoleSplittingKernel& split) {
 
   if ( info.spectatorX() < xMin() ) {
     jacobian(0.0);
     return false;
   }
 
   double weight = 1.0;
 
   Energy pt = generatePt(kappa,info.scale(),
 			 info.emitterX(),info.spectatorX(),
 			 info.index(),split,
 			 weight);
 
   if ( pt < IRCutoff() || pt > info.hardPt() ) {
     jacobian(0.0);
     return false;
   }
 
   double z = 0.0;
 
   if ( info.index().emitterData()->id() == ParticleID::g ) {
     if ( info.emissionData()->id() != ParticleID::g ) {
       z = generateZ(xi,pt,FlatZ,
 		    info,split,weight);
     } else {
       z = generateZ(xi,pt,OneOverZOneMinusZ,
 		    info,split,weight);
     }
   } else {
     z = generateZ(xi,pt,OneOverOneMinusZ,
 		  info,split,weight);
   }
 
   double x = 1./(1.+sqr(pt/info.scale())/(z*(1.-z)));
 
   if ( z < 0.0 || z > 1.0 ||
        x < info.spectatorX() || x > 1.0 ) {
     jacobian(0.0);
     return false;
   }
 
   double phi = 2.*Constants::pi*rphi;
 
   jacobian(weight);
 
   lastPt(pt);
   lastZ(z);
   lastPhi(phi);
   lastSpectatorZ(x);
 
   if ( theMCCheck )
     theMCCheck->book(1.,info.spectatorX(),info.scale(),info.hardPt(),pt,z,jacobian());
 
   return true;
 
 }
 
 void FILightKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
 					   const Lorentz5Momentum& pSpectator,
 					   const DipoleSplittingInfo& dInfo) {
 
   Energy pt = dInfo.lastPt();
   double z = dInfo.lastZ();
   double x = 1./(1.+sqr(pt/dInfo.scale())/(z*(1.-z)));
-
+  
   Lorentz5Momentum kt =
-    getKt (pSpectator, pEmitter, pt, dInfo.lastPhi(),true);
+    getKt(pEmitter, pSpectator, pt, dInfo.lastPhi(), true);
 
   Lorentz5Momentum em = z*pEmitter + (1.-z)*((1.-x)/x)*pSpectator + kt;
   Lorentz5Momentum emm = (1.-z)*pEmitter + z*((1.-x)/x)*pSpectator - kt;
   Lorentz5Momentum spe = (1./x)*pSpectator;
   
   em.setMass(ZERO);
   em.rescaleEnergy();
 
   emm.setMass(ZERO);
   emm.rescaleEnergy();
   
   spe.setMass(ZERO);
   spe.rescaleEnergy();
 
   emitterMomentum(em);
   emissionMomentum(emm);
   spectatorMomentum(spe);
 
 }
 
 // If needed, insert default implementations of function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FILightKinematics::persistentOutput(PersistentOStream & ) const {
 }
 
 void FILightKinematics::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<FILightKinematics> FILightKinematics::initFILightKinematics;
 // Definition of the static class description member.
 
 void FILightKinematics::Init() {
 
   static ClassDocumentation<FILightKinematics> documentation
     ("FILightKinematics implements massless splittings "
      "off a final-initial dipole.");
 
 }
 
diff --git a/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.cc b/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.cc
--- a/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.cc
+++ b/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.cc
@@ -1,512 +1,452 @@
 // -*- C++ -*-
 //
 // FIMassiveDecayKinematics.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 FIMassiveDecayKinematics class.
 //
 
 #include "FIMassiveDecayKinematics.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 #include "ThePEG/Repository/UseRandom.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
 #include "Herwig/Shower/Dipole/Kernels/DipoleSplittingKernel.h"
 
 #include "ThePEG/Interface/Switch.h"
 
 
 using namespace Herwig;
 
 FIMassiveDecayKinematics::FIMassiveDecayKinematics() 
-  : DipoleSplittingKinematics(), theFullJacobian(true) {}
+  : DipoleSplittingKinematics() {}
 
 FIMassiveDecayKinematics::~FIMassiveDecayKinematics() {}
 
 IBPtr FIMassiveDecayKinematics::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FIMassiveDecayKinematics::fullclone() const {
   return new_ptr(*this);
 }
 
 pair<double,double> FIMassiveDecayKinematics::kappaSupport(const DipoleSplittingInfo&) const {
   return {0.0,1.0};
 }
 
 pair<double,double> FIMassiveDecayKinematics::xiSupport(const DipoleSplittingInfo& split) const {
 
   double c = sqrt(1.-4.*sqr(IRCutoff()/generator()->maximumCMEnergy()));
 
   if ( split.index().emitterData()->id() == ParticleID::g ) {
     if ( split.emissionData()->id() != ParticleID::g ){
       return {0.5*(1.-c),0.5*(1.+c)};
     }
     double b = log((1.+c)/(1.-c));
     return {-b,b};
   }
   return {-log(0.5*(1.+c)),-log(0.5*(1.-c))};
 }
 
 Energy FIMassiveDecayKinematics::dipoleScale(const Lorentz5Momentum&,
-					     const Lorentz5Momentum& pSpectator) const {
+                                             const Lorentz5Momentum& pSpectator) const {
   return pSpectator.m();
 }
 
 Energy FIMassiveDecayKinematics::recoilMassKin(const Lorentz5Momentum& pEmitter,
-					       const Lorentz5Momentum& pSpectator) const {
+                                               const Lorentz5Momentum& pSpectator) const {
   Lorentz5Momentum pk = pSpectator - pEmitter;
   Energy pkmass = pk.m();
   return pkmass;
 }
 
 Energy FIMassiveDecayKinematics::ptMax(Energy dScale, 
-				       double, double,
-				       const DipoleSplittingInfo& dInfo,
-				       const DipoleSplittingKernel& split) const {
+                                       double, double,
+                                       const DipoleSplittingInfo& dInfo,
+                                       const DipoleSplittingKernel& split) const {
 
 
   DipoleIndex ind = dInfo.index();
   double mui2 = 0.;
 
   // g->gg and g->qqbar
   if ( abs(split.emitter(ind)->id()) == abs(split.emission(ind)->id()) ) {
     mui2 = sqr(split.emitter(ind)->mass() / dScale);
   }
   // Otherwise have X->Xg (should work for SUSY)
   else {
     mui2 = sqr(dInfo.emitterMass()/dScale);
   }
-  double mu2  = sqr(split.emission(ind)->mass() / dScale);
+  double muj2  = sqr( split.emission(ind)->mass() / dScale );
   
   // Mass of recoil system
-  double muj = dInfo.recoilMass() / dScale;
+  double muk = dInfo.recoilMass() / dScale;
 
-  return rootOfKallen( mui2, mu2, sqr(1.-muj) ) / ( 2.-2.*muj ) * dScale;
+  return rootOfKallen( mui2, muj2, sqr(1.-muk) ) / ( 2.-2.*muk ) * dScale;
 }
 
 
 Energy FIMassiveDecayKinematics::ptMax(Energy dScale, 
-				       double, double,
-				       const DipoleIndex& ind,
-				       const DipoleSplittingKernel& split,
-				       tPPtr emitter, tPPtr spectator) const {
+                                       double, double,
+                                       const DipoleIndex& ind,
+                                       const DipoleSplittingKernel& split,
+                                       tPPtr emitter, tPPtr spectator) const {
   double mui2 = 0.;
   // g->gg and g->qqbar
   if ( abs(split.emitter(ind)->id()) == abs(split.emission(ind)->id()) ) {
     mui2 = sqr(split.emitter(ind)->mass() / dScale);
   }
   // Otherwise have X->Xg (should work for SUSY)
   else {
     mui2 = sqr(emitter->mass()/dScale);
   }
-  double mu2  = sqr(split.emission(ind)->mass() / dScale);
+  double muj2  = sqr(split.emission(ind)->mass() / dScale);
   
   // Mass of recoil system
-  double muj = recoilMassKin(emitter->momentum(),spectator->momentum()) / dScale;
+  double muk = recoilMassKin(emitter->momentum(),spectator->momentum()) / dScale;
 
-  return rootOfKallen( mui2, mu2, sqr(1.-muj) ) / ( 2.-2.*muj ) * dScale;
+  return rootOfKallen( mui2, muj2, sqr(1.-muk) ) / ( 2.-2.*muk ) * dScale;
 }
 
 
 Energy FIMassiveDecayKinematics::QMax(Energy dScale, 
-				      double, double,
-				      const DipoleSplittingInfo& dInfo,
-				      const DipoleSplittingKernel&) const {
+                                      double, double,
+                                      const DipoleSplittingInfo& dInfo,
+                                      const DipoleSplittingKernel&) const {
   assert(false && "implementation missing");
   // Mass of recoil system
-  double Muj2 = sqr( dInfo.recoilMass() / dScale );
-  double Muj = sqrt( Muj2 );
+  double Muk2 = sqr( dInfo.recoilMass() / dScale );
+  double Muk = sqrt( Muk2 );
 
-  return dScale * ( 1.-2.*Muj+Muj2 );
+  return dScale * ( 1.-2.*Muk+Muk2 );
 }
 
 // The name of this function is misleading
 // scale here is defined as sqr(scale) = sqr(qi+qj)
 // Here, scale is Q
 Energy FIMassiveDecayKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
   double zPrime = split.lastSplittingParameters()[0];
   
   // masses
   Energy2 mi2 = ZERO;
   // g->gg and g->qqbar
   if ( abs(split.emitterData()->id()) == abs(split.emissionData()->id()) ) {
     mi2 = sqr( split.emitterData()->mass());
   }
   // Otherwise have X->Xg (should work for SUSY)
   else {
     mi2 = sqr(split.emitterMass());
   }
   Energy2 m2  = sqr(split.emissionData()->mass());
 
   Energy2 pt2 = zPrime*(1.-zPrime)*sqr(scale) - (1-zPrime)*mi2 - zPrime*m2;
   assert(pt2 >= ZERO);
   return sqrt(pt2);
 }
 
 
 // This is simply the inverse of PtFromQ
 Energy FIMassiveDecayKinematics::QFromPt(Energy pt, const DipoleSplittingInfo& split) const {
   double zPrime = split.lastSplittingParameters()[0];
   
   // masses
   Energy2 mi2 = ZERO;
   // g->gg and g->qqbar
   if ( abs(split.emitterData()->id()) == abs(split.emissionData()->id()) ) {
     mi2 = sqr( split.emitterData()->mass());
   }
   // Otherwise have X->Xg (should work for SUSY)
   else {
     mi2 = sqr(split.emitterMass());
   }
   Energy2 m2  = sqr(split.emissionData()->mass());
 
   Energy2 Q2 = (sqr(pt) + (1-zPrime)*mi2 + zPrime*m2)/(zPrime*(1.-zPrime));
   return sqrt(Q2);
 }
 
 double FIMassiveDecayKinematics::ptToRandom(Energy pt, Energy,
-					    double,double,
-					    const DipoleIndex&,
-					    const DipoleSplittingKernel&) const {
+                                            double,double,
+                                            const DipoleIndex&,
+                                            const DipoleSplittingKernel&) const {
   return log(pt/IRCutoff()) / log(0.5 * generator()->maximumCMEnergy()/IRCutoff());
 }
 
+// SW, 14/02/2019: Tidied to match thesis
+bool FIMassiveDecayKinematics::generateSplitting(double kappa, double xi, double rphi,
+                                                 DipoleSplittingInfo& info,
+                                                 const DipoleSplittingKernel&) {
+  
+  // Scale 's' and masses
+  Energy2 Qijk = sqr(info.scale());
+  Energy2 mij2 = sqr(info.emitterMass());
+  Energy2 Mk2 = sqr(info.recoilMass());
 
-bool FIMassiveDecayKinematics::generateSplitting(double kappa, double xi, double rphi,
-						 DipoleSplittingInfo& info,
-						 const DipoleSplittingKernel&) {
-
-  // scaled masses
-  double Mui2 = sqr(info.emitterMass() / info.scale());
-  double Muj2 = sqr(info.recoilMass() / info.scale());
-  double muj2 = Muj2;
-
-  double mui2 = 0.;
-  // g->gg and g->qqbar
-  if ( abs(info.emitterData()->id()) == abs(info.emissionData()->id()) ) {
-    mui2 = sqr(info.emitterData()->mass()/info.scale());
-  }
-  // Otherwise have X->Xg (should work for SUSY)
-  else {
-    mui2 = Mui2;
-  }
-  double mu2 = sqr(info.emissionData()->mass()/info.scale() );
-
-  
   // To solve issue with scale during presampling
-  // need to enforce that Qijk-mij2-mk2 = 2*pij.pk > 0,
-  // so combine checks by comparing against square root.
-  if ( 1.-Mui2-Muj2 < sqrt(4.*Mui2*Muj2) ) {
+  // need to enforce that Qijk-mij2-mk2 = 2*pij.pk > 0.
+  // Combine checks by comparing against square root
+  if ( Qijk-mij2-Mk2 < sqrt(4.*mij2*Mk2) ) {
     jacobian(0.0);
     return false;
   }
 
-  Energy2 Qijk = sqr(info.scale());
-  double suijk = 0.5*( 1. - Mui2 - Muj2 + sqrt( sqr(1.-Mui2-Muj2) - 4.*Mui2*Muj2 ) );
+  Energy2 mk2 = Mk2;  
+  Energy2 mi2 = ZERO;
+  // g->gg and g->qqbar
+  if ( abs(info.emitterData()->id()) == abs(info.emissionData()->id()) ) {
+    mi2 = sqr(info.emitterData()->mass());
+  }
+  // Otherwise have X->Xg (should work for SUSY)
+  else {
+    mi2 = mij2;
+  }
+  Energy2 mj2 = sqr(info.emissionData()->mass());
 
-  // Calculate pt
+  // Calculate pt 
   Energy pt = IRCutoff() * pow(0.5 * generator()->maximumCMEnergy()/IRCutoff(),kappa);
   Energy2 pt2 = sqr(pt);
-
+  
   if ( pt > info.hardPt() || pt < IRCutoff() ) {
     jacobian(0.0);
     return false;
   }
 
-  // Generate zPrime (i.e. the new definition of z specific to massive FF and decays)
-  double zPrime;
+  // Generate z
+  double z;
   if ( info.index().emitterData()->id() == ParticleID::g ) {
     if ( info.emissionData()->id() != ParticleID::g ) {
-      zPrime = xi;
+      z = xi;
     } 
     else {
-      zPrime = exp(xi)/(1.+exp(xi));
+      z = exp(xi)/(1.+exp(xi));
     }
   } 
   else {
-    zPrime = 1.-exp(-xi);
+    z = 1.-exp(-xi);
   }
 
   // new: 2011-08-31
   // 2011-11-08: this does happen
-  if( sqrt(mui2)+sqrt(mu2)+sqrt(muj2) > 1. ){
-    jacobian(0.0);
-    return false;
-  }
-  
-  // Have derived and checked the equations for zp1 and zm1, these apply to zPrime
-  // phasespace constraint to incorporate ptMax
-  Energy hard = info.hardPt();
-
-  if(openZBoundaries()>0){
-    // From ptMax(..)
-    hard = rootOfKallen( mui2, mu2, sqr(1.-sqrt(muj2)) ) /
-      ( 2.-2.*sqrt(muj2) ) * info.scale();
-    assert(pt<=hard);
-  }
-  
-  double ptRatio = sqrt(1.-sqr(pt/hard));
-  double zp1 = ( 1.+mui2-mu2+muj2-2.*sqrt(muj2) +
-		 rootOfKallen(mui2,mu2,sqr(1-sqrt(muj2))) * ptRatio) /
-    ( 2.*sqr(1.-sqrt(muj2)) );
-  double zm1 = ( 1.+mui2-mu2+muj2-2.*sqrt(muj2) -
-		 rootOfKallen(mui2,mu2,sqr(1-sqrt(muj2))) * ptRatio) /
-    ( 2.*sqr(1.-sqrt(muj2)) );
-  
-  if ( zPrime > zp1 || zPrime < zm1 ) {
+  if( (sqrt(mi2)+sqrt(mj2)+sqrt(mk2))/ sqrt(Qijk) > 1. ){
     jacobian(0.0);
     return false;
   }
 
-  // Calculate A:=xij*w
-  double A = (1./(suijk*zPrime*(1.-zPrime))) * ( pt2/Qijk + zPrime*mu2 + (1.-zPrime)*mui2 - zPrime*(1.-zPrime)*Mui2 );
+  // Limits on z.
+  // Phasespace constraint to incorporate ptMax.
+  Energy hard = info.hardPt();
+  Energy2 sqrRootQijkMk = sqr(sqrt(Qijk)-sqrt(mk2));
 
-  // Calculate y from A (can also write explicitly in terms of qt, zPrime and masses however we need A anyway)
-  double bar = 1.-mui2-mu2-muj2;
-  double y = (1./bar) * (A*suijk + Mui2 - mui2 - mu2 );
+  if(openZBoundaries()>0){
+	// From ptMax(..)
+	hard = rootOfKallen(mi2, mj2, sqrRootQijkMk) / ( 2.*sqrt(sqrRootQijkMk) );
+	assert(pt<=hard);
+  }
 
-  // kinematic phasespace boundaries for y
-  // same as in Dittmaier hep-ph/9904440v2 (equivalent to CS)
-  double ym = 2.*sqrt(mui2)*sqrt(mu2)/bar;
-  double yp = 1. - 2.*sqrt(muj2)*(1.-sqrt(muj2))/bar;
+  double ptRatio = sqrt(1.-sqr(pt/hard));  
+  double zp1 = ( mi2 - mj2 + sqrRootQijkMk +
+                 rootOfKallen(mi2,mj2,sqrRootQijkMk) * ptRatio )
+    / 2. / sqrRootQijkMk ;
+  double zm1 = ( mi2 - mj2 + sqrRootQijkMk -
+                 rootOfKallen(mi2,mj2,sqrRootQijkMk) * ptRatio )
+    / 2. / sqrRootQijkMk ;
+  
+  if ( z > zp1 || z < zm1 ) {
+    jacobian(0.0);
+    return false;
+  }
+
+  // Calculate y
+  Energy2 sbar = Qijk - mi2 - mj2 - mk2;
+  double y = (pt2 + sqr(1.-z)*mi2 + sqr(z)*mj2)
+    / sbar / z / (1.-z);
+
+  // Kinematic phasespace boundaries for y.
+  // Same as in Dittmaier hep-ph/9904440v2 (equivalent to CS).
+  double ym = 2.*sqrt(mi2)*sqrt(mj2)/sbar;
+  double yp = 1. - 2.*sqrt(mk2)*sqrt(sqrRootQijkMk) / sbar;
   if ( y < ym || y > yp ) {
     jacobian(0.0);
     return false;
   }
 
+  // Virtuality of emitted pair and other invariant scale
+  Energy2 Qij2 = (pt2 + (1.-z)*mi2 + z*mj2) / z / (1.-z);
+  Energy2 sijk = 0.5*( Qijk - mij2 - Mk2 + rootOfKallen(Qijk,mij2,mk2) );
+  
   // Calculate xk and xij
-  double lambdaK = 1. + (Muj2/suijk);
-  double lambdaIJ = 1. + (Mui2/suijk);
-  double xk = (1./(2.*lambdaK)) * ( (lambdaK + (Muj2/suijk)*lambdaIJ - A) + sqrt( sqr(lambdaK + (Muj2/suijk)*lambdaIJ - A) - 4.*lambdaK*lambdaIJ*Muj2/suijk) );
-  double xij = 1. - ( (Muj2/suijk) * (1.-xk) / xk );
+  double lambdaIJ = 1. + (mij2/sijk);
+  double lambdaK = 1. + (mk2/sijk);
+  double fac1 = lambdaIJ*lambdaK + (mk2 - Qij2)/sijk;
+  double xk =
+    ( fac1 + sqrt( sqr(fac1) - 4.*lambdaIJ*lambdaK*mk2/sijk ) )
+    / 2. / lambdaK ;
+  double xij = 1. - mk2*(1.-xk) / xk / sijk;
 
-  // Transform to standard z definition as used in the kernels (i.e. that used in CS and standard sudakov parametrisations)
-  double z = ( (zPrime*xij*xk*suijk/2.) + (Muj2/ ( 2.*xk*xij*suijk*zPrime))*(pt2/Qijk + mui2) ) /
-    ( (xij*xk*suijk/2.) + (Muj2/(2.*xk*xij))*(Mui2/suijk + A) );
+  // Calculate zi
+  double zi =
+    ( z*xij*xk*sijk + mk2*(pt2+mi2) / (z*xij*xk*sijk) )
+    / (1.-y) / sbar;
 
-  // These apply to z, not zPrime
-  double zm = ( (2.*mui2+bar*y)*(1.-y) - sqrt(y*y-ym*ym)*sqrt(sqr(2.*muj2+bar-bar*y)-4.*muj2) ) /
-    ( 2.*(1.-y)*(mui2+mu2+bar*y) );
-  double zp = ( (2.*mui2+bar*y)*(1.-y) + sqrt(y*y-ym*ym)*sqrt(sqr(2.*muj2+bar-bar*y)-4.*muj2) ) /
-    ( 2.*(1.-y)*(mui2+mu2+bar*y) );
+  // Limits on zi
+  double facA = (2.*mi2 + sbar*y) / 2. / (mi2 + mj2 + sbar*y);
+  // viji*vijk
+  double facB =
+    sqrt( (sqr(2.*mk2 + sbar*(1.-y)) - 4.*mk2*Qijk) *
+          (sqr(sbar)*sqr(y) - 4.*mi2*mj2))
+    / sbar / (1.-y) / (sbar*y + 2.*mi2);
+  double zim = facA * (1. - facB);
+  double zip = facA * (1. + facB);
 
-  if ( z < zm || z > zp ) {
+  if ( zi < zim || zi > zip ) {
     jacobian(0.0);
     return false;
   }
-
-  double phi = 2.*Constants::pi*rphi;
-
+  
   double mapZJacobian;
   if ( info.index().emitterData()->id() == ParticleID::g ) {
     if ( info.emissionData()->id() != ParticleID::g ) {
       mapZJacobian = 1.;
     } 
     else {
       mapZJacobian = z*(1.-z);
     }
   } 
   else {
     mapZJacobian = 1.-z;
   }
 
-
   // Compute and store the jacobian
   double jac = 0.0;
-  double propCntrb = 1./ ( 1. + (mui2+mu2-Mui2)/(bar*y) );
-
-  // TODO - SW - Tidy up notation everywhere alongside writing for the manual
-  // The full jacobian including the z->zprime jacobian
-  if ( theFullJacobian ) {
-
-    // Sort out variables
-    Energy2 sbar = Qijk*bar;
-    Energy2 sijk = Qijk*suijk;
-    Energy2 mi2 = Qijk*mui2;
-    Energy2 mj2 = Qijk*mu2;
-    Energy2 mk2 = Qijk*muj2;    
-    
-    // Compute dy/dzPrime and pt2* dy/dpt2
-    double dyBydzPrime = (1./sbar) * ( -pt2*(1.-2.*zPrime)/sqr(zPrime*(1.-zPrime)) - mi2/sqr(zPrime) + mj2/sqr(1.-zPrime) );
-    InvEnergy2 dyBydpt2 = 1./(sbar*zPrime*(1.-zPrime));
-
-    // Compute dA/dzPrime and dA/dpt2
-    double dABydzPrime = (sbar/sijk) * dyBydzPrime;
-    InvEnergy2 dABydpt2 = (sbar/sijk) * dyBydpt2;
-
-    // Compute dxk/dzPrime, dxk/dpt2, dxij/dzPrime and dxij/dpt2
-    double factor = (0.5/lambdaK) * (-1. - (1./sqrt( sqr(lambdaK + (mk2/sijk)*lambdaIJ - A) - 4.*lambdaK*lambdaIJ*mk2/sijk)) * (lambdaK + (mk2/sijk)*lambdaIJ - A));
-    
-    double dxkBydzPrime = factor * dABydzPrime;
-    InvEnergy2 dxkBydpt2 = factor * dABydpt2;
-
-    double dxijBydzPrime = (mk2/sijk) * (1./sqr(xk)) * dxkBydzPrime;
-    InvEnergy2 dxijBydpt2 = (mk2/sijk) * (1./sqr(xk)) * dxkBydpt2;
-
-    Energy2 dqiDotqkBydzPrime = xij*xk*0.5*sijk + zPrime*dxijBydzPrime*xk*0.5*sijk + zPrime*xij*dxkBydzPrime*0.5*sijk
-      + 0.5*(mk2/sijk)*(pt2 + mi2) * (-1./(xk*xij*sqr(zPrime)) - dxkBydzPrime/(zPrime*xij*sqr(xk)) - dxijBydzPrime/(zPrime*xk*sqr(xij)));
-
-    double dqiDotqkBydpt2 =  dxijBydpt2*zPrime*xk*0.5*sijk + zPrime*xij*dxkBydpt2*0.5*sijk
-      + (0.5*mk2/sijk) * (1./(zPrime*xk*xij)) * (1. + (pt2+mi2)*(-dxkBydpt2/xk - dxijBydpt2/xij) );
-
-    
-    // Compute dzBydzPrime and dzBydpt2
-    Energy2 qiDotqk = (zPrime*xij*xk*sijk*0.5) + (mk2/ ( 2.*xk*xij*sijk*zPrime))*(pt2 + mi2);
-
-    double dzBydzPrime = (1./sbar) * ( 2.*qiDotqk*dyBydzPrime/sqr(1.-y) + (1./(1.-y)) * 2.*dqiDotqkBydzPrime );
-    InvEnergy2 dzBydpt2    = (1./sbar) * ( 2.*qiDotqk*dyBydpt2/sqr(1.-y) + (1./(1.-y)) * 2.*dqiDotqkBydpt2 );
-
-    double pt2Jac = pt2*abs(dzBydpt2*dyBydzPrime - dzBydzPrime*dyBydpt2);
-
-    // Include the other terms and calculate the jacobian
-    jac = propCntrb * bar / rootOfKallen(1.,Mui2,Muj2) * (1.-y)/y * pt2Jac;
-  }
-  
-  else {
-    double jacPt2 = 1. / ( 1. + sqr(1.-zPrime)*Qijk*mui2/pt2 + zPrime*zPrime*Qijk*mu2/pt2 );
-    jac = propCntrb * bar / rootOfKallen(1.,Mui2,Muj2) * (1.-y) * jacPt2;
-  }
+  jac = sbar / rootOfKallen(Qijk,mij2,mk2) * (1.-y) / ( 1. + (mi2 + mj2 - mij2)/sbar/y )
+    * (pt2 / (pt2 + sqr(1.-z)*mi2+sqr(z)*mj2))
+    * abs(1. - 2.*mk2*Qij2 / (sbar*(1.-y)*xij*xk*sijk));
 
   jacobian(jac * mapZJacobian * 2. * log(0.5 * generator()->maximumCMEnergy()/IRCutoff()) );
-
-
+  
   // Record the physical variables, as used by the CS kernel definitions
+  double phi = 2.*Constants::pi*rphi;
+   
   lastPt(pt);
   lastZ(z);
   lastPhi(phi);
 
-  // Record zPrime for use in kinematics generation
+  // Record zi for use in kinematics generation and kernel evaluation
   splittingParameters().clear();
-  splittingParameters().push_back(zPrime);
-
+  splittingParameters().push_back(zi);
+  
   if ( theMCCheck ) {
     theMCCheck->book(1.,1.,info.scale(),info.hardPt(),pt,z,jacobian());
   }
   return true;
-
+  
 }
 
+// SW, 14/02/2019: Tidied to match thesis
 void FIMassiveDecayKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
-						  const Lorentz5Momentum& pSpectator,
-						  const DipoleSplittingInfo& dInfo) {
+                                                  const Lorentz5Momentum& pSpectator,
+                                                  const DipoleSplittingInfo& dInfo) {
 
-  // The only value stored in dInfo.lastSplittingParameters() should be zPrime
-  assert(dInfo.lastSplittingParameters().size() == 1 );
-  double zPrime = dInfo.lastSplittingParameters()[0];
+  double z = dInfo.lastZ();
   Energy pt = dInfo.lastPt();
   Energy2 pt2 = sqr(pt);
 
   // Momentum of the recoil system
   Lorentz5Momentum pk = pSpectator - pEmitter;
   Lorentz5Momentum pij = pEmitter;
-  
+
   // scaled masses
-  double Mui2 = sqr(dInfo.emitterMass() / dInfo.scale());
-  double Muk2 = sqr(dInfo.recoilMass() / dInfo.scale());
-  //double muk2 = Muk2;
+  Energy2 mij2 = sqr(dInfo.emitterMass());
+  Energy2 Mk2 = sqr(dInfo.recoilMass());
+  Energy2 mk2 = Mk2;
 
-  Energy mi = ZERO;
+  Energy2 mi2 = ZERO;
   // g->gg and g->qqbar
   if ( abs(dInfo.emitterData()->id()) == abs(dInfo.emissionData()->id()) ) {
-    mi = dInfo.emitterData()->mass();
+    mi2 = sqr(dInfo.emitterData()->mass());
   }
   // Otherwise have X->Xg (should work for SUSY)
   else {
-    mi = dInfo.emitterMass();
+    mi2 = mij2;
   }
-  double mui2 = sqr(mi/dInfo.scale());
-  double mu2 = sqr(dInfo.emissionData()->mass()/dInfo.scale() );
-    
+  Energy2 mj2 = sqr(dInfo.emissionData()->mass());
+
+  // Scales
   Energy2 Qijk = sqr(dInfo.scale());
-  double suijk = 0.5*( 1. - Mui2 - Muk2 + sqrt( sqr(1.-Mui2-Muk2) - 4.*Mui2*Muk2 ) );
-  double suijk2 = sqr(suijk);
+  Energy2 Qij2 = (pt2 + (1.-z)*mi2 + z*mj2) / z / (1.-z);
+  Energy2 sijk = 0.5*( Qijk - mij2 - mk2 + rootOfKallen(Qijk,mij2,mk2) );
+  Energy4 sijk2 = sqr(sijk);
 
-  // Calculate A:=xij*w
-  double A = (1./(suijk*zPrime*(1.-zPrime))) * ( pt2/Qijk + zPrime*mu2 + (1.-zPrime)*mui2 - zPrime*(1.-zPrime)*Mui2 );
-
-  // Calculate the scaling factors, xk and xij
-  double lambdaK = 1. + (Muk2/suijk);
-  double lambdaIJ = 1. + (Mui2/suijk);
-  double xk = (1./(2.*lambdaK)) * ( (lambdaK + (Muk2/suijk)*lambdaIJ - A) + sqrt( sqr(lambdaK + (Muk2/suijk)*lambdaIJ - A) - 4.*lambdaK*lambdaIJ*Muk2/suijk) );
-  double xij = 1. - ( (Muk2/suijk) * (1.-xk) / xk );
-
-  // Construct reference momenta nk, nij, nt
-  Lorentz5Momentum nij = ( suijk2 / (suijk2-Mui2*Muk2) ) * (pij - (Mui2/suijk)*pk);
-  Lorentz5Momentum nk = ( suijk2 / (suijk2-Mui2*Muk2) ) * (pk - (Muk2/suijk)*pij);
-
-  // Following notation in notes, qt = sqrt(wt)*nt
-  Lorentz5Momentum qt = getKt(nij,nk,pt,dInfo.lastPhi());
+  // Calculate xk and xij
+  double lambdaIJ = 1. + (mij2/sijk);
+  double lambdaK = 1. + (mk2/sijk);
+  double fac1 = lambdaIJ*lambdaK + (mk2 - Qij2)/sijk;
+  double xk =
+    ( fac1 + sqrt( sqr(fac1) - 4.*lambdaIJ*lambdaK*mk2/sijk ) )
+    / 2. / lambdaK ;
+  double xij = 1. - mk2*(1.-xk) / xk / sijk;
+  
+  // Construct reference momenta nk and nij
+  Lorentz5Momentum nij = ( sijk2 / (sijk2-mij2*Mk2) ) * (pij - (mij2/sijk)*pk);
+  Lorentz5Momentum nk = ( sijk2 / (sijk2-mij2*Mk2) ) * (pk - (Mk2/sijk)*pij);
 
   // Construct qij, qk, qi and qj
-  Lorentz5Momentum qij = xij*nij + (Mui2/(xij*suijk))*nk;
-  Lorentz5Momentum qk = xk*nk + (Muk2/(xk*suijk))*nij;
+  Lorentz5Momentum qij = xij*nij + (mij2/(xij*sijk))*nk;
+  Lorentz5Momentum qk = xk*nk + (Mk2/(xk*sijk))*nij;
+  
+  Lorentz5Momentum qt = getKt(pij, pk, pt, dInfo.lastPhi());
 
   // No need to actually calculate nt and wt:
-  Lorentz5Momentum qi = zPrime*qij + ((pt2/Qijk + mui2 - zPrime*zPrime*Mui2)/(xij*suijk*zPrime))*nk + qt;
-  Lorentz5Momentum qj = (1.-zPrime)*qij + ((pt2/Qijk + mu2 - sqr(1.-zPrime)*Mui2)/(xij*suijk*(1.-zPrime)))*nk - qt;
+  Lorentz5Momentum qi = z*qij + ((pt2 + mi2 - z*z*mij2)/(xij*sijk*z))*nk + qt;
+  Lorentz5Momentum qj = (1.-z)*qij + ((pt2 + mj2 - sqr(1.-z)*mij2)/(xij*sijk*(1.-z)))*nk - qt;
 
-
-  qi.setMass(mi);
+  qi.setMass(sqrt(mi2));
   qi.rescaleEnergy();
   
-  qj.setMass(dInfo.emissionData()->mass());
+  qj.setMass(sqrt(mj2));
   qj.rescaleEnergy();
-  
+
   emitterMomentum(qi);
   emissionMomentum(qj);
   spectatorMomentum(pSpectator);
 
   // Required for absorbing recoil in DipoleEventRecord::update
   splitRecoilMomentum(qk);
 
 }
 
-
+Lorentz5Momentum FIMassiveDecayKinematics::nVector(const Lorentz5Momentum& pEmitter, const Lorentz5Momentum& pSpectator, const DipoleSplittingInfo&) const {
+  return (pSpectator-pEmitter);
+}
+  
 // If needed, insert default implementations of function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
-void FIMassiveDecayKinematics::persistentOutput(PersistentOStream & os) const {
-  os << theFullJacobian;
+void FIMassiveDecayKinematics::persistentOutput(PersistentOStream &) const {
+  //os << ;
 }
 
-void FIMassiveDecayKinematics::persistentInput(PersistentIStream & is, int) {
-  is >> theFullJacobian;
+void FIMassiveDecayKinematics::persistentInput(PersistentIStream &, int) {
+  //is >> ;
 }
 
 ClassDescription<FIMassiveDecayKinematics> FIMassiveDecayKinematics::initFIMassiveDecayKinematics;
 // Definition of the static class description member.
 
 void FIMassiveDecayKinematics::Init() {
 
   static ClassDocumentation<FIMassiveDecayKinematics> documentation
     ("FIMassiveDecayKinematics implements implements massive splittings "
      "off a final-initial decay dipole.");
 
-  
-  static Switch<FIMassiveDecayKinematics,bool> interfaceFullJacobian
-    ("FullJacobian",
-     "Use the full jacobian expression for the FI Decay kinematics.",
-     &FIMassiveDecayKinematics::theFullJacobian, true, false, false);
-  static SwitchOption interfaceFullJacobianYes
-    (interfaceFullJacobian,
-     "Yes",
-     "Use the full jacobian.",
-     true);
-  static SwitchOption interfaceFullJacobianNo
-    (interfaceFullJacobian,
-     "No",
-     "Do not use the full jacobian.",
-     false);
-  interfaceFullJacobian.rank(-1);
 }
diff --git a/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.h b/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.h
--- a/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.h
+++ b/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.h
@@ -1,309 +1,331 @@
 // -*- C++ -*-
 //
 // FIMassiveDecayKinematics.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_FIMassiveDecayKinematics_H
 #define HERWIG_FIMassiveDecayKinematics_H
 //
 // This is the declaration of the FIMassiveDecayKinematics class.
 //
 
 #include "DipoleSplittingKinematics.h"
 #include "ThePEG/EventRecord/Particle.h"
 #include "ThePEG/Utilities/UtilityBase.h"
 
 namespace Herwig {
 
   using namespace ThePEG;
 
   /**
    * \ingroup DipoleShower
    * \author Stephen Webster
    *
    * \brief FIMassiveDecayKinematics implements massive splittings
    * off a final-initial decay dipole.
    *
    */
   class FIMassiveDecayKinematics: public DipoleSplittingKinematics {
 
   public:
 
     /** @name Standard constructors and destructors. */
     //@{
     /**
      * The default constructor.
      */
     FIMassiveDecayKinematics();
 
     /**
      * The destructor.
      */
     virtual ~FIMassiveDecayKinematics();
     //@}
 
   public:
 
     /**
      * Return the boundaries in between the evolution
      * variable random number is to be sampled; the lower
      * cuoff is assumed to correspond to the infrared cutoff.
      */
     virtual pair<double,double> kappaSupport(const DipoleSplittingInfo& dIndex) const;
 
     /**
      * Return the boundaries in between the momentum
      * fraction random number is to be sampled.
      */
     virtual pair<double,double> xiSupport(const DipoleSplittingInfo& dIndex) const;
 
     /**
      * Return the boundaries on the momentum fraction
      */
     virtual pair<double,double> zBoundaries(Energy,
 					    const DipoleSplittingInfo&,
 					    const DipoleSplittingKernel&) const {
       return {0.0,1.0};
     }
 
     /**
      * Return the dipole scale associated to the
      * given pair of emitter and spectator. This
      * should be the invariant mass or absolute value
      * final/final or initial/initial and the absolute
      * value of the momentum transfer for intial/final or
      * final/initial dipoles.
      */
     virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
 			       const Lorentz5Momentum& pSpectator) const;
 
     /**
      * Return the mass of the system absorbing 
      * the recoil in the dipole splitting. 
      * This is only used in decay dipoles.
      */
     virtual Energy recoilMassKin(const Lorentz5Momentum& pEmitter,
 			      const Lorentz5Momentum& pSpectator) const;
 
     /**
      * Return the maximum pt for the given dipole scale.
      */
     virtual Energy ptMax(Energy dScale, 
 			 double emX, double specX,
 			 const DipoleSplittingInfo& dInfo,
 			 const DipoleSplittingKernel& split) const;
     
     /**
      * Return the maximum pt for the given dipole scale.
      */
     virtual Energy ptMax(Energy dScale, 
 			 double, double,
 			 const DipoleIndex& dIndex,
 			 const DipoleSplittingKernel& split,
 			 tPPtr emitter, tPPtr spectator) const;
       
     /**
      * Return the maximum virtuality for the given dipole scale.
      */
     virtual Energy QMax(Energy dScale, 
 			double emX, double specX,
 			const DipoleSplittingInfo& dInfo,
 			const DipoleSplittingKernel& split) const;
 
     /**
      * Return the maximum pt for the given dipole scale.
      */
     virtual Energy ptMax(Energy, 
 			 double, double,
 			 const DipoleIndex&,
 			 const DipoleSplittingKernel&) const {
       // Only the DipoleSplittingInfo version should be used for the decays.
       assert(false);
       return ZERO;
     }
   
     /**
      * Return the maximum virtuality for the given dipole scale.
      */
     virtual Energy QMax(Energy, 
     			double, double,
     			const DipoleIndex&,
     			const DipoleSplittingKernel&) const { 
       // Only the DipoleSplittingInfo version should be used for the decays.
       assert(false);
       return ZERO;
     }
 
     /**
      * Return the pt given a virtuality.
      */
     virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
 
     /**
      * Return the virtuality given a pt.
      */
     virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
 
     /**
      * Return the random number associated to
      * the given pt.
      */
     virtual double ptToRandom(Energy pt, Energy dScale,
 			      double emX, double specX,
 			      const DipoleIndex& dIndex,
 			      const DipoleSplittingKernel& split) const;
 
     /**
      * Generate splitting variables given three random numbers
      * and the momentum fractions of the emitter and spectator.
      * Return true on success.
      */
     virtual bool generateSplitting(double kappa, double xi, double phi,
 				   DipoleSplittingInfo& info,
 				   const DipoleSplittingKernel& split);
 
     /**
      * Generate the full kinematics given emitter and
      * spectator momentum and a previously completeted
      * DipoleSplittingInfo object.
      */
     virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
 				    const Lorentz5Momentum& pSpectator,
 				    const DipoleSplittingInfo& dInfo);
-
+    
+    /**
+     * Return the nVector as required for spin correlations.
+     */
+    virtual Lorentz5Momentum nVector(const Lorentz5Momentum& pEmitter, const Lorentz5Momentum& pSpectator, const DipoleSplittingInfo& dInfo) const;
+    
     /*
      * Return true if this splitting is of a dipole which contains
      * a decayed parton and requires the remnant to absorb the recoil.
      */
     virtual bool isDecay() const { return true; }
 
     /**
      * Perform the recoil in the case of a decayed parton
      */   
     virtual void decayRecoil ( PList& recoilSystem ) {
       PList::iterator beginRecoil = recoilSystem.begin();
       PList::iterator endRecoil = recoilSystem.end();
-      const ThreeVector<Energy> transformMom = splitRecoilMomentum().vect();
-      ThePEG::UtilityBase::setMomentum(beginRecoil, endRecoil, transformMom );
+
+      // This is the final momentum that we must transform the system to
+      const Momentum3 transformMom = splitRecoilMomentum().vect();
+
+      // Calculate required Lorentz rotation
+      Lorentz5Momentum sum = ThePEG::UtilityBase::sumMomentum(beginRecoil, endRecoil);
+      LorentzRotation rot = ThePEG::UtilityBase::transformToCMS(sum);
+      rot = ThePEG::UtilityBase::transformFromCMS
+        (Lorentz5Momentum(transformMom, sqrt(transformMom.mag2() + sum.m2()))) * rot;
+      
+      // Transform the particle spinInfo if required
+      for ( const auto& p : recoilSystem ) {
+        if ( p->spinInfo() )
+          p->spinInfo()->transform(p->momentum(),rot);
+      }
+      
+      ThePEG::UtilityBase::transform(beginRecoil, endRecoil, rot );
     }
     
  
   public:
   
     /**
      * Triangular / Kallen function
      */
-    template <class T>
-    inline double rootOfKallen (T a, T b, T c) const {
-      double sres=a*a + b*b + c*c - 2.*( a*b+a*c+b*c );
-      return sres>0.?sqrt( sres ):0.; }
-  
+  template <class T>
+  inline T rootOfKallen (T a, T b, T c) const {
+    if ( a*a + b*b + c*c - 2.*(a*b + a*c + b*c) > ZERO )
+      return sqrt(a*a + b*b + c*c - 2.*(a*b + a*c + b*c) ) ;
+    else 
+      return ZERO; }
+      
   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;
     //@}
 
 
     // If needed, insert declarations of virtual function defined in the
     // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
   private:
 
     /**
      * The static object used to initialize the description of this class.
      * Indicates that this is a concrete class with persistent data.
      */
     static ClassDescription<FIMassiveDecayKinematics> initFIMassiveDecayKinematics;
 
     /**
      * The assignment operator is private and must never be called.
      * In fact, it should not even be implemented.
      */
     FIMassiveDecayKinematics & operator=(const FIMassiveDecayKinematics &) = delete;
 
     /**
      * Option to use the full jacobian, including the z->zprime jacobian.
      **/
     bool  theFullJacobian;
   };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
   /** @cond TRAITSPECIALIZATIONS */
 
   /** This template specialization informs ThePEG about the
    *  base classes of FIMassiveDecayKinematics. */
   template <>
   struct BaseClassTrait<Herwig::FIMassiveDecayKinematics,1> {
     /** Typedef of the first base class of FIMassiveDecayKinematics. */
     typedef Herwig::DipoleSplittingKinematics NthBase;
   };
 
   /** This template specialization informs ThePEG about the name of
    *  the FIMassiveDecayKinematics class and the shared object where it is defined. */
   template <>
   struct ClassTraits<Herwig::FIMassiveDecayKinematics>
     : public ClassTraitsBase<Herwig::FIMassiveDecayKinematics> {
     /** Return a platform-independent class name */
     static string className() { return "Herwig::FIMassiveDecayKinematics"; }
     /**
      * The name of a file containing the dynamic library where the class
      * FIMassiveDecayKinematics is implemented. It may also include several, space-separated,
      * libraries if the class FIMassiveDecayKinematics depends on other classes (base classes
      * excepted). In this case the listed libraries will be dynamically
      * linked in the order they are specified.
      */
     static string library() { return "HwDipoleShower.so"; }
   };
 
   /** @endcond */
 
 }
 
 #endif /* HERWIG_FIMassiveDecayKinematics_H */
diff --git a/Shower/Dipole/Kinematics/FIMassiveKinematics.cc b/Shower/Dipole/Kinematics/FIMassiveKinematics.cc
--- a/Shower/Dipole/Kinematics/FIMassiveKinematics.cc
+++ b/Shower/Dipole/Kinematics/FIMassiveKinematics.cc
@@ -1,385 +1,385 @@
 // -*- C++ -*-
 //
 // FIMassiveKinematics.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 FIMassiveKinematics class.
 //
 
 #include "FIMassiveKinematics.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 #include "ThePEG/Repository/UseRandom.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
 #include "Herwig/Shower/Dipole/Kernels/DipoleSplittingKernel.h"
 
 using namespace Herwig;
 
 FIMassiveKinematics::FIMassiveKinematics() 
   : DipoleSplittingKinematics() {}
 
 FIMassiveKinematics::~FIMassiveKinematics() {}
 
 IBPtr FIMassiveKinematics::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr FIMassiveKinematics::fullclone() const {
   return new_ptr(*this);
 }
 
 pair<double,double> FIMassiveKinematics::kappaSupport(const DipoleSplittingInfo&) const {
   return {0.0,1.0};
 }
 
 pair<double,double> FIMassiveKinematics::xiSupport(const DipoleSplittingInfo& split) const {
   double c = sqrt(1.-4.*sqr(IRCutoff()/generator()->maximumCMEnergy()));
   if ( split.index().emitterData()->id() == ParticleID::g ) {
     if ( split.emissionData()->id() != ParticleID::g )
     return {0.5*(1.-c),0.5*(1.+c)};
     double b = log((1.+c)/(1.-c));
         return {-b,b};
   }
     return {-log(0.5*(1.+c)),-log(0.5*(1.-c))};
 }
 
 // sbar
 Energy FIMassiveKinematics::dipoleScale(const Lorentz5Momentum& pEmitter,
 				      const Lorentz5Momentum& pSpectator) const {
   return sqrt(2.*(pEmitter*pSpectator));
 }
 
 Energy FIMassiveKinematics::ptMax(Energy dScale, 
-				  double, double specX,
+				double, double specX,
 				  const DipoleSplittingInfo& dInfo,				 
-				  const DipoleSplittingKernel& split) const {
+				const DipoleSplittingKernel& split) const {
 
   DipoleIndex ind = dInfo.index();
 
   Energy2 mij2 = sqr(dInfo.emitterMass());
   Energy2 mi2 = ZERO;
   // g->gg and g->qqbar
   if ( abs(split.emitter(ind)->id()) == abs(split.emission(ind)->id()) ) {
     mi2 = sqr(split.emitter(ind)->mass());
   }
   // Otherwise have X->Xg (should work for SUSY)
   else {
     mi2 = mij2;
   }
 
   Energy2 mj2 = sqr(split.emission(ind)->mass());
 
   Energy2 sPrime = sqr(dScale) * (1.-specX)/specX + mij2;
   return .5 * sqrt(sPrime) * rootOfKallen( sPrime/sPrime, mi2/sPrime, mj2/sPrime );
 }
 
 
 Energy FIMassiveKinematics::ptMax(Energy dScale, 
 				  double, double specX,
 				  const DipoleIndex& ind,
 				  const DipoleSplittingKernel& split,
 				  tPPtr emitter, tPPtr) const {
 
   Energy2 mij2 = sqr(emitter->mass());
   Energy2 mi2 = ZERO;
   // g->gg and g->qqbar
   if ( abs(split.emitter(ind)->id()) == abs(split.emission(ind)->id()) ) {
     mi2 = sqr(split.emitter(ind)->mass());
   }
   // Otherwise have X->Xg (should work for SUSY)
   else {
     mi2 = mij2;
   }
   Energy2 mj2 = sqr(split.emission(ind)->mass());
   
   Energy2 sPrime = sqr(dScale) * (1.-specX)/specX + mij2;
   return .5 * sqrt(sPrime) * rootOfKallen( sPrime/sPrime, mi2/sPrime, mj2/sPrime );
 }
 
   
 
 Energy FIMassiveKinematics::QMax(Energy dScale, 
-				 double, double specX,
+			       double, double specX,
 				 const DipoleSplittingInfo&,				 
-				 const DipoleSplittingKernel&) const {
+				const DipoleSplittingKernel&) const {
   generator()->log() << "FIMassiveKinematics::QMax called.\n" << flush;
   assert(false && "implementation missing");
   // this is sqrt( 2qi*q ) -> max;
   return dScale * sqrt((1.-specX)/specX);
 }
 
 Energy FIMassiveKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
   // from Martin's thesis
   double z = split.lastZ();
 
   // masses
   Energy2 mi2 = ZERO;;
   if ( abs(split.emitterData()->id()) == abs(split.emissionData()->id()) ) {
     mi2 = sqr(split.emitterData()->mass());
   }
   // Otherwise have X->Xg (should work for SUSY)
   else {
     mi2 = sqr(split.emitterMass());
   }
   Energy2 mj2 = sqr(split.emissionData()->mass());
   
-  Energy2 pt2 = z*(1.-z)*sqr(scale) - (1-z)*mi2 - z*mj2;
+  Energy2 pt2 = z*(1.-z)*sqr(scale) - (1.-z)*mi2 - z*mj2;
   assert(pt2 >= ZERO);
   return sqrt(pt2);
 }
 
 Energy FIMassiveKinematics::QFromPt(Energy pt, const DipoleSplittingInfo& split) const {
   // from Martin's thesis
   double z = split.lastZ();
   
   // masses
   Energy2 mi2 = ZERO;;
   if ( abs(split.emitterData()->id()) == abs(split.emissionData()->id()) ) {
     mi2 = sqr(split.emitterData()->mass());
   }
   // Otherwise have X->Xg (should work for SUSY)
   else {
     mi2 = sqr(split.emitterMass());
   }
   Energy2 mj2 = sqr(split.emissionData()->mass());
   
-  Energy2 Q2 = (sqr(pt) + (1-z)*mi2 + z*mj2)/(z*(1.-z));
+  Energy2 Q2 = (sqr(pt) + (1.-z)*mi2 + z*mj2)/(z*(1.-z));
   return sqrt(Q2);
 }
 
 double FIMassiveKinematics::ptToRandom(Energy pt, Energy,
 				       double,double,
 				       const DipoleIndex&,
 				       const DipoleSplittingKernel&) const {
   return log(pt/IRCutoff()) / log(0.5 * generator()->maximumCMEnergy()/IRCutoff());
 }
 
 bool FIMassiveKinematics::generateSplitting(double kappa, double xi, double rphi,
 					  DipoleSplittingInfo& info,
 					    const DipoleSplittingKernel&) {
 
   if ( info.spectatorX() < xMin() ) {
     jacobian(0.0);
     return false;
   }
 
   Energy pt = IRCutoff() * pow(0.5 * generator()->maximumCMEnergy()/IRCutoff(),kappa);
 
   if ( pt > info.hardPt() || pt < IRCutoff() ) {
     jacobian(0.0);
     return false;
   }
 
   double z;
   double mapZJacobian;
 
   if ( info.index().emitterData()->id() == ParticleID::g ) {
     if ( info.emissionData()->id() != ParticleID::g ) {
       z = xi;
       mapZJacobian = 1.;
     } else {
       z = exp(xi)/(1.+exp(xi));
       mapZJacobian = z*(1.-z);
     }
   } else {
     z = 1.-exp(-xi);
     mapZJacobian = 1.-z;
   }
 
   // Construct mass squared variables
   Energy2 mij2 = sqr(info.emitterMass());
   Energy2 mi2 = ZERO;
   // g->gg and g->qqbar
   if ( abs(info.emitterData()->id()) == abs(info.emissionData()->id()) ) {
     mi2 = sqr(info.emitterData()->mass());
   }
   // Otherwise have X->Xg (should work for SUSY)
   else {
     mi2 = mij2;
   }  
   Energy2 mj2  = sqr(info.emissionData()->mass());
 
   Energy2 pt2 = sqr(pt);
 
   
   // 2 pij.pb
   Energy2 sbar = sqr(info.scale());
 
   // Compute x
   double x = 1. / ( 1. +
 		    ( pt2 + (1.-z)*mi2 + z*mj2 - z*(1.-z)*mij2 ) /
 		    ( z*(1.-z)*sbar ) );
 
   // Check the limit on x
   double xs = info.spectatorX();
   
   if ( x < xs ) {
     jacobian(0.0);
     return false;
   }
 
 
   // Compute and check the z limits
   Energy2 sPrime = sbar * (1.-xs)/xs + mij2;
   Energy hard=info.hardPt();
 
   if(openZBoundaries()==1){
     hard=.5 * sqrt(sPrime) * rootOfKallen( sPrime/sPrime, mi2/sPrime, mj2/sPrime );
   }
 
   if(openZBoundaries()==2){
     Energy2 s = mij2 - sbar;
 	hard=min(0.5*sqrt(sPrime) * 
 		rootOfKallen( sPrime/sPrime, mi2/sPrime, mj2/sPrime ) , 
 		 0.5*sqrt(s)  * 
 		 rootOfKallen( s/s, mi2/s, mj2/s ));
  }
 
   double ptRatio = sqrt(1.-sqr(pt/hard));
 
   double zm1 = .5*( 1.+(mi2-mj2)/sPrime - rootOfKallen(sPrime/sPrime,mi2/sPrime,mj2/sPrime) * ptRatio);
   double zp1 = .5*( 1.+(mi2-mj2)/sPrime + rootOfKallen(sPrime/sPrime,mi2/sPrime,mj2/sPrime) * ptRatio);
 
   if ( z > zp1 || z < zm1 ) {
     jacobian(0.0);
     return false;
   }
 
   // additional purely kinematic constraints from
   // the integration limits in Catani-Seymour
   double mui2CS = x*mi2/sbar;
   double muj2CS  = x*mj2/sbar;
   double muij2CS = x*mij2/sbar;
 
   // Limit on x
   double xp = 1. + muij2CS - sqr(sqrt(mui2CS)+sqrt(muj2CS));  
   if (x > xp ) {
     jacobian(0.0);
     return false;
   }
 
   // Limit on z
   double root = sqr(1.-x+muij2CS-mui2CS-muj2CS)-4.*mui2CS*muj2CS;
 
   if( root < 0. && root>-1e-10 ) {
     //    assert(false);
     root = 0.;
   }
   else if (root <0. ) {
     jacobian(0.0);
     return false;
   }
 
   root = sqrt(root);
   double zm2 = .5*( 1.-x+muij2CS+mui2CS-muj2CS - root ) / (1.-x+muij2CS);
   double zp2 = .5*( 1.-x+muij2CS+mui2CS-muj2CS + root ) / (1.-x+muij2CS);
 
   if ( z > zp2 || z < zm2 ) {
     jacobian(0.0);
     return false;
   }
 
   // Store the splitting variables
   double phi = 2.*Constants::pi*rphi;
   
   // Compute and store the jacobian
   double jacPt2 = 1. / ( 1. + (1.-z)*mi2/pt2 + z*mj2/pt2 - z*(1.-z)*mij2/pt2 );
   jacobian( jacPt2 * mapZJacobian * 2.*log(0.5 * generator()->maximumCMEnergy()/IRCutoff()));
 
   lastPt(pt);
   lastZ(z);
   lastPhi(phi);
   lastSpectatorZ(x);
 
   if ( theMCCheck )
     theMCCheck->book(1.,info.spectatorX(),info.scale(),info.hardPt(),pt,z,jacobian());
 
   return true;
 
 }
 
 void FIMassiveKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
 					   const Lorentz5Momentum& pSpectator,
 					   const DipoleSplittingInfo& dInfo) {
-  
+
   // Get splitting variables
   Energy pt = dInfo.lastPt();
   double z = dInfo.lastZ();
 
   // Compute sqr scales
   Energy2 pt2 = sqr(pt);
   Energy2 sbar = sqr(dInfo.scale());
   
-  Lorentz5Momentum kt =
-    getKt (pSpectator, pEmitter, pt, dInfo.lastPhi(),true);
-
   // Construct mass squared variables
   Energy2 mij2 = sqr(dInfo.emitterMass());
   Energy mi = ZERO;
   // g->gg and g->qqbar
   if ( abs(dInfo.emitterData()->id()) == abs(dInfo.emissionData()->id()) ) {
     mi = dInfo.emitterData()->mass();
   }
   // Otherwise have X->Xg (should work for SUSY)
   else {
     mi = dInfo.emitterMass();
   }
   Energy2 mi2 = sqr(mi);
   Energy2 mj2  = sqr(dInfo.emissionData()->mass());
-  
+
   double xInv = ( 1. +
 		  (pt2+(1.-z)*mi2+z*mj2-z*(1.-z)*mij2) /
 		  (z*(1.-z)*sbar) );
 
+  Lorentz5Momentum kt = getKt(pEmitter, pSpectator, pt, dInfo.lastPhi(), true);
+
   Lorentz5Momentum em = z*pEmitter +
     (pt2+mi2-z*z*mij2)/(z*sbar)*pSpectator + kt;
   Lorentz5Momentum emm = (1.-z)*pEmitter +
     (pt2+mj2-sqr(1.-z)*mij2)/((1.-z)*sbar)*pSpectator - kt;
   Lorentz5Momentum spe = xInv*pSpectator;
 
   em.setMass(mi);
   em.rescaleEnergy();
 
   emm.setMass(dInfo.emissionData()->mass());
   emm.rescaleEnergy();
-  
+
   spe.setMass(ZERO);
   spe.rescaleEnergy();
-  
+
   emitterMomentum(em);
   emissionMomentum(emm);
   spectatorMomentum(spe);
 
 }
 
+
 // If needed, insert default implementations of function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void FIMassiveKinematics::persistentOutput(PersistentOStream & ) const {
 }
 
 void FIMassiveKinematics::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<FIMassiveKinematics> FIMassiveKinematics::initFIMassiveKinematics;
 // Definition of the static class description member.
 
 void FIMassiveKinematics::Init() {
 
   static ClassDocumentation<FIMassiveKinematics> documentation
     ("FIMassiveKinematics implements massless splittings "
      "off a final-initial dipole.");
 
 }
 
diff --git a/Shower/Dipole/Kinematics/IFLightKinematics.cc b/Shower/Dipole/Kinematics/IFLightKinematics.cc
--- a/Shower/Dipole/Kinematics/IFLightKinematics.cc
+++ b/Shower/Dipole/Kinematics/IFLightKinematics.cc
@@ -1,255 +1,255 @@
 // -*- C++ -*-
 //
 // IFLightKinematics.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 IFLightKinematics class.
 //
 
 #include "IFLightKinematics.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Switch.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 #include "ThePEG/Repository/UseRandom.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
 
 using namespace Herwig;
 
 IFLightKinematics::IFLightKinematics() 
   : DipoleSplittingKinematics(), theCollinearScheme(true) {}
 
 IFLightKinematics::~IFLightKinematics() {}
 
 IBPtr IFLightKinematics::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr IFLightKinematics::fullclone() const {
   return new_ptr(*this);
 }
 
 Energy IFLightKinematics::ptMax(Energy dScale, 
 				double emX, double,
 				const DipoleIndex&,
 				const DipoleSplittingKernel&) const {
   return dScale * sqrt((1.-emX)/emX) /2.;
 }
 
 Energy IFLightKinematics::QMax(Energy, 
 			       double, double,
 			       const DipoleIndex&,
 			       const DipoleSplittingKernel&) const {
   assert(false && "add this");
   return 0.0*GeV;
 }
 
 Energy IFLightKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
   double z = split.lastZ();
   return scale*sqrt(1.-z);
 }
 
 Energy IFLightKinematics::QFromPt(Energy scale, const DipoleSplittingInfo& split) const {
   double z = split.lastZ();
   return scale/sqrt(1.-z);
 }
 
 pair<double,double> IFLightKinematics::zBoundaries(Energy pt,
 						   const DipoleSplittingInfo& dInfo,
 						   const DipoleSplittingKernel&) const {
   double x = dInfo.emitterX();
 
   Energy hard=dInfo.hardPt();
   if(openZBoundaries()==1)hard=dInfo.scale() * sqrt((1.-x)/x) /2.;
   if(openZBoundaries()==2)hard=dInfo.scale() * min(1.,sqrt((1.-x)/x) /2.);
   if(hard<pt)return {0.5*(1.+x),0.5*(1.+x)};
 
   double s = sqrt(1.-sqr(pt/hard));
 
   return {0.5*(1.+x-(1.-x)*s),0.5*(1.+x+(1.-x)*s)};
 }
 
 
 bool IFLightKinematics::generateSplitting(double kappa, double xi, double rphi,
 					  DipoleSplittingInfo& info,
 					  const DipoleSplittingKernel& split) {
 
   if ( info.emitterX() < xMin() ) {
     jacobian(0.0);
     return false;
   }
 
   double weight = 1.0;
 
   Energy pt = generatePt(kappa,info.scale(),
 			 info.emitterX(),info.spectatorX(),
 			 info.index(),split,
 			 weight);
 
   if ( pt < IRCutoff() || pt > info.hardPt() ) {
     jacobian(0.0);
     return false;
   }
 
   double z = 0.0;
 
   if ( info.index().emitterData()->id() == ParticleID::g ) {
     if ( info.emitterData()->id() == ParticleID::g ) {
       z = generateZ(xi,pt,OneOverZOneMinusZ,
 		    info,split,weight);
     } else {
       z = generateZ(xi,pt,OneOverZ,
 		    info,split,weight);
     }
   }
 
   if ( info.index().emitterData()->id() != ParticleID::g ) {
     if ( info.emitterData()->id() != ParticleID::g ) {
       z = generateZ(xi,pt,OneOverOneMinusZ,
 		    info,split,weight);
     } else {
       z = generateZ(xi,pt,FlatZ,
 		    info,split,weight);
     }
   }
 
   if ( weight == 0. && z == -1. ) {
     jacobian(0.0);
     return false;
   }
 
   double ratio = sqr(pt/info.scale());
-
+  
   double rho = 1. - 4.*ratio*z*(1.-z)/sqr(1.-z+ratio);
   if ( rho < 0.0 ) {
     jacobian(0.0);
     return false;
   }
 
   double x = 0.5*((1.-z+ratio)/ratio)*(1.-sqrt(rho));
   double u = 0.5*((1.-z+ratio)/(1.-z))*(1.-sqrt(rho));
 
   if ( x < info.emitterX() || x > 1. ||
        u < 0. || u > 1. ) {
     jacobian(0.0);
     return false;
   }
 
   double phi = 2.*Constants::pi*rphi;
 
-    jacobian(weight*(1./(u+x-2.*u*x)));
+  jacobian(weight*(1./(u+x-2.*u*x)));
   
   lastPt(pt);
   lastZ(z);
   lastPhi(phi);
   lastEmitterZ(x);
 
   if ( theMCCheck )
     theMCCheck->book(info.emitterX(),1.,info.scale(),info.hardPt(),pt,z,jacobian());
 
   return true;
 
 }
 
 void IFLightKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
 					   const Lorentz5Momentum& pSpectator,
 					   const DipoleSplittingInfo& dInfo) {
 
   Energy pt = dInfo.lastPt();
   double z = dInfo.lastZ();
 
   double ratio = sqr(pt)/(2.*pEmitter*pSpectator);
   double rho = 1. - 4.*ratio*z*(1.-z)/sqr(1.-z+ratio);
-
+  
   double x = 0.5*((1.-z+ratio)/ratio)*(1.-sqrt(rho));
   double u = 0.5*((1.-z+ratio)/(1.-z))*(1.-sqrt(rho));
 
   Lorentz5Momentum kt =
-    getKt (pEmitter, pSpectator, pt, dInfo.lastPhi(),true);
+    getKt(pEmitter, pSpectator, pt, dInfo.lastPhi(), true);
 
   // Initialise the momenta
   Lorentz5Momentum em;
   Lorentz5Momentum emm;
   Lorentz5Momentum spe;
 
   if ( !theCollinearScheme &&
        x > u && (1.-x)/(x-u) < 1. ) {
-
+    
     assert(false);
 
     em = ((1.-u)/(x-u))*pEmitter + ((u/x)*(1.-x)/(x-u))*pSpectator - kt/(x-u);
     emm = ((1.-x)/(x-u))*pEmitter + ((u/x)*(1.-u)/(x-u))*pSpectator - kt/(x-u);
     spe = (1.-u/x)*pSpectator;
 
   } else {
 
     em = (1./x)*pEmitter;
     emm = ((1.-x)*(1.-u)/x)*pEmitter + u*pSpectator + kt;
     spe = ((1.-x)*u/x)*pEmitter + (1.-u)*pSpectator - kt;
   }
 
   em.setMass(ZERO);
   em.rescaleEnergy();
 
   emm.setMass(ZERO);
   emm.rescaleEnergy();
 
   spe.setMass(ZERO);
   spe.rescaleEnergy();
   
   emitterMomentum(em);
   emissionMomentum(emm);
   spectatorMomentum(spe);
 
 }
 
 // If needed, insert default implementations of function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void IFLightKinematics::persistentOutput(PersistentOStream &) const {
   //os << theCollinearScheme;
 }
 
 void IFLightKinematics::persistentInput(PersistentIStream &, int) {
   //is >> theCollinearScheme;
 }
 
 ClassDescription<IFLightKinematics> IFLightKinematics::initIFLightKinematics;
 // Definition of the static class description member.
 
 void IFLightKinematics::Init() {
 
   static ClassDocumentation<IFLightKinematics> documentation
     ("IFLightKinematics implements massless splittings "
      "off a initial-final dipole.");
 
   /*
   static Switch<IFLightKinematics,bool> interfaceCollinearScheme
     ("CollinearScheme",
      "[experimental] Switch on or off the collinear scheme",
      &IFLightKinematics::theCollinearScheme, false, false, false);
   static SwitchOption interfaceCollinearSchemeYes
     (interfaceCollinearScheme,
      "Yes",
      "Switch on the collinear scheme.",
      true);
   static SwitchOption interfaceCollinearSchemeNo
     (interfaceCollinearScheme,
      "No",
      "Switch off the collinear scheme",
      false);
-
+  
   interfaceCollinearScheme.rank(-1);
   */
 
 }
 
diff --git a/Shower/Dipole/Kinematics/IFMassiveDecayKinematics.cc b/Shower/Dipole/Kinematics/IFMassiveDecayKinematics.cc
--- a/Shower/Dipole/Kinematics/IFMassiveDecayKinematics.cc
+++ b/Shower/Dipole/Kinematics/IFMassiveDecayKinematics.cc
@@ -1,390 +1,392 @@
 // -*- C++ -*-
 //
 // IFMassiveDecayKinematics.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 IFMassiveDecayKinematics class.
 //
 
 #include "IFMassiveDecayKinematics.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 #include "ThePEG/Repository/UseRandom.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
 #include "Herwig/Shower/Dipole/Kernels/DipoleSplittingKernel.h"
 
 
 using namespace Herwig;
 
 IFMassiveDecayKinematics::IFMassiveDecayKinematics() 
   : DipoleSplittingKinematics() {}
 
 IFMassiveDecayKinematics::~IFMassiveDecayKinematics() {}
 
 IBPtr IFMassiveDecayKinematics::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr IFMassiveDecayKinematics::fullclone() const {
   return new_ptr(*this);
 }
 
 pair<double,double> IFMassiveDecayKinematics::kappaSupport(const DipoleSplittingInfo&) const {
   return {0.0,1.0};
 }
 
 pair<double,double> IFMassiveDecayKinematics::xiSupport(const DipoleSplittingInfo& split) const {
 
   double c = sqrt(1.-4.*sqr(IRCutoff()/generator()->maximumCMEnergy()));
 
   if ( split.index().emitterData()->id() == ParticleID::g ) {
     if ( split.emissionData()->id() != ParticleID::g ){
       return {0.5*(1.-c),0.5*(1.+c)};}
     double b = log((1.+c)/(1.-c));
     return {-b,b};
   }
     return {-log(0.5*(1.+c)),-log(0.5*(1.-c))};
 }
 
 Energy IFMassiveDecayKinematics::dipoleScale(const Lorentz5Momentum& pEmitter,
 				       const Lorentz5Momentum&) const {
   return pEmitter.m();
 }
 
 Energy IFMassiveDecayKinematics::recoilMassKin(const Lorentz5Momentum& pEmitter,
 				      const Lorentz5Momentum& pSpectator) const {
   Lorentz5Momentum pk = pEmitter - pSpectator;
   double pkmass = pk.m();
   return pkmass;
 }
 
 Energy IFMassiveDecayKinematics::ptMax(Energy dScale, 
 				 double, double,
 				 const DipoleSplittingInfo& dInfo,
 				 const DipoleSplittingKernel& split) const {
   DipoleIndex ind = dInfo.index();
   double mui = split.spectator(ind)->mass() / dScale;
   double mu  = split.emission(ind)->mass() / dScale;
 
   // Mass of recoil system
   // Use abs() due to generation of negative
   // recoilMass during sampling.
   double muj = abs(dInfo.recoilMass() / dScale);
 
   double mui2 = sqr( mui ), mu2  = sqr( mu );
 
   return rootOfKallen( mui2, mu2, sqr(1.-muj) ) / ( 2.-2.*muj ) * dScale;
 }
 
 Energy IFMassiveDecayKinematics::QMax(Energy dScale, 
 				double, double,
 				const DipoleSplittingInfo& dInfo,
 				const DipoleSplittingKernel&) const {
   assert(false && "implementation missing");
 
   // Mass of recoil system
   double Muj = abs(dInfo.recoilMass() / dScale); 
 
   return dScale * ( 1.-2.*Muj+sqr(Muj) );
 }
 
 Energy IFMassiveDecayKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
   // from Martin's thesis
   double zPrime = split.lastSplittingParameters()[0];
   Energy mi = split.spectatorData()->mass();
   Energy m = split.emissionData()->mass();
   Energy2 pt2 = zPrime*(1.-zPrime)*sqr(scale) - (1-zPrime)*sqr(mi) - zPrime*sqr(m);
   assert(pt2 >= ZERO);
   return sqrt(pt2);
 }
 
 Energy IFMassiveDecayKinematics::QFromPt(Energy scale, const DipoleSplittingInfo& split) const {
   // from Martin's thesis 
   double zPrime = split.lastSplittingParameters()[0];
   Energy mi = split.spectatorData()->mass();
   Energy m = split.emissionData()->mass();
   Energy2 Q2 = (sqr(scale) + (1-zPrime)*sqr(mi) + zPrime*sqr(m))/(zPrime*(1.-zPrime));
   return sqrt(Q2);
 }
 
 double IFMassiveDecayKinematics::ptToRandom(Energy pt, Energy,
 				       double,double,
 				       const DipoleIndex&,
 				       const DipoleSplittingKernel&) const {
   return log(pt/IRCutoff()) / log(0.5 * generator()->maximumCMEnergy()/IRCutoff());
 }
 
 
 bool IFMassiveDecayKinematics::generateSplitting(double kappa, double xi, double rphi,
 					    DipoleSplittingInfo& info,
 					    const DipoleSplittingKernel&) {
 
   // Construct mass squared variables
   Energy2 mi2 = sqr( info.spectatorData()->mass() );
   Energy2 mj2 = sqr( info.emissionData()->mass() );
 
   // Specific to the IFDecay kinematics
   Energy2 mij2 = mi2;
 
   Energy2 mk2 = sqr( info.recoilMass() );
   Energy2 Qijk = sqr( info.scale());
 
   // To solve issue with scale during presampling
   // need to enforce that Qijk-mij2-mk2 = 2*pij.pk > 0,
   // so combine checks by comparing against square root.
   if ( Qijk-mij2-mk2 < sqrt(4.*mij2*mk2) ) {
     jacobian(0.0);
     return false;
   }
 
   Energy2 sijk = 0.5*( Qijk - mij2 - mk2 + sqrt( sqr(Qijk-mij2-mk2) - 4.*mij2*mk2 ) );
 
   // Calculate pt
   Energy pt = IRCutoff() * pow(0.5 * generator()->maximumCMEnergy()/IRCutoff(),kappa);
   Energy2 pt2 = sqr(pt);
 
   if ( pt > info.hardPt() || pt < IRCutoff() ) {
     jacobian(0.0);
     return false;
   }
 
   // Generate zPrime (i.e. the new definition of z specific to massive FF and decays)
   double zPrime;
 
   // TODO: This may need to change along with the emitter and spectator usage, if IFDecays are implemented again
   if ( info.index().emitterData()->id() == ParticleID::g ) {
     if ( info.emissionData()->id() != ParticleID::g ) {
       zPrime = xi;
     } 
     else {
       zPrime = exp(xi)/(1.+exp(xi));
     }
   } 
   else {
     zPrime = 1.-exp(-xi);
   }
 
  // scaled masses *** TODO: rewrite above in terms of mu to avoid this calculation ***, and mix up of notation
   double mui2 = mi2 / Qijk;
   double mu2  = mj2 / Qijk;
   double muj2 = mk2 / Qijk;
 
   double Mui2 = mui2;
   double Muj2 = muj2;
 
   // Check limit on pt
   Energy ptmax1 = rootOfKallen( mui2, mu2, sqr(1.-sqrt(muj2)) ) /
     ( 2.-2.*sqrt(muj2) ) * info.scale();
   Energy auxHardPt = ptmax1 > info.hardPt() ? info.hardPt() : ptmax1;
 
   // 24/05/2015: Moved this check from the zPrime limit checks
   if ( pt > auxHardPt ){
     jacobian(0.0);
     return false;
   }
 
   // 2011-11-09
   //assert(ptmax1>info.hardPt());
   // 24/05/2015:
   // The simple >= assert above is triggered 
   // during sampling due to precision.
   // Have added a tolerance to deal with this.
   assert( abs(ptmax1 - info.hardPt()) <= 1e-8 || ptmax1>=info.hardPt() );
 
   // new: 2011-08-31
   // 2011-11-08: this does happen
   if( sqrt(mui2)+sqrt(mu2)+sqrt(muj2) > 1. ){
     jacobian(0.0);
     return false;
   }
 
   
   // I have derived and checked the equations for zp1 and zm1, these apply to zPrime!!!
   // phasespace constraint to incorporate ptMax
   double zp1 = ( 1.+mui2-mu2+muj2-2.*sqrt(muj2) +
     rootOfKallen(mui2,mu2,sqr(1-sqrt(muj2))) *
     sqrt( 1.-sqr(pt/auxHardPt) ) ) /
     ( 2.*sqr(1.-sqrt(muj2)) );
   double zm1 = ( 1.+mui2-mu2+muj2-2.*sqrt(muj2) -
     rootOfKallen(mui2,mu2,sqr(1-sqrt(muj2))) *
     sqrt( 1.-sqr(pt/auxHardPt) ) ) /
     ( 2.*sqr(1.-sqrt(muj2)) );
 
   if ( zPrime > zp1 || zPrime < zm1 ) {
     jacobian(0.0);
     return false;
   }
 
   // Calculate A:=xij*w
   double A = (1./(sijk*zPrime*(1.-zPrime))) * ( pt2 + zPrime*mj2 + (1.-zPrime)*mi2 - zPrime*(1.-zPrime)*mij2 );
 
   // Calculate y from A (can also write explicitly in terms of qt, zPrime and masses however we need A anyway)
   Energy2 sbar = Qijk - mi2 - mj2 - mk2;
   double y = (1./sbar) * (A*sijk + mij2 - mi2 - mj2);
 
   // kinematic phasespace boundaries for y
   // same as in Dittmaier hep-ph/9904440v2 (equivalent to CS)
   double bar = 1.-mui2-mu2-muj2;
   double ym = 2.*sqrt(mui2)*sqrt(mu2)/bar;
   double yp = 1. - 2.*sqrt(muj2)*(1.-sqrt(muj2))/bar;
   if ( y < ym || y > yp ) {
     jacobian(0.0);
     return false;
   }
 
   // Calculate xk and xij
   double lambdaK = 1. + (mk2/sijk);
   double lambdaIJ = 1. + (mij2/sijk);
   double xk = (1./(2.*lambdaK)) * ( (lambdaK + (mk2/sijk)*lambdaIJ - A) + sqrt( sqr(lambdaK + (mk2/sijk)*lambdaIJ - A) - 4.*lambdaK*lambdaIJ*mk2/sijk) );
   double xij = 1. - ( (mk2/sijk) * (1.-xk) / xk );
 
   // Transform to standard z definition as used in the kernels (i.e. that used in CS and standard sudakov parametrisations)
   double z = 
     ( (zPrime*xij*xk*sijk/2.) + (mk2/ ( 2.*xk*xij*sijk*zPrime))*(pt2 + mi2) ) /
     ( (xij*xk*sijk/2.) + (mk2*mij2/(2.*xk*xij*sijk)) + (mk2/(2.*xk*xij))*A );
 
   // I think these apply to z but need to double check
   double zm = ( (2.*mui2+bar*y)*(1.-y) - sqrt(y*y-ym*ym)*sqrt(sqr(2.*muj2+bar-bar*y)-4.*muj2) ) /
     ( 2.*(1.-y)*(mui2+mu2+bar*y) );
   double zp = ( (2.*mui2+bar*y)*(1.-y) + sqrt(y*y-ym*ym)*sqrt(sqr(2.*muj2+bar-bar*y)-4.*muj2) ) /
     ( 2.*(1.-y)*(mui2+mu2+bar*y) );
 
   if ( z < zm || z > zp ) {
     jacobian(0.0);
     return false;
   }
 
   double phi = 2.*Constants::pi*rphi;
 
     // TODO: This may need changing due to different definitions of z
   double mapZJacobian;
   if ( info.index().emitterData()->id() == ParticleID::g ) {
     if ( info.emissionData()->id() != ParticleID::g ) {
       mapZJacobian = 1.;
     } 
     else {
       mapZJacobian = z*(1.-z);
     }
   } 
   else {
     mapZJacobian = 1.-z;
   }
 
   // TODO: May need a redefinition due to different definitions of z
   jacobian( 2. * mapZJacobian * (1.-y) * 
 	    log(0.5 * generator()->maximumCMEnergy()/IRCutoff()) *
 	    bar / rootOfKallen(1.,Mui2,Muj2) );
 
   // Record the physical variables, as used by the CS kernel definitions
   lastPt(pt);
   lastZ(z);
   lastPhi(phi);
 
   // Record zPrime for use in kinematics generation and kernel evaluation
   splittingParameters().clear();
   splittingParameters().push_back(zPrime);
 
   if ( theMCCheck ) {
     theMCCheck->book(1.,1.,info.scale(),info.hardPt(),pt,z,jacobian());
   }
   return true;
 
 }
 
 
 
 // Check use of const
 void IFMassiveDecayKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
 					    const Lorentz5Momentum& pSpectator,
 					    const DipoleSplittingInfo& dInfo) {
 
-
+  // There is no plan to implement IF-type decays,
+  // therefore these kinematics have not been kept up-to-date,
+  // have not had any bug fixes and have not been kept up-to-date
+  // with other developments since their creation.
+  assert(false && "The should be no initial-final type decay dipoles being showered, something is wrong.");  
 
   // The only value stored in dInfo.lastSplittingParameters() should be zPrime
   assert(dInfo.lastSplittingParameters().size() == 1 );
   double zPrime = dInfo.lastSplittingParameters()[0];
   Energy pt = dInfo.lastPt();
   Energy2 pt2 = sqr(pt);
 
   // Momentum of the recoil system
   Lorentz5Momentum pk = pEmitter-pSpectator;
   Lorentz5Momentum pij = pSpectator;
 
   // Masses - Currently not using the mu-ratio formalism and using a different notation to Simon
   Energy2 mi2 = sqr( dInfo.spectatorData()->mass() ); 
   Energy2 mj2 = sqr( dInfo.emissionData()->mass() );
 
   Energy2 mij2 = mi2;
   Energy2 mk2 = sqr(dInfo.recoilMass());
 
   Energy2 Qijk = sqr(dInfo.scale());
   Energy2 sijk = 0.5*( Qijk - mij2 - mk2 + sqrt( sqr(Qijk-mij2-mk2) - 4.*mij2*mk2 ) );
   Energy4 sijk2 = sqr(sijk);
 
   // Calculate A:=xij*w
   double A = (1./(sijk*zPrime*(1.-zPrime))) * ( pt2 + zPrime*mj2 + (1.-zPrime)*mi2 - zPrime*(1.-zPrime)*mij2 );
 
   // Calculate xk and xij
   double lambdaK = 1. + (mk2/sijk);
   double lambdaIJ = 1. + (mij2/sijk);
 
   double xk = (1./(2.*lambdaK)) * ( (lambdaK + (mk2/sijk)*lambdaIJ - A) + sqrt( sqr(lambdaK + (mk2/sijk)*lambdaIJ - A) - 4.*lambdaK*lambdaIJ*mk2/sijk) );
   double xij = 1. - ( (mk2/sijk) * (1.-xk) / xk );
 
   // Construct reference momenta nk, nij, nt
   Lorentz5Momentum nij = ( sijk2 / (sijk2-mij2*mk2) ) * (pij - (mij2/sijk)*pk);
   Lorentz5Momentum nk = ( sijk2 / (sijk2-mij2*mk2) ) * (pk - (mk2/sijk)*pij);
 
-  //Lorentz5Momentum nt = getKt(nij,nk,sqrt(sijk),dInfo.lastPhi());
   // Following notation in notes, qt = sqrt(wt)*nt
-  Lorentz5Momentum qt = getKt(nij,nk,pt,dInfo.lastPhi());
+  Lorentz5Momentum qt = getKt(nij, nk, pt, dInfo.lastPhi());
 
   // Construct qij, qk, qi and qj
   Lorentz5Momentum qij = xij*nij + (mij2/(xij*sijk))*nk;
   Lorentz5Momentum qk = xk*nk + (mk2/(xk*sijk))*nij;
 
   // No need to actually calculate nt and wt:
   Lorentz5Momentum qi = zPrime*qij + ((pt2 + mi2 - zPrime*zPrime*mij2)/(xij*sijk*zPrime))*nk + qt;
   Lorentz5Momentum qj = (1.-zPrime)*qij + ((pt2 + mj2 - sqr(1.-zPrime)*mij2)/(xij*sijk*(1.-zPrime)))*nk - qt;
 
   // book
   spectatorMomentum(qi);
   emissionMomentum(qj);
   emitterMomentum(pEmitter);
   
   //recoilMomentum is not currently used
   //recoilMomentum(pk); 
 
   splitRecoilMomentum(qk);
 }
 
 
-
-  // If needed, insert default implementations of function defined
+// If needed, insert default implementations of function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void IFMassiveDecayKinematics::persistentOutput(PersistentOStream & ) const {
 }
 
 void IFMassiveDecayKinematics::persistentInput(PersistentIStream & , int) {
 }
 
 ClassDescription<IFMassiveDecayKinematics> IFMassiveDecayKinematics::initIFMassiveDecayKinematics;
 // Definition of the static class description member.
 
 void IFMassiveDecayKinematics::Init() {
 
   static ClassDocumentation<IFMassiveDecayKinematics> documentation
     ("IFMassiveDecayKinematics implements implements massive splittings "
      "off an initial-final decay dipole.");
 }
diff --git a/Shower/Dipole/Kinematics/IFMassiveKinematics.cc b/Shower/Dipole/Kinematics/IFMassiveKinematics.cc
--- a/Shower/Dipole/Kinematics/IFMassiveKinematics.cc
+++ b/Shower/Dipole/Kinematics/IFMassiveKinematics.cc
@@ -1,373 +1,373 @@
 // -*- C++ -*-
 //
 // IFMassiveKinematics.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 IFMassiveKinematics class.
 //
 
 #include "IFMassiveKinematics.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Switch.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 #include "ThePEG/Repository/UseRandom.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
 #include "Herwig/Shower/Dipole/Kernels/DipoleSplittingKernel.h"
 
 using namespace Herwig;
 
 IFMassiveKinematics::IFMassiveKinematics() 
   : DipoleSplittingKinematics(), theCollinearScheme(true) {}
 
 IFMassiveKinematics::~IFMassiveKinematics() {}
 
 IBPtr IFMassiveKinematics::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr IFMassiveKinematics::fullclone() const {
   return new_ptr(*this);
 }
 
 pair<double,double> IFMassiveKinematics::kappaSupport(const DipoleSplittingInfo&) const {
   return {0.0,1.0};
 }
 
 pair<double,double> IFMassiveKinematics::xiSupport(const DipoleSplittingInfo& split) const {
 
   double c = sqrt(1.-4.*sqr(IRCutoff()/generator()->maximumCMEnergy()));
 
   if ( split.index().emitterData()->id() == ParticleID::g ) {
     if ( split.emitterData()->id() == ParticleID::g ) {
       double b = log((1.+c)/(1.-c));
       return {-b,b};
     } else {
       return {log(0.5*(1.-c)),log(0.5*(1.+c))};
     }
   }
 
   if ( split.index().emitterData()->id() != ParticleID::g &&
        split.emitterData()->id() != ParticleID::g ) {
     return {-log(0.5*(1.+c)),-log(0.5*(1.-c))};
   }
 
   return {0.5*(1.-c),0.5*(1.+c)};
 
 }
 
 // sbar
 Energy IFMassiveKinematics::dipoleScale(const Lorentz5Momentum& pEmitter,
 					const Lorentz5Momentum& pSpectator) const {
   return sqrt(2.*(pEmitter*pSpectator));
 }
 
 Energy IFMassiveKinematics::ptMax(Energy dScale, 
 				  double emX, double,
 				  const DipoleSplittingInfo& dInfo,	
 				  const DipoleSplittingKernel&) const {
 
   Energy2 A = sqr(dScale) * (1.-emX)/emX;
   Energy2 mk2 = sqr(dInfo.spectatorMass());
   Energy ptMax = 0.5*A/sqrt(mk2+A);
   return ptMax;
 }
 
 Energy IFMassiveKinematics::ptMax(Energy dScale, 
 				  double emX, double,
 				  const DipoleIndex&,
 				  const DipoleSplittingKernel&,
 				  tPPtr, tPPtr spectator) const {
 
   Energy2 A = sqr(dScale) * (1.-emX)/emX;
   Energy2 mk2 = sqr(spectator->mass());
   Energy ptMax = 0.5*A/sqrt(mk2+A);
   return ptMax;
 }
 
 Energy IFMassiveKinematics::QMax(Energy, 
 				 double, double,
 				 const DipoleSplittingInfo&,
 				 const DipoleSplittingKernel&) const {
   assert(false && "add this");
   return 0.0*GeV;
 }
 
 Energy IFMassiveKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
   double z = split.lastZ();
   return scale*sqrt(1.-z);
 }
 
 Energy IFMassiveKinematics::QFromPt(Energy pt, const DipoleSplittingInfo& split) const {
   double z = split.lastZ();
   return pt/sqrt(1.-z);
 }
 
 
 double IFMassiveKinematics::ptToRandom(Energy pt, Energy,
 				       double,double,
 				       const DipoleIndex&,
 				       const DipoleSplittingKernel&) const {
   return log(pt/IRCutoff()) / log(0.5 * generator()->maximumCMEnergy()/IRCutoff());
 }
 
 bool IFMassiveKinematics::generateSplitting(double kappa, double xi, double rphi,
 					    DipoleSplittingInfo& info,
 					    const DipoleSplittingKernel&) {
 
   // Check emitter x against xmin
   if ( info.emitterX() < xMin() ) {
     jacobian(0.0);
     return false;
   }
 
   // Generate pt and check it against max allowed
   Energy pt = IRCutoff() * pow(0.5 * generator()->maximumCMEnergy()/IRCutoff(),kappa);
   if ( pt < IRCutoff() || pt > info.hardPt() ) {
     jacobian(0.0);
     return false;
   }
 
   // Compute scales required
   Energy2 pt2 = sqr(pt);
   Energy2 saj = sqr(info.scale());
   Energy2 mk2 = sqr(info.spectatorMass());
 
   // Generate z
   double z = 0.;
   double mapZJacobian = 0.;
 
   if ( info.index().emitterData()->id() == ParticleID::g ) {
     if ( info.emitterData()->id() == ParticleID::g ) {
       z = exp(xi)/(1.+exp(xi));
       mapZJacobian = z*(1.-z);
     } else {
       z = exp(xi);
       mapZJacobian = z;
     }
   }
 
   if ( info.index().emitterData()->id() != ParticleID::g ) {
     if ( info.emitterData()->id() != ParticleID::g ) {
       z = 1.-exp(-xi);
       mapZJacobian = 1.-z;
     } else {
       z = xi;
       mapZJacobian = 1.;
     }
   }
 
   // Check limits on z
   double xe = info.emitterX();
   Energy hard = info.hardPt();
 
   if(openZBoundaries()==1){
         Energy2 A = saj*(1.-xe)/xe;
         hard = 0.5*A/sqrt(mk2+A);          
   }
   if(openZBoundaries()==2){
         Energy2 A = saj*min(1.,(1.-xe)/xe);
         hard= 0.5*A/sqrt(mk2+A);
 	assert(pt2<=sqr(hard));
   }
 
   double ptRatio = sqrt(1. - pt2/sqr(hard) );
   double zp = 0.5*(1.+xe + (1.-xe)*ptRatio);
   double zm = 0.5*(1.+xe - (1.-xe)*ptRatio);
   
   if ( z < zm || z > zp ) {
     jacobian(0.0);
     return false;
   }
     
   // Calculate x and u in terms of z and pt
   double r = pt2/saj;
   double muk2 = mk2/saj;
   double rho = 1. - 4.*r*(1.-muk2)*z*(1.-z)/sqr(1.-z+r);
   if ( rho < 0.0 ) {
     // This has never happened
     jacobian(0.0);
     return false;
   }
 
   double x = 0.5*((1.-z+r)/(r*(1.-muk2))) * (1. - sqrt(rho));
   double u = x*r / (1.-z);
 
   // Check limits on x and u      
   // Following Catani-Seymour paper
   double muk2CS = x*muk2;
   double up = (1.-x) / ( 1.-x + muk2CS );
   if ( x < xe || x > 1. ||
        u < 0. || u > up ) {
     jacobian(0.0);
     return false;
   }
 
 
-  // Jacobian
-  // Jacobian for dpt2 dz -> dx du
-  Energy2 jac = saj*abs( (1.+x*(muk2-1.))*(-u*(1.-u)/sqr(x)) - (1.+u*(muk2-1.))*((1.-2.*u)*(1.-x)/x - 2.*u*muk2) );
-  jacobian( (pt2/(x*u*jac)) * mapZJacobian * 2. * log(0.5 * generator()->maximumCMEnergy()/IRCutoff()));
+  // Compute the Jacobian
+  double jac = 1./(u + x - 2.*u*x*(1.-muk2));
+
+  jacobian( jac * mapZJacobian * 2. * log(0.5 * generator()->maximumCMEnergy()/IRCutoff()));
     
   // Log results
   double phi = 2.*Constants::pi*rphi;
   lastPt(pt);
   lastZ(z);
   lastPhi(phi);
   lastEmitterZ(x);
 
   if ( theMCCheck )
     theMCCheck->book(info.emitterX(),1.,info.scale(),info.hardPt(),pt,z,jacobian());
 
   return true;
 
 }
 
 void IFMassiveKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
 					     const Lorentz5Momentum& pSpectator,
 					     const DipoleSplittingInfo& dInfo) {
 
   // Initialise the momenta
   Lorentz5Momentum em;
   Lorentz5Momentum emm;
   Lorentz5Momentum spe;
 
-  // TODO: adjust phasespace boundary condition
   if (!theCollinearScheme) {
     assert(false);
 
     Energy2 sbar = 2.*pEmitter*pSpectator;
     Energy pt = dInfo.lastPt();
     double ratio = pt*pt/sbar;
     double z = dInfo.lastZ();
     double x = (z*(1.-z)-ratio)/(1.-z-ratio);
     double u = ratio / (1.-z);
 
     pt = sqrt(sbar*u*(1.-u)*(1.-x));
     Energy magKt = 
-      sqrt(sbar*u*(1.-u)*(1.-x)/x - sqr(u*dInfo.spectatorData()->mass()));
+      sqrt(sbar*u*(1.-u)*(1.-x)/x - sqr(u*dInfo.spectatorMass()));
     Lorentz5Momentum kt =
-      getKt (pEmitter, pSpectator, magKt, dInfo.lastPhi(),true);
+      getKt (pSpectator, pEmitter, magKt, dInfo.lastPhi(),true);
 
     Energy2 mj2 = sqr(dInfo.spectatorMass());
     double alpha = 1. - 2.*mj2/sbar;
 
     if ( x > u && (1.-x)/(x-u) < 1. ) {
 
       double fkt = sqrt(sqr(x-u)+4.*x*u*mj2/sbar);
 
       //    em =
       //      ((1.-u)/(x-u))*pEmitter + ((u/x)*(1.-x)/(x-u))*pSpectator - kt/(x-u);
       Energy2 fa = (sbar*(x+u-2.*x*z)+2.*mj2*x*u) / sqrt(sqr(x-u)+4.*x*u*mj2/sbar);
       double a = (-sbar+fa) / (2.*x*(sbar-mj2));
       double ap = (sbar+alpha*fa) / (2.*x*(sbar-mj2));
       em = ap*pEmitter + a*pSpectator - fkt*kt;
 
       //    emm =
       //      ((1.-x)/(x-u))*pEmitter + ((u/x)*(1.-u)/(x-u))*pSpectator - kt/(x-u);
       Energy2 fb = abs(sbar*(u*(1.-u)-x*(1.-x))+2.*mj2*x*u) / sqrt(sqr(x-u)+4.*x*u*mj2/sbar);
       double b = (-sbar*(1.-x-u)+fb) / (2.*x*(sbar-mj2));
       double bp = (sbar*(1.-x-u)+alpha*fb) / (2.*x*(sbar-mj2));
       emm = bp*pEmitter + b*pSpectator + fkt*kt;
 
       //    spe =
       //      (1.-u/x)*pSpectator;
       Energy2 fc = sqrt(sqr(sbar*(x-u))+4.*sbar*mj2*x*u);
       double c = (sbar*(x-u)-2.*x*mj2+fc) / (2.*x*(sbar-mj2));
       double cp = (-sbar*(x-u)+2.*x*mj2+alpha*fc) / (2.*x*(sbar-mj2));
       spe = cp*pEmitter + c*pSpectator;
 
     }
   }
 
   else {
     
     // Get z, pt and the relevant scales
     double z = dInfo.lastZ();
     Energy pt = dInfo.lastPt();
     
     Energy2 pt2 = sqr(pt);
     Energy2 saj = 2.*pEmitter*pSpectator;
 
     double muk2 = sqr(dInfo.spectatorMass())/saj;
     double r = pt2/saj;
     
     // Calculate x and u
     double rho = 1. - 4.*r*(1.-muk2)*z*(1.-z)/sqr(1.-z+r);
     double x = 0.5*((1.-z+r)/(r*(1.-muk2))) * (1. - sqrt(rho));
     double u = x*r / (1.-z);
     
     // Generate kt
-    Lorentz5Momentum kt = getKt (pEmitter, pSpectator, pt, dInfo.lastPhi(), true);
+    Lorentz5Momentum kt = getKt(pEmitter, pSpectator, pt, dInfo.lastPhi(), true);
  
     // Set the momenta  
     em = (1./x)*pEmitter;
     emm = ((1.-x)*(1.-u)/x - 2.*u*muk2)*pEmitter + u*pSpectator + kt;
     spe = ((1.-x)*u/x + 2.*u*muk2)*pEmitter + (1.-u)*pSpectator - kt;
     
   }
   
   em.setMass(ZERO);
   em.rescaleEnergy();
 
   emm.setMass(ZERO);
   emm.rescaleEnergy();
 
   spe.setMass(dInfo.spectatorMass());
   spe.rescaleEnergy();
 
   emitterMomentum(em);
   emissionMomentum(emm);
   spectatorMomentum(spe);
 }
 
+
 // If needed, insert default implementations of function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void IFMassiveKinematics::persistentOutput(PersistentOStream &) const {
   //os << theCollinearScheme;
 }
 
 void IFMassiveKinematics::persistentInput(PersistentIStream &, int) {
   //is >> theCollinearScheme;
 }
 
 ClassDescription<IFMassiveKinematics> IFMassiveKinematics::initIFMassiveKinematics;
 // Definition of the static class description member.
 
 void IFMassiveKinematics::Init() {
 
   static ClassDocumentation<IFMassiveKinematics> documentation
     ("IFMassiveKinematics implements massless splittings "
      "off a initial-final dipole.");
 
   /*
     static Switch<IFMassiveKinematics,bool> interfaceCollinearScheme
     ("CollinearScheme",
     "[experimental] Switch on or off the collinear scheme",
     &IFMassiveKinematics::theCollinearScheme, false, false, false);
     static SwitchOption interfaceCollinearSchemeYes
     (interfaceCollinearScheme,
     "Yes",
     "Switch on the collinear scheme.",
     true);
     static SwitchOption interfaceCollinearSchemeNo
     (interfaceCollinearScheme,
     "No",
     "Switch off the collinear scheme",
     false);
 
     interfaceCollinearScheme.rank(-1);
   */
 
 }
 
diff --git a/Shower/Dipole/Kinematics/IFMassiveKinematics.h b/Shower/Dipole/Kinematics/IFMassiveKinematics.h
--- a/Shower/Dipole/Kinematics/IFMassiveKinematics.h
+++ b/Shower/Dipole/Kinematics/IFMassiveKinematics.h
@@ -1,279 +1,279 @@
 // -*- C++ -*-
 //
 // IFLightKinematics.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_IFLightKinematics_H
 #define HERWIG_IFLightKinematics_H
 //
 // This is the declaration of the IFLightKinematics class.
 //
 
 #include "DipoleSplittingKinematics.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer, Martin Stoll
  *
  * \brief IFMassiveKinematics implements massless splittings
  * off an initial-final dipole.
  *
  * @see \ref IFMassiveKinematicsInterfaces "The interfaces"
  * defined for IFMassiveKinematics.
  */
 class IFMassiveKinematics: public DipoleSplittingKinematics {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   IFMassiveKinematics();
 
   /**
    * The destructor.
    */
   virtual ~IFMassiveKinematics();
   //@}
 
 public:
 
   /**
    * Return the boundaries in between the evolution
    * variable random number is to be sampled; the lower
    * cuoff is assumed to correspond to the infrared cutoff.
    */
   virtual pair<double,double> kappaSupport(const DipoleSplittingInfo& dIndex) const;
 
   /**
    * Return the boundaries in between the momentum
    * fraction random number is to be sampled.
    */
   virtual pair<double,double> xiSupport(const DipoleSplittingInfo& dIndex) const;
 
   /**
    * Return the boundaries on the momentum fraction
    */
   virtual pair<double,double> zBoundaries(Energy,
 					  const DipoleSplittingInfo&,
 					  const DipoleSplittingKernel&) const {
     return {0.0,1.0};
   }
 
   /**
    * Return the dipole scale associated to the
    * given pair of emitter and spectator. This
    * should be the invariant mass or absolute value
    * final/final or initial/initial and the absolute
    * value of the momentum transfer for intial/final or
    * final/initial dipoles.
    */
   virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
 			     const Lorentz5Momentum& pSpectator) const;
 
   /**
    * Return the maximum pt for the given dipole scale.
    */
   virtual Energy ptMax(Energy dScale, 
 		       double emX, double specX,
 		       const DipoleSplittingInfo& dInfo,
 		       const DipoleSplittingKernel& split) const;
   
   /**
    * Return the maximum pt for the given dipole scale.
    */
   virtual Energy ptMax(Energy dScale, 
 		       double, double,
 		       const DipoleIndex& dIndex,
 		       const DipoleSplittingKernel& split,
 		       tPPtr emitter, tPPtr) const;
   
   /**
    * Return the maximum pt for the given dipole scale.
    */
   virtual Energy ptMax(Energy, 
 		       double, double,
 		       const DipoleIndex&,
 		       const DipoleSplittingKernel&) const {
       // Only the DipoleSplittingInfo version should be used for massive
       // dipoles, for now anyway.
     assert(false);
     return ZERO;
   }
   
   /**
    * Return the maximum virtuality for the given dipole scale.
    */
   virtual Energy QMax(Energy dScale, 
 		      double emX, double specX,
 		      const DipoleSplittingInfo& dInfo,
 		      const DipoleSplittingKernel& split) const;
   
   /**
    * Return the maximum virtuality for the given dipole scale.
    */
   virtual Energy QMax(Energy, 
 		      double, double,
 		      const DipoleIndex&,
 		      const DipoleSplittingKernel&) const { 
     // Only the DipoleSplittingInfo version should be used for massive
     // dipoles, for now anyway.
     assert(false);
     return ZERO;
   }
   
   /**
    * Return the pt given a virtuality.
    */
   virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
 
   /**
    * Return the virtuality given a pt.
    */
   virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
 
   /**
    * Return the random number associated to
    * the given pt.
    */
   virtual double ptToRandom(Energy pt, Energy dScale,
 			    double emX, double specX,
 			    const DipoleIndex& dIndex,
 			    const DipoleSplittingKernel&) const;
 
   /**
    * Generate splitting variables given three random numbers
    * and the momentum fractions of the emitter and spectator.
    * Return true on success.
    */
   virtual bool generateSplitting(double kappa, double xi, double phi,
 				 DipoleSplittingInfo& dIndex,
 				 const DipoleSplittingKernel&);
 
   /**
    * Generate the full kinematics given emitter and
    * spectator momentum and a previously completeted
    * DipoleSplittingInfo object.
    */
   virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
 				  const Lorentz5Momentum& pSpectator,
 				  const DipoleSplittingInfo& dInfo);
 
 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<IFMassiveKinematics> initIFMassiveKinematics;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
-  IFMassiveKinematics & operator=(const IFMassiveKinematics &) = delete;
+  IFMassiveKinematics & operator=(const IFMassiveKinematics &);
 
 private:
 
   /**
    * Wether or not to choose the `collinear' scheme
    */
   bool theCollinearScheme;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of IFMassiveKinematics. */
 template <>
 struct BaseClassTrait<Herwig::IFMassiveKinematics,1> {
   /** Typedef of the first base class of IFMassiveKinematics. */
   typedef Herwig::DipoleSplittingKinematics NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the IFMassiveKinematics class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::IFMassiveKinematics>
   : public ClassTraitsBase<Herwig::IFMassiveKinematics> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::IFMassiveKinematics"; }
   /**
    * The name of a file containing the dynamic library where the class
    * IFMassiveKinematics is implemented. It may also include several, space-separated,
    * libraries if the class IFMassiveKinematics depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_IFMassiveKinematics_H */
diff --git a/Shower/Dipole/Kinematics/IILightKinematics.cc b/Shower/Dipole/Kinematics/IILightKinematics.cc
--- a/Shower/Dipole/Kinematics/IILightKinematics.cc
+++ b/Shower/Dipole/Kinematics/IILightKinematics.cc
@@ -1,290 +1,358 @@
 // -*- C++ -*-
 //
 // IILightKinematics.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 IILightKinematics class.
 //
 
 #include "IILightKinematics.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Switch.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 #include "ThePEG/Repository/UseRandom.h"
 #include "ThePEG/Repository/EventGenerator.h"
 #include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
 
 using namespace Herwig;
 
 IILightKinematics::IILightKinematics() 
-  : DipoleSplittingKinematics(), theCollinearScheme(true), didCollinear(false) {}
+  : DipoleSplittingKinematics(), theCollinearScheme(true), didCollinear(false),
+    theTransformationCalculated(false) {}
+//theTransformHardOnly(false) {}
 
 IILightKinematics::~IILightKinematics() {}
 
 IBPtr IILightKinematics::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr IILightKinematics::fullclone() const {
   return new_ptr(*this);
 }
 
 Energy IILightKinematics::ptMax(Energy dScale, 
 				double emX, double specX,
 				const DipoleIndex&,
 				const DipoleSplittingKernel&) const {
   double tau = 
     !theCollinearScheme ? emX*specX : emX;
   return (1.-tau) * dScale / (2.*sqrt(tau));
 }
 
 Energy IILightKinematics::QMax(Energy, 
 			       double, double,
 			       const DipoleIndex&,
 			       const DipoleSplittingKernel&) const {
   assert(false && "add this");
   return 0.0*GeV;
 }
 
 Energy IILightKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
   double z = split.lastZ();
   return scale*sqrt(1.-z);
 }
 
 Energy IILightKinematics::QFromPt(Energy scale, const DipoleSplittingInfo& split) const {
   double z = split.lastZ();
   return scale/sqrt(1.-z);
 }
 
 pair<double,double> IILightKinematics::zBoundaries(Energy pt,
 						   const DipoleSplittingInfo& dInfo,
 						   const DipoleSplittingKernel&) const {
   double x = 
     !theCollinearScheme ?
     dInfo.emitterX()*dInfo.spectatorX() :
     dInfo.emitterX();
 
-
   Energy hard=dInfo.hardPt();
   if(openZBoundaries()==1)hard=(1.-x) *dInfo.scale()/(2.*sqrt(x));
   if(openZBoundaries()==2)hard=min(dInfo.scale(),(1.-x) *dInfo.scale()/(2.*sqrt(x)));
   if(hard<pt)return {0.5*(1.+x),0.5*(1.+x)};
 
   double s = sqrt(1.-sqr(pt/hard));
 
-            
   return {0.5*(1.+x-(1.-x)*s),0.5*(1.+x+(1.-x)*s)};
 }
 
 bool IILightKinematics::generateSplitting(double kappa, double xi, double rphi,
 					  DipoleSplittingInfo& info,
 					  const DipoleSplittingKernel& split) {
 
   if ( info.emitterX() < xMin() ||
        info.spectatorX() < xMin() ) {
     jacobian(0.0);
     return false;
   }
 
   double weight = 1.0;
 
   Energy pt = generatePt(kappa,info.scale(),
 			 info.emitterX(),info.spectatorX(),
 			 info.index(),split,
 			 weight);
 
   if ( pt < IRCutoff() || pt > info.hardPt() ) {
     jacobian(0.0);
     return false;
   }
 
   double z = 0.0;
 
   if ( info.index().emitterData()->id() == ParticleID::g ) {
     if ( info.emitterData()->id() == ParticleID::g ) {
       z = generateZ(xi,pt,OneOverZOneMinusZ,
 		    info,split,weight);
     } else {
       z = generateZ(xi,pt,OneOverZ,
 		    info,split,weight);
     }
   }
-
   if ( info.index().emitterData()->id() != ParticleID::g ) {
     if ( info.emitterData()->id() != ParticleID::g ) {
       z = generateZ(xi,pt,OneOverOneMinusZ,
 		    info,split,weight);
     } else {
       z = generateZ(xi,pt,FlatZ,
 		    info,split,weight);
     }
   }
 
   if ( weight == 0. && z == -1. ) {
     jacobian(0.0);
     return false;
   }
 
   double ratio = sqr(pt/info.scale());
-
   double x = z*(1.-z)/(1.-z+ratio);
   double v = ratio*z /(1.-z+ratio);
 
   if ( x < 0. || x > 1. || v < 0. || v > 1.-x ) {
     jacobian(0.0);
     return false;
   }
-
+  
   if ( !theCollinearScheme &&
        (1.-v-x)/(v+x) < 1. ) {
     if ( (x+v) < info.emitterX() ||
-	 x/(x+v) < info.spectatorX() ) {
+         x/(x+v) < info.spectatorX() ) {
       jacobian(0.0);
       return false;
     }
   } else {
     if ( x < info.emitterX() ) {
       jacobian(0.0);
       return false;
     }
   }
-
+  
   double phi = 2.*Constants::pi*rphi;
 
   jacobian(weight*(1./z));
 
   lastPt(pt);
   lastZ(z);
   lastPhi(phi);
 
   if ( !theCollinearScheme &&
        (1.-v-x)/(v+x) < 1. ) {
     lastEmitterZ(x+v);
     lastSpectatorZ(x/(x+v));
   } else {
     lastEmitterZ(x);
     lastSpectatorZ(1.);
   }
 
   if ( theMCCheck )
     theMCCheck->book(info.emitterX(),info.spectatorX(),info.scale(),info.hardPt(),pt,z,jacobian());
 
   return true;
 
 }
 
 void IILightKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
 					   const Lorentz5Momentum& pSpectator,
 					   const DipoleSplittingInfo& dInfo) {
 
-  Energy pt = dInfo.lastPt();
+  Energy pt = dInfo.lastPt(); 
   double z = dInfo.lastZ();
 
   double ratio = sqr(pt)/(2.*pEmitter*pSpectator);
 
   double x = z*(1.-z)/(1.-z+ratio);
   double v = ratio*z /(1.-z+ratio);
-
+    
   Lorentz5Momentum kt =
-    getKt (pEmitter, pSpectator, pt, dInfo.lastPhi());
+    getKt(pEmitter, pSpectator, pt, dInfo.lastPhi());
 
   // Initialise the momenta
   Lorentz5Momentum em;
   Lorentz5Momentum emm;
   Lorentz5Momentum spe;
   
   if ( !theCollinearScheme &&
        (1.-v-x)/(v+x) < 1. ) {
 
     assert(false);
 
     em = (1./(v+x))*pEmitter+(v*(1.-v-x)/(x*(x+v)))*pSpectator+kt/(x+v);
     emm = ((1.-v-x)/(v+x))*pEmitter+(v/(x*(x+v)))*pSpectator+kt/(x+v);
     spe = (1.+v/x)*pSpectator;
     
     didCollinear = false;
 
   } else {
 
     em = (1./x)*pEmitter;
     emm = ((1.-x-v)/x)*pEmitter+v*pSpectator+kt;
     spe = pSpectator;
 
     K = em + spe - emm;
     K2 = K.m2();
     
     Ktilde = pEmitter + pSpectator;
     KplusKtilde = K + Ktilde;
-    
     KplusKtilde2 = KplusKtilde.m2();
 
     didCollinear = true;
 
+    // Set indicator that the transformation,
+    // required for spin correlations, hasn't
+    // been calculated.
+    theTransformationCalculated = false;
   }
-
-  
+ 
   em.setMass(ZERO);
   em.rescaleEnergy();
   
   emm.setMass(ZERO);
   emm.rescaleEnergy();
   
   spe.setMass(ZERO);
   spe.rescaleEnergy();
   
   emitterMomentum(em);
   emissionMomentum(emm);
   spectatorMomentum(spe);
   
 }
 
+void IILightKinematics::setTransformation () {
+  
+    // Construct transformation for spin correlations
+    // Clear the rotation
+    theRecoilTransformation = LorentzRotation();
+  
+    // Construct boost part
+    Energy KplusKtildeT = KplusKtilde.t();
+    Energy KT = K.t();
+  
+    double tt = 1. - 2.*sqr(KplusKtildeT)/KplusKtilde2            + 2.*KT*Ktilde.t()/K2;
+    double tx =      2.*KplusKtildeT*KplusKtilde.x()/KplusKtilde2 - 2.*KT*Ktilde.x()/K2;
+    double ty =      2.*KplusKtildeT*KplusKtilde.y()/KplusKtilde2 - 2.*KT*Ktilde.y()/K2;  
+    double tz =      2.*KplusKtildeT*KplusKtilde.z()/KplusKtilde2 - 2.*KT*Ktilde.z()/K2;
+    
+    theRecoilTransformation.boost(tx/tt, ty/tt, tz/tt, tt);
+    
+    // Rotate KtildeSpinCorrTrans to z-axis
+    Lorentz5Momentum KtildeSpinCorrTrans = theRecoilTransformation*Lorentz5Momentum(Ktilde);
+    Axis axis(KtildeSpinCorrTrans.vect().unit());
+    if( axis.perp2() > 1e-12 ) {
+      double sinth(sqrt(1.-sqr(axis.z())));
+      theRecoilTransformation.rotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.));
+    }
+    else if( axis.z() < 0. ) {
+      theRecoilTransformation.rotate(Constants::pi,Axis(1.,0.,0.));
+    }
+    
+    // Rotate from z-axis to K
+    Axis axis2(K.vect().unit());
+    if( axis2.perp2() > 1e-12 ) {
+      double sinth(sqrt(1.-sqr(axis2.z())));
+      theRecoilTransformation.rotate(acos(axis2.z()),Axis(-axis2.y()/sinth,axis2.x()/sinth,0.));
+    }
+    else if( axis2.z() < 0. ) {
+      theRecoilTransformation.rotate(Constants::pi,Axis(1.,0.,0.));
+    }
+  
+    // SW 30/01/2019: Test feature only, not for release.
+    // Required for absorbing recoil in hard particles only
+    //splitRecoilMomentum(K);
+
+    // Set indicator that the transformation,
+    // has been calculated
+    theTransformationCalculated = true;
+  }
+
+
 // If needed, insert default implementations of function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void IILightKinematics::persistentOutput(PersistentOStream &) const {
+  //os << theTransformHardOnly;
   //os << theCollinearScheme;
 }
 
 void IILightKinematics::persistentInput(PersistentIStream &, int) {
+  //is >> theTransformHardOnly;
   //is >> theCollinearScheme;
 }
 
 ClassDescription<IILightKinematics> IILightKinematics::initIILightKinematics;
 // Definition of the static class description member.
 
 void IILightKinematics::Init() {
 
   static ClassDocumentation<IILightKinematics> documentation
     ("IILightKinematics implements massless splittings "
      "off an initial-initial dipole.");
 
   /*
+  static Switch<IILightKinematics,bool> interfaceTransformHardOnly
+    ("TransformHardOnly",
+     "[Dev only] Apply recoil transformation to colourless particles only.",
+     &IILightKinematics::theTransformHardOnly, false, false, false);
+  static SwitchOption interfaceTransformHardOnlyYes
+    (interfaceTransformHardOnly,
+     "Yes",
+     "Transform only colourless particles.",
+     true);
+  static SwitchOption interfaceTransformHardOnlyNo
+    (interfaceTransformHardOnly,
+     "No",
+     "Transform all particles.",
+     false);
+
+  interfaceTransformHardOnly.rank(-1);
+  */
+  /*
   static Switch<IILightKinematics,bool> interfaceCollinearScheme
     ("CollinearScheme",
      "[experimental] Switch on or off the collinear scheme",
      &IILightKinematics::theCollinearScheme, false, false, false);
   static SwitchOption interfaceCollinearSchemeYes
     (interfaceCollinearScheme,
      "Yes",
      "Switch on the collinear scheme.",
      true);
   static SwitchOption interfaceCollinearSchemeNo
     (interfaceCollinearScheme,
      "No",
      "Switch off the collinear scheme",
      false);
 
   interfaceCollinearScheme.rank(-1);
   */
 
 }
 
diff --git a/Shower/Dipole/Kinematics/IILightKinematics.h b/Shower/Dipole/Kinematics/IILightKinematics.h
--- a/Shower/Dipole/Kinematics/IILightKinematics.h
+++ b/Shower/Dipole/Kinematics/IILightKinematics.h
@@ -1,232 +1,295 @@
 // -*- C++ -*-
 //
 // IILightKinematics.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_IILightKinematics_H
 #define HERWIG_IILightKinematics_H
 //
 // This is the declaration of the IILightKinematics class.
 //
 
 #include "DipoleSplittingKinematics.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
-/**
- * \ingroup DipoleShower
- * \author Simon Platzer
- *
- * \brief IILightKinematics implements massless splittings
- * off an initial-initial dipole.
- *
- * @see \ref IILightKinematicsInterfaces "The interfaces"
- * defined for IILightKinematics.
- */
-class IILightKinematics: public DipoleSplittingKinematics {
+  /**
+   * \ingroup DipoleShower
+   * \author Simon Platzer
+   *
+   * \brief IILightKinematics implements massless splittings
+   * off an initial-initial dipole.
+   *
+   * @see \ref IILightKinematicsInterfaces "The interfaces"
+   * defined for IILightKinematics.
+   */
+  class IILightKinematics: public DipoleSplittingKinematics {
 
-public:
+  public:
 
-  /** @name Standard constructors and destructors. */
-  //@{
-  /**
-   * The default constructor.
-   */
-  IILightKinematics();
+    /** @name Standard constructors and destructors. */
+    //@{
+    /**
+     * The default constructor.
+     */
+    IILightKinematics();
 
-  /**
-   * The destructor.
-   */
-  virtual ~IILightKinematics();
-  //@}
+    /**
+     * The destructor.
+     */
+    virtual ~IILightKinematics();
+    //@}
 
-public:
+  public:
 
-  /**
-   * Return the maximum pt for the given dipole scale.
-   */
-  virtual Energy ptMax(Energy dScale, 
-		       double emX, double specX,
-		       const DipoleIndex&,
-		       const DipoleSplittingKernel&) const;
+    /**
+     * Return the maximum pt for the given dipole scale.
+     */
+    virtual Energy ptMax(Energy dScale, 
+                         double emX, double specX,
+                         const DipoleIndex&,
+                         const DipoleSplittingKernel&) const;
 
-  /**
-   * Return the maximum virtuality for the given dipole scale.
-   */
-  virtual Energy QMax(Energy dScale, 
-		      double emX, double specX,
-		      const DipoleIndex& dIndex,
-		      const DipoleSplittingKernel&) const;
+    /**
+     * Return the maximum virtuality for the given dipole scale.
+     */
+    virtual Energy QMax(Energy dScale, 
+                        double emX, double specX,
+                        const DipoleIndex& dIndex,
+                        const DipoleSplittingKernel&) const;
 
-  /**
-   * Return the pt given a virtuality.
-   */
-  virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
+    /**
+     * Return the pt given a virtuality.
+     */
+    virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
 
-  /**
-   * Return the virtuality given a pt.
-   */
-  virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
+    /**
+     * Return the virtuality given a pt.
+     */
+    virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
 
-  /**
-   * Return the boundaries on the momentum fraction
-   */
-  virtual pair<double,double> zBoundaries(Energy pt,
-					  const DipoleSplittingInfo& dInfo,
-					  const DipoleSplittingKernel& split) const;
+    /**
+     * Return the boundaries on the momentum fraction
+     */
+    virtual pair<double,double> zBoundaries(Energy pt,
+                                            const DipoleSplittingInfo& dInfo,
+                                            const DipoleSplittingKernel& split) const;
 
-  /**
-   * Generate splitting variables given three random numbers
-   * and the momentum fractions of the emitter and spectator.
-   * Return true on success.
-   */
-  virtual bool generateSplitting(double kappa, double xi, double phi,
-				 DipoleSplittingInfo& dIndex,
-				 const DipoleSplittingKernel&);
+    /**
+     * Generate splitting variables given three random numbers
+     * and the momentum fractions of the emitter and spectator.
+     * Return true on success.
+     */
+    virtual bool generateSplitting(double kappa, double xi, double phi,
+                                   DipoleSplittingInfo& dIndex,
+                                   const DipoleSplittingKernel&);
 
-  /**
-   * Generate the full kinematics given emitter and
-   * spectator momentum and a previously completeted
-   * DipoleSplittingInfo object.
-   */
-  virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
-				  const Lorentz5Momentum& pSpectator,
-				  const DipoleSplittingInfo& dInfo);
+    /**
+     * Generate the full kinematics given emitter and
+     * spectator momentum and a previously completeted
+     * DipoleSplittingInfo object.
+     */
+    virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
+                                    const Lorentz5Momentum& pSpectator,
+                                    const DipoleSplittingInfo& dInfo);
 
-  /*
-   * Return true, if there is a transformation which should
-   * be applied to all other final state particles except the ones
-   * involved in the splitting after having performed the splitting
-   */
-  virtual bool doesTransform () const { return theCollinearScheme || didCollinear; }
+    /**
+     * Return true, if there is a transformation which should
+     * be applied to all other final state particles except the ones
+     * involved in the splitting after having performed the splitting
+     */
+    virtual bool doesTransform () const { return theCollinearScheme || didCollinear; }
 
-  /*
-   * perform the transformation, if existing
-   */
-  virtual Lorentz5Momentum transform (const Lorentz5Momentum& p) const {
-    if ( !theCollinearScheme && !didCollinear ) return p;
-    return p-(2.*(KplusKtilde*p)/KplusKtilde2)*KplusKtilde+(2.*(Ktilde*p)/K2)*K;
-  }
+    /**
+     * Calculate and store a required Lorentz transformation
+     **/
+    virtual void setTransformation () ;
+    
+    /*
+     * perform the transformation, if existing
+     */
+    virtual void transform (PPtr& part) {
+      if ( !theCollinearScheme && !didCollinear ) return;
 
-public:
+      Lorentz5Momentum mom = part->momentum();
 
-  /** @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;
+      // If particle has SpinInfo check that we're 
+      // not dealing with an intermediate spectator.
+      if ( part->spinInfo() 
+	   && !(part->spinInfo()->timelike() && part->children().size() == 1 ) 
+	   && !(!part->spinInfo()->timelike() && part->parents()[0]->children().size() == 1 ) ) {
+	  
+        if ( !theTransformationCalculated )
+          setTransformation();
+	 
+        part->spinInfo()->transform(mom,theRecoilTransformation);
+      }
 
-  /**
-   * 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);
-  //@}
+      part->set5Momentum(mom-(2.*(KplusKtilde*mom)/KplusKtilde2)*KplusKtilde+(2.*(Ktilde*mom)/K2)*K);
+      
+    }
 
-  /**
-   * 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();
+    /*
+     * SW 30/01/2019: Test feature only, not for release.
+     * Return true to only apply the transformation to non-coloured particles.
+     * Note this requires careful handling in DipoleEventRecord
+     */
+    //virtual bool transformHardOnly() const { return theTransformHardOnly; }
 
-protected:
 
-  /** @name Clone Methods. */
-  //@{
-  /**
-   * Make a simple clone of this object.
-   * @return a pointer to the new object.
-   */
-  virtual IBPtr clone() const;
+    /**
+     * SW 30/01/2019: Test feature only, not for release.
+     * Perform the recoil in the case of a decayed parton
+     */   
+    // virtual void transformHard ( PPtr& hard ) {
+    // if ( !theTransformationCalculated ) {
+    //   setTransformation();
+    //   theTransformationCalculated = true;
+    // }
+    //   hard->setMomentum(splitRecoilMomentum());
+    //   hard->rescaleMass();
+    // }
 
-  /** 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;
-  //@}
+  
+  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;
 
-// If needed, insert declarations of virtual function defined in the
-// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
+    /**
+     * 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();
 
-private:
+  protected:
 
-  /**
-   * The static object used to initialize the description of this class.
-   * Indicates that this is a concrete class with persistent data.
-   */
-  static ClassDescription<IILightKinematics> initIILightKinematics;
+    /** @name Clone Methods. */
+    //@{
+    /**
+     * Make a simple clone of this object.
+     * @return a pointer to the new object.
+     */
+    virtual IBPtr clone() const;
 
-  /**
-   * The assignment operator is private and must never be called.
-   * In fact, it should not even be implemented.
-   */
-  IILightKinematics & operator=(const IILightKinematics &) = delete;
+    /** 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:
 
-  /**
-   * Wether or not to choose the `collinear' scheme
-   */
-  bool theCollinearScheme;
+    // If needed, insert declarations of virtual function defined in the
+    // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
-  bool didCollinear;
 
-  Lorentz5Momentum K;
-  Energy2 K2;
-  Lorentz5Momentum Ktilde;
-  Lorentz5Momentum KplusKtilde;
-  Energy2 KplusKtilde2;
+  private:
 
-};
+    /**
+     * The static object used to initialize the description of this class.
+     * Indicates that this is a concrete class with persistent data.
+     */
+    static ClassDescription<IILightKinematics> initIILightKinematics;
+
+    /**
+     * The assignment operator is private and must never be called.
+     * In fact, it should not even be implemented.
+     */
+    IILightKinematics & operator=(const IILightKinematics &) = delete;
+
+  private:
+
+    /**
+     * Wether or not to choose the `collinear' scheme
+     */
+    bool theCollinearScheme;
+
+    bool didCollinear;
+
+    /**
+     * SW 30/01/2019: Test feature only, not for release.
+     * Whether to transform only hard (i.e. non-coloured) particles.
+     */
+    //bool theTransformHardOnly;
+  
+    Lorentz5Momentum K;
+    Energy2 K2;
+    Lorentz5Momentum Ktilde;
+    Lorentz5Momentum KplusKtilde;
+    Energy2 KplusKtilde2;
+
+    /**
+     * Store the LorentzRotation object equivalent to the 
+     * transformation applied to the outgoing particles.
+     * Need this to apply to the particle SpinInfo if spin
+     * correlations are included.
+     */
+    LorentzRotation theRecoilTransformation;
+
+    /**
+     * Bool to avoid unecessary recalculation of the 
+     * Lorentz transformation.
+     */
+    bool theTransformationCalculated;
+    
+  };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
-/** @cond TRAITSPECIALIZATIONS */
+  /** @cond TRAITSPECIALIZATIONS */
 
-/** This template specialization informs ThePEG about the
- *  base classes of IILightKinematics. */
-template <>
-struct BaseClassTrait<Herwig::IILightKinematics,1> {
-  /** Typedef of the first base class of IILightKinematics. */
-  typedef Herwig::DipoleSplittingKinematics NthBase;
-};
+  /** This template specialization informs ThePEG about the
+   *  base classes of IILightKinematics. */
+  template <>
+  struct BaseClassTrait<Herwig::IILightKinematics,1> {
+    /** Typedef of the first base class of IILightKinematics. */
+    typedef Herwig::DipoleSplittingKinematics NthBase;
+  };
 
-/** This template specialization informs ThePEG about the name of
- *  the IILightKinematics class and the shared object where it is defined. */
-template <>
-struct ClassTraits<Herwig::IILightKinematics>
-  : public ClassTraitsBase<Herwig::IILightKinematics> {
-  /** Return a platform-independent class name */
-  static string className() { return "Herwig::IILightKinematics"; }
-  /**
-   * The name of a file containing the dynamic library where the class
-   * IILightKinematics is implemented. It may also include several, space-separated,
-   * libraries if the class IILightKinematics depends on other classes (base classes
-   * excepted). In this case the listed libraries will be dynamically
-   * linked in the order they are specified.
-   */
-  static string library() { return "HwDipoleShower.so"; }
-};
+  /** This template specialization informs ThePEG about the name of
+   *  the IILightKinematics class and the shared object where it is defined. */
+  template <>
+  struct ClassTraits<Herwig::IILightKinematics>
+    : public ClassTraitsBase<Herwig::IILightKinematics> {
+    /** Return a platform-independent class name */
+    static string className() { return "Herwig::IILightKinematics"; }
+    /**
+     * The name of a file containing the dynamic library where the class
+     * IILightKinematics is implemented. It may also include several, space-separated,
+     * libraries if the class IILightKinematics depends on other classes (base classes
+     * excepted). In this case the listed libraries will be dynamically
+     * linked in the order they are specified.
+     */
+    static string library() { return "HwDipoleShower.so"; }
+  };
 
-/** @endcond */
+  /** @endcond */
 
 }
 
 #endif /* HERWIG_IILightKinematics_H */
diff --git a/Shower/Dipole/Makefile.am b/Shower/Dipole/Makefile.am
--- a/Shower/Dipole/Makefile.am
+++ b/Shower/Dipole/Makefile.am
@@ -1,23 +1,24 @@
-SUBDIRS = Base Kernels Kinematics Utility AlphaS Merging Colorea
+SUBDIRS = Base Kernels Kinematics Utility AlphaS Merging SpinCorrelations Colorea
 
 pkglib_LTLIBRARIES = HwDipoleShower.la
 
 HwDipoleShower_la_LDFLAGS = $(AM_LDFLAGS) -module -version-info 10:0:0
 
 HwDipoleShower_la_LIBADD = \
 	Base/libHwDipoleShowerBase.la \
 	Kernels/libHwDipoleShowerKernels.la \
 	Kinematics/libHwDipoleShowerKinematics.la \
 	Utility/libHwDipoleShowerUtility.la \
 	Merging/libHwDipoleShowerMerging.la \
+	SpinCorrelations/libHwDipoleShowerSpinCorrelations.la \
         Colorea/libHwDipoleShowerColorea.la
 
 HwDipoleShower_la_SOURCES =  \
 	DipoleShowerHandler.h DipoleShowerHandler.fh DipoleShowerHandler.cc
 
 
 pkglib_LTLIBRARIES += HwKrknloEventReweight.la
 HwKrknloEventReweight_la_SOURCES = \
 	KrkNLO/KrknloEventReweight.h KrkNLO/KrknloEventReweight.cc
 
 HwKrknloEventReweight_la_LDFLAGS = $(AM_LDFLAGS) -module -version-info 2:0:0
diff --git a/Shower/Dipole/SpinCorrelations/DipoleShowerParticle.cc b/Shower/Dipole/SpinCorrelations/DipoleShowerParticle.cc
new file mode 100644
--- /dev/null
+++ b/Shower/Dipole/SpinCorrelations/DipoleShowerParticle.cc
@@ -0,0 +1,341 @@
+// -*- C++ -*-
+//
+// DipoleShowerParticle.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 2 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 DipoleShowerParticle class.
+//
+
+#include "DipoleShowerParticle.h"
+
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/EventRecord/SpinInfo.h"
+#include "ThePEG/EventRecord/RhoDMatrix.h"
+
+#include "ThePEG/Helicity/FermionSpinInfo.h"
+#include "ThePEG/Helicity/VectorSpinInfo.h"
+
+#include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
+
+using namespace Herwig;
+
+void DipoleShowerParticle::Init() {
+
+  static ClassDocumentation<DipoleShowerParticle> documentation
+    ("The DipoleShowerParticle class is the implementation of a "
+     "vertex for a shower for the Herwig spin correlation algorithm");
+
+}
+
+
+void DipoleShowerParticle::clear() {
+  theParticle = PPtr();
+  theDecayVertex = DSVertexPtr();
+}
+
+
+void DipoleShowerParticle::prepare( PPtr& part, const Helicity::Direction emmDir, const Helicity::Direction specDir, const Lorentz5Momentum& pVector, const Lorentz5Momentum& nVector ) {
+
+  // Set the member variables
+  theParticle = part;
+  theDecayVertex = new_ptr(DipoleShowerVertex());
+
+  // Set the pVector and nVector of the splitting vertex
+  theDecayVertex->pVector(pVector);
+  theDecayVertex->nVector(nVector);
+  theDecayVertex->dipoleConfig( {emmDir == outgoing,specDir == outgoing} );
+  
+  // Calculate and store the transformation 
+  // between the frame of this splitting and the working frame
+  theDecayVertex->boostToSplitting();
+  
+  // Create the decay basis states of the emitter in the frame
+  // of the splitting and compute the state mappings
+  if ( theParticle->dataPtr()->iSpin() == PDT::Spin0 )
+    assert(false);
+  
+  else if ( theParticle->dataPtr()->iSpin() == PDT::Spin1Half ) {
+    vector<LorentzSpinor<SqrtEnergy> > decayBasis = createFermionDecayStates();
+    setFermionMapping( decayBasis );
+  }
+  
+  else if ( theParticle->dataPtr()->iSpin() == PDT::Spin1 ) {
+    createVectorDecayStates();
+    setVectorMapping();
+  }
+  
+  else
+    assert(false);
+
+  // Set the decay vertex of the particle
+  assert(theParticle->spinInfo());
+  theParticle->spinInfo()->decayVertex(theDecayVertex);
+  
+}
+
+
+vector<LorentzSpinor<SqrtEnergy> > DipoleShowerParticle::createFermionDecayStates() {
+
+  // Note - Based on createFermionSpinInfo in ShowerParticle.cc
+  FermionSpinPtr fspin = dynamic_ptr_cast<FermionSpinPtr>(theParticle->spinInfo());
+
+  // Create the decay basis states
+  LorentzRotation decayRot = theDecayVertex->boostToSplitting();
+  Lorentz5Momentum decayPorig = decayRot*Lorentz5Momentum(theParticle->momentum());
+  
+  // Calculate the basis for the particle
+  // in the frame of its splitting 
+  SpinorWaveFunction wave;
+  if( theParticle->id()>0 )
+    wave=SpinorWaveFunction(decayPorig, theParticle->dataPtr(), incoming);
+  else
+    wave=SpinorWaveFunction(decayPorig, theParticle->dataPtr(), outgoing);
+
+  // Initialise basis to return from function
+  // Store decay states in decay frame in this
+  vector<LorentzSpinor<SqrtEnergy> > decayBasis;
+
+  LorentzRotation decayRotInv = decayRot.inverse();
+  // Compute the decay basis states
+  for(unsigned int ix=0;ix<2;++ix) {
+    wave.reset(ix);
+    LorentzSpinor<SqrtEnergy> basis = wave.dimensionedWave();
+    decayBasis.push_back(basis);
+    
+    // Rotate the decay states to the lab frame 
+    // and store them in the spin info
+    basis.transform(decayRotInv);
+    fspin->setDecayState(ix,basis);
+    
+  }
+  
+  return decayBasis;
+}
+
+
+void DipoleShowerParticle::createVectorDecayStates() {
+  
+  // Note - Based on createVectorSpinInfo in ShowerParticle.cc
+  VectorSpinPtr vspin = dynamic_ptr_cast<VectorSpinPtr>(theParticle->spinInfo());
+  bool massless(theParticle->id()==ParticleID::g||theParticle->id()==ParticleID::gamma);
+
+  // Create the decay basis states
+  LorentzRotation decayRot = theDecayVertex->boostToSplitting();
+  Lorentz5Momentum decayPorig = decayRot*Lorentz5Momentum(theParticle->momentum());
+
+  // Calculate the basis for the particle
+  // in the frame of its splitting
+  VectorWaveFunction wave(decayPorig, theParticle->dataPtr(),
+                          vspin->timelike() ? outgoing : incoming );
+
+  
+  LorentzRotation decayRotInv = decayRot.inverse();
+  // Compute the decay basis states
+  for(unsigned int ix=0;ix<3;++ix) {
+    LorentzPolarizationVector basis;
+    if(massless&&ix==1) {
+      basis = LorentzPolarizationVector();
+    }
+    else {
+      wave.reset(ix,vector_phase);
+      basis = wave.wave();
+    }
+    
+    // Rotate the decay states to the lab frame 
+    // and store them in the spin info
+    basis.transform(decayRotInv);
+    vspin->setDecayState(ix,basis);
+  }
+  
+}
+
+
+void DipoleShowerParticle::setFermionMapping( const vector<LorentzSpinor<SqrtEnergy>>& decayBasis ) {
+  
+  FermionSpinPtr fspin = dynamic_ptr_cast<FermionSpinPtr>(theParticle->spinInfo());
+  LorentzRotation rotToDecay = theDecayVertex->boostToSplitting();
+
+  // Access the basis states and transform them into the decay frame
+  vector<LorentzSpinor<SqrtEnergy> > prodBasis;
+  for(unsigned int ix=0;ix<2;++ix) {
+    prodBasis.push_back(fspin->getCurrentBasisState(ix));
+    prodBasis.back().transform(rotToDecay);
+  } 
+  
+  // Calculate the mapping from the production/current
+  // basis states to the decay basis states
+  RhoDMatrix mapDec2Prod = RhoDMatrix(PDT::Spin1Half,false);
+  
+  // Check the direction of the particle in the decay frame and
+  // construct the mapping from the basis states accordingly.
+  Lorentz5Momentum decayPorig = rotToDecay*Lorentz5Momentum(theParticle->momentum());
+  SqrtEnergy sqrtGeV = sqrt(1.0*GeV);
+  if (decayPorig.z() > ZERO ) {
+    for(unsigned int ix=0;ix<2;++ix) {
+      if( abs(decayBasis[0].s2()/sqrtGeV) < 1e-3 ) {
+        assert( abs(decayBasis[1].s2()/sqrtGeV) > 1e-5 );
+        mapDec2Prod(ix,0) = prodBasis[ix].s3()/decayBasis[0].s3();
+        mapDec2Prod(ix,1) = prodBasis[ix].s2()/decayBasis[1].s2();
+      }
+      else {
+        assert( abs(decayBasis[1].s2()/sqrtGeV) < 1e-3 );
+        mapDec2Prod(ix,0) = prodBasis[ix].s2()/decayBasis[0].s2();
+        mapDec2Prod(ix,1) = prodBasis[ix].s3()/decayBasis[1].s3();
+      }
+    }
+  }
+  else {
+    for(unsigned int ix=0;ix<2;++ix) {
+      if(abs(decayBasis[0].s1()/sqrtGeV) < 1e-3 ) {
+        assert( abs(decayBasis[1].s1()/sqrtGeV) > 1e-5 );
+        mapDec2Prod(ix,0) = prodBasis[ix].s4()/decayBasis[0].s4();
+        mapDec2Prod(ix,1) = prodBasis[ix].s1()/decayBasis[1].s1();
+      }
+      else {
+        assert( abs(decayBasis[1].s1()/sqrtGeV) < 1e-3 );
+        mapDec2Prod(ix,0) = prodBasis[ix].s1()/decayBasis[0].s1();
+        mapDec2Prod(ix,1) = prodBasis[ix].s4()/decayBasis[1].s4();
+      }
+    }
+  }
+  
+  // The mapping prod->dec is simply the adjoint of the dec->prod mapping
+  RhoDMatrix mapProd2Dec = RhoDMatrix(mapDec2Prod.iSpin(),false);
+  for (int ix=0; ix<mapDec2Prod.iSpin(); ++ix) {
+    for (int iy=0; iy<mapDec2Prod.iSpin(); ++iy) {
+      mapProd2Dec(ix,iy) = conj(mapDec2Prod(iy,ix));
+    }
+  }
+  
+  // Set the mapping in the decay vertex
+  theDecayVertex->mappingD2P(mapDec2Prod);
+  theDecayVertex->mappingP2D(mapProd2Dec);
+
+}
+
+ 
+void DipoleShowerParticle::setVectorMapping() {
+  
+  VectorSpinPtr vspin = dynamic_ptr_cast<VectorSpinPtr>(theParticle->spinInfo());
+  
+  // Access the basis and decay states
+  vector<LorentzPolarizationVector> prodBasis;
+  for(unsigned int ix=0;ix<3;++ix) {
+    prodBasis.push_back(vspin->getCurrentBasisState(ix));
+  }
+  vector<LorentzPolarizationVector> decayBasis;
+  for(unsigned int ix=0;ix<3;++ix) {
+    decayBasis.push_back(vspin->getDecayBasisState(ix));
+  }
+
+  // Compute the mapping from the decay basis states to the
+  // production/current basis states
+  RhoDMatrix mapDec2Prod = RhoDMatrix(PDT::Spin1,false);
+
+  for(unsigned int ix=0;ix<3;++ix) {
+    for(unsigned int iy=0;iy<3;++iy) {
+      
+      // For outgoing both the production and decay states are eps*
+      // Need -eps_a dot eps_i*
+      if ( vspin->timelike() )
+        mapDec2Prod(ix,iy) = -prodBasis[ix].conjugate().dot(decayBasis[iy]);
+      // For incoming both the production and decay states are eps
+      else
+        mapDec2Prod(ix,iy) = -prodBasis[ix].dot(decayBasis[iy].conjugate());
+				   
+      if(theParticle->id()<0) {
+        mapDec2Prod(ix,iy)=conj(mapDec2Prod(ix,iy));
+      }
+    }
+  }
+
+  // The mapping prod->decay is simply the adjoint of the dec->prod mapping
+  RhoDMatrix mapProd2Dec = RhoDMatrix(mapDec2Prod.iSpin(),false);
+  for (int ix=0; ix<mapDec2Prod.iSpin(); ++ix) {
+    for (int iy=0; iy<mapDec2Prod.iSpin(); ++iy) {
+      mapProd2Dec(ix,iy) = conj(mapDec2Prod(iy,ix));
+    }
+  }
+  
+  // Set the mapping in the decay vertex
+  theDecayVertex->mappingD2P(mapDec2Prod);
+  theDecayVertex->mappingP2D(mapProd2Dec);
+
+}
+
+
+void DipoleShowerParticle::createNewFermionSpinInfo( PPtr& newp, Helicity::Direction dir ) {
+
+  // Create the new spin info
+  FermionSpinPtr fspin = new_ptr(FermionSpinInfo(newp->momentum(),dir==outgoing));
+  newp->spinInfo(fspin);
+  
+  // Create the production basis states
+  LorentzRotation rot = theDecayVertex->boostToSplitting();
+  Lorentz5Momentum outPorig = rot*Lorentz5Momentum(newp->momentum());
+  
+  // Calculate the basis for the particle
+  // in the frame of the splitting that produced it
+  SpinorWaveFunction wave;
+  if(newp->id()>0)
+    wave=SpinorWaveFunction(outPorig,newp->dataPtr(),incoming);
+  else
+    wave=SpinorWaveFunction(outPorig,newp->dataPtr(),outgoing);
+  
+  // Rotate the basis states back to the lab frame
+  // and store them in the spin info
+  LorentzRotation rotInv = rot.inverse();
+  for(unsigned int ix=0;ix<2;++ix) {
+    wave.reset(ix);
+    LorentzSpinor<SqrtEnergy> basis = wave.dimensionedWave();
+    basis.transform(rotInv);
+    fspin->setBasisState(ix,basis);
+  }
+}
+
+
+void DipoleShowerParticle::createNewVectorSpinInfo( PPtr& newp, Helicity::Direction dir ) {
+
+  // Create the new spin info
+  VectorSpinPtr vspin = new_ptr(VectorSpinInfo(newp->momentum(),dir==outgoing));
+  newp->spinInfo(vspin);
+  
+  bool massless(newp->id()==ParticleID::g||newp->id()==ParticleID::gamma);
+  Lorentz5Momentum partMom = newp->momentum();
+  
+  // Extract the required information
+  LorentzRotation rot = theDecayVertex->boostToSplitting();
+  // Get the particle momentum and transform
+  // it to the frame of the parent splitting
+  Lorentz5Momentum outPorig = rot*Lorentz5Momentum(partMom);
+  
+  // Calculate the basis for the particle in the frame of
+  // the splitting that produced it
+  VectorWaveFunction wave(outPorig,newp->dataPtr(),
+                          vspin->timelike() ? outgoing : incoming );
+  
+  LorentzRotation rotInv = rot.inverse();
+  for(unsigned int ix=0;ix<3;++ix) {
+    LorentzPolarizationVector basis;
+    if(massless&&ix==1) {
+      basis = LorentzPolarizationVector();
+    }
+    else {
+      wave.reset(ix,vector_phase);
+      basis = wave.wave();
+    }
+    
+    // Rotate the basis states back to the lab frame
+    // and store them in the spin info
+    basis.transform(rotInv);
+    vspin->setBasisState(ix,basis);
+  }
+  
+}
diff --git a/Shower/Dipole/SpinCorrelations/DipoleShowerParticle.fh b/Shower/Dipole/SpinCorrelations/DipoleShowerParticle.fh
new file mode 100644
--- /dev/null
+++ b/Shower/Dipole/SpinCorrelations/DipoleShowerParticle.fh
@@ -0,0 +1,18 @@
+// -*- C++ -*-
+//
+// This is the forward declaration of the DipoleShowerParticle class.
+//
+#ifndef HERWIG_DipoleShowerParticle_FH
+#define HERWIG_DipoleShowerParticle_FH
+
+#include "ThePEG/Config/Pointers.h"
+
+namespace Herwig {
+  using namespace ThePEG;
+  
+  class DipoleShowerParticle;
+  ThePEG_DECLARE_POINTERS(DipoleShowerParticle,DSParticlePtr); 
+  
+}
+
+#endif
diff --git a/Shower/Dipole/SpinCorrelations/DipoleShowerParticle.h b/Shower/Dipole/SpinCorrelations/DipoleShowerParticle.h
new file mode 100644
--- /dev/null
+++ b/Shower/Dipole/SpinCorrelations/DipoleShowerParticle.h
@@ -0,0 +1,182 @@
+// -*- C++ -*-
+//
+// DipoleShowerParticle.h is a part of Herwig - A multi-purpose Monte Carlo event generator
+// Copyright (C) 2002-2007 The Herwig Collaboration
+//
+// Herwig is licenced under version 2 of the GPL, see COPYING for details.
+// Please respect the MCnet academic guidelines, see GUIDELINES for details.
+//
+#ifndef HERWIG_DipoleShowerParticle_H
+#define HERWIG_DipoleShowerParticle_H
+//
+// This is the declaration of the DipoleShowerParticle class.
+//
+
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Helicity/WaveFunction/WaveFunctionBase.h"
+#include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
+
+#include "DipoleShowerVertex.h"
+
+namespace Herwig {
+
+  using namespace ThePEG;
+  
+  /** \ingroup DipoleShower
+   *
+   * \author Stephen Webster
+   *
+   */
+  class DipoleShowerParticle : public Base {
+    
+  public:
+
+    /**
+     * Default constructor
+     */
+    DipoleShowerParticle() {}
+
+    /** 
+     * Default destructor
+     **/
+    ~DipoleShowerParticle() {}
+
+  public:   
+
+    /**
+     * Reset the member variables of the object.
+     */
+    void clear();
+
+    /**
+     * Set up the decay vertex for the emitter.
+     */
+    void prepare( PPtr& part,
+                  const Helicity::Direction emmDir,
+                  const Helicity::Direction specDir,
+                  const Lorentz5Momentum& pVector,
+                  const Lorentz5Momentum& nVector );
+    
+    /**
+     * Return the associated decay vertex,
+     * a DipoleShowerVertex.
+     **/
+    DSVertexPtr decayVertex() { return theDecayVertex; }
+    
+    /**
+     * Create fermion decay basis states.
+     * It returns the decay basis states in the 
+     * decay frame as required for the mapping.
+     */
+    vector<LorentzSpinor<SqrtEnergy> > createFermionDecayStates();
+
+    /**
+     * Create vector decay basis states.
+     */
+    void createVectorDecayStates();
+    
+    /**
+     * Create fermion production basis states
+     * for the given particle produced in the splitting.
+     */
+    void createNewFermionSpinInfo( PPtr& outgoing, Helicity::Direction dir);
+
+    /**
+     * Create vector production basis states
+     * for the given particle produced in the splitting.
+     */
+    void createNewVectorSpinInfo( PPtr& outgoing, Helicity::Direction dir);
+    
+    /**
+     * Create the mappings between the production
+     * and decay states for the fermion and
+     * store them in the associated decay vertex.
+     * (No longer applicable) reason for passing the
+     * decay states as an argument:
+     * Previously used a check on zero values for computing
+     * the mapping, rather than a </> 1e-5, this would only
+     * work when using the original decay state as calculated
+     * in the decay frame (i.e. without transforming to the 
+     * lab frame and back). Now it simply avoids doing an
+     * unnecessary rotation of the decay basis
+     */
+    void setFermionMapping( const vector<LorentzSpinor<SqrtEnergy>>& decayBasis );
+
+    /**
+     * Create the mappings between the production
+     * and decay states the boson and
+     * store them in the associated decay vertex.
+     */
+
+    void setVectorMapping();
+
+  public:
+
+    /**
+     * 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();
+
+  private:
+
+    /**
+     * The pptr to this particle.
+     */
+    PPtr theParticle;
+    
+    /**
+     * The dipole shower vertex associated 
+     * with this particle.
+     */
+    DSVertexPtr theDecayVertex;
+
+  private:
+
+    /**
+     * The assignment operator is private and must never be called.
+     * In fact, it should not even be implemented.
+     */
+    DipoleShowerParticle & operator=(const DipoleShowerParticle &);
+
+  };
+}
+
+#include "ThePEG/Utilities/ClassTraits.h"
+
+namespace ThePEG {
+
+  /** @cond TRAITSPECIALIZATIONS */
+
+  /** This template specialization informs ThePEG about the
+   *  base classes of DipoleShowerParticle. */
+  template <>
+  struct BaseClassTrait<Herwig::DipoleShowerParticle,1> {
+    /** Typedef of the first base class of DipoleShowerParticle. */
+    typedef Base NthBase;
+  };
+
+  /** This template specialization informs ThePEG about the name of
+   *  the DipoleShowerParticle class and the shared object where it is defined. */
+  template <>
+  struct ClassTraits<Herwig::DipoleShowerParticle>
+    : public ClassTraitsBase<Herwig::DipoleShowerParticle> {
+    /** Return a platform-independent class name */
+    static string className() { return "Herwig::DipoleShowerParticle"; }
+    /**
+     * The name of a file containing the dynamic library where the class
+     * DipoleShowerParticle is implemented. It may also include several, space-separated,
+     * libraries if the class DipoleShowerParticle depends on other classes (base classes
+     * excepted). In this case the listed libraries will be dynamically
+     * linked in the order they are specified.
+     */
+    static string library() { return "HwDipoleShower.so"; }
+  };
+
+  /** @endcond */
+
+}
+#endif /* HERWIG_DipoleShowerParticle_H */
diff --git a/Shower/Dipole/SpinCorrelations/DipoleShowerVertex.cc b/Shower/Dipole/SpinCorrelations/DipoleShowerVertex.cc
new file mode 100644
--- /dev/null
+++ b/Shower/Dipole/SpinCorrelations/DipoleShowerVertex.cc
@@ -0,0 +1,302 @@
+// -*- C++ -*-
+//
+// DipoleShowerVertex.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 2 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 DipoleShowerVertex class.
+//
+
+
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+#include "ThePEG/EventRecord/SpinInfo.h"
+
+#include "DipoleShowerVertex.h"
+
+using namespace Herwig;
+using namespace Herwig::Helicity;
+using namespace ThePEG;
+
+// Notes:
+// The mappings are defined and stored such
+// that they are relevant to the particle of
+// which this is the decay vertex.
+// For a timelike particle this is the incoming to the vertex.
+// For a spacelike particle, this is one of the outgoing.
+
+namespace {
+
+  void doMapping( RhoDMatrix& rho, const RhoDMatrix& mapping, bool isDecayMatrix ) {
+    RhoDMatrix rhop(rho.iSpin(),false);
+
+    // Note: The mapping of the rho (decay) matrix for FSR
+    // and the rho (decay) matrix for ISR follow the same
+    // pattern of mapping conjugates, despite them doing
+    // different things.
+    // We simply have to pass the correct state mapping,
+    // dec2prod or prod2dec, to this function in each case
+    
+    // Rho matrix mapping
+    if ( !isDecayMatrix ) {
+      for(int ixa=0;ixa<rho.iSpin();++ixa) {
+        for(int ixb=0;ixb<rho.iSpin();++ixb) {
+          for(int iya=0;iya<rho.iSpin();++iya) {
+            for(int iyb=0;iyb<rho.iSpin();++iyb) {
+              rhop(ixa,ixb) += rho(iya,iyb)*mapping(iya,ixa)*conj(mapping(iyb,ixb));
+            }
+          }
+        }
+      }
+    }
+
+    // Decay matrix mapping
+    else { 
+      for(int ixa=0;ixa<rho.iSpin();++ixa) {
+        for(int ixb=0;ixb<rho.iSpin();++ixb) {
+          for(int iya=0;iya<rho.iSpin();++iya) {
+            for(int iyb=0;iyb<rho.iSpin();++iyb) {
+              rhop(ixa,ixb) += rho(iya,iyb)*conj(mapping(iya,ixa))*mapping(iyb,ixb);
+            }
+          }
+        }
+      }
+    }
+
+    rhop.normalize();
+    rho = rhop;
+  }
+}
+
+DescribeNoPIOClass<DipoleShowerVertex,HelicityVertex>
+describeDipoleShowerVertex ("Herwig::DipoleShowerVertex","");
+
+void DipoleShowerVertex::Init() {
+
+  static ClassDocumentation<DipoleShowerVertex> documentation
+    ("The DipoleShowerVertex class is the implementation of a "
+     "vertex for a shower for the Herwig spin correlation algorithm");
+
+}
+
+DipoleShowerVertex::DipoleShowerVertex() :
+  theBoostCalculated(false) {}
+
+
+RhoDMatrix DipoleShowerVertex::getRhoMatrix(int i, bool) const {
+
+  // Check if we are returning the rho matrix of a spacelike parton
+  bool spaceLike = false;
+  if ( !outgoing()[i]->timelike() )
+    spaceLike = true;
+  
+  // Initialise the output and get the rho matrix of the incoming
+  RhoDMatrix densityMatrix(outgoing()[i]->iSpin(),false);
+  RhoDMatrix input=incoming()[0]->rhoMatrix();
+  
+  // If the incoming is timelike, we need to map
+  // its rho matrix to its decay frame
+  if ( incoming()[0]->timelike() ) {
+    RhoDMatrix mapping = theMappingDecay2Prod;
+    doMapping(input,mapping,false);
+  }
+ 
+  // Test that we are dealing with an emitter
+  assert( theMatrixElement->nOut()==2 );
+  assert( outgoing().size() == 2 );
+  
+  // Get the decay matrices for the outgoing particles
+  vector<RhoDMatrix> rhoout;
+  for(unsigned int ix=0,N=outgoing().size();ix<N;++ix) {
+    if(int(ix)!=i) {
+
+      // If the outgoing is timelike, no need to map.
+      if ( outgoing()[ix]->timelike() ) {
+        rhoout.push_back(outgoing()[ix]->DMatrix());
+      }
+	
+      // If the 'outgoing' is spacelike then its 
+      // decay matrix needs mapping to the frame of this vertex
+      else {
+        assert( !spaceLike );
+        assert( !incoming()[0]->timelike() );
+        RhoDMatrix mapping = theMappingDecay2Prod;
+        RhoDMatrix tempMatrix = outgoing()[ix]->DMatrix();
+        doMapping(tempMatrix, mapping, true);
+        rhoout.push_back(tempMatrix);
+      }
+    }
+  }
+  
+  // calculate the spin density matrix
+  densityMatrix = theMatrixElement->calculateRhoMatrix(i,input,rhoout);
+
+  // If the 'outgoing' particle we are calculating for is spacelike
+  // we must map the rho matrix to its production frame
+  if ( spaceLike ) {
+    RhoDMatrix mapping = theMappingProd2Decay;
+    doMapping(densityMatrix,mapping, false);
+  }
+  
+  return densityMatrix;
+
+}
+
+
+RhoDMatrix DipoleShowerVertex::getDMatrix(int) const {
+
+  // Flag indicating if we are returning the
+  // decay matrix of a spacelike parton
+  bool spaceLike = false;
+  
+  // Initialise the output
+  RhoDMatrix decayMatrix;
+ 
+  // Test that we are dealing with an emitter
+  assert( theMatrixElement->nOut()==2 );
+  assert( outgoing().size() == 2);
+  
+  // Get the decay matrices for the outgoing particles
+  vector<RhoDMatrix> Dout;
+    
+  for(unsigned int ix=0,N=outgoing().size();ix<N;++ix) {
+    
+    // If there is a spacelike outgoing its
+    // decay matrix needs mapping to this frame
+    if ( !outgoing()[ix]->timelike() ) {
+      assert(!incoming()[0]->timelike());
+      spaceLike = true;
+      
+      RhoDMatrix tempMatrix = outgoing()[ix]->DMatrix();
+      RhoDMatrix mapping = theMappingDecay2Prod;
+      doMapping(tempMatrix, mapping, true);
+      Dout.push_back(tempMatrix);
+    }
+    
+    // If the outgoing is timelike, no need to map.
+    else
+      Dout.push_back(outgoing()[ix]->DMatrix());
+  }
+
+  // calculate the decay matrix
+  decayMatrix = theMatrixElement->calculateDMatrix(Dout);
+
+  // For a timelike 'incoming' need to map the decay
+  // matrix from its decay frame to its production frame.
+  if ( !spaceLike ) {
+    RhoDMatrix mapping = theMappingProd2Decay;
+    doMapping(decayMatrix,mapping, true);
+  }
+  
+  return decayMatrix;
+
+}
+
+
+LorentzRotation DipoleShowerVertex::boostToSplitting() {
+  
+  if ( !theBoostCalculated ) {
+
+    LorentzRotation output;
+
+    bool spacelike = false;
+    // If dealing with IF or FI, use Breit frame
+    if ( theDipoleConfig.first != theDipoleConfig.second )
+      spacelike = true;
+
+
+    // Construct the Lorentz tranformation as in getKt
+    // see DipoleSplittingKinematics::getKt for more details
+    Lorentz5Momentum P;
+    if ( !spacelike )
+      P = thePVector + theNVector;
+    else
+      P = thePVector - theNVector;
+  
+    Energy mag = sqrt(abs(P.m2()));
+
+    Lorentz5Momentum Q = 
+      !spacelike ? 
+      Lorentz5Momentum(ZERO,ZERO,ZERO,mag,mag) :
+      Lorentz5Momentum(ZERO,ZERO,mag,ZERO,-mag);
+
+    // Required to make sure gamma (the boost parameter) is positive:
+    if ( spacelike && P.z() < ZERO )
+      Q.setZ(-Q.z());
+  
+    Energy2 Q2 = Q.m2();
+    bool boost =
+      abs((P-Q).vect().mag2()/GeV2) > 1e-10 ||
+      abs((P-Q).t()/GeV) > 1e-5;
+    
+    if ( boost ) {
+      
+      // Separately construct the components of the
+      // analytic expression in getKt
+      Lorentz5Momentum PQ = P+Q;
+      Energy PQt=PQ.t(), Qt=Q.t();
+      
+      InvEnergy2 den1 = 1./(P*Q + Q2);
+      InvEnergy2 den2 = 2./Q2;
+      
+      double tt = 1. - den1*PQt*PQt    + den2*Qt*P.t();                      
+      double tx =      den1*PQt*PQ.x() - den2*Qt*P.x();
+      double ty =      den1*PQt*PQ.y() - den2*Qt*P.y();  
+      double tz =      den1*PQt*PQ.z() - den2*Qt*P.z();
+      
+      // Construct the boost
+      output.boost(tx/tt, ty/tt, tz/tt, tt);
+            
+      // In the spacelike case, i.e. Breit frame, the transform
+      // also involves a rotation
+      if ( spacelike ) {
+        Axis axis((output*P).vect().unit());
+        if ( axis.perp2() > 1e-12 ) {
+          double sinth(sqrt(1.-sqr(axis.z())));
+          if ( Q.z() > ZERO )
+            output.rotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.));
+          else 
+            output.rotate(Constants::pi-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.));
+        }
+      }
+    }
+
+
+    // Now deal with the rotation (timelike) or boost (spacelike)
+    // to the z-axis
+    Lorentz5Momentum pTrans = output*thePVector;
+    
+    // Timelike : Rotate so the pVector lies along the (+ve) z-axis
+    if ( !spacelike ) {
+      Axis axis(pTrans.vect().unit());
+      if( axis.perp2() > 1e-12 ) {
+        double sinth(sqrt(1.-sqr(axis.z())));
+        output.rotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.));
+      }
+      else if( axis.z() < 0. ) {
+        output.rotate(Constants::pi,Axis(1.,0.,0.));
+      }
+    }
+    
+    // Spacelike : Boost in x and y so the pVector lies along the (+ve/-ve) z-axis
+    else {
+      Boost transX = -ThreeVector<double>(pTrans.x()/pTrans.e(),0.,0.);
+      output.boost(transX);
+      pTrans.boost(transX);
+      Boost transY = -ThreeVector<double>(0.,pTrans.y()/pTrans.e(),0.);
+      output.boost(transY);
+      pTrans.boost(transY);
+      
+      if ( pTrans.z() < ZERO )
+        output.rotate(Constants::pi,Axis(1.,0.,0.));
+    }
+    
+    theBoostToSplitting = output;
+    theBoostCalculated = true;
+  }  
+  return theBoostToSplitting; 
+}
diff --git a/Shower/Dipole/SpinCorrelations/DipoleShowerVertex.fh b/Shower/Dipole/SpinCorrelations/DipoleShowerVertex.fh
new file mode 100644
--- /dev/null
+++ b/Shower/Dipole/SpinCorrelations/DipoleShowerVertex.fh
@@ -0,0 +1,18 @@
+// -*- C++ -*-
+//
+// This is the forward declaration of the DipoleShowerVertex class.
+//
+#ifndef HERWIG_DipoleShowerVertex_FH
+#define HERWIG_DipoleShowerVertex_FH
+
+#include "ThePEG/Config/ThePEG.h"
+#include "ThePEG/Config/Pointers.h"
+
+namespace Herwig {  
+  using namespace ThePEG;
+  
+  class DipoleShowerVertex;
+  ThePEG_DECLARE_POINTERS(DipoleShowerVertex, DSVertexPtr);
+}
+
+#endif // HERWIG_DipoleShowerVertex_FH
diff --git a/Shower/Dipole/SpinCorrelations/DipoleShowerVertex.h b/Shower/Dipole/SpinCorrelations/DipoleShowerVertex.h
new file mode 100644
--- /dev/null
+++ b/Shower/Dipole/SpinCorrelations/DipoleShowerVertex.h
@@ -0,0 +1,285 @@
+// -*- C++ -*-
+//
+// DipoleShowerVertex.h is a part of Herwig - A multi-purpose Monte Carlo event generator
+// Copyright (C) 2002-2007 The Herwig Collaboration
+//
+// Herwig is licenced under version 2 of the GPL, see COPYING for details.
+// Please respect the MCnet academic guidelines, see GUIDELINES for details.
+//
+#ifndef HERWIG_DipoleShowerVertex_H
+#define HERWIG_DipoleShowerVertex_H
+//
+// This is the declaration of the DipoleShowerVertex class.
+//
+
+
+#include "ThePEG/EventRecord/HelicityVertex.h"
+#include "Herwig/Decay/DecayMatrixElement.h"
+
+#include "DipoleShowerVertex.fh"
+
+namespace Herwig {
+
+  using namespace ThePEG;
+
+  /** \ingroup DipoleShower
+   *
+   * This class represents the vertex for a given splitting
+   * in the dipole shower.
+   *
+   * \author Stephen Webster
+   *
+   */
+  class DipoleShowerVertex: public HelicityVertex {
+    
+  public:
+    
+    /**
+     * Default constructor
+     */
+    DipoleShowerVertex();
+
+    /** 
+     * Default destructor
+     **/
+    ~DipoleShowerVertex() {}
+
+  public:
+
+    /**
+     *  Return the matrix element for this vertex.
+     */
+    inline const DecayMEPtr ME() const {
+      return theMatrixElement;
+    }
+
+    /**
+     * Set the matrix element
+     */
+    inline void ME(DecayMEPtr in) {
+      theMatrixElement = in;
+    }
+    
+
+  public:
+  
+    /**
+     * Method to calculate the \f$\rho\f$ matrix for one of the decay products
+     * in the frame of this splitting vertex.
+     *
+     * @param iprod The splitting product to compute the \f$\rho\f$ matrix for.
+     */
+    RhoDMatrix getRhoMatrix(int iprod, bool ) const;
+
+    /**
+     * Method to calculate the \f$D\f$ matrix for the decaying 
+     * particle / the incoming to the vertex, in the frame of
+     * the vertex. The argument is a dummy argument.
+     */
+    RhoDMatrix getDMatrix(int) const;
+    
+    /**
+     * Get the lorentz rotation from the working frame
+     * to the frame of the splitting.
+     */
+    LorentzRotation boostToSplitting();
+    
+    /**
+     * Set the p vector for this splitting
+     */
+    void pVector( const Lorentz5Momentum& emitterMom ) { thePVector = emitterMom; }
+
+    /**
+     * Set the n vector for this splitting
+     */
+    void nVector( const Lorentz5Momentum& nMom ) { theNVector = nMom; }
+    
+    /**
+     * Set the emitter,Spectator Config (II,IF,FF,FI - F=true, I=false)
+     */
+    void dipoleConfig(const pair<bool,bool>& newConfig) { theDipoleConfig = newConfig; }
+  
+    /**
+     * Return the p vector for this splitting
+     */
+    Lorentz5Momentum pVector() const { return thePVector; }
+
+    /**
+     * Return the n/spectator vector for this splitting
+     */
+    Lorentz5Momentum nVector() const { return theNVector; }
+
+    /**
+     * Return the emitter,Spectator Config (II,IF,FF,FI - F=true, I=false)
+     */
+    const pair<bool,bool>& dipoleConfig() const { return theDipoleConfig; }
+
+
+    /**
+     * Set the decay state to production state
+     *  mapping for this vertex.
+     */
+    void mappingD2P( RhoDMatrix& mapping ) { theMappingDecay2Prod = mapping; }
+
+    /**
+     * Return the mapping from the decay 
+     * states to the production states.
+     */
+    RhoDMatrix mappingD2P() { return theMappingDecay2Prod; }
+    
+    /**
+     * Set the production state to decay state
+     *  mapping for this vertex.
+     */
+    void mappingP2D( RhoDMatrix& mapping ) { theMappingProd2Decay = mapping; }
+
+    /**
+     * Return the mapping from the production 
+     * states to the decay states.
+     */
+    RhoDMatrix mappingP2D() { return theMappingProd2Decay; }
+
+    
+    /**
+     * Set the new to old spectator mapping
+     * for this vertex.
+     */
+    void mappingSpecNewToOld( RhoDMatrix& mapping ) { theMappingSpectatorNewToOld = mapping; }
+
+    /**
+     * Return the new to old spectator mapping
+     * for this vertex.
+     */
+    RhoDMatrix mappingSpecNewToOld() { return theMappingSpectatorNewToOld; }
+    
+    /**
+     * Set the new to old spectator mapping
+     * for this vertex.
+     */
+    void mappingSpecOldToNew( RhoDMatrix& mapping ) { theMappingSpectatorOldToNew = mapping; }
+
+    /**
+     * Return the new to old spectator mapping
+     * for this vertex.
+     */
+    RhoDMatrix mappingSpecOldToNew() { return theMappingSpectatorOldToNew; }
+
+    
+    
+  public:
+
+    /**
+     * 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();
+
+  private:
+
+    /**
+     * Storage of the decay matrix element.
+     */
+    DecayMEPtr theMatrixElement;
+
+    /**
+     * The p vector of the 'splitting basis' 
+     * associated with this vertex.
+     **/
+    Lorentz5Momentum thePVector;
+
+    /**
+     * The n vector of the 'splitting basis'
+     * associated with this vertex.
+     **/
+    Lorentz5Momentum theNVector;
+
+    /**
+     * Initial/final config {emitter, spectator}
+     */
+    pair<bool,bool> theDipoleConfig;
+
+    /**
+     * An indicator flag to record if the
+     * boost to shower for this vertex has been done
+     */
+    bool theBoostCalculated;
+
+    /**
+     * The lorentz transformation from the 
+     * working frame to this splitting.
+     */
+    LorentzRotation theBoostToSplitting;
+
+    /**
+     * The mapping from the decay basis states
+     * to the production basis states.
+     */
+     RhoDMatrix theMappingDecay2Prod;
+    
+    /**
+     * The mapping from the production basis states
+     * to the decay basis states.
+     */
+     RhoDMatrix theMappingProd2Decay;
+
+    
+    /**
+     * The mapping from the new spectator basis
+     * states to the old spectator basis states.
+     */
+     RhoDMatrix theMappingSpectatorNewToOld;
+    
+    /**
+     * The mapping from the old spectator basis
+     * states to the new spectator basis states.
+     */
+     RhoDMatrix theMappingSpectatorOldToNew;
+   
+  private:
+
+    /**
+     * The assignment operator is private and must never be called.
+     * In fact, it should not even be implemented.
+     */
+    DipoleShowerVertex & operator=(const DipoleShowerVertex &);
+
+  };
+}
+
+#include "ThePEG/Utilities/ClassTraits.h"
+
+namespace ThePEG {
+
+  /** @cond TRAITSPECIALIZATIONS */
+
+  /** This template specialization informs ThePEG about the
+   *  base classes of DipoleShowerVertex. */
+  template <>
+  struct BaseClassTrait<Herwig::DipoleShowerVertex,1> {
+    /** Typedef of the first base class of DipoleShowerVertex. */
+    typedef HelicityVertex NthBase;
+  };
+
+  /** This template specialization informs ThePEG about the name of
+   *  the DipoleShowerVertex class and the shared object where it is defined. */
+  template <>
+  struct ClassTraits<Herwig::DipoleShowerVertex>
+    : public ClassTraitsBase<Herwig::DipoleShowerVertex> {
+    /** Return a platform-independent class name */
+    static string className() { return "Herwig::DipoleShowerVertex"; }
+    /**
+     * The name of a file containing the dynamic library where the class
+     * DipoleShowerVertex is implemented. It may also include several, space-separated,
+     * libraries if the class DipoleShowerVertex depends on other classes (base classes
+     * excepted). In this case the listed libraries will be dynamically
+     * linked in the order they are specified.
+     */
+    static string library() { return "HwDipoleShower.so"; }
+  };
+
+  /** @endcond */
+
+}
+#endif /* HERWIG_DipoleShowerVertex_H */
diff --git a/Shower/Dipole/SpinCorrelations/DipoleVertexRecord.cc b/Shower/Dipole/SpinCorrelations/DipoleVertexRecord.cc
new file mode 100644
--- /dev/null
+++ b/Shower/Dipole/SpinCorrelations/DipoleVertexRecord.cc
@@ -0,0 +1,414 @@
+// -*- C++ -*-
+//
+// DipoleVertexRecord.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 2 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 DipoleVertexRecord class.
+//
+
+#include "DipoleVertexRecord.h"
+
+#include "ThePEG/Interface/ClassDocumentation.h"
+#include "ThePEG/EventRecord/Particle.h"
+#include "ThePEG/Repository/UseRandom.h"
+
+#include "ThePEG/Repository/EventGenerator.h"
+#include "ThePEG/Utilities/DescribeClass.h"
+
+#include "ThePEG/Helicity/FermionSpinInfo.h"
+#include "ThePEG/Helicity/VectorSpinInfo.h"
+
+#include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
+#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
+
+#include "ThePEG/EventRecord/HelicityVertex.h"
+
+
+using namespace Herwig;
+
+void DipoleVertexRecord::clear() {
+  // Clear all member variables
+  theCurrentEmitter.clear();
+  //theEmitterInfoRecord.clear();
+  theDecayParentSpinInfo = SpinPtr();
+}
+
+
+void DipoleVertexRecord::generatePhi(DipoleSplittingInfo& dInfo, Dipole& dip) {
+
+  // Set up the emitter spin info and its decay vertex
+  prepareSplitting(dInfo, dip);
+
+  // Compute the rho matrix (outgoing emitter) or decay matrix
+  // (incoming emitter) required to generate phi
+  PPtr emitter = dip.emitter(dInfo.configuration());
+  RhoDMatrix rho = emitterDensityMatrix(emitter);
+  
+  // Compute the weights from the kernel
+  // Pair components A (int) and B (complex):
+  // weight = B*exp(i*A)
+  vector< pair<int, Complex> > wgts;
+  wgts = dInfo.splittingKernel()->generatePhi(dInfo,rho);
+
+  // Generate a value of phi
+  unsigned int nTry = 0;
+  double phi = 0.0;
+  double phiMax = 0.0;
+  double wgt = 0.0;
+  double wgtMax = 0.0;
+  static const Complex ii(0.,1.);
+  
+  do {
+    phi = Constants::twopi*UseRandom::rnd();
+    
+    Complex spinWgt = 0.;
+    for(unsigned int ix=0;ix<wgts.size();++ix) {
+      if(wgts[ix].first==0)
+        spinWgt += wgts[ix].second;
+      else
+        spinWgt += exp(double(wgts[ix].first)*ii*phi)*wgts[ix].second;
+    }  
+    wgt = spinWgt.real();
+    
+    // Store the phi with maximum weight in case there
+    // are too many failed attempts to generate phi.
+    if ( wgt>wgtMax ) {
+      phiMax = phi;
+      wgtMax = wgt;
+    }
+    nTry++;
+  }
+  
+  // Accept / reject phi
+  while (wgt<UseRandom::rnd() && nTry < 10000);
+  if(nTry == 10000) {
+    phi = phiMax;
+  }
+
+  // Set the azimuthal angle in the splitting info
+  dInfo.lastPhi( phi );
+
+  // Set the matrix element of the emitter vertex
+  theCurrentEmitter.decayVertex()->ME(dInfo.splittingKernel()->matrixElement(dInfo));  
+}
+
+
+void DipoleVertexRecord::prepareSplitting(const DipoleSplittingInfo& dInfo, const Dipole& dip ) {
+
+  // Extract the required information from the splitting info and dipole
+  PPtr emitter = dip.emitter(dInfo.configuration());
+  PPtr spectator = dip.spectator(dInfo.configuration());
+
+  // Get the pVector and nVector that define the decay frame
+  Lorentz5Momentum pVector = dInfo.splittingKinematics()->
+    pVector(emitter->momentum(), spectator->momentum(), dInfo);
+  Lorentz5Momentum nVector = dInfo.splittingKinematics()->
+    nVector(emitter->momentum(), spectator->momentum(), dInfo);
+  
+  // Get the emitter and spectator directions
+  Helicity::Direction emmDir = dInfo.index().initialStateEmitter() ? incoming : outgoing;
+  Helicity::Direction specDir = dInfo.index().initialStateSpectator() ? incoming : outgoing;
+
+  // Create spinInfo if required (e.g. secondary processes)
+  if ( !emitter->spinInfo() )
+    createSpinInfo(emitter, emmDir);
+  if ( !spectator->spinInfo() )
+    createSpinInfo(spectator, specDir);
+  
+  // Setup the emitter for spin correlation calculations
+  theCurrentEmitter.prepare(emitter, emmDir, specDir, pVector, nVector);
+}
+
+
+RhoDMatrix DipoleVertexRecord::emitterDensityMatrix(PPtr emitter) {
+
+  // Update the rho/decay matrices upto the emitter
+  emitter->spinInfo()->decay(true);
+  
+  RhoDMatrix rho = emitter->spinInfo()->timelike() ?
+    emitter->spinInfo()->rhoMatrix() : emitter->spinInfo()->DMatrix();
+
+  // Map the rho/decay matrix to the decay frame
+  RhoDMatrix mapping = theCurrentEmitter.decayVertex()->mappingD2P();
+  RhoDMatrix rhop(rho.iSpin(),false);
+  if ( emitter->spinInfo()->timelike() ) {
+    for(int ixa=0;ixa<rho.iSpin();++ixa) {
+      for(int ixb=0;ixb<rho.iSpin();++ixb) {
+        for(int iya=0;iya<rho.iSpin();++iya) {
+          for(int iyb=0;iyb<rho.iSpin();++iyb) {
+            rhop(ixa,ixb) += rho(iya,iyb)*mapping(iya,ixa)*conj(mapping(iyb,ixb));
+          }
+        }
+      }
+    }
+  }
+  else {
+    for(int ixa=0;ixa<rho.iSpin();++ixa) {
+      for(int ixb=0;ixb<rho.iSpin();++ixb) {
+        for(int iya=0;iya<rho.iSpin();++iya) {
+          for(int iyb=0;iyb<rho.iSpin();++iyb) {
+            rhop(ixa,ixb) += rho(iya,iyb)*conj(mapping(iya,ixa))*mapping(iyb,ixb);
+          }
+        }
+      }
+    }
+  }
+
+  rhop.normalize();
+  return rhop;
+}
+
+
+void DipoleVertexRecord::update(const DipoleSplittingInfo& dInfo) {
+
+  // Get splitting particles.
+  PPtr oldEmitter = dInfo.emitter();
+  PPtr oldSpectator = dInfo.spectator();
+  PPtr newEmitter = dInfo.splitEmitter();
+  PPtr newSpectator = dInfo.splitSpectator();
+  PPtr emission = dInfo.emission();
+  
+  assert(oldEmitter->spinInfo() && oldSpectator->spinInfo());
+  assert(!newEmitter->spinInfo() && !newSpectator->spinInfo() && !emission->spinInfo() );
+
+  // Create new emitter splitting info
+  Helicity::Direction emmDir = dInfo.index().initialStateEmitter() ? incoming : outgoing;
+  if ( abs(newEmitter->id()) <= 6 )
+    theCurrentEmitter.createNewFermionSpinInfo(newEmitter, emmDir);
+  else {
+    assert( newEmitter->id() == 21 );
+    theCurrentEmitter.createNewVectorSpinInfo(newEmitter, emmDir);
+  }
+
+  // Create new emission splitting info
+  if ( abs(emission->id()) <= 6 )
+    theCurrentEmitter.createNewFermionSpinInfo(emission, outgoing);
+  else {
+    assert( emission->id() == 21 );
+    theCurrentEmitter.createNewVectorSpinInfo(emission, outgoing);
+  }
+
+  // Initialise the emitter and emission decay matrices to delta matrices
+  initDecayMatrix(newEmitter,emmDir);
+  initDecayMatrix(emission, outgoing);
+
+  // Set the outgoing of the decay vertex
+  newEmitter->spinInfo()->productionVertex(theCurrentEmitter.decayVertex());
+  emission->spinInfo()->productionVertex(theCurrentEmitter.decayVertex());
+
+  // Develop the emitter
+  oldEmitter->spinInfo()->needsUpdate();
+  oldEmitter->spinInfo()->develop();
+  
+  
+  // Deal with spectators:
+  if ( !dInfo.index().incomingDecaySpectator() )
+    updateSpinInfo(oldSpectator, newSpectator);
+
+  // If the spectator is a decayed particle, don't want to do any transformations
+  else
+    newSpectator->spinInfo(oldSpectator->spinInfo());
+
+  
+  // Tidy up
+  theCurrentEmitter.clear();
+}
+
+
+void DipoleVertexRecord::createSpinInfo(PPtr& part,
+                                        const Helicity::Direction& dir) {
+
+  // Identify the type of particle and use the appropriate function
+  // to create the spinInfo
+  if ( part->dataPtr()->iSpin() == PDT::Spin0 )
+    assert(false);
+  
+  else if ( part->dataPtr()->iSpin() == PDT::Spin1Half )
+    createFermionSpinInfo(part, dir);
+
+  else if ( part->dataPtr()->iSpin() == PDT::Spin1 )
+    createVectorSpinInfo(part, dir);
+  
+  else
+    assert(false);
+}
+
+
+void DipoleVertexRecord::createFermionSpinInfo(PPtr& part,
+                                               const Helicity::Direction& dir) {
+
+  // Create the spin info
+  const Lorentz5Momentum& partMom = part->momentum();
+  FermionSpinPtr fspin = new_ptr(FermionSpinInfo(partMom, dir==outgoing));
+  part->spinInfo(fspin);
+  
+  // Calculate the basis for the particle in the lab frame
+  SpinorWaveFunction wave;
+  if(part->id()>0)
+    wave=SpinorWaveFunction(partMom, part->dataPtr(), incoming);
+  else
+    wave=SpinorWaveFunction(partMom, part->dataPtr(), outgoing);
+ 
+  // Store the basis states in the spin info
+  for(unsigned int ix=0;ix<2;++ix) {
+    wave.reset(ix);
+    LorentzSpinor<SqrtEnergy> basis = wave.dimensionedWave();
+    fspin->setBasisState(ix,basis);
+  }
+}
+
+
+void DipoleVertexRecord::createVectorSpinInfo(PPtr& part,
+                                              const Helicity::Direction& dir) {
+  
+  // Create the spin info
+  const Lorentz5Momentum& partMom = part->momentum();
+  VectorSpinPtr vspin = new_ptr(VectorSpinInfo(partMom, dir==outgoing));
+  part->spinInfo(vspin);
+      
+  // Calculate the basis for the particle in the lab frame
+  VectorWaveFunction wave(partMom, part->dataPtr(),
+                          vspin->timelike() ? outgoing : incoming );
+  bool massless(part->id()==ParticleID::g||part->id()==ParticleID::gamma);
+  for(unsigned int ix=0;ix<3;++ix) {
+    LorentzPolarizationVector basis;
+    if(massless&&ix==1) {
+      basis = LorentzPolarizationVector();
+    }
+    else {
+      wave.reset(ix,vector_phase);
+      basis = wave.wave();
+    }
+    
+    // Store the basis states in the spin info
+    vspin->setBasisState(ix,basis);
+  }
+}
+
+
+void DipoleVertexRecord::updateSpinInfo( PPtr& oldPart,
+                                         PPtr& newPart ) {
+
+  // Copied from DipoleVertexRecord::updateSpinInfo,
+  // would be better to use a common function
+  const Lorentz5Momentum& oldMom = oldPart->momentum();
+  const Lorentz5Momentum& newMom = newPart->momentum();
+
+  // Rotation from old momentum to +ve z-axis
+  LorentzRotation oldToZAxis;
+  Axis axisOld(oldMom.vect().unit());
+  if( axisOld.perp2() > 1e-12 ) {
+    double sinth(sqrt(1.-sqr(axisOld.z())));
+    oldToZAxis.rotate( -acos(axisOld.z()),Axis(-axisOld.y()/sinth,axisOld.x()/sinth,0.));
+  }
+
+  // Rotation from new momentum to +ve z-axis
+  LorentzRotation newToZAxis;
+  Axis axisNew(newMom.vect().unit());
+  if( axisNew.perp2() > 1e-12 ) {
+    double sinth(sqrt(1.-sqr(axisNew.z())));
+    newToZAxis.rotate( -acos(axisNew.z()),Axis(-axisNew.y()/sinth,axisNew.x()/sinth,0.));
+  }
+
+  // Boost from old momentum to new momentum along z-axis
+  Lorentz5Momentum momOldRotated = oldToZAxis*Lorentz5Momentum(oldMom);
+  Lorentz5Momentum momNewRotated = newToZAxis*Lorentz5Momentum(newMom);
+  
+  Energy2 a = sqr(momOldRotated.z()) + sqr(momNewRotated.t());
+  Energy2 b = 2.*momOldRotated.t()*momOldRotated.z();
+  Energy2 c = sqr(momOldRotated.t()) - sqr(momNewRotated.t());
+  double beta;
+  
+  // The rotated momentum should always lie along the +ve z-axis
+  if ( momOldRotated.z() > ZERO )
+    beta = (-b + sqrt(sqr(b)-4.*a*c)) / 2. / a;
+  else
+    beta = (-b - sqrt(sqr(b)-4.*a*c)) / 2. / a;
+  
+  LorentzRotation boostOldToNew(0., 0., beta);
+
+  // Total transform
+  LorentzRotation transform = (newToZAxis.inverse())*boostOldToNew*oldToZAxis;
+  
+  // Assign the same spin info to the old and new particles
+  newPart->spinInfo(oldPart->spinInfo());
+  newPart->spinInfo()->transform(oldMom, transform);
+}
+
+
+void DipoleVertexRecord::prepareParticleDecay( const PPtr& decayIncoming ) {
+
+  // Need to set stopUpdate flag in the latest parent with spinInfo
+  PPtr parent = decayIncoming;
+  while ( !parent->spinInfo() )
+    parent = parent->parents()[0];
+  parent->spinInfo()->stopUpdate();
+  theDecayParentSpinInfo = parent->spinInfo();
+}
+
+
+void DipoleVertexRecord::updateParticleDecay() {
+  theDecayParentSpinInfo->needsUpdate();
+  theDecayParentSpinInfo->develop();
+  // Clear theDecayParentSpinInfo
+  theDecayParentSpinInfo = SpinPtr();
+}
+
+
+// Note: The develop function in SpinInfo.cc does not handle this properly
+void DipoleVertexRecord::initDecayMatrix( PPtr& particle, Helicity::Direction dir ) {
+
+  // If not a vector boson, no extra considerations
+  if ( particle->dataPtr()->iSpin() != PDT::Spin1 )
+    particle->spinInfo()->develop();
+
+  // If particle is a vector boson
+  else {
+    // Massless is a special case:
+    if ( particle->id() == ParticleID::g || particle->id() == ParticleID::gamma ) {
+      if ( dir == outgoing ) {
+        particle->spinInfo()->DMatrix()(0,0) = 0.5;
+        particle->spinInfo()->DMatrix()(2,2) = 0.5;
+      }
+      else {
+        particle->spinInfo()->rhoMatrix()(0,0) = 0.5;
+        particle->spinInfo()->rhoMatrix()(2,2) = 0.5;
+
+      } 
+    }
+
+    // Massive case is the default
+    else
+      particle->spinInfo()->develop();
+  }
+
+}
+
+
+// *** Attention *** The following static variable is needed for the type
+// description in ThePEG. Please check that the template arguments
+// are correct (the class and its base class), and that the constructor
+// arguments are correct (the class name and the name of the dynamically
+// loadable library where the class implementation can be found).
+
+DescribeNoPIOClass<DipoleVertexRecord,Base>
+describeHerwigDipoleVertexRecord("Herwig::DipoleVertexRecord", "DipoleVertexRecord.so");
+
+void DipoleVertexRecord::Init() {
+
+
+  // *** Attention *** The following static variable is needed for the type
+  // description in ThePEG. Please check that the template arguments
+  // are correct (the class and its base class), and that the constructor
+  // arguments are correct (the class name and the name of the dynamically
+  // loadable library where the class implementation can be found).
+  
+  static ClassDocumentation<DipoleVertexRecord> documentation
+    ("There is no documentation for the DipoleVertexRecord class");
+
+}
diff --git a/Shower/Dipole/SpinCorrelations/DipoleVertexRecord.h b/Shower/Dipole/SpinCorrelations/DipoleVertexRecord.h
new file mode 100644
--- /dev/null
+++ b/Shower/Dipole/SpinCorrelations/DipoleVertexRecord.h
@@ -0,0 +1,207 @@
+// -*- C++ -*-
+#ifndef Herwig_DipoleVertexRecord_H
+#define Herwig_DipoleVertexRecord_H
+//
+// This is the declaration of the DipoleVertexRecord class.
+//
+
+#include "ThePEG/Config/ThePEG.h"
+#include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
+#include "Herwig/Shower/Dipole/Base/Dipole.h"
+#include "ThePEG/EventRecord/RhoDMatrix.h"
+#include "DipoleShowerParticle.h"
+
+namespace Herwig {
+
+  using namespace ThePEG;
+
+  /**
+   * Here is the documentation of the DipoleVertexRecord class.
+   */
+  class DipoleVertexRecord: public Base {
+
+  public:
+
+    /** @name Standard constructors and destructors. */
+    //@{
+    /**
+     * The default constructor.
+     */
+    DipoleVertexRecord() {}
+
+    /**
+     * The destructor.
+     */
+    virtual ~DipoleVertexRecord() { clear(); }
+    //@}
+
+  public:
+
+    /**
+     * Prepare the emitter and spectator
+     * for the spin correlations computations.
+     **/
+    void prepareSplitting( const DipoleSplittingInfo& dInfo, const Dipole& dip);
+
+    /**
+     * Correctly initialise the decay matrix 
+     * to a delta matrix for an external particle.
+     */
+    void initDecayMatrix(PPtr& particle, Helicity::Direction dir);
+
+    /**
+     * Compute the spin density matrix for the given emitter.
+     * This tracks the path between the given emitter and 
+     * the previous emitter, calculating a rho/decay matrix
+     * at each vertex as appropriate.
+     */
+    RhoDMatrix emitterDensityMatrix(PPtr emitter);
+
+    /**
+     * Generate the spin-correlated azimuthal angle for a splitting.
+     */
+    void generatePhi(DipoleSplittingInfo& dInfo, Dipole& dip);
+
+
+    /**
+     * Identify the type of particle and use the appropriate function
+     * to set up the spin info.
+     * Required for e.g. MPI
+     */
+    void createSpinInfo(PPtr& part,
+                        const Helicity::Direction& dir);
+    
+    /**
+     * Create and set up fermion spin info.
+     * Required for e.g. MPI
+     */
+    void createFermionSpinInfo(PPtr& part,
+                               const Helicity::Direction& dir);
+      
+    /**
+     * Create and set up vector spin info. 
+     * Required for e.g. MPI
+     */
+    void createVectorSpinInfo(PPtr& part,
+                              const Helicity::Direction& dir);
+    
+    /**
+     * Update the vertex record following a splitting.
+     */
+    void update(const DipoleSplittingInfo& dInfo);
+
+    /**
+     * For spectators. Set new particle spin info the that of the 
+     * old particle. Update the spin info to include any momentum changes.
+     */
+    void updateSpinInfo( PPtr& oldPart,
+                         PPtr& newPart );
+    
+    /**
+     * Set the stopUpdate flag in the spin info of a particle
+     * incoming to the current decay.
+     */
+    void prepareParticleDecay( const PPtr& parent );
+
+    /**
+     * Update the spin info of the incoming to the decay
+     * following showering of the decay.
+     */
+    void updateParticleDecay();
+
+    /**
+     * SW 06/02/2019: Required for NearestNeighbourDipoleAnalysis tests.
+     * Access the emitter info record.
+     */
+    //map<PPtr,DipoleSplittingInfo> emitterInfoRecord() const {
+    //return theEmitterInfoRecord;
+    //}    
+    
+    /**
+     * SW 06/02/2019: Required for NearestNeighbourDipoleAnalysis tests.
+     * Add a splitting to the emitter info record.
+     */
+    // void addToRecord(const DipoleSplittingInfo& dInfo) {
+    //   assert(dInfo.emitter());
+    //   theEmitterInfoRecord[dInfo.emitter()] = dInfo;
+    // }
+    
+    /**
+     * Clear the vertex record: Give up ownership
+     * on any object involved in the evolution.
+     */
+    virtual void clear();
+     
+    /**
+     * 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();
+    
+  private:
+
+    /**
+     * The current emitter.
+     */
+    DipoleShowerParticle theCurrentEmitter;
+
+    /**
+     * SW 06/02/2019: Required for NearestNeighbourDipoleAnalysis tests.
+     * Record of the splittings as 
+     * required for the testing analysis.
+     */
+    //map<PPtr, DipoleSplittingInfo> theEmitterInfoRecord;
+
+    /**
+     * The spin info of a particle incoming to the decay
+     * under consideration.
+     */
+    tcSpinPtr theDecayParentSpinInfo;
+    
+    /**
+     * The assignment operator is private and must never be called.
+     * In fact, it should not even be implemented.
+     */
+    DipoleVertexRecord & operator=(const DipoleVertexRecord &);
+
+  };
+
+}
+
+#include "ThePEG/Utilities/ClassTraits.h"
+
+namespace ThePEG {
+
+  /** @cond TRAITSPECIALIZATIONS */
+
+  /** This template specialization informs ThePEG about the
+   *  base classes of DipoleVertexRecord. */
+  template <>
+  struct BaseClassTrait<Herwig::DipoleVertexRecord,1> {
+    /** Typedef of the first base class of DipoleVertexRecord. */
+    typedef Base NthBase;
+  };
+
+  /** This template specialization informs ThePEG about the name of
+   *  the DipoleVertexRecord class and the shared object where it is defined. */
+  template <>
+  struct ClassTraits<Herwig::DipoleVertexRecord>
+    : public ClassTraitsBase<Herwig::DipoleVertexRecord> {
+    /** Return a platform-independent class name */
+    static string className() { return "Herwig::DipoleVertexRecord"; }
+    /**
+     * The name of a file containing the dynamic library where the class
+     * DipoleVertexRecord is implemented. It may also include several, space-separated,
+     * libraries if the class DipoleVertexRecord depends on other classes (base classes
+     * excepted). In this case the listed libraries will be dynamically
+     * linked in the order they are specified.
+     */
+    static string library() { return "HwDipoleShower.so"; }
+  };
+
+  /** @endcond */
+
+}
+#endif /* Herwig_DipoleVertexRecord_H */
diff --git a/Shower/Dipole/SpinCorrelations/Makefile.am b/Shower/Dipole/SpinCorrelations/Makefile.am
new file mode 100644
--- /dev/null
+++ b/Shower/Dipole/SpinCorrelations/Makefile.am
@@ -0,0 +1,6 @@
+noinst_LTLIBRARIES = libHwDipoleShowerSpinCorrelations.la
+
+libHwDipoleShowerSpinCorrelations_la_SOURCES = \
+	DipoleShowerVertex.fh DipoleShowerVertex.h DipoleShowerVertex.cc \
+	DipoleShowerParticle.h DipoleShowerParticle.cc \
+	DipoleVertexRecord.h DipoleVertexRecord.cc
diff --git a/Shower/Dipole/Utility/ConstituentReshuffler.cc b/Shower/Dipole/Utility/ConstituentReshuffler.cc
--- a/Shower/Dipole/Utility/ConstituentReshuffler.cc
+++ b/Shower/Dipole/Utility/ConstituentReshuffler.cc
@@ -1,602 +1,659 @@
 // -*- C++ -*-
 //
 // ConstituentReshuffler.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.
 //
 //
 // This is the implementation of the non-inlined, non-templated member
 // functions of the ConstituentReshuffler class.
 //
 
 #include <config.h>
 #include "ConstituentReshuffler.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 
 #include <limits>
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 #include "DipolePartonSplitter.h"
 
 #include "Herwig/Utilities/GSLBisection.h"
 
 #include "Herwig/Shower/Dipole/DipoleShowerHandler.h"
 
 #include "Herwig/Shower/ShowerHandler.h"
 
 using namespace Herwig;
 
 ConstituentReshuffler::ConstituentReshuffler() 
   : HandlerBase() {}
 
 ConstituentReshuffler::~ConstituentReshuffler() {}
 
 IBPtr ConstituentReshuffler::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr ConstituentReshuffler::fullclone() const {
   return new_ptr(*this);
 }
 
 double ConstituentReshuffler::ReshuffleEquation::aUnit() {
   return 1.;
 }
 
 double ConstituentReshuffler::ReshuffleEquation::vUnit() {
   return 1.;
 }
 
 double ConstituentReshuffler::DecayReshuffleEquation::aUnit() {
   return 1.;
 }
 
 double ConstituentReshuffler::DecayReshuffleEquation::vUnit() {
   return 1.;
 }
 
 
 double ConstituentReshuffler::ReshuffleEquation::operator() (double xi) const {
 
   double r = - w/GeV;
 
   for (PList::iterator p = p_begin; p != p_end; ++p) {
     r += sqrt(sqr((**p).dataPtr()->constituentMass()) +
 	      xi*xi*(sqr((**p).momentum().t())-sqr((**p).dataPtr()->mass()))) / GeV;
   }
   return r;  
 
 }
 
 double ConstituentReshuffler::DecayReshuffleEquation::operator() (double xi) const {
   double r = - w/GeV;
 
   for (PList::iterator pIt = p_begin; pIt != p_end; ++pIt) {
     r += sqrt(sqr((**pIt).dataPtr()->constituentMass()) +
  	      xi*xi*(sqr((**pIt).momentum().t())-sqr((**pIt).dataPtr()->mass()))) / GeV;
   }
 
   for (PList::iterator rIt = r_begin; rIt != r_end; ++rIt) {
     r +=  sqrt(sqr((**rIt).momentum().m()) +
 	       xi*xi*(sqr((**rIt).momentum().t())-sqr((**rIt).momentum().m()))) / GeV;
   }
 
   return r;  
 
 }
 
 void ConstituentReshuffler::reshuffle(PList& out,
 				      PPair& in,
 				      PList& intermediates,
 				      const bool decay,
 				      PList& decayPartons,
 				      PList& decayRecoilers) {
 
   assert(ShowerHandler::currentHandler()->retConstituentMasses());
 
   if ( !decay ) {
   
     if (out.size() == 0)
       return;
 
     if (out.size() == 1) {
 
       PPtr recoiler;
       PPtr parton = out.front();
 
       if (DipolePartonSplitter::colourConnected(parton,in.first) &&
 	  DipolePartonSplitter::colourConnected(parton,in.second)) {
 	if (UseRandom::rnd() < .5)
 	  recoiler = in.first;
 	else
 	  recoiler = in.second;
       } else if (DipolePartonSplitter::colourConnected(parton,in.first)) {
 	recoiler = in.first;
       } else if (DipolePartonSplitter::colourConnected(parton,in.second)) {
 	recoiler = in.second;
       } else assert(false);
 
       assert(abs(recoiler->momentum().vect().perp2()/GeV2) < 1e-6);
 
       double sign = recoiler->momentum().z() < 0.*GeV ? -1. : 1.;
 
       Energy2 qperp2 = parton->momentum().perp2();
 
       if (qperp2/GeV2 < Constants::epsilon) {
 	// no emission off a 2 -> singlet process which
 	// needed a single forced splitting: should never happen (?)
 	assert(false);
 	throw Veto();
       }
 
       Energy2 m2 = sqr(parton->dataPtr()->constituentMass());
       
       Energy abs_q = parton->momentum().vect().mag();
       Energy qz = parton->momentum().z();
       Energy abs_pz = recoiler->momentum().t();
       assert(abs_pz > 0.*GeV);
 
       Energy xi_pz = sign*(2.*qperp2*abs_pz + m2*(abs_q + sign*qz))/(2.*qperp2);
       Energy x_qz = (2.*qperp2*qz + m2*(qz+sign*abs_q))/(2.*qperp2);
 
       Lorentz5Momentum recoiler_momentum 
 	(0.*GeV,0.*GeV,xi_pz,xi_pz < 0.*GeV ? - xi_pz : xi_pz);
 
       recoiler_momentum.rescaleMass();
 
       Lorentz5Momentum parton_momentum 
 	(parton->momentum().x(),parton->momentum().y(),x_qz,sqrt(m2+qperp2+x_qz*x_qz));
 
       parton_momentum.rescaleMass();
 
       PPtr n_parton = new_ptr(Particle(parton->dataPtr()));
       n_parton->set5Momentum(parton_momentum);
 
       DipolePartonSplitter::change(parton,n_parton,false);
 
       out.pop_front();
       intermediates.push_back(parton);
       out.push_back(n_parton);
 
       PPtr n_recoiler = new_ptr(Particle(recoiler->dataPtr()));
       n_recoiler->set5Momentum(recoiler_momentum);
 
       DipolePartonSplitter::change(recoiler,n_recoiler,true);
 
       intermediates.push_back(recoiler);
 
       if (recoiler == in.first) {
 	in.first = n_recoiler;
       }
 
       if (recoiler == in.second) {
 	in.second = n_recoiler;
       }
 
       return;
 
     }
 
   }
 
   Energy zero (0.*GeV);
   Lorentz5Momentum Q (zero,zero,zero,zero);
     
   for (PList::iterator p = out.begin();
        p != out.end(); ++p) {
     Q += (**p).momentum();
   }
 
   Boost beta = Q.findBoostToCM();
 
   list<Lorentz5Momentum> mbackup;
 
   bool need_boost = (beta.mag2() > Constants::epsilon);
 
   if (need_boost) {
 
     for (PList::iterator p = out.begin();
 	 p != out.end(); ++p) {
       Lorentz5Momentum mom = (**p).momentum();
       mbackup.push_back(mom);
       (**p).set5Momentum(mom.boost(beta));
     }
 
   }
 
   double xi;
 
   // Only partons
   if ( decayRecoilers.size()==0 ) {
     ReshuffleEquation solve (Q.m(),out.begin(),out.end());
 
     GSLBisection solver(1e-10,1e-8,10000);
 
     try {
       xi = solver.value(solve,0.0,1.1);
     } catch (GSLBisection::GSLerror) {
       throw DipoleShowerHandler::RedoShower();
     } catch (GSLBisection::IntervalError) {
       throw DipoleShowerHandler::RedoShower();
     }
   }
 
   // Partons and decaying recoilers
   else {
     DecayReshuffleEquation solve (Q.m(),decayPartons.begin(),decayPartons.end(),decayRecoilers.begin(),decayRecoilers.end());
 
     GSLBisection solver(1e-10,1e-8,10000);
 
     try {
       xi = solver.value(solve,0.0,1.1);
     } catch (GSLBisection::GSLerror) {
       throw DipoleShowerHandler::RedoShower();
     } catch (GSLBisection::IntervalError) {
       throw DipoleShowerHandler::RedoShower();
     }
   }
 
 
   PList reshuffled;
 
   list<Lorentz5Momentum>::const_iterator backup_it;
   if (need_boost)
     backup_it = mbackup.begin();
     
 
   // Reshuffling of non-decaying partons only
   if ( decayRecoilers.size()==0 ) {
 
     for (PList::iterator p = out.begin();
 	 p != out.end(); ++p) {
 
       PPtr rp = new_ptr(Particle((**p).dataPtr()));
 
       DipolePartonSplitter::change(*p,rp,false);
 
       Lorentz5Momentum rm;
 
       rm = Lorentz5Momentum (xi*(**p).momentum().x(),
 			     xi*(**p).momentum().y(),
 			     xi*(**p).momentum().z(),
 			     sqrt(sqr((**p).dataPtr()->constituentMass()) +
 				  xi*xi*(sqr((**p).momentum().t())-sqr((**p).dataPtr()->mass()))));
      
       rm.rescaleMass();
 
       if (need_boost) {
 	(**p).set5Momentum(*backup_it);
 	++backup_it;
 	rm.boost(-beta);
       }
 
       rp->set5Momentum(rm);
 
       intermediates.push_back(*p);
       reshuffled.push_back(rp);
       
 
     }
   }
 
   // For the case of a decay process with non-partonic recoilers
   else {
     assert ( decay );
 
     for (PList::iterator p = out.begin();
 	 p != out.end(); ++p) {
 
+      // Flag to update spinInfo
+      bool updateSpin = false;
+
       PPtr rp = new_ptr(Particle((**p).dataPtr()));
 
       DipolePartonSplitter::change(*p,rp,false);
 
       Lorentz5Momentum rm;
 
       // If the particle is a parton and not a recoiler
       if ( find( decayRecoilers.begin(), decayRecoilers.end(), *p ) == decayRecoilers.end() ) {
 	rm = Lorentz5Momentum (xi*(**p).momentum().x(),
 			       xi*(**p).momentum().y(),
 			       xi*(**p).momentum().z(),
 			       sqrt(sqr((**p).dataPtr()->constituentMass()) +
 				    xi*xi*(sqr((**p).momentum().t())-sqr((**p).dataPtr()->mass()))));
       }
 
 
       // Otherwise the parton is a recoiler 
       // and its invariant mass must be preserved
       else {
+        if ( (*p)-> spinInfo() )
+          updateSpin = true;
 	rm = Lorentz5Momentum (xi*(**p).momentum().x(),
 			       xi*(**p).momentum().y(),
 			       xi*(**p).momentum().z(),
 			       sqrt(sqr((**p).momentum().m()) +
 				    xi*xi*(sqr((**p).momentum().t())-sqr((**p).momentum().m()))));
       }
  
       rm.rescaleMass();
 
       if (need_boost) {
 	(**p).set5Momentum(*backup_it);
 	++backup_it;
 	rm.boost(-beta);
       }
 
       rp->set5Momentum(rm);
 
+      // Update SpinInfo if required
+      if ( updateSpin )
+        updateSpinInfo(*p, rp);
+      
       intermediates.push_back(*p);
       reshuffled.push_back(rp);
       
 
     }
   }
  
   out.clear();
   out.splice(out.end(),reshuffled);
 
 }
 
 
 void ConstituentReshuffler::hardProcDecayReshuffle(PList& decaying,
 						   PList& eventOutgoing,
 						   PList& eventHard,
 						   PPair& eventIncoming,
 						   PList& eventIntermediates) {
   
   // Note, when this function is called, the particle pointers
   // in theDecays/decaying are those prior to the showering.
   // Here we find the newest pointers in the outgoing.
   // The update of the PPtrs in theDecays is done in DipoleShowerHandler::constituentReshuffle()
   // as this needs to be done if ConstituentReshuffling is switched off.
 
   
   //Make sure the shower should return constituent masses:
   assert(ShowerHandler::currentHandler()->retConstituentMasses());
 
   // Find the outgoing decaying particles
   PList recoilers;
   for ( PList::iterator decIt = decaying.begin(); decIt != decaying.end(); ++decIt) {
     
     // First find the particles in the intermediates
     PList::iterator pos = find(eventIntermediates.begin(),eventIntermediates.end(), *decIt);
 
     // Colourless particle or coloured particle that did not radiate.
     if(pos==eventIntermediates.end()) {
       
       // Check that this is not a particle from a subsequent decay.
       // e.g. the W from a top decay from an LHE file.
       if ( find( eventHard.begin(), eventHard.end(), *decIt ) == eventHard.end() &&
 	   find( eventOutgoing.begin(), eventOutgoing.end(), *decIt ) == eventOutgoing.end() )
       continue;
     
       else
 	recoilers.push_back( *decIt );
 
     }
     
     // Coloured decaying particle that radiated
     else {
       PPtr unstable = *pos;
       while(!unstable->children().empty()) {
 	unstable = unstable->children()[0];
       }
       assert( find( eventOutgoing.begin(),eventOutgoing.end(), unstable ) != eventOutgoing.end() );
 
       recoilers.push_back( unstable );
     }
   }
 
   // Make a list of partons
   PList partons;
   for ( PList::iterator outPos = eventOutgoing.begin(); outPos != eventOutgoing.end(); ++outPos ) {
     if ( find (recoilers.begin(), recoilers.end(), *outPos ) == recoilers.end() ) {
       partons.push_back( *outPos );
     }
   }
 
 
   // If no outgoing partons, do nothing
   if ( partons.size() == 0 ){
     return;
   }
   
   // Otherwise reshuffling needs to be done.
 
   // If there is only one parton, attempt to reshuffle with 
   // the incoming to be consistent with the reshuffle for a
   // hard process with no decays.
-  else if ( partons.size() == 1 && ( DipolePartonSplitter::colourConnected(partons.front(),eventIncoming.first) || 
+  else if ( partons.size() == 1 &&
+            ( DipolePartonSplitter::colourConnected(partons.front(),eventIncoming.first) || 
 				     DipolePartonSplitter::colourConnected(partons.front(),eventIncoming.second) ) ) {
       
     // Erase the parton from the event outgoing
     eventOutgoing.erase( find( eventOutgoing.begin(), eventOutgoing.end(), partons.front() ) );
     // Perform the reshuffle, this update the intermediates and the incoming
     reshuffle(partons, eventIncoming, eventIntermediates);
     // Update the outgoing
     eventOutgoing.push_back(partons.front());
     return;
   }
     
   // If reshuffling amongst the incoming is not possible
   // or if we have multiple outgoing partons.
   else {
 
     // Create a complete list of the outgoing from the process
     PList out;
     // Make an empty list for storing the new intermediates
     PList intermediates;
-    // Empty in particles pair
+    // Empty incoming particles pair
     PPair in;
 
     // A single parton which cannot be reshuffled 
     // with the incoming.
     if ( partons.size() == 1 ) {
 
       // Populate the out for the reshuffling
       out.insert(out.end(),partons.begin(),partons.end());
       out.insert(out.end(),recoilers.begin(),recoilers.end());
       assert( out.size() > 1 );
     
       // Perform the reshuffle with the temporary particle lists
       reshuffle(out, in, intermediates, true, partons, recoilers);    
     }
   
     // If there is more than one parton, reshuffle only
     // amongst the partons
     else {
       assert(partons.size() > 1);
 
       // Populate the out for the reshuffling
       out.insert(out.end(),partons.begin(),partons.end());
       assert( out.size() > 1 );
     
       // Perform the reshuffle with the temporary particle lists
       reshuffle(out, in, intermediates, true);
     }
   
     // Update the dipole event record
     updateEvent(intermediates, eventIntermediates, out, eventOutgoing, eventHard );
     return;
   }
 }
     
 
 void ConstituentReshuffler::decayReshuffle(PerturbativeProcessPtr& decayProc,
 					   PList& eventOutgoing,
 					   PList& eventHard,
 					   PList& eventIntermediates ) {
   
   // Separate particles into those to be assigned constituent masses
   // i.e. non-decaying coloured partons
   // and those which must only absorb recoil
   // i.e. non-coloured and decaying particles
   PList partons;
   PList recoilers;
 
   //Make sure the shower should return constituent masses:
   assert(ShowerHandler::currentHandler()->retConstituentMasses());
   
 
   // Populate the particle lists from the outgoing of the decay process
   for( unsigned int ix = 0; ix<decayProc->outgoing().size(); ++ix) {
 
     // Identify recoilers
     if ( !decayProc->outgoing()[ix].first->coloured() || 
 	 ShowerHandler::currentHandler()->decaysInShower(decayProc->outgoing()[ix].first->id() ) )
       recoilers.push_back(decayProc->outgoing()[ix].first);
 
     else 
       partons.push_back(decayProc->outgoing()[ix].first);
   }
 
   // If there are no outgoing partons, then no reshuffling
   // needs to be done
   if ( partons.size() == 0 )
     return;
 
   // Reshuffling needs to be done:
   else {
 
     // Create a complete list of the outgoing from the process
     PList out;
     // Make an empty list for storing the new intermediates
     PList intermediates;
     // Empty incoming particles pair
     PPair in;
 
 
     // SW - 15/06/2018, 31/01/2019 - Always include 'recoilers' in
     // reshuffling, regardless of the number of partons to be put on their
     // constituent mass shell. This is because reshuffling between 2 partons
     // frequently leads to a redoShower exception. This treatment is
     // consistent with the AO shower
+
+      // Populate the out for the reshuffling
+      out.insert(out.end(),partons.begin(),partons.end());
+      out.insert(out.end(),recoilers.begin(),recoilers.end());
+      assert( out.size() > 1 );
     
-    // Populate the out for the reshuffling
-    out.insert(out.end(),partons.begin(),partons.end());
-    out.insert(out.end(),recoilers.begin(),recoilers.end());
-    assert( out.size() > 1 );
-    
-    // Perform the reshuffle with the temporary particle lists
-    reshuffle(out, in, intermediates, true, partons, recoilers);    
-    
+      // Perform the reshuffle with the temporary particle lists
+      reshuffle(out, in, intermediates, true, partons, recoilers);    
+
     // Update the dipole event record and the decay process
     updateEvent(intermediates, eventIntermediates, out, eventOutgoing, eventHard, decayProc );
     return;
   }
 }
 
 
 void ConstituentReshuffler::updateEvent( PList& intermediates,
 					 PList& eventIntermediates,
 					 PList& out,
 					 PList& eventOutgoing,
 					 PList& eventHard,
 					 PerturbativeProcessPtr decayProc ) {
 
   // Loop over the new intermediates following the reshuffling
   for (PList::iterator p = intermediates.begin();
        p != intermediates.end(); ++p) {
 
     // Update the event record intermediates
     eventIntermediates.push_back(*p);
 
     // Identify the reshuffled particle
     assert( (*p)->children().size()==1 );
     PPtr reshuffled = (*p)->children()[0];
     assert( find(out.begin(), out.end(), reshuffled) != out.end() );
 
     // Update the event record outgoing
     PList::iterator posOut = find(eventOutgoing.begin(), eventOutgoing.end(), *p);
 
     if ( posOut != eventOutgoing.end() ) {
       eventOutgoing.erase(posOut);
       eventOutgoing.push_back(reshuffled);
     }
       
     else {
       PList::iterator posHard = find(eventHard.begin(), eventHard.end(), *p);
       assert( posHard != eventHard.end() );
       eventHard.erase(posHard);
       eventHard.push_back(reshuffled);
     }
     
     // Replace the particle in the the decay process outgoing
     if ( decayProc ) {
       vector<pair<PPtr,PerturbativeProcessPtr> >::iterator decayOutIt = decayProc->outgoing().end();
       for ( decayOutIt = decayProc->outgoing().begin();
 	    decayOutIt!= decayProc->outgoing().end(); ++decayOutIt ) {
 	
 	if ( decayOutIt->first == *p ){
 	  break;
 	}
       }
       assert( decayOutIt != decayProc->outgoing().end() );
       decayOutIt->first = reshuffled;
     }
   }  
 }
+ 
+void ConstituentReshuffler::updateSpinInfo( PPtr& oldPart,
+                                            PPtr& newPart ) {
+
+  const Lorentz5Momentum& oldMom = oldPart->momentum();
+  const Lorentz5Momentum& newMom = newPart->momentum();
+
+  // Rotation from old momentum to +ve z-axis
+  LorentzRotation oldToZAxis;
+  Axis axisOld(oldMom.vect().unit());
+  if( axisOld.perp2() > 1e-12 ) {
+    double sinth(sqrt(1.-sqr(axisOld.z())));
+    oldToZAxis.rotate( -acos(axisOld.z()),Axis(-axisOld.y()/sinth,axisOld.x()/sinth,0.));
+  }
+
+  // Rotation from new momentum to +ve z-axis
+  LorentzRotation newToZAxis;
+  Axis axisNew(newMom.vect().unit());
+  if( axisNew.perp2() > 1e-12 ) {
+    double sinth(sqrt(1.-sqr(axisNew.z())));
+    newToZAxis.rotate( -acos(axisNew.z()),Axis(-axisNew.y()/sinth,axisNew.x()/sinth,0.));
+  }
+
+  // Boost from old momentum to new momentum along z-axis
+  Lorentz5Momentum momOldRotated = oldToZAxis*Lorentz5Momentum(oldMom);
+  Lorentz5Momentum momNewRotated = newToZAxis*Lorentz5Momentum(newMom);
+  
+  Energy2 a = sqr(momOldRotated.z()) + sqr(momNewRotated.t());
+  Energy2 b = 2.*momOldRotated.t()*momOldRotated.z();
+  Energy2 c = sqr(momOldRotated.t()) - sqr(momNewRotated.t());
+  double beta;
+  
+  // The rotated momentum should always lie along the +ve z-axis
+  if ( momOldRotated.z() > ZERO )
+    beta = (-b + sqrt(sqr(b)-4.*a*c)) / 2. / a;
+  else
+    beta = (-b - sqrt(sqr(b)-4.*a*c)) / 2. / a;
+  
+  LorentzRotation boostOldToNew(0., 0., beta);
+
+  // Total transform
+  LorentzRotation transform = (newToZAxis.inverse())*boostOldToNew*oldToZAxis;
+
+  // Assign the same spin info to the old and new particles
+  newPart->spinInfo(oldPart->spinInfo());
+  newPart->spinInfo()->transform(oldMom, transform);
+}
 
 // If needed, insert default implementations of virtual function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void ConstituentReshuffler::persistentOutput(PersistentOStream &) const {
 }
 
 void ConstituentReshuffler::persistentInput(PersistentIStream &, int) {
 }
 
 ClassDescription<ConstituentReshuffler> ConstituentReshuffler::initConstituentReshuffler;
 // Definition of the static class description member.
 
 void ConstituentReshuffler::Init() {
 
   static ClassDocumentation<ConstituentReshuffler> documentation
     ("The ConstituentReshuffler class implements reshuffling "
      "of partons on their nominal mass shell to their constituent "
      "mass shells.");
 
 }
 
diff --git a/Shower/Dipole/Utility/ConstituentReshuffler.h b/Shower/Dipole/Utility/ConstituentReshuffler.h
--- a/Shower/Dipole/Utility/ConstituentReshuffler.h
+++ b/Shower/Dipole/Utility/ConstituentReshuffler.h
@@ -1,290 +1,299 @@
 // -*- C++ -*-
 //
 // ConstituentReshuffler.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_ConstituentReshuffler_H
 #define HERWIG_ConstituentReshuffler_H
 //
 // This is the declaration of the ConstituentReshuffler class.
 //
 
 #include "ThePEG/Handlers/HandlerBase.h"
 #include "ThePEG/Utilities/Exception.h"
 #include "Herwig/Shower/PerturbativeProcess.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer, Stephen Webster
  * 
  * \brief The ConstituentReshuffler class implements reshuffling
  * of partons on their nominal mass shell to their constituent 
  * mass shells.
  *
  */
 class ConstituentReshuffler: public HandlerBase {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   ConstituentReshuffler();
 
   /**
    * The destructor.
    */
   virtual ~ConstituentReshuffler();
   //@}
 
 public:
 
   /**
    * Reshuffle the outgoing partons to constituent
    * masses. Optionally, incoming partons are given
    * to absorb recoils. Add the non-reshuffled partons
    * to the intermediates list. Throw ConstituentReshufflerProblem
    * if a numerical problem prevents the solution of
    * the reshuffling equation.
    */
   void reshuffle(PList& out,
 		 PPair& in,
 		 PList& intermediates,
 		 const bool decay,
 		 PList& decayPartons,
 		 PList& decayRecoilers);
 
   /**
    * Reshuffle the outgoing partons to constituent
    * masses. Optionally, incoming partons are given
    * to absorb recoils. Add the non-reshuffled partons
    * to the intermediates list. Throw ConstituentReshufflerProblem
    * if a numerical problem prevents the solution of
    * the reshuffling equation.
    */
   void reshuffle(PList& out,
 		 PPair& in,
 		 PList& intermediates,
 		 const bool decay=false) {
 
     PList decayPartons;
     PList decayRecoilers;
 
     reshuffle(out,
 	      in,
 	      intermediates,
 	      decay,
 	      decayPartons,
 	      decayRecoilers);
   }
 
 
   /**
    * Reshuffle the outgoing partons following the showering
    * of the initial hard interaction to constituent masses,
    * for the case of outgoing decaying particles.
    * Throw ConstituentReshufflerProblem
    * if a numerical problem prevents the solution of
    * the reshuffling equation.
    */
   void hardProcDecayReshuffle(PList& decaying,
 			      PList& eventOutgoing,
 			      PList& eventHard,
 			      PPair& eventIncoming,
 			      PList& eventIntermediates) ;
 
   /**
    * Reshuffle the outgoing partons following the showering
    * of a particle decay to constituent masses. 
    * Throw ConstituentReshufflerProblem
    * if a numerical problem prevents the solution of
    * the reshuffling equation.
    */
   void decayReshuffle(PerturbativeProcessPtr& decayProc,
 		      PList& eventOutgoing,
 		      PList& eventHard,
 		      PList& eventIntermediates) ;
 
   /**
    * Update the dipole event record and, if appropriate,
    * the relevant decay process.
    **/
   void updateEvent( PList& intermediates,
 		    PList& eventIntermediates,
 		    PList& out,
 		    PList& eventOutgoing,
 		    PList& eventHard,
 		    PerturbativeProcessPtr decayProc = PerturbativeProcessPtr() ) ;
 
+
+  /** 
+   * Update the spinInfo of a particle following reshuffling 
+   * to take account of the change in momentum.
+   * Used only for unstable particles that need to be dealt with.
+   **/
+  void updateSpinInfo( PPtr& oldPart,
+                       PPtr& newPart ) ;
+  
 protected:
 
   /**
    * The function object defining the equation
    * to be solved.
    */
   struct ReshuffleEquation {
 
     ReshuffleEquation (Energy q,
 		       PList::iterator m_begin,
 		       PList::iterator m_end)
       : w(q), p_begin(m_begin), p_end(m_end) {}
 
     typedef double ArgType;
     typedef double ValType;
 
     static double aUnit();
     static double vUnit();
 
     double operator() (double xi) const;
 
     Energy w;
 
     PList::iterator p_begin;
     PList::iterator p_end;
 
   };
 
   /**
    * The function object defining the equation
    * to be solved in the case of separate recoilers
    * TODO - refine the whole implementation of separate partons and recoilers
    */
   struct DecayReshuffleEquation {
 
     DecayReshuffleEquation (Energy q,
 			    PList::iterator m_begin,
 			    PList::iterator m_end,
 			    PList::iterator n_begin,
 			    PList::iterator n_end)
       : w(q), p_begin(m_begin), p_end(m_end), r_begin(n_begin), r_end(n_end) {}
 
     typedef double ArgType;
     typedef double ValType;
 
     static double aUnit();
     static double vUnit();
 
     double operator() (double xi) const;
 
     Energy w;
 
     PList::iterator p_begin;
     PList::iterator p_end;
 
     PList::iterator r_begin;
     PList::iterator r_end;
   };
 
 
 
 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<ConstituentReshuffler> initConstituentReshuffler;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   ConstituentReshuffler & operator=(const ConstituentReshuffler &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of ConstituentReshuffler. */
 template <>
 struct BaseClassTrait<Herwig::ConstituentReshuffler,1> {
   /** Typedef of the first base class of ConstituentReshuffler. */
   typedef HandlerBase NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the ConstituentReshuffler class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::ConstituentReshuffler>
   : public ClassTraitsBase<Herwig::ConstituentReshuffler> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::ConstituentReshuffler"; }
   /**
    * The name of a file containing the dynamic library where the class
    * ConstituentReshuffler is implemented. It may also include several, space-separated,
    * libraries if the class ConstituentReshuffler depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_ConstituentReshuffler_H */
diff --git a/Shower/Dipole/Utility/IntrinsicPtGenerator.cc b/Shower/Dipole/Utility/IntrinsicPtGenerator.cc
--- a/Shower/Dipole/Utility/IntrinsicPtGenerator.cc
+++ b/Shower/Dipole/Utility/IntrinsicPtGenerator.cc
@@ -1,198 +1,198 @@
 // -*- C++ -*-
 //
 // IntrinsicPtGenerator.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 IntrinsicPtGenerator class.
 //
 
 #include "IntrinsicPtGenerator.h"
 #include "ThePEG/Interface/ClassDocumentation.h"
 #include "ThePEG/Interface/Parameter.h"
 
 #include "ThePEG/Persistency/PersistentOStream.h"
 #include "ThePEG/Persistency/PersistentIStream.h"
 
 #include "ThePEG/Config/Constants.h"
 
 #include "DipolePartonSplitter.h"
 
 #include "Herwig/Shower/ShowerHandler.h"
 #include "Herwig/PDF/HwRemDecayer.h"
 
 using namespace Herwig;
 
 IntrinsicPtGenerator::IntrinsicPtGenerator() 
   : HandlerBase(),
     theValenceIntrinsicPtScale(1.0*GeV),
     theSeaIntrinsicPtScale(1.0*GeV) {}
 
 IntrinsicPtGenerator::~IntrinsicPtGenerator() {}
 
 IBPtr IntrinsicPtGenerator::clone() const {
   return new_ptr(*this);
 }
 
 IBPtr IntrinsicPtGenerator::fullclone() const {
   return new_ptr(*this);
 }
 
-SpinOneLorentzRotation IntrinsicPtGenerator::kick(PPair& in,
+LorentzRotation IntrinsicPtGenerator::kick(PPair& in,
 						  PList& intermediates) {
 
   if ( theValenceIntrinsicPtScale == 0.0*GeV &&
        theSeaIntrinsicPtScale == 0.0*GeV )
-    return SpinOneLorentzRotation();
+    return LorentzRotation();
 
   assert(ShowerHandler::currentHandler());
 
   tHwRemDecPtr remDec = ShowerHandler::currentHandler()->remnantDecayer();
 
   assert(remDec);
 
   Lorentz5Momentum Q = in.first->momentum() + in.second->momentum();
 
   // first parton
 
   if (in.first->coloured()) {
 
     Axis perp;
     Energy pt = 0.*GeV;
 
     double phi = 2.*Constants::pi*UseRandom::rnd();
 
     Axis dir = in.first->momentum().vect().unit();
     perp = dir.orthogonal();
     perp.rotate(phi,dir);
 
     double r = sqrt(-log(1.-UseRandom::rnd()));
 
     if ( remDec->content().first.isValenceQuark(in.first) )
       pt = sqrt(2.) * theValenceIntrinsicPtScale * r;
     else {
       assert(in.first->id() == ParticleID::g || 
 	     remDec->content().first.isSeaQuark(in.first));
       pt = sqrt(2.) * theSeaIntrinsicPtScale * r;
     }
 
     PPtr nin = new_ptr(Particle(in.first->dataPtr())); 
 
     DipolePartonSplitter::change(in.first,nin,true);
 
     nin->set5Momentum(Lorentz5Momentum(0.*GeV,in.first->momentum().vect() +
 				       pt * perp));
 
     intermediates.push_back(in.first);
     in.first = nin;
 
   }
 
   // second parton
 
   if (in.second->coloured()) {
 
     Axis perp;
     Energy pt = 0.*GeV;
 
     double phi = 2.*Constants::pi*UseRandom::rnd();
 
     Axis dir = in.second->momentum().vect().unit();
     perp = dir.orthogonal();
     perp.rotate(phi,dir);
 
     double r = sqrt(-log(1.-UseRandom::rnd()));
 
     if ( remDec->content().second.isValenceQuark(in.second) )
       pt = sqrt(2.) * theValenceIntrinsicPtScale * r;
     else {
       assert(in.second->id() == ParticleID::g || 
 	     remDec->content().second.isSeaQuark(in.second));
       pt = sqrt(2.) * theSeaIntrinsicPtScale * r;
     }
 
     PPtr nin = new_ptr(Particle(in.second->dataPtr())); 
     nin->colourInfo(new_ptr(ColourBase()));
 
     DipolePartonSplitter::change(in.second,nin,true);
 
     nin->set5Momentum(Lorentz5Momentum(0.*GeV,in.second->momentum().vect() +
 				       pt * perp));
 
     intermediates.push_back(in.second);
     in.second = nin;
 
   }
 
   // restore mometum conservation
 
   Lorentz5Momentum nQ = in.first->momentum() + in.second->momentum();
 
   double x = Q.m()/nQ.m();
 
   nQ *= x;
 
   // work around for constructor problems
   // in Lorentz5Vector constructor, mass is not guaranteed
   // to be zero, event it was set as such before,
   // since gets recalculated in the LorentzVector
   Lorentz5Momentum scaled = x * in.first->momentum(); 
   scaled.setMass(ZERO); scaled.rescaleEnergy();
   in.first->set5Momentum(scaled);
   scaled = x * in.second->momentum(); 
   scaled.setMass(ZERO); scaled.rescaleEnergy();
   in.second->set5Momentum(scaled);
 
   // apparently, this is more stable than boosting directly with
   // n_Q.boostVector()-Q.boostVector()
 
   Boost beta1 = -Q.boostVector();
   Boost beta2 = nQ.boostVector();
 
-  SpinOneLorentzRotation transform (beta1);
+  LorentzRotation transform (beta1);
   transform.boost(beta2);
 
   return transform;
 
 }
 
 // If needed, insert default implementations of virtual function defined
 // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
 
 
 void IntrinsicPtGenerator::persistentOutput(PersistentOStream & os) const {
   os << ounit(theValenceIntrinsicPtScale,GeV) << ounit(theSeaIntrinsicPtScale,GeV);
 }
 
 void IntrinsicPtGenerator::persistentInput(PersistentIStream & is, int) {
   is >> iunit(theValenceIntrinsicPtScale,GeV) >> iunit(theSeaIntrinsicPtScale,GeV);
 }
 
 ClassDescription<IntrinsicPtGenerator> IntrinsicPtGenerator::initIntrinsicPtGenerator;
 // Definition of the static class description member.
 
 void IntrinsicPtGenerator::Init() {
 
   static ClassDocumentation<IntrinsicPtGenerator> documentation
     ("IntrinsicPtGenerator generates intrinsic pt for massless "
      "incoming partons in a shower independent way.");
 
 
   static Parameter<IntrinsicPtGenerator,Energy> interfaceValenceIntrinsicPtScale
     ("ValenceIntrinsicPtScale",
      "The width of the intrinsic pt Gaussian distribution for valence partons.",
      &IntrinsicPtGenerator::theValenceIntrinsicPtScale, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
      false, false, Interface::lowerlim);
 
   static Parameter<IntrinsicPtGenerator,Energy> interfaceSeaIntrinsicPtScale
     ("SeaIntrinsicPtScale",
      "The width of the intrinsic pt Gaussian distribution for sea partons.",
      &IntrinsicPtGenerator::theSeaIntrinsicPtScale, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
      false, false, Interface::lowerlim);
 
 }
 
diff --git a/Shower/Dipole/Utility/IntrinsicPtGenerator.h b/Shower/Dipole/Utility/IntrinsicPtGenerator.h
--- a/Shower/Dipole/Utility/IntrinsicPtGenerator.h
+++ b/Shower/Dipole/Utility/IntrinsicPtGenerator.h
@@ -1,174 +1,174 @@
 // -*- C++ -*-
 //
 // IntrinsicPtGenerator.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_IntrinsicPtGenerator_H
 #define HERWIG_IntrinsicPtGenerator_H
 //
 // This is the declaration of the IntrinsicPtGenerator class.
 //
 
 #include "ThePEG/Handlers/HandlerBase.h"
-#include "ThePEG/Vectors/SpinOneLorentzRotation.h"
+#include "ThePEG/Vectors/LorentzRotation.h"
 
 namespace Herwig {
 
 using namespace ThePEG;
 
 /**
  * \ingroup DipoleShower
  * \author Simon Platzer
  * 
  * \brief IntrinsicPtGenerator generates intrinsic pt for massless
  * incoming partons in a shower independent way.
  *
  * @see \ref IntrinsicPtGeneratorInterfaces "The interfaces"
  * defined for IntrinsicPtGenerator.
  */
 class IntrinsicPtGenerator: public HandlerBase {
 
 public:
 
   /** @name Standard constructors and destructors. */
   //@{
   /**
    * The default constructor.
    */
   IntrinsicPtGenerator();
 
   /**
    * The destructor.
    */
   virtual ~IntrinsicPtGenerator();
   //@}
 
 public:
 
   /**
    * Generate intrinsic pt for the given incoming
    * partons and return the transformation to be
    * applied on the final state particles. Add the
    * old incoming partons to the given list.
    */
-  SpinOneLorentzRotation kick(PPair& in,
+  LorentzRotation kick(PPair& in,
 			      PList& intermediates);
 
 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;
   //@}
 
 
 // If needed, insert declarations of virtual function defined in the
 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
 
 private:
 
   /**
    * The mean of the Gaussian distribution for
    * the intrinsic pt of valence partons.
    */
   Energy theValenceIntrinsicPtScale;
 
   /**
    * The mean of the Gaussian distribution for
    * the intrinsic pt of sea partons.
    */
   Energy theSeaIntrinsicPtScale;
 
 private:
 
   /**
    * The static object used to initialize the description of this class.
    * Indicates that this is a concrete class with persistent data.
    */
   static ClassDescription<IntrinsicPtGenerator> initIntrinsicPtGenerator;
 
   /**
    * The assignment operator is private and must never be called.
    * In fact, it should not even be implemented.
    */
   IntrinsicPtGenerator & operator=(const IntrinsicPtGenerator &) = delete;
 
 };
 
 }
 
 #include "ThePEG/Utilities/ClassTraits.h"
 
 namespace ThePEG {
 
 /** @cond TRAITSPECIALIZATIONS */
 
 /** This template specialization informs ThePEG about the
  *  base classes of IntrinsicPtGenerator. */
 template <>
 struct BaseClassTrait<Herwig::IntrinsicPtGenerator,1> {
   /** Typedef of the first base class of IntrinsicPtGenerator. */
   typedef HandlerBase NthBase;
 };
 
 /** This template specialization informs ThePEG about the name of
  *  the IntrinsicPtGenerator class and the shared object where it is defined. */
 template <>
 struct ClassTraits<Herwig::IntrinsicPtGenerator>
   : public ClassTraitsBase<Herwig::IntrinsicPtGenerator> {
   /** Return a platform-independent class name */
   static string className() { return "Herwig::IntrinsicPtGenerator"; }
   /**
    * The name of a file containing the dynamic library where the class
    * IntrinsicPtGenerator is implemented. It may also include several, space-separated,
    * libraries if the class IntrinsicPtGenerator depends on other classes (base classes
    * excepted). In this case the listed libraries will be dynamically
    * linked in the order they are specified.
    */
   static string library() { return "HwDipoleShower.so"; }
 };
 
 /** @endcond */
 
 }
 
 #endif /* HERWIG_IntrinsicPtGenerator_H */
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -1,244 +1,245 @@
 dnl Process this file with autoconf to produce a configure script.
 
 AC_PREREQ([2.63])
 AC_INIT([Herwig],[devel],[herwig@projects.hepforge.org],[Herwig])
 AC_CONFIG_SRCDIR([Utilities/HerwigStrategy.cc])
 AC_CONFIG_AUX_DIR([Config])
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_HEADERS([Config/config.h])
 dnl AC_PRESERVE_HELP_ORDER
 AC_CANONICAL_HOST
 
 dnl === disable debug symbols by default =====
 if test "x$CXXFLAGS" = "x"; then
    CXXFLAGS=-O2
 fi
 if test "x$CFLAGS" = "x"; then
    CFLAGS=-O2
 fi
 
 AC_LANG([C++])
 
 AM_INIT_AUTOMAKE([1.11 subdir-objects gnu dist-bzip2 no-dist-gzip -Wall -Wno-portability])
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
 
 dnl Checks for C++ compiler. Handle C++11 flags.
 AC_PROG_CXX
 AX_CXX_COMPILE_STDCXX([11],[noext],[mandatory])
 
 dnl check for POSIX
 AC_CHECK_HEADER([unistd.h],[],
       [AC_MSG_ERROR([Herwig needs "unistd.h". Non-POSIX systems are not supported.])])
 AC_CHECK_HEADER([sys/stat.h],[],
       [AC_MSG_ERROR([Herwig needs "sys/stat.h". Non-POSIX systems are not supported.])])
 
 dnl Checks for programs.
 AC_PROG_INSTALL
 AC_PROG_MAKE_SET
 AC_PROG_LN_S
 
 dnl modified search order
 AC_PROG_FC([gfortran g95 g77]) 
 dnl xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn xlf90 f90 pgf90 pghpf epcf90 xlf f77 frt pgf77 cf77 fort77 fl32 af77])
 AC_LANG_PUSH([Fortran])
 AC_MSG_CHECKING([if the Fortran compiler ($FC) works])
 AC_COMPILE_IFELSE(
    	AC_LANG_PROGRAM([],[      print *[,]"Hello"]),
 	[AC_MSG_RESULT([yes])],
 	[AC_MSG_RESULT([no])
 	 AC_MSG_ERROR([A Fortran compiler is required to build Herwig.])
 	]
 )
 AC_LANG_POP([Fortran])
 AC_FC_WRAPPERS
 
 
 LT_PREREQ([2.2.6])
 LT_INIT([disable-static dlopen pic-only])
 
 dnl ####################################
 dnl ####################################
 
 dnl for Doc/fixinterfaces.pl
 AC_PATH_PROG(PERL, perl)
 
 dnl for Models/Feynrules
 AM_PATH_PYTHON([2.6],, [:])
 AM_CONDITIONAL([HAVE_PYTHON], [test "x$PYTHON" != "x:"])
 
 HERWIG_CHECK_GSL
 
 HERWIG_CHECK_THEPEG
 
 BOOST_REQUIRE([1.41])
 BOOST_FIND_HEADER([boost/numeric/ublas/io.hpp])
 dnl Boost 1.64 is missing a required header to make these work
 dnl we just assume they're there if io.hpp has been found OK above
 dnl BOOST_FIND_HEADER([boost/numeric/ublas/matrix.hpp])
 dnl BOOST_FIND_HEADER([boost/numeric/ublas/matrix_proxy.hpp])
 dnl BOOST_FIND_HEADER([boost/numeric/ublas/matrix_sparse.hpp])
 dnl BOOST_FIND_HEADER([boost/numeric/ublas/symmetric.hpp])
 dnl BOOST_FIND_HEADER([boost/numeric/ublas/vector.hpp])
 BOOST_FIND_HEADER([boost/operators.hpp])
 BOOST_TEST()
 
 HERWIG_CHECK_VBFNLO
 
 HERWIG_CHECK_NJET
 
 HERWIG_CHECK_GOSAM
 
 HERWIG_CHECK_GOSAM_CONTRIB
 
 HERWIG_CHECK_OPENLOOPS
 
 HERWIG_CHECK_MADGRAPH
 
 HERWIG_CHECK_EVTGEN
 HERWIG_CHECK_PYTHIA
 
 HERWIG_COMPILERFLAGS
 
 HERWIG_LOOPTOOLS
 
 FASTJET_CHECK_FASTJET
 
 HERWIG_ENABLE_MODELS
 
 SHARED_FLAG=-shared
 AM_CONDITIONAL(NEED_APPLE_FIXES,
 		[test "xx${host/darwin/foundit}xx" != "xx${host}xx"])
 if test "xx${host/darwin/foundit}xx" != "xx${host}xx"; then
    APPLE_DSO_FLAGS=-Wl,-undefined,dynamic_lookup
    SHARED_FLAG=-bundle
 fi
 AC_SUBST([APPLE_DSO_FLAGS])
 AC_SUBST([SHARED_FLAG])
 
 AC_CONFIG_FILES([UnderlyingEvent/Makefile
 		Models/Makefile
 		Models/StandardModel/Makefile
 		Models/RSModel/Makefile
 		Models/General/Makefile
 		Models/Susy/Makefile
 		Models/Susy/NMSSM/Makefile
 		Models/Susy/RPV/Makefile
 		Models/UED/Makefile
 		Models/LH/Makefile
 		Models/LHTP/Makefile
 		Models/Transplanckian/Makefile
 		Models/Leptoquarks/Makefile
 		Models/Zprime/Makefile
 		Models/TTbAsymm/Makefile
 		Models/Feynrules/Makefile
 		Models/Feynrules/python/Makefile-FR
 		Models/ADD/Makefile
 		Models/Sextet/Makefile
 		Decay/Makefile
 		Decay/FormFactors/Makefile
 		Decay/Tau/Makefile
 		Decay/Baryon/Makefile
 		Decay/VectorMeson/Makefile
 		Decay/Perturbative/Makefile
 		Decay/ScalarMeson/Makefile
 		Decay/TensorMeson/Makefile
 		Decay/WeakCurrents/Makefile
 		Decay/Partonic/Makefile
 		Decay/General/Makefile	
 		Decay/Radiation/Makefile
 		Decay/EvtGen/Makefile
 		Doc/refman.conf
 		Doc/refman.h
 		PDT/Makefile
 		PDF/Makefile
 		MatrixElement/Makefile
 		MatrixElement/General/Makefile
 		MatrixElement/Lepton/Makefile
 		MatrixElement/Hadron/Makefile
 		MatrixElement/DIS/Makefile
 		MatrixElement/Powheg/Makefile
 		MatrixElement/Gamma/Makefile
 		MatrixElement/Reweighters/Makefile
 		MatrixElement/Matchbox/Makefile
 		MatrixElement/Matchbox/Base/Makefile
 		MatrixElement/Matchbox/Utility/Makefile
 		MatrixElement/Matchbox/Phasespace/Makefile
 		MatrixElement/Matchbox/Dipoles/Makefile
 		MatrixElement/Matchbox/InsertionOperators/Makefile
 		MatrixElement/Matchbox/Matching/Makefile
 		MatrixElement/Matchbox/Cuts/Makefile
 		MatrixElement/Matchbox/Scales/Makefile
 		MatrixElement/Matchbox/ColorFull/Makefile
 		MatrixElement/Matchbox/CVolver/Makefile
 		MatrixElement/Matchbox/Builtin/Makefile
 		MatrixElement/Matchbox/Builtin/Amplitudes/Makefile
 		MatrixElement/Matchbox/Tests/Makefile
 		MatrixElement/Matchbox/External/Makefile
 		MatrixElement/Matchbox/External/BLHAGeneric/Makefile
 		MatrixElement/Matchbox/External/VBFNLO/Makefile
 		MatrixElement/Matchbox/External/NJet/Makefile
 		MatrixElement/Matchbox/External/GoSam/Makefile
 		MatrixElement/Matchbox/External/OpenLoops/Makefile
 		MatrixElement/Matchbox/External/MadGraph/Makefile
 		MatrixElement/Matchbox/External/MadGraph/mg2herwig
 		Sampling/Makefile
 		Sampling/CellGrids/Makefile
 		Shower/Makefile
 		Shower/QTilde/Makefile
 		Shower/QTilde/Matching/Makefile
 		Shower/Dipole/Makefile
 		Shower/Dipole/Base/Makefile
 		Shower/Dipole/Kernels/Makefile
 		Shower/Dipole/Kinematics/Makefile
 		Shower/Dipole/Utility/Makefile
 		Shower/Dipole/AlphaS/Makefile
+		Shower/Dipole/SpinCorrelations/Makefile
 		Utilities/Makefile
 		Utilities/XML/Makefile
 		Utilities/Statistics/Makefile
 		Hadronization/Makefile
 		lib/Makefile
 		include/Makefile
 		src/Makefile
 		src/defaults/Makefile
 		src/snippets/Makefile
 		src/Matchbox/Makefile
 		src/herwig-config
 		Doc/Makefile
 		Doc/HerwigDefaults.in
 		Looptools/Makefile
 		Analysis/Makefile
 		API/Makefile
 		src/Makefile-UserModules
 		src/defaults/Analysis.in
 		src/defaults/MatchboxDefaults.in
 		src/defaults/Decays.in
 		src/defaults/decayers.in
 		src/defaults/setup.gosam.in
 		src/Matchbox/LO-DefaultShower.in
 		src/Matchbox/LO-DipoleShower.in
 		src/Matchbox/MCatLO-DefaultShower.in
 		src/Matchbox/MCatLO-DipoleShower.in
 		src/Matchbox/LO-NoShower.in
 		src/Matchbox/MCatNLO-DefaultShower.in
 		src/Matchbox/MCatNLO-DipoleShower.in
 		src/Matchbox/NLO-NoShower.in
 		src/Matchbox/Powheg-DefaultShower.in
 		src/Matchbox/Powheg-DipoleShower.in
 		src/Merging/Makefile
 		Shower/Dipole/Merging/Makefile
 		Shower/Dipole/Colorea/Makefile
 		src/defaults/MatchboxMergingDefaults.in
 		Contrib/Makefile
 		Contrib/make_makefiles.sh
 		Tests/Makefile
 		Makefile])
 
 AC_CONFIG_LINKS([Doc/BSMlibs.in:Doc/BSMlibs.in])
 AC_CONFIG_FILES([Doc/fixinterfaces.pl],[chmod +x Doc/fixinterfaces.pl])
 AC_CONFIG_HEADERS([PDF/SaSPhotonPDF.cc])
 HERWIG_OVERVIEW
 
 AC_CONFIG_COMMANDS([summary],[cat config.herwig])
 
 AC_OUTPUT
diff --git a/src/LHC-GammaGamma.in b/src/LHC-GammaGamma.in
--- a/src/LHC-GammaGamma.in
+++ b/src/LHC-GammaGamma.in
@@ -1,73 +1,73 @@
 # -*- ThePEG-repository -*-
 
 ##################################################
 # Example generator based on LEP parameters
 # usage: Herwig read LEP.in
 ##################################################
 
 read snippets/PPCollider.in
 
 ##################################################
 # Technical parameters for this run
 ##################################################
 cd /Herwig/Generators
 set EventGenerator:EventHandler:Sampler:Ntry 10000
 
 ##################################################
 # Choice of phase-space generation for PDFs
 ##################################################
 set /Herwig/Partons/PPExtractor:FlatSHatY 0
 
 ##################################################
 # Change the proton PDFs to those for photon radiation
 ##################################################
 set /Herwig/Particles/p+:PDF    /Herwig/Partons/BudnevPDF
 set /Herwig/Particles/pbar-:PDF /Herwig/Partons/BudnevPDF
 set /Herwig/Partons/PPExtractor:FirstPDF /Herwig/Partons/BudnevPDF
 set /Herwig/Partons/PPExtractor:SecondPDF /Herwig/Partons/BudnevPDF
 set /Herwig/Shower/ShowerHandler:PDFA NULL
 set /Herwig/Shower/ShowerHandler:PDFB NULL
 
 ##################################################
 #  Cuts
 ##################################################
 cd /Herwig/Cuts
-set Cuts:ScaleMin 0.0
+set Cuts:ScaleMin 0.0*GeV2
 set Cuts:X1Min 0
 set Cuts:X2Min 0
 set Cuts:X1Max 1.
 set Cuts:X2Max 1.
 set Cuts:MHatMin 1.*GeV
 erase Cuts:MultiCuts 0
 set LeptonKtCut:MinKT 3*GeV
 
 ##################################################
 # Selected the hard process
 ##################################################
 cd /Herwig/MatrixElements
 
 # fermion-antifermion 
 insert SubProcess:MatrixElements 0 /Herwig/MatrixElements/MEgg2ff
 set /Herwig/MatrixElements/MEgg2ff:Process Muon
 # W+W-
 #insert SubProcess:MatrixElements 0 /Herwig/MatrixElements/MEgg2WW
 
 ##################################################
 # LHC physics parameters (override defaults) 
 ##################################################
 cd /Herwig/Generators
 set EventGenerator:EventHandler:CascadeHandler:MPIHandler NULL
 
 ##################################################
 ## prepare for Rivet analysis or HepMC output
 ## when running with parton shower
 ##################################################
 #read snippets/Rivet.in
 #insert /Herwig/Analysis/Rivet:Analyses 0 XXX_2015_ABC123
 #read snippets/HepMC.in
 #set /Herwig/Analysis/HepMC:PrintEvent NNN
 
 ###################################################
 # Save run for later usage with 'Herwig run'
 ##################################################
 saverun LHC-GammaGamma EventGenerator
diff --git a/src/Matchbox/CMEC.in b/src/Matchbox/CMEC.in
new file mode 100644
--- /dev/null
+++ b/src/Matchbox/CMEC.in
@@ -0,0 +1,45 @@
+# -*- ThePEG-repository -*-
+
+##################################################
+## Turn on subleading Nc corrections
+##################################################
+
+set /Herwig/DipoleShower/DipoleShowerHandler:DoSubleadingNc On
+
+## Set the number of subleading Nc emissions to calculate
+set /Herwig/DipoleShower/DipoleShowerHandler:SubleadingNcEmissionsLimit 5
+
+##################################################
+## Calculate the CMECs
+##################################################
+
+## Set detuning
+set /Herwig/DipoleShower/DipoleShowerHandler:Detuning 2
+
+## Create an object of the CMEC class
+create Herwig::ColourMatrixElementCorrection /Herwig/DipoleShower/DipoleSplittingReweight
+
+## Set the splitting reweight to be the CMEC (it is a derived class of
+## DipoleSplittingReweight)
+set /Herwig/DipoleShower/DipoleShowerHandler:SplittingReweight /Herwig/DipoleShower/DipoleSplittingReweight
+
+##################################################
+## Set the density operator evolution scheme
+##################################################
+## Schemes:
+## 0 - Eikonal with cutoff
+## 1 - Eikonal without cutoff
+## 2 - Constant
+## 3 - Semi-leading Nc, only emitter/spectator have non-zero Vijk
+
+set /Herwig/DipoleShower/DipoleShowerHandler:DensityOperatorEvolution 1
+set /Herwig/DipoleShower/DipoleShowerHandler:DensityOperatorCutoff 1.0*GeV2
+
+##################################################
+## Turn on partial unweighting and set the
+## reference weight
+##################################################
+
+#set /Herwig/DipoleShower/DipoleShowerHandler:DoPartialUnweighting Off
+#set /Herwig/DipoleShower/DipoleShowerHandler:DoPartialUnweightingAtEmission Off
+#set /Herwig/DipoleShower/DipoleShowerHandler:ReferenceWeight 4.0
diff --git a/src/Matchbox/Makefile.am b/src/Matchbox/Makefile.am
--- a/src/Matchbox/Makefile.am
+++ b/src/Matchbox/Makefile.am
@@ -1,65 +1,66 @@
 BUILT_SOURCES = done-all-links
 
 Matchboxdir = ${pkgdatadir}/Matchbox
 
 INPUTFILES = \
+CMEC.in \
 DefaultEEJets.in \
 DefaultEPJets.in \
 DefaultPPJets.in \
 DiagonalCKM.in \
 FiveFlavourNoBMassScheme.in \
 FiveFlavourScheme.in \
 FourFlavourScheme.in \
 GoSam-GoSam.in \
 HiggsEffective.in \
 HJets.in \
 IdentifiedBs.in \
 InclusiveDurhamJets.in \
 IncreaseVerbosity.in \
 KrkNLO-DipoleShower.in \
 LO-DefaultShower.in \
 LO-DipoleShower.in \
 LO.in \
 LO-NoShower.in \
 MadGraph-GoSam.in \
 MadGraph-MadGraph.in \
 MadGraph-NJet.in \
 MadGraph-OpenLoops.in \
 MCatLO-DefaultShower.in \
 MCatLO-DipoleShower.in \
 MCatNLO-DefaultShower.in \
 MCatNLO-Dipole-HardAlphaSTune.in \
 MCatNLO-DipoleShower.in \
 MMHT2014.in \
 MuDown.in \
 MuQDown.in \
 MuQUp.in \
 MuUp.in \
 NJet-NJet.in \
 NLO-NoShower.in \
 NonDiagonalCKM.in \
 OnShellHProduction.in \
 OnShellTopProduction.in \
 OnShellWProduction.in \
 OnShellZProduction.in \
 OpenLoops-OpenLoops.in \
 Powheg-DefaultShower.in \
 Powheg-DipoleShower.in \
 Powheg.in \
 PQCDLevel.in \
 StandardModelLike.in \
 ShowerBenchmarks.in \
 VBFDiagramsOnly.in \
 VBFNLO.in \
 VBFNLOPhasespace.in
 
 dist_Matchbox_DATA = $(INPUTFILES)
 
 CLEANFILES = done-all-links
 
 done-all-links: $(INPUTFILES)
 	@echo "Linking input files"
 	@for i in $(INPUTFILES); do \
 	if test -f $(srcdir)/$$i -a ! -e $$i; then \
 	$(LN_S) -f $(srcdir)/$$i; fi; done
 	@touch done-all-links