diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/charm/d0_to_ksks.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/charm/d0_to_ksks.py
index e8209cc70adfc94857dabbd1bcd67ecab0045785..36c13d0de5055daa286f008598b2bf614771eb35 100644
--- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/charm/d0_to_ksks.py
+++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/charm/d0_to_ksks.py
@@ -20,14 +20,16 @@ TODO: the LLDD lines temporarily employ the decay descriptor D0 -> KL0 KS0
       the same particle with different selections.
 """
 
-from Moore.config import register_line_builder
+import Functors as F
 from GaudiKernel.SystemOfUnits import MeV, mm
-from Hlt2Conf.standard_particles import make_down_pions, make_long_pions
+from Moore.config import register_line_builder
 from Moore.lines import Hlt2Line
 from RecoConf.reconstruction_objects import make_pvs
+from Hlt2Conf.standard_particles import make_down_pions, make_long_pions
 from Hlt2Conf.algorithms import ParticleContainersMerger
+from Hlt2Conf.algorithms_thor import (ParticleCombiner, ParticleFilter,
+                                      require_all)
 from .prefilters import charm_prefilters
-from .builders import filter_particles, combine_2body
 from .particle_properties import _KS_M, _PION_M
 from .taggers import make_tagging_pions
 
@@ -37,119 +39,144 @@ from .taggers import make_tagging_pions
 
 
 def _make_long_pions_from_ks():
-    return filter_particles(make_long_pions(), pvs=make_pvs(), mipchi2_min=36.)
+    return ParticleFilter(
+        make_long_pions(),
+        F.FILTER(F.MINIPCHI2CUT(IPChi2Cut=36., Vertices=make_pvs())))
 
 
 def _make_down_pions_from_ks():
-    return filter_particles(
-        make_down_pions(), pvs=make_pvs(), pt_min=175 * MeV, p_min=3000 * MeV)
+    return ParticleFilter(
+        make_down_pions(),
+        F.FILTER(require_all(F.PT > 175 * MeV, F.P > 3000 * MeV)))
 
 
 def _make_ll_ks(descriptor="KS0 -> pi+ pi-"):
     """Returns maker for KS0 -> pi+ pi- constructed with two long pions."""
-    return combine_2body(
-        _make_long_pions_from_ks(),
-        _make_long_pions_from_ks(),
-        descriptor,
-        pvs=make_pvs(),
-        name="Charm_D0ToKsKs_LL",
-        comb_m_max=_KS_M + 50 * MeV,
-        comb_m_min=_KS_M - 50 * MeV,
-        comb_pt_min=450 * MeV,
-        m_max=_KS_M + 35 * MeV,
-        m_min=_KS_M - 35 * MeV,
-        vchi2dof_max=30,  # TODO: study if this cut can be tightened
-        z_min=-100 * mm,
-        z_max=500 * mm,
-        pt_min=500 * MeV)
+    return ParticleCombiner(
+        [_make_long_pions_from_ks(),
+         _make_long_pions_from_ks()],
+        DecayDescriptor=descriptor,
+        name="Charm_D0ToKsKs_Ks_LL",
+        CombinationCut=require_all(
+            F.MASS < _KS_M + 50 * MeV,
+            F.MASS > _KS_M - 50 * MeV,
+            F.PT > 450 * MeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < _KS_M + 35 * MeV,
+            F.MASS > _KS_M - 35 * MeV,
+            F.CHI2DOF < 30,  # TODO: study if this cut can be tightened
+            F.END_VZ > -100 * mm,
+            F.END_VZ < 500 * mm,
+            F.PT > 500 * MeV,
+        ),
+    )
 
 
 def _make_ll_ks_tight(descriptor="KS0 -> pi+ pi-"):
     """Returns maker for KS0 -> pi+ pi- constructed with two long pions with
     a tighter mass cut.
     """
-    return combine_2body(
-        _make_long_pions_from_ks(),
-        _make_long_pions_from_ks(),
-        descriptor,
-        pvs=make_pvs(),
-        name="Charm_D0ToKsKs_LL_Tight",
-        comb_m_max=_KS_M + 50 * MeV,
-        comb_m_min=_KS_M - 50 * MeV,
-        comb_pt_min=450 * MeV,
-        m_max=_KS_M + 30 * MeV,
-        m_min=_KS_M - 30 * MeV,
-        vchi2dof_max=30,  # TODO: study if this cut can be tightened
-        z_min=-100 * mm,
-        z_max=500 * mm,
-        pt_min=500 * MeV)
+    return ParticleCombiner(
+        [_make_long_pions_from_ks(),
+         _make_long_pions_from_ks()],
+        DecayDescriptor=descriptor,
+        name="Charm_D0ToKsKs_Ks_LL_Tight",
+        CombinationCut=require_all(
+            F.MASS < _KS_M + 50 * MeV,
+            F.MASS > _KS_M - 50 * MeV,
+            F.PT > 450 * MeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < _KS_M + 30 * MeV,
+            F.MASS > _KS_M - 30 * MeV,
+            F.CHI2DOF < 30,  # TODO: study if this cut can be tightened
+            F.END_VZ > -100 * mm,
+            F.END_VZ < 500 * mm,
+            F.PT > 500 * MeV,
+        ),
+    )
 
 
 def _make_dd_ks(descriptor="KS0 -> pi+ pi-"):
     """Returns maker for KS0 -> pi+ pi- constructed with two downstream pions.
     """
-    return combine_2body(
-        _make_down_pions_from_ks(),
-        _make_down_pions_from_ks(),
-        descriptor,
-        pvs=make_pvs(),
-        name="Charm_D0ToKsKs_DD",
-        comb_m_max=_KS_M + 80 * MeV,
-        comb_m_min=_KS_M - 80 * MeV,
-        comb_pt_min=450 * MeV,
-        m_max=_KS_M + 64 * MeV,
-        m_min=_KS_M - 64 * MeV,
-        vchi2dof_max=30,  # TODO: study if this cut can be tightened
-        z_min=300 * mm,
-        z_max=2275 * mm,
-        pt_min=500 * MeV)
+    return ParticleCombiner(
+        [_make_down_pions_from_ks(),
+         _make_down_pions_from_ks()],
+        DecayDescriptor=descriptor,
+        name="Charm_D0ToKsKs_Ks_DD",
+        CombinationCut=require_all(
+            F.MASS < _KS_M + 80 * MeV,
+            F.MASS > _KS_M - 80 * MeV,
+            F.PT > 450 * MeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < _KS_M + 64 * MeV,
+            F.MASS > _KS_M - 64 * MeV,
+            F.CHI2DOF < 30,  # TODO: study if this cut can be tightened
+            F.END_VZ > 300 * mm,
+            F.END_VZ < 2275 * mm,
+            F.PT > 500 * MeV,
+        ),
+    )
 
 
 def _make_dd_ks_tight(descriptor="KS0 -> pi+ pi-"):
     """Returns maker for KS0 -> pi+ pi- constructed with two downstream pions
     with a tighter mass cut.
     """
-    return combine_2body(
-        _make_down_pions_from_ks(),
-        _make_down_pions_from_ks(),
-        descriptor,
-        pvs=make_pvs(),
-        name="Charm_D0ToKsKs_DD_Tight",
-        comb_m_max=_KS_M + 80 * MeV,
-        comb_m_min=_KS_M - 80 * MeV,
-        comb_pt_min=450 * MeV,
-        m_max=_KS_M + 60 * MeV,
-        m_min=_KS_M - 60 * MeV,
-        vchi2dof_max=30,  # TODO: study if this cut can be tightened
-        z_min=300 * mm,
-        z_max=2275 * mm,
-        pt_min=500 * MeV)
-
-
-def _make_dstars(dzeros, descriptor):
+    return ParticleCombiner(
+        [_make_down_pions_from_ks(),
+         _make_down_pions_from_ks()],
+        DecayDescriptor=descriptor,
+        name="Charm_D0ToKsKs_Ks_DD_Tight",
+        CombinationCut=require_all(
+            F.MASS < _KS_M + 80 * MeV,
+            F.MASS > _KS_M - 80 * MeV,
+            F.PT > 450 * MeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < _KS_M + 60 * MeV,
+            F.MASS > _KS_M - 60 * MeV,
+            F.CHI2DOF < 30,  # TODO: study if this cut can be tightened
+            F.END_VZ > 300 * mm,
+            F.END_VZ < 2275 * mm,
+            F.PT > 500 * MeV,
+        ),
+    )
+
+
+def _make_dstars(dzeros, pions, descriptor):
     """Returns maker for D*+- -> D0 pi+-."""
-    return combine_2body(
-        dzeros,
-        make_tagging_pions(),
-        descriptor,
-        pvs=make_pvs(),
+    return ParticleCombiner(
+        [dzeros, pions],
+        DecayDescriptor=descriptor,
         name="Charm_D0ToKsKs_Dstars",
-        comb_delta_m_max=175 * MeV - _PION_M,
-        delta_m_max=170 * MeV - _PION_M,
-        vchi2dof_max=25)
+        CombinationCut=F.MASS - F.CHILD(1, F.MASS) - F.CHILD(2, F.MASS) <
+        175 * MeV - _PION_M,
+        CompositeCut=require_all(
+            F.MASS - F.CHILD(1, F.MASS) - F.CHILD(2, F.MASS) <
+            170 * MeV - _PION_M,
+            F.CHI2DOF < 25.,
+        ),
+    )
 
 
-def _make_dstars_tight(dzeros, descriptor):
+def _make_dstars_tight(dzeros, pions, descriptor):
     """Returns maker for D*+- -> D0 pi+- with a tighter mass cut."""
-    return combine_2body(
-        dzeros,
-        make_tagging_pions(),
-        descriptor,
-        pvs=make_pvs(),
+    return ParticleCombiner(
+        [dzeros, pions],
+        DecayDescriptor=descriptor,
         name="Charm_D0ToKsKs_DstarsTight",
-        comb_delta_m_max=170 * MeV - _PION_M,
-        delta_m_max=160 * MeV - _PION_M,
-        vchi2dof_max=25)
+        CombinationCut=F.MASS - F.CHILD(1, F.MASS) - F.CHILD(2, F.MASS) <
+        170 * MeV - _PION_M,
+        CompositeCut=require_all(
+            F.MASS - F.CHILD(1, F.MASS) - F.CHILD(2, F.MASS) <
+            160 * MeV - _PION_M,
+            F.CHI2DOF < 25,
+        ),
+    )
 
 
 #########################
@@ -162,138 +189,188 @@ all_lines = {}
 @register_line_builder(all_lines)
 def dst_to_d0pi_d0toksks_ll_line(
         name="Hlt2Charm_DstpToD0Pip_D0ToKsKs_LLLL_Line"):
-    dzeros = combine_2body(
-        _make_ll_ks(),
-        _make_ll_ks(),
-        "D0 -> KS0 KS0",
-        pvs=make_pvs(),
-        comb_m_min=1730 * MeV,
-        comb_m_max=2000 * MeV,
-        m_min=1775 * MeV,
-        m_max=1955 * MeV,
-        sum_pt_min=1500 * MeV,
-        bpvfdchi2_min=5,
-        vchi2dof_max=10,
-        bpvdira_min=0.9994)
-
-    dstarp = _make_dstars(dzeros, "D*(2010)+ -> D0 pi+")
-    dstarm = _make_dstars(dzeros, "D*(2010)- -> D0 pi-")
+    pvs = make_pvs()
+    kshorts = _make_ll_ks()
+    dzeros = ParticleCombiner(
+        [kshorts, kshorts],
+        DecayDescriptor="D0 -> KS0 KS0",
+        name="Charm_D0ToKsKs_D0ToKsKs_LLLL",
+        CombinationCut=require_all(
+            F.MASS > 1730 * MeV,
+            F.MASS < 2000 * MeV,
+            F.SUM(F.PT) > 1500 * MeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 1775 * MeV,
+            F.MASS < 1955 * MeV,
+            F.BPVFDCHI2(pvs) > 5,
+            F.CHI2DOF < 10,
+            F.BPVDIRA(pvs) > 0.9994,
+        ),
+    )
+
+    dstarp = _make_dstars(dzeros, make_tagging_pions(), "D*(2010)+ -> D0 pi+")
+    dstarm = _make_dstars(dzeros, make_tagging_pions(), "D*(2010)- -> D0 pi-")
     dstars = ParticleContainersMerger([dstarp, dstarm])
 
-    return Hlt2Line(name=name, algs=charm_prefilters() + [dstars])
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [kshorts, dzeros, dstars])
 
 
 @register_line_builder(all_lines)
 def dst_to_d0pi_d0toksks_ll_tightline(
         name="Hlt2Charm_DstpToD0Pip_D0ToKsKs_LLLL_Tight_Line"):
-    dzeros = combine_2body(
-        _make_ll_ks_tight(),
-        _make_ll_ks_tight(),
-        "D0 -> KS0 KS0",
-        pvs=make_pvs(),
-        comb_m_min=1730 * MeV,
-        comb_m_max=2000 * MeV,
-        m_min=1775 * MeV,
-        m_max=1955 * MeV,
-        sum_pt_min=1500 * MeV,
-        bpvfdchi2_min=5,
-        vchi2dof_max=10,
-        bpvdira_min=0.9994)
-
-    dstarp = _make_dstars_tight(dzeros, "D*(2010)+ -> D0 pi+")
-    dstarm = _make_dstars_tight(dzeros, "D*(2010)- -> D0 pi-")
+    pvs = make_pvs()
+    kshorts = _make_ll_ks_tight()
+    dzeros = ParticleCombiner(
+        [kshorts, kshorts],
+        DecayDescriptor="D0 -> KS0 KS0",
+        name="Charm_D0ToKsKs_D0ToKsKs_LLLL_Tight",
+        CombinationCut=require_all(
+            F.MASS > 1730 * MeV,
+            F.MASS < 2000 * MeV,
+            F.SUM(F.PT) > 1500 * MeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 1775 * MeV,
+            F.MASS < 1955 * MeV,
+            F.BPVFDCHI2(pvs) > 5,
+            F.CHI2DOF < 10,
+            F.BPVDIRA(pvs) > 0.9994,
+        ),
+    )
+
+    dstarp = _make_dstars_tight(dzeros, make_tagging_pions(),
+                                "D*(2010)+ -> D0 pi+")
+    dstarm = _make_dstars_tight(dzeros, make_tagging_pions(),
+                                "D*(2010)- -> D0 pi-")
     dstars = ParticleContainersMerger([dstarp, dstarm])
 
-    return Hlt2Line(name=name, algs=charm_prefilters() + [dstars])
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [kshorts, dzeros, dstars])
 
 
 @register_line_builder(all_lines)
 def dst_to_d0pi_d0toksks_ld_line(
         name="Hlt2Charm_DstpToD0Pip_D0ToKsKs_LLDD_Line"):
-    dzeros = combine_2body(
-        _make_dd_ks("KL0 -> pi+ pi-"),  # TODO
-        _make_ll_ks(),
-        "D0 -> KL0 KS0",  # TODO
-        pvs=make_pvs(),
-        comb_m_min=1730 * MeV,
-        comb_m_max=2000 * MeV,
-        m_min=1775 * MeV,
-        m_max=1955 * MeV,
-        sum_pt_min=1500 * MeV,
-        vchi2dof_max=10,
-        bpvdira_min=0.9994)
-
-    dstarp = _make_dstars(dzeros, "D*(2010)+ -> D0 pi+")
-    dstarm = _make_dstars(dzeros, "D*(2010)- -> D0 pi-")
+    pvs = make_pvs()
+    dd_kshorts = _make_dd_ks("KL0 -> pi+ pi-")  # TODO
+    ll_kshorts = _make_ll_ks()
+    dzeros = ParticleCombiner(
+        [dd_kshorts, ll_kshorts],
+        DecayDescriptor="D0 -> KL0 KS0",  # TODO
+        name="Charm_D0ToKsKs_D0ToKsKs_LLDD",
+        CombinationCut=require_all(
+            F.MASS > 1730 * MeV,
+            F.MASS < 2000 * MeV,
+            F.SUM(F.PT) > 1500 * MeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < 1955 * MeV,
+            F.MASS > 1775 * MeV,
+            F.CHI2DOF < 10,
+            F.BPVDIRA(pvs) > 0.9994,
+        ),
+    )
+
+    dstarp = _make_dstars(dzeros, make_tagging_pions(), "D*(2010)+ -> D0 pi+")
+    dstarm = _make_dstars(dzeros, make_tagging_pions(), "D*(2010)- -> D0 pi-")
     dstars = ParticleContainersMerger([dstarp, dstarm])
 
-    return Hlt2Line(name=name, algs=charm_prefilters() + [dstars])
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_kshorts, dzeros, dstars])
 
 
 @register_line_builder(all_lines)
 def dst_to_d0pi_d0toksks_ld_tightline(
         name="Hlt2Charm_DstpToD0Pip_D0ToKsKs_LLDD_Tight_Line"):
-    dzeros = combine_2body(
-        _make_dd_ks_tight("KL0 -> pi+ pi-"),  # TODO
-        _make_ll_ks_tight(),
-        "D0 -> KL0 KS0",  # TODO
-        pvs=make_pvs(),
-        comb_m_min=1730 * MeV,
-        comb_m_max=2000 * MeV,
-        m_min=1775 * MeV,
-        m_max=1955 * MeV,
-        sum_pt_min=1500 * MeV,
-        vchi2dof_max=10,
-        bpvdira_min=0.9994)
-
-    dstarp = _make_dstars_tight(dzeros, "D*(2010)+ -> D0 pi+")
-    dstarm = _make_dstars_tight(dzeros, "D*(2010)- -> D0 pi-")
+    pvs = make_pvs()
+    dd_kshorts = _make_dd_ks_tight("KL0 -> pi+ pi-")  # TODO
+    ll_kshorts = _make_ll_ks_tight()
+    dzeros = ParticleCombiner(
+        [dd_kshorts, ll_kshorts],
+        DecayDescriptor="D0 -> KL0 KS0",  # TODO
+        name="Charm_D0ToKsKs_D0ToKsKs_LLDD_Tight",
+        CombinationCut=require_all(
+            F.MASS > 1730 * MeV,
+            F.MASS < 2000 * MeV,
+            F.SUM(F.PT) > 1500 * MeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < 1955 * MeV,
+            F.MASS > 1775 * MeV,
+            F.CHI2DOF < 10,
+            F.BPVDIRA(pvs) > 0.9994,
+        ),
+    )
+
+    dstarp = _make_dstars_tight(dzeros, make_tagging_pions(),
+                                "D*(2010)+ -> D0 pi+")
+    dstarm = _make_dstars_tight(dzeros, make_tagging_pions(),
+                                "D*(2010)- -> D0 pi-")
     dstars = ParticleContainersMerger([dstarp, dstarm])
 
-    return Hlt2Line(name=name, algs=charm_prefilters() + [dstars])
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_kshorts, dzeros, dstars])
 
 
 @register_line_builder(all_lines)
 def dst_to_d0pi_d0toksks_dd_line(
         name="Hlt2Charm_DstpToD0Pip_D0ToKsKs_DDDD_Line"):
-    dzeros = combine_2body(
-        _make_dd_ks(),
-        _make_dd_ks(),
-        "D0 -> KS0 KS0",
-        pvs=make_pvs(),
-        comb_m_min=1730 * MeV,
-        comb_m_max=2000 * MeV,
-        m_min=1775 * MeV,
-        m_max=1955 * MeV,
-        sum_pt_min=1500 * MeV,
-        vchi2dof_max=10,
-        bpvdira_min=0.9994)
-
-    dstarp = _make_dstars(dzeros, "D*(2010)+ -> D0 pi+")
-    dstarm = _make_dstars(dzeros, "D*(2010)- -> D0 pi-")
+    pvs = make_pvs()
+    dd_kshorts = _make_dd_ks()
+    dzeros = ParticleCombiner(
+        [dd_kshorts, dd_kshorts],
+        DecayDescriptor="D0 -> KS0 KS0",
+        name="Charm_D0ToKsKs_D0ToKsKs_DDDD",
+        CombinationCut=require_all(
+            F.MASS > 1730 * MeV,
+            F.MASS < 2000 * MeV,
+            F.SUM(F.PT) > 1500 * MeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < 1955 * MeV,
+            F.MASS > 1775 * MeV,
+            F.CHI2DOF < 10,
+            F.BPVDIRA(pvs) > 0.9994,
+        ),
+    )
+
+    dstarp = _make_dstars(dzeros, make_tagging_pions(), "D*(2010)+ -> D0 pi+")
+    dstarm = _make_dstars(dzeros, make_tagging_pions(), "D*(2010)- -> D0 pi-")
     dstars = ParticleContainersMerger([dstarp, dstarm])
 
-    return Hlt2Line(name=name, algs=charm_prefilters() + [dstars])
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_kshorts, dzeros, dstars])
 
 
 @register_line_builder(all_lines)
 def dst_to_d0pi_d0toksks_dd_tightline(
         name="Hlt2Charm_DstpToD0Pip_D0ToKsKs_DDDD_Tight_Line"):
-    dzeros = combine_2body(
-        _make_dd_ks_tight(),
-        _make_dd_ks_tight(),
-        "D0 -> KS0 KS0",
-        pvs=make_pvs(),
-        comb_m_min=1730 * MeV,
-        comb_m_max=2000 * MeV,
-        m_min=1775 * MeV,
-        m_max=1955 * MeV,
-        sum_pt_min=1500 * MeV,
-        vchi2dof_max=10,
-        bpvdira_min=0.9994)
-
-    dstarp = _make_dstars_tight(dzeros, "D*(2010)+ -> D0 pi+")
-    dstarm = _make_dstars_tight(dzeros, "D*(2010)- -> D0 pi-")
+    pvs = make_pvs()
+    dd_kshorts = _make_dd_ks_tight()
+    dzeros = ParticleCombiner(
+        [dd_kshorts, dd_kshorts],
+        DecayDescriptor="D0 -> KS0 KS0",
+        name="Charm_D0ToKsKs_D0ToKsKs_DDDD_Tight",
+        CombinationCut=require_all(
+            F.MASS > 1730 * MeV,
+            F.MASS < 2000 * MeV,
+            F.SUM(F.PT) > 1500 * MeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < 1955 * MeV,
+            F.MASS > 1775 * MeV,
+            F.CHI2DOF < 10,
+            F.BPVDIRA(pvs) > 0.9994,
+        ),
+    )
+
+    dstarp = _make_dstars_tight(dzeros, make_tagging_pions(),
+                                "D*(2010)+ -> D0 pi+")
+    dstarm = _make_dstars_tight(dzeros, make_tagging_pions(),
+                                "D*(2010)- -> D0 pi-")
     dstars = ParticleContainersMerger([dstarp, dstarm])
 
-    return Hlt2Line(name=name, algs=charm_prefilters() + [dstars])
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_kshorts, dzeros, dstars])