diff --git a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref
index 201a8038ae0458148bd77cdd83b34d8300d47654..df116303bdfd2e3cf56eef495725832bc0301b96 100644
--- a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref
+++ b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref
@@ -1350,6 +1350,16 @@ HLT_g35_loose_mu18_L1EM24VHI:
     7: 2
 HLT_g35_medium_g25_medium_L12EM20VH:
   eventCount: 0
+HLT_g35_tight_icalotight_mu15noL1_mu2noL1_L1EM22VHI:
+  eventCount: 0
+  stepCounts:
+    0: 5
+    1: 5
+    2: 5
+  stepFeatures:
+    0: 10
+    1: 10
+    2: 11
 HLT_g35_tight_icalotight_mu18noL1_L1EM22VHI:
   eventCount: 0
   stepCounts:
diff --git a/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref b/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref
index 571575bba8b21bcd209ca1dee45c2257cb1f3f7f..1bbb99ec0c345bb5e0554ca413206b2ef229c0b9 100644
--- a/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref
+++ b/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref
@@ -318,12 +318,6 @@ HLT_cscmon_CSCPEB_L1All:
     0: 20
 HLT_e12_lhloose_2mu10_L12MU10:
   eventCount: 0
-  stepCounts:
-    0: 1
-    1: 1
-  stepFeatures:
-    0: 2
-    1: 5
 HLT_e140_lhloose_L1EM22VHI:
   eventCount: 0
 HLT_e140_lhloose_nod0_L1EM22VHI:
@@ -614,6 +608,8 @@ HLT_g35_loose_mu18_L1EM24VHI:
   eventCount: 0
 HLT_g35_medium_g25_medium_L12EM20VH:
   eventCount: 0
+HLT_g35_tight_icalotight_mu15noL1_mu2noL1_L1EM22VHI:
+  eventCount: 0
 HLT_g35_tight_icalotight_mu18noL1_L1EM22VHI:
   eventCount: 0
 HLT_g3_loose_LArPEB_L1EM3:
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py
index 6c4a49f123ef6ae1440a745938efb5a6485c3b67..d10b30487f711a3476dcb0c1aad258ebbe51bd9e 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py
@@ -17,7 +17,7 @@ def mergeChainDefs(listOfChainDefs, chainDict):
 
     strategy = chainDict["mergingStrategy"]
     offset = chainDict["mergingOffset"]
-    log.info("%s: Combine by using %s merging", chainDict['chainName'], strategy)
+    log.info("[mergeChainDefs] %s: Combine by using %s merging", chainDict['chainName'], strategy)
 
     if strategy=="parallel":
         return mergeParallel(listOfChainDefs,  offset)
@@ -30,7 +30,7 @@ def mergeChainDefs(listOfChainDefs, chainDict):
         for ich,cConfig in enumerate(listOfChainDefs):
             chain_ag = cConfig.alignmentGroups[0]
             if chain_ag not in ordering:
-                log.error("Alignment group %s can't be auto-merged because it's not in the grouping list!",chain_ag)
+                log.error("[mergeChainDefs] Alignment group %s can't be auto-merged because it's not in the grouping list!",chain_ag)
             if chain_ag in merging_dict:
                 merging_dict[chain_ag] += [ich]
             else:
@@ -53,7 +53,7 @@ def mergeChainDefs(listOfChainDefs, chainDict):
             
         
     else:
-        log.error("Merging failed for %s. Merging strategy '%s' not known.", (listOfChainDefs, strategy))
+        log.error("[mergeChainDefs] Merging failed for %s. Merging strategy '%s' not known.", (listOfChainDefs, strategy))
         return -1
 
 
@@ -61,8 +61,9 @@ def mergeChainDefs(listOfChainDefs, chainDict):
 def mergeParallel(chainDefList, offset):
 
     if offset != -1:
-        log.error("Offset for parallel merging not implemented.")
-        
+        log.error("[mergeParallel] Offset for parallel merging not implemented.")
+        raise Exception("[mergeParallel] Cannot merge this chain, exiting.")
+
     allSteps = []
     nSteps = []
     chainName = ''
@@ -73,17 +74,18 @@ def mergeParallel(chainDefList, offset):
         if chainName == '':
             chainName = cConfig.name
         elif chainName != cConfig.name:
-            log.error("Something is wrong with the combined chain name: cConfig.name = %s while chainName = %s", cConfig.name, chainName)
-        
+            log.error("[mergeParallel] Something is wrong with the combined chain name: cConfig.name = %s while chainName = %s", cConfig.name, chainName)
+            raise Exception("[mergeParallel] Cannot merge this chain, exiting.")
         allSteps.append(cConfig.steps)
         nSteps.append(len(cConfig.steps))
         l1Thresholds.extend(cConfig.vseeds)
         if len(cConfig.alignmentGroups) > 1:
-            log.error("Merging an already merged chain? This is odd! %s",cConfig.alignmentGroups)
+            log.error("[mergeParallel] Parallel merging an already merged chain? This is odd! %s",cConfig.alignmentGroups)
+            raise Exception("[mergeParallel] Complicated situation currently unimplemented. exiting.")
         elif len(cConfig.alignmentGroups) == 1:
             alignmentGroups.append(cConfig.alignmentGroups[0])
         else: 
-            log.info("Alignment groups are empty for this combined chain - if this is not _newJO, this is not ok!")
+            log.info("[mergeParallel] Alignment groups are empty for this combined chain - if this is not _newJO, this is not ok!")
     import itertools
     if 'zip_longest' in dir(itertools):
         from itertools import zip_longest
@@ -93,17 +95,20 @@ def mergeParallel(chainDefList, offset):
     orderedSteps = list(zip_longest(*allSteps))
 
     combChainSteps =[]
-    log.debug("len(orderedSteps): %d", len(orderedSteps))
+    log.debug("[mergeParallel] len(orderedSteps): %d", len(orderedSteps))
+    for chain_index in range(len(chainDefList)):
+        log.debug('[mergeParallel] Chain object to merge (i.e. chainDef) %s', chainDefList[chain_index])
+
     for step_index, steps in enumerate(orderedSteps):
         mySteps = list(steps)
-        log.debug("Merging step counter %d", step_index+1)
-        combStep = makeCombinedStep(mySteps, step_index+1, chainDefList)
+        log.debug("[mergeParallel] Merging step counter %d", step_index+1)
+        combStep = makeCombinedStep(mySteps, step_index+1, chainDefList, orderedSteps, combChainSteps)
         combChainSteps.append(combStep)
                                   
     combinedChainDef = Chain(chainName, ChainSteps=combChainSteps, L1Thresholds=l1Thresholds, 
                                 nSteps = nSteps, alignmentGroups = alignmentGroups)
 
-    log.debug("Parallel merged chain %s with these steps:", chainName)
+    log.debug("[mergeParallel] Parallel merged chain %s with these steps:", chainName)
     for step in combinedChainDef.steps:
         log.debug('\n   %s', step)
 
@@ -114,65 +119,180 @@ def getEmptySeqName(stepName, chain_index, step_number, alignGroup):
     if re.search('^Step[0-9]_',stepName):
         stepName = stepName[6:]
 
-    seqName = 'Empty'+ alignGroup +'Seq'+str(step_number)+ '_'+ stepName + '_leg' + str(chain_index)
+    seqName = 'Empty'+ alignGroup +'Seq'+str(step_number)+ '_'+ stepName
     return seqName
 
 
-def getEmptyMenuSequence(flags, name):
-    return EmptyMenuSequence(name)
+def getEmptyMenuSequence(flags, name, mergeUsingFeature = False):
+    return EmptyMenuSequence(name, mergeUsingFeature = mergeUsingFeature)
 
+def getMultiplicityPerLeg(multiplicities):
+    mult_per_leg = []
+    for mult in multiplicities:
+        if mult == 1: 
+            mult_per_leg += ['1']
+        elif mult > 1: 
+            mult_per_leg += ['N']
+        else: 
+            raise Exception("[serial_zip] multiplicity not an expected value: %s",mult) 
+    return mult_per_leg
+
+def isFullScanRoI(inputL1Nav):
+    fsRoIList = ['HLTNav_L1FSNOSEED','HLTNav_L1MET','HLTNav_L1J']
+    if inputL1Nav in fsRoIList:
+        return True
+    else:
+        return False
+
+def noPrecedingStepsPreMerge(newsteps,chain_index,ileg):
+    for step in newsteps:
+        seq = step[chain_index].sequences[ileg]
+        if type(seq).__name__ == 'EmptyMenuSequence':
+            continue
+        else:
+            #if there's a non-empty sequence in a step before, there is clearly a
+            #preceding step in this chain.
+            return False
+    return True
+
+def noPrecedingStepsPostMerge(newsteps, ileg):
+    for step in newsteps:
+        seq = step.sequences[ileg]
+        if type(seq).__name__ == 'EmptyMenuSequence':
+            continue
+        else:
+            #if there's a non-empty sequence in a step before, there is clearly a
+            #preceding step in this chain.
+            return False
+    return True
+        
 
 def serial_zip(allSteps, chainName, chainDefList):
-    n_chains = len(allSteps)
+
+    legs_per_part = [len(cd.steps[0].multiplicity) for cd in chainDefList]
+    n_parts = len(allSteps)
+    log.debug('[serial_zip] configuring chain with %d parts with multiplicities %s', n_parts, legs_per_part)
     newsteps = []
-    for chain_index, chainsteps in enumerate(allSteps):
-        for step_index, step in enumerate(chainsteps):
-            log.debug('chain_index: %s step_index: %s', chain_index, step_index)
-            # create list of correct length
-            stepList = [None]*n_chains
-            
+
+    doBonusDebug = False
+
+    for chain_index, chainSteps in enumerate(allSteps): #per-part (horizontal) iteration
+        for step_index, step in enumerate(chainSteps):  #serial step iteration
+            log.debug('[serial_zip] chain_index: %s step_index: %s', chain_index, step_index)
+            # create list of correct length (chainSteps in parallel)
+            stepList = [None]*n_parts
+
             # put the step from the current sub-chain into the right place
             stepList[chain_index] = step
-            log.debug('Put step: %s', step.name)
+            log.debug('[serial_zip] Put step: %s', step.name)
 
-            # all other steps should contain an empty sequence
-            for step_index2, emptyStep in enumerate(stepList):
+            # all other chain parts' steps should contain an empty sequence
+            for chain_index2, (emptyStep, nLegs) in enumerate(zip(stepList,legs_per_part)): #more per-leg iteration
                 if emptyStep is None:
-                    seqName = getEmptySeqName(step.name, chain_index, step_index+1, chainDefList[0].alignmentGroups[0])
-                    emptySeq =  RecoFragmentsPool.retrieve(getEmptyMenuSequence, flags=None, name=seqName)
-                    stepList[step_index2] = ChainStep( seqName, Sequences=[emptySeq], chainDicts=step.stepDicts)            
-            
+                    mult_per_leg = getMultiplicityPerLeg(chainDefList[chain_index2].steps[0].multiplicity)
+
+                    #this WILL NOT work for jets!
+                    step_mult = []
+                    emptyChainDicts = []
+                    if chain_index2 < chain_index:
+                        emptyChainDicts = allSteps[chain_index2][-1].stepDicts
+                    else:
+                        emptyChainDicts = allSteps[chain_index2][0].stepDicts
+
+                    sigNames = []
+                    for emptyChainDict in emptyChainDicts:
+                        if isFullScanRoI(chainDefList[chain_index2].L1decisions[0]):
+                            sigNames +=[emptyChainDict['chainParts'][0]['signature']+'FS']
+                        else:
+                            sigNames +=[emptyChainDict['chainParts'][0]['signature']]
+
+                    seqMultName = '_'.join([mult+sigName for mult, sigName in zip(mult_per_leg,sigNames)])
+                    seqStepName = 'Empty' + chainDefList[chain_index].alignmentGroups[0]+'Align'+str(step_index+1)+'_'+seqMultName
+
+                    seqNames = [getEmptySeqName(emptyChainDicts[iSeq]['signature'], chain_index, step_index+1, chainDefList[chain_index].alignmentGroups[0]) for iSeq in range(nLegs)]
+                    if doBonusDebug:                        
+                        log.debug("[serial_zip] step name for this leg: %s", seqStepName)
+                        log.debug("[serial_zip] created empty sequence(s): %s", seqNames)
+                        log.debug("[serial_zip] L1decisions %s ", chainDefList[chain_index2].L1decisions)
+
+                    emptySequences = []
+                    for ileg in range(nLegs):
+                        if isFullScanRoI(chainDefList[chain_index2].L1decisions[0]) and noPrecedingStepsPreMerge(newsteps,chain_index2, ileg):
+                            log.debug("[serial_zip] adding FS empty sequence with mergeUsingFeature = False ")
+                            emptySequences += [RecoFragmentsPool.retrieve(getEmptyMenuSequence, flags=None, name=seqNames[ileg]+"FS", mergeUsingFeature = False)]
+                        elif isFullScanRoI(chainDefList[chain_index2].L1decisions[0]):
+                            log.debug("[serial_zip] adding FS empty sequence with mergeUsingFeature = True ")
+                            emptySequences += [RecoFragmentsPool.retrieve(getEmptyMenuSequence, flags=None, name=seqNames[ileg]+"FS", mergeUsingFeature = True)]
+                        else:
+                            log.debug("[serial_zip] adding non-FS empty sequence")
+                            emptySequences += [RecoFragmentsPool.retrieve(getEmptyMenuSequence, flags=None, name=seqNames[ileg])]
+
+                    #this WILL NOT work for jets!
+                    step_mult = []
+                    emptyChainDicts = []
+                    if chain_index2 < chain_index:
+                        emptyChainDicts = allSteps[chain_index2][-1].stepDicts
+                    else:
+                        emptyChainDicts = allSteps[chain_index2][0].stepDicts
+
+                    if doBonusDebug:
+                        log.debug("[serial_zip] emptyChainDicts %s",emptyChainDicts)
+
+                    if len(emptySequences) != len(emptyChainDicts):
+                        log.error("[serial_zip] different number of empty sequences/legs %d to stepDicts %d", len(emptySequences), len(emptyChainDicts))
+                        raise Exception("[serial_zip] Cannot create this chain step, exiting.")
+
+                    for sd in emptyChainDicts:
+                        if len(sd['chainParts']) != 1:
+                            log.error("[serial_zip] stepDict chainParts has length != 1 within a leg! %s",sd)
+                            raise Exception("[serial_zip] Cannot create this chain step, exiting.")
+                        step_mult += [int(sd['chainParts'][0]['multiplicity'])] 
+
+                    if len(emptySequences) != len(step_mult):
+                        log.error("[serial_zip] different number of empty sequences/legs %d to multiplicities %d", len(emptySequences), len(step_mult))
+                        raise Exception("[serial_zip] Cannot create this chain step, exiting.")
+
+                    if doBonusDebug:
+                        log.debug('[serial_zip] step multiplicity %s',step_mult)
+
+                    stepList[chain_index2] = ChainStep( seqStepName, Sequences=emptySequences,
+                                                  multiplicity = step_mult, chainDicts=emptyChainDicts,
+                                                  isEmpty = True)
+
             newsteps.append(stepList)
     log.debug('After serial_zip')
     for s in newsteps:
         log.debug( ', '.join(map(str, [step.name for step in s]) ) )
     return newsteps
 
+
 def mergeSerial(chainDefList):
     allSteps = []
     nSteps = []
     chainName = ''
     l1Thresholds = []
     alignmentGroups = []
-    log.debug('Merge chainDefList:')
+    log.debug('[mergeSerial] Merge chainDefList:')
     log.debug(chainDefList)
 
     for cConfig in chainDefList:
+
         if chainName == '':
             chainName = cConfig.name
         elif chainName != cConfig.name:
-            log.error("Something is wrong with the combined chain name: cConfig.name = %s while chainName = %s", cConfig.name, chainName)
-            
+            log.error("[mergeSerial] Something is wrong with the combined chain name: cConfig.name = %s while chainName = %s", cConfig.name, chainName)
+            raise Exception("[mergeSerial] Cannot merge this chain, exiting.")
+
         allSteps.append(cConfig.steps)
         nSteps.append(len(cConfig.steps))
         l1Thresholds.extend(cConfig.vseeds)
-        if len(cConfig.alignmentGroups) > 1:
-            log.error("Merging an already merged chain? This is odd! %s",cConfig.alignmentGroups)
-        alignmentGroups.append(cConfig.alignmentGroups[0])
+        alignmentGroups.extend(cConfig.alignmentGroups)
 
-    serialSteps = serial_zip(allSteps, chainName,chainDefList)
+    serialSteps = serial_zip(allSteps, chainName, chainDefList)
     mySerialSteps = deepcopy(serialSteps)
     combChainSteps =[]
+    for chain_index in range(len(chainDefList)):
+        log.debug('[mergeSerial] Chain object to merge (i.e. chainDef) %s', chainDefList[chain_index])
     for step_index, steps in enumerate(mySerialSteps):
         mySteps = list(steps)
         combStep = makeCombinedStep(mySteps, step_index+1, chainDefList)
@@ -181,78 +301,112 @@ def mergeSerial(chainDefList):
     # check if all chain parts have the same number of steps
     sameNSteps = all(x==nSteps[0] for x in nSteps) 
     if sameNSteps is True:
-        log.info("All chain parts have the same number of steps")
+        log.info("[mergeSerial] All chain parts have the same number of steps")
     else:
-        log.info("Have to deal with uneven number of chain steps, there might be none's appearing in sequence list => to be fixed")
+        log.info("[mergeSerial] Have to deal with uneven number of chain steps, there might be none's appearing in sequence list => to be fixed")
                                   
     combinedChainDef = Chain(chainName, ChainSteps=combChainSteps, L1Thresholds=l1Thresholds,
                                nSteps = nSteps, alignmentGroups = alignmentGroups)
 
-    log.debug("Serial merged chain %s with these steps:", chainName)
+    log.debug("[mergeSerial] Serial merged chain %s with these steps:", chainName)
     for step in combinedChainDef.steps:
         log.debug('   %s', step)
 
     return combinedChainDef
 
 
-def makeCombinedStep(steps, stepNumber, chainDefList):
+def makeCombinedStep(parallel_steps, stepNumber, chainDefList, allSteps = [], currentChainSteps = []):
     from TrigCompositeUtils.TrigCompositeUtils import legName
     stepName = 'merged' #we will renumber all steps after chains are aligned #Step' + str(stepNumber)
     stepSeq = []
     stepMult = []
-    log.verbose(" steps %s ", steps)
+    log.verbose("[makeCombinedStep] steps %s ", parallel_steps)
     stepDicts = []
     comboHypoTools = []
     comboHypo = None
 
     # this function only makes sense if we are merging steps corresponding to the chains in the chainDefList
-    assert len(chainDefList)==len(steps), "makeCombinedStep: Length of chain defs %d does not match length of steps to merge %d" % (len(chainDefList), len(steps))
+    assert len(chainDefList)==len(parallel_steps), "[makeCombinedStep] makeCombinedStep: Length of chain defs %d does not match length of steps to merge %d" % (len(chainDefList), len(allSteps))
     
-    for chain_index, step in enumerate(steps):
+    leg_counter = 0
+  
+    for chain_index, step in enumerate(parallel_steps): #this is a horizontal merge!
         if step is None:
             # this happens for merging chains with different numbers of steps, we need to "pad" out with empty sequences to propogate the decisions
-            currentStepName = "Step" + str(stepNumber) + "_Empty" + str(chain_index)
-            seqName = getEmptySeqName(currentStepName, chain_index, stepNumber, chainDefList[0].alignmentGroups[0])
-            log.debug("  step %s,  empty sequence %s", currentStepName, seqName)
-            emptySeq = RecoFragmentsPool.retrieve(getEmptyMenuSequence, flags=None, name=seqName)
+            # all other chain parts' steps should contain an empty sequence
 
-            stepSeq.append(emptySeq)
-            stepMult.append(1)
+            new_stepDict = deepcopy(chainDefList[chain_index].steps[-1].stepDicts[-1])
+            
+            seqName = getEmptySeqName(new_stepDict['signature'], chain_index, stepNumber, chainDefList[0].alignmentGroups[0])
+
+            currentStepName = ''
+            if isFullScanRoI(chainDefList[chain_index].L1decisions[0]):
+                if noPrecedingStepsPostMerge(currentChainSteps, chain_index):
+                    stepSeq.append(RecoFragmentsPool.retrieve(getEmptyMenuSequence, flags=None, name=seqName+"FS", mergeUsingFeature = False))
+                else:
+                    stepSeq.append(RecoFragmentsPool.retrieve(getEmptyMenuSequence, flags=None, name=seqName+'FS', mergeUsingFeature = True))
+                currentStepName = 'Empty' + chainDefList[chain_index].alignmentGroups[0]+'Align'+str(stepNumber)+'_'+new_stepDict['chainParts'][0]['multiplicity']+new_stepDict['signature']+'FS'
+            else:
+                stepSeq.append(RecoFragmentsPool.retrieve(getEmptyMenuSequence, flags=None, name=seqName))
+                currentStepName = 'Empty' + chainDefList[chain_index].alignmentGroups[0]+'Align'+str(stepNumber)+'_'+new_stepDict['chainParts'][0]['multiplicity']+new_stepDict['signature']
+
+            log.debug("[makeCombinedStep]  step %s,  empty sequence %s", currentStepName, seqName)
+
+            #stepNumber is indexed from 1, need the previous step indexed from 0, so do - 2
+            prev_step_mult = int(currentChainSteps[stepNumber-2].multiplicity[chain_index])
+            stepMult.append(prev_step_mult)
             # we need a chain dict here, use the one corresponding to this leg of the chain
-            stepDicts.append(deepcopy(chainDefList[chain_index].steps[-1].stepDicts[-1]))
+            oldLegName = new_stepDict['chainName']
+            if re.search('^leg[0-9]{3}_',oldLegName):
+                oldLegName = oldLegName[7:]
+            new_stepDict['chainName'] = legName(oldLegName,leg_counter)
+            stepDicts.append(new_stepDict)
+            leg_counter += 1
         else:
             # Standard step, append it to the combined step
-            log.debug("  step %s, multiplicity  = %s", step.name, str(step.multiplicity))
+            log.debug("[makeCombinedStep]  step %s, multiplicity  = %s", step.name, str(step.multiplicity))
             if len(step.sequences):
-                log.debug("      with sequences = %s", ' '.join(map(str, [seq.name for seq in step.sequences])))
+                log.debug("[makeCombinedStep]    with sequences = %s", ' '.join(map(str, [seq.name for seq in step.sequences])))
 
             # this function only works if the input chains are single-object chains (one menu seuqnce)
             if len(step.sequences) > 1:
-                log.error("More than one menu sequence found in combined chain!!")
+                log.debug("[makeCombinedStep] combining in an already combined chain")
+
             comboHypo = step.comboHypoCfg
             currentStepName = step.name
-            #remove redundant instances of StepN_
+            #remove redundant instances of StepN_ and merged_ (happens when merging already merged chains)
             if re.search('^Step[0-9]_',currentStepName):
                 currentStepName = currentStepName[6:]
-
-            if len(step.sequences):
-                seq = step.sequences[0]
-                stepSeq.append(seq)
+            if re.search('^merged_',currentStepName):
+                currentStepName = currentStepName[7:]
+            stepSeq.extend(step.sequences)
             # set the multiplicity of all the legs 
-            stepMult.append(sum(step.multiplicity))
+            if len(step.multiplicity) == 0:
+                stepMult.append(0)
+            else:
+                stepMult.extend(step.multiplicity)
             comboHypoTools.extend(step.comboToolConfs)
             # update the chain dict list for the combined step with the chain dict from this step
-            stepDicts += deepcopy(step.stepDicts)
+            log.debug('[makeCombinedStep] adding step dictionaries %s',step.stepDicts)
+            
+            for new_stepDict in deepcopy(step.stepDicts):
+                oldLegName = new_stepDict['chainName']
+                if re.search('^leg[0-9]{3}_',oldLegName):
+                    oldLegName = oldLegName[7:]
+                new_stepDict['chainName'] = legName(oldLegName,leg_counter)
+                log.debug("[makeCombinedStep] stepDict naming old: %s, new: %s", oldLegName, new_stepDict['chainName'])
+                stepDicts.append(new_stepDict)
+                leg_counter += 1
 
 
         # the step naming for combined chains needs to be revisted!!
         stepName += '_' + currentStepName
+        log.debug('[makeCombinedStep] current step name %s',stepName)
         # for merged steps, we need to update the name to add the leg name
-        stepDicts[-1]['chainName'] = legName(stepDicts[-1]['chainName'], chain_index)
         
     comboHypoTools = list(set(comboHypoTools))
     theChainStep = ChainStep(stepName, Sequences=stepSeq, multiplicity=stepMult, chainDicts=stepDicts, comboHypoCfg=comboHypo, comboToolConfs=comboHypoTools) 
-    log.info("Merged step: \n %s", theChainStep)
+    log.info("[makeCombinedStep] Merged step: \n %s", theChainStep)
   
     
     return theChainStep
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/GenerateMenuMT.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/GenerateMenuMT.py
index b4674557188ccdb593075f10ee510797d10c6bd1..deb952c1f7cf58c7827d1d8dade4e0a1acc55821 100755
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/GenerateMenuMT.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/GenerateMenuMT.py
@@ -307,7 +307,7 @@ class GenerateMenuMT(object, metaclass=Singleton):
                   alignedChainConfig = menuAlignment.single_align(chainDict, chainConfig)
                   TriggerConfigHLT.registerChain( chainDict, alignedChainConfig )
 
-              elif len(alignmentGroups) == 2:
+              elif len(alignmentGroups) >= 2:
                   alignedChainConfig = menuAlignment.multi_align(chainDict, chainConfig, lengthOfChainConfigs)
                   TriggerConfigHLT.registerChain( chainDict, alignedChainConfig )              
 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
index 1821f9279060881a01c797833c7af6d69d52d729..1e1dc9f132aa5745a19e1b4cb497c74251896e81 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
@@ -425,7 +425,7 @@ def setupMenu():
 #        ChainProp(name='HLT_e9_lhvloose_mu20_mu8noL1_L1MU20', l1SeedThresholds=['EM3','MU20','FSNOSEED'], stream=[PhysicsStream], groups=EgammaMuonGroup),
 #        ChainProp(name='HLT_g35_loose_mu15_mu2noL1_L1EM22VHI', l1SeedThresholds=['EM22VHI','MU6','FSNOSEED'], stream=[PhysicsStream], groups=EgammaMuonGroup),
         ChainProp(name='HLT_g35_tight_icalotight_mu18noL1_L1EM22VHI', l1SeedThresholds=['EM22VHI','FSNOSEED'], stream=[PhysicsStream], groups=EgammaMuonGroup),
-        #        ChainProp(name='HLT_g35_tight_icalotight_mu15noL1_mu2noL1_L1EM22VHI', l1SeedThresholds=['EM22VHI','FSNOSEED','FSNOSEED'], stream=[PhysicsStream], groups=EgammaMuonGroup),
+        ChainProp(name='HLT_g35_tight_icalotight_mu15noL1_mu2noL1_L1EM22VHI', l1SeedThresholds=['EM22VHI','FSNOSEED','FSNOSEED'], stream=[PhysicsStream], groups=EgammaMuonGroup),
     
     ]
     TriggerFlags.HeavyIonSlice.signatures  = TriggerFlags.HeavyIonSlice.signatures() + []
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py
index 023c5dcc0011f223216a66b2f2da763cb4965a92..95c607bf26690336021fccfffd89a60765f08ab1 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py
@@ -355,10 +355,11 @@ class EmptyMenuSequence(object):
     """ Class to emulate reco sequences with no Hypo"""
     """ By construction it has no Hypo;"""
     
-    def __init__(self, the_name):
+    def __init__(self, the_name, mergeUsingFeature = False):
         self._name = the_name
         Maker = CompFactory.InputMakerForRoI("IM"+the_name)
         Maker.RoITool = CompFactory.ViewCreatorInitialROITool()
+        Maker.mergeUsingFeature = mergeUsingFeature
         self._maker       = InputMakerNode( Alg = Maker )
         self._seed=''
         self._sequence    = Node( Alg = seqAND(the_name, [Maker]))
@@ -740,6 +741,9 @@ class CFSequence(object):
         the filter is connected only once (to avoid multiple DH links)
         """
         log.debug("CFSequence: connect Filter %s with %d menuSequences of step %s, using %d connections", compName(self.filter.Alg), len(self.step.sequences), self.step.name, len(connections))
+        log.debug("   --- sequences: ")
+        for seq in self.step.sequences:
+            log.debug(seq)
         if len(connections) == 0:
             log.error("ERROR, no filter outputs are set!")
 
@@ -789,19 +793,24 @@ class StepComponent(object):
 # next:  can we remove multiplicity array, if it can be retrieved from the ChainDict?
 class ChainStep(object):
     """Class to describe one step of a chain; if multiplicity is greater than 1, the step is combo/combined.  Set one multiplicity value per sequence"""
-    def __init__(self, name,  Sequences=[], multiplicity=[1], chainDicts=[], comboHypoCfg=ComboHypoCfg, comboToolConfs=[]):
+    def __init__(self, name,  Sequences=[], multiplicity=[1], chainDicts=[], comboHypoCfg=ComboHypoCfg, comboToolConfs=[], isEmpty = False):
 
         # include cases of emtpy steps with multiplicity = [] or multiplicity=[0,0,0///]
         if sum(multiplicity)==0:
             multiplicity=[]
         else:
             # sanity check on inputs, excluding empty steps
+            if len(chainDicts) != len(multiplicity):
+                log.error("[ChainStep] Sequences: %s",Sequences)
+                log.error("[ChainStep] chainDicts: %s",chainDicts)
+                log.error("[ChainStep] multiplicity: %s",multiplicity)
+                raise RuntimeError("[ChainStep] Tried to configure a ChainStep %s with %i multiplicity and %i dictionaries. These lists must have the same size" % (name, len(multiplicity), len(chainDicts)) )
+            
             if len(Sequences) != len(multiplicity):
+                log.error("[ChainStep] Sequences: %s",Sequences)
+                log.error("[ChainStep] multiplicities: %s",multiplicity)
                 raise RuntimeError("Tried to configure a ChainStep %s with %i Sequences and %i multiplicities. These lists must have the same size" % (name, len(Sequences), len(multiplicity)) )
-
-            if len(Sequences) != len(chainDicts):
-                raise RuntimeError("Tried to configure a ChainStep %s with %i Sequences and %i dictionaries. These lists must have the same size" % (name, len(Sequences), len(chainDicts)) )
-
+ 
         self.name = name
         self.sequences=Sequences
         self.multiplicity = multiplicity
@@ -809,7 +818,7 @@ class ChainStep(object):
         self.comboToolConfs=comboToolConfs
         self.stepDicts = chainDicts # one dict per leg
         self.isCombo=sum(multiplicity)>1
-        self.isEmpty=sum(multiplicity)==0
+        self.isEmpty=(sum(multiplicity)==0 or isEmpty)
         self.combo=None
         if self.isCombo:
             self.makeCombo()