diff --git a/modules/mol/mm/src/heuristic_block_modifiers.cc b/modules/mol/mm/src/heuristic_block_modifiers.cc
index 6576376f95bfd553a9d644965c3aad9183ef553f..9d415088a4c688996284262994889ac44f4e936d 100644
--- a/modules/mol/mm/src/heuristic_block_modifiers.cc
+++ b/modules/mol/mm/src/heuristic_block_modifiers.cc
@@ -10,125 +10,159 @@ void HeuristicHydrogenConstructor::ApplyOnBuildingBlock(BuildingBlockPtr p){
   //we assume, that the hydrogens are already correct in the building block...
 }
 
-void HeuristicHydrogenConstructor::ApplyOnResidue(ost::mol::ResidueHandle& res, ost::mol::XCSEditor& edi){
-  if(!res.IsValid()) return;
-  std::vector<String> atoms=building_block_->GetAtoms();
-  std::vector<Real> masses=building_block_->GetMasses();
-  std::vector<MMInteractionPtr>  bonds=building_block_->GetBonds();
-  //int natoms=atoms.size();
-  std::vector<Real>::iterator mass;
-  std::vector<String>::iterator aname;
-  //We loop through all atoms and for each one seek which atoms it's bonded to
-  //If there are hydrogens with missing positions, we reconstruct them
-  for( aname=atoms.begin(), mass=masses.begin(); aname!=atoms.end(); aname++ , mass++){
-    AtomHandle a=res.FindAtom(*aname);
-    if(!a.IsValid() || *mass<1.9) continue;// if mass is smaller than 1.9 then it is a hydrogen
-    std::cout<< "checking " << *aname << "\n";
-    //Find all the bonds containing atom a
-    std::vector<MMInteractionPtr> bond_list;
-    std::vector<String> antecedent_names,hydrogen_names;
-    AtomHandleList antecedents;
-    String aname_new;
-    for (std::vector<MMInteractionPtr>::iterator bond=bonds.begin() ; bond!=bonds.end() ; bond++){
-      std::vector<String> names=(*bond)->GetNames();
-      if (*aname!=names[0] && *aname!=names[1]) continue;
-      if (*aname==names[0]) aname_new=names[1];
-      else aname_new=names[0];
-      int aindex=std::distance(atoms.begin(),std::find(atoms.begin(),atoms.end(),aname_new));
-      AtomHandle anew=res.FindAtom(aname_new);
+HeuristicHydrogenConstructor::HeuristicHydrogenConstructor(BuildingBlockPtr block){
+  std::vector<String> atom_names = block->GetAtoms();
+  std::vector<MMInteractionPtr> bonds = block->GetBonds();
+
+  for(std::vector<String>::iterator aname = atom_names.begin(); 
+      aname != atom_names.end(); ++aname){
+    if((*aname)[0] == 'H') continue; //it's a hydrogen
+
+    std::vector<String> antecedent_names, hydrogen_names;
+    String aname_other;
+
+    for (std::vector<MMInteractionPtr>::iterator i = bonds.begin() ; 
+         i != bonds.end(); ++i){
+
+      std::vector<String> bond_names=(*i)->GetNames();
+
+      if (*aname!=bond_names[0] && *aname!=bond_names[1]) continue;//bond has nothing to do
+                                                                   //with current atom
+      if (*aname==bond_names[0]) aname_other=bond_names[1];
+      else aname_other=bond_names[0]; 
+
       //check whether it's a hydrogen
-      if (masses[aindex]>1.9) {
-        if (!anew.IsValid()){
-          std::cout << "invalid heavy atom" << aname_new << "stopping reconstruction" << std::endl;
-          return;
-        }
-        antecedents.push_back(anew);
-        antecedent_names.push_back(aname_new);
+      if (aname_other[0] == 'H') {
+        hydrogen_names.push_back(aname_other);
       }
-      else if (anew.IsValid()){
-        antecedents.push_back(anew);
-        antecedent_names.push_back(aname_new);        
+      else{
+        antecedent_names.push_back(aname_other);
       }
-      else {
-        hydrogen_names.push_back(aname_new);
-        bond_list.push_back(*bond);
-        }
+    }
+    if(!hydrogen_names.empty()){
+      if(antecedent_names.empty()){
+        std::stringstream ss;
+        ss << "Can only reconstruct hydrogens when at least one ";
+        ss << "antecedent atom is present!";
+        throw ost::Error(ss.str());
       }
-    if (hydrogen_names.size()==0){
-      std::cout << "Nothing to reconstruct around " << *aname << std::endl;
-      continue;
+      if(antecedent_names.size() + hydrogen_names.size() > 4){
+        std::stringstream ss;
+        ss << "Antecedent and hydrogen atoms sum up to more than four ";
+        ss << "around anchor atom "<<*aname<<". This is not possible with ";
+        ss << "the used block modifier implementation!";
+        throw ost::Error(ss.str());
+      }
+      anchor_atom_names_.push_back(*aname);
+      antecedent_names_.push_back(antecedent_names);
+      hydrogen_names_.push_back(hydrogen_names);
     }
-    //Now we treat the different cases
-    std::cout<< "number of antecedents is " << antecedents.size() << " and number of hydrogens "<< hydrogen_names.size() << std::endl;
+  } 
+}
+
+void HeuristicHydrogenConstructor::ApplyOnResidue(ost::mol::ResidueHandle& res, ost::mol::XCSEditor& edi){
+
+  if(!res.IsValid()) return;
+
+  for(uint i = 0; i < anchor_atom_names_.size(); ++i){
+
+    ost::mol::AtomHandle anchor_atom = res.FindAtom(anchor_atom_names_[i]);
+    if(!anchor_atom.IsValid()){
+      std::stringstream ss;
+      ss << "Anchor atom of name " << anchor_atom_names_[i];
+      ss << " cannot be found in residue "<<res.GetQualifiedName()<<"!";
+      throw ost::Error(ss.str());
+    }
+
+    geom::Vec3List antecedent_positions;
+    for(std::vector<String>::iterator j = antecedent_names_[i].begin();
+        j != antecedent_names_[i].end(); ++j){
+      ost::mol::AtomHandle at = res.FindAtom(*j);
+      if(!at.IsValid()){
+        std::stringstream ss;
+        ss << "Cannot find required antecedent atom of name "<<*j;
+        ss << " in residue "<<res.GetQualifiedName()<<"!";
+        throw ost::Error(ss.str());
+      }
+      antecedent_positions.push_back(at.GetPos());
+    }
+
     Real bond_length=1.08;
     String ele(1,'H');
-    geom::Vec3List vl=geom::Vec3List();
-    for (AtomHandleList::iterator aa=antecedents.begin(),e=antecedents.end();aa!=e;aa++) vl.push_back((*aa).GetPos());
-    geom::Vec3 antecedents_cm=vl.GetCenter();
-    geom::Vec3 pa=a.GetPos();
+    geom::Vec3 antecedents_cm=antecedent_positions.GetCenter();
+    geom::Vec3 pa=anchor_atom.GetPos();
     geom::Vec3 v=geom::Normalize(pa-antecedents_cm);
     geom::Vec3 n=geom::OrthogonalVector(v),direction=geom::Vec3(),hpos=geom::Vec3();
     geom::Mat3 R=geom::Mat3();
     Real bond_angle;
     AtomHandle ha=mol::AtomHandle();
-    if (antecedents.size()==0) continue; // We do not reconstruc water hydrogens
-    switch (hydrogen_names.size()){
+
+    switch (hydrogen_names_[i].size()){
       case 1:{  
-        if (antecedents.size()==1){
+        if (antecedent_names_[i].size()==1){
           bond_angle=0.4*M_PI;
-          }
+        }
         else {
           bond_angle=0.0;
-          }
-        //AtomHandle aa=res.FindAtom(antecedents[0]);
+        }
         R=geom::AxisRotation(n,bond_angle);
         direction=R*v;
         hpos=pa+bond_length*direction;
-        ha=edi.InsertAtom(res,hydrogen_names[0],hpos,ele);
-        edi.Connect(a,ha);
+        ha = res.FindAtom(hydrogen_names_[i][0]);
+        if(!ha.IsValid()) ha=edi.InsertAtom(res,hydrogen_names_[i][0],hpos,ele);
+        else edi.SetAtomPos(ha,hpos);
         break;
-        }
+      }
       case 2:{
-        if (antecedents.size()==1){
+        if (antecedent_names_[i].size()==1){
           bond_angle=M_PI/3.;
-          }
+        }
         else {
-          bond_angle=0.4*M_PI;
-          n=geom::Normalize(antecedents[0].GetPos()-antecedents[1].GetPos());
-          }
+          bond_angle = 0.4*M_PI;
+          n=geom::Normalize(antecedent_positions[0]-antecedent_positions[1]);
+        }
+
         R=geom::AxisRotation(n,bond_angle);
         direction=R*v;
         hpos=pa+bond_length*direction;
-        ha=edi.InsertAtom(res,hydrogen_names[0],hpos,ele);
-        edi.Connect(a,ha);
+        ha = res.FindAtom(hydrogen_names_[i][0]);
+        if(!ha.IsValid()) ha=edi.InsertAtom(res,hydrogen_names_[i][0],hpos,ele);
+        else edi.SetAtomPos(ha,hpos);
+
         R=geom::AxisRotation(v,M_PI);
         direction=R*direction;
         hpos=pa+bond_length*direction;
-        ha=edi.InsertAtom(res,hydrogen_names[1],hpos,ele);
-        edi.Connect(a,ha);
+        ha = res.FindAtom(hydrogen_names_[i][1]);
+        if(!ha.IsValid()) ha=edi.InsertAtom(res,hydrogen_names_[i][1],hpos,ele);
+        else edi.SetAtomPos(ha,hpos);
+
         break;
-        }
+      }
       case 3:{
         bond_angle=0.4*M_PI;
+
         R=geom::AxisRotation(n,bond_angle);
         direction=R*v;
         hpos=pa+bond_length*direction;
-        edi.InsertAtom(res,hydrogen_names[0],hpos,ele);
+        ha = res.FindAtom(hydrogen_names_[i][0]);
+        if(!ha.IsValid()) ha=edi.InsertAtom(res,hydrogen_names_[i][0],hpos,ele);
+        else edi.SetAtomPos(ha,hpos);
+
         R=geom::AxisRotation(v,2.*M_PI/3.);
         direction=R*direction;
         hpos=pa+bond_length*direction;
-        ha=edi.InsertAtom(res,hydrogen_names[1],hpos,ele);
-        edi.Connect(a,ha);
+        ha = res.FindAtom(hydrogen_names_[i][1]);
+        if(!ha.IsValid()) ha=edi.InsertAtom(res,hydrogen_names_[i][1],hpos,ele);
+        else edi.SetAtomPos(ha,hpos);
+
         direction=R*direction;
         hpos=pa+bond_length*direction;
-        ha=edi.InsertAtom(res,hydrogen_names[2],hpos,ele);
-        edi.Connect(a,ha);
+        ha = res.FindAtom(hydrogen_names_[i][2]);
+        if(!ha.IsValid()) ha=edi.InsertAtom(res,hydrogen_names_[i][2],hpos,ele);
+        else edi.SetAtomPos(ha,hpos);
         break;
-        }
-      default :{
-        std::cout << "number of hydrogens is " << hydrogen_names.size() << " for "<< *aname <<" not reconstructing them." <<std::endl;
-        }
       }
+    }
   }
 }
 
diff --git a/modules/mol/mm/src/heuristic_block_modifiers.hh b/modules/mol/mm/src/heuristic_block_modifiers.hh
index a8527752802e293aa18a10c92beb8cfbb9aa7f17..457a2d85d3bbec42f1b536e27ef286cf22b360c0 100644
--- a/modules/mol/mm/src/heuristic_block_modifiers.hh
+++ b/modules/mol/mm/src/heuristic_block_modifiers.hh
@@ -30,7 +30,7 @@ class HeuristicHydrogenConstructor : public HydrogenConstructor{
 
 public:
 
-  HeuristicHydrogenConstructor( BuildingBlockPtr block): building_block_(block) { }
+  HeuristicHydrogenConstructor(BuildingBlockPtr block);
 
   virtual void ApplyOnBuildingBlock(BuildingBlockPtr);
 
@@ -44,13 +44,68 @@ public:
   
   void Serialize(DS& ds){
 
+    if(ds.IsSource()){
+      int num_anchor_atoms = 0;
+      int num_antecendents = 0;
+      int num_hydrogens = 0;
+      String loaded_string;
+
+      ds & num_anchor_atoms;
+
+      for(int i = 0; i < num_anchor_atoms; ++i){
+        ds & num_antecendents;
+        ds & num_hydrogens;
+
+        ds & loaded_string;
+        anchor_atom_names_.push_back(loaded_string);
+
+        antecedent_names_.push_back(std::vector<String>());
+        for(uint j = 0; j < num_antecendents; ++j){
+          ds & loaded_string;
+          antecedent_names_[i].push_back(loaded_string);
+        }
+
+        hydrogen_names_.push_back(std::vector<String>());
+        for(uint j = 0; j < num_hydrogens; ++j){
+          ds & loaded_string;
+          hydrogen_names_[i].push_back(loaded_string);
+        }
+      }
+    }
+    else{
+      int num_anchor_atoms = anchor_atom_names_.size();
+      int num_antecendents = 0;
+      int num_hydrogens = 0;
+
+      ds & num_anchor_atoms;
+
+      for(uint i = 0; i < num_anchor_atoms; ++i){
+
+        num_antecendents = antecedent_names_[i].size();
+        num_hydrogens = hydrogen_names_[i].size();
+        ds & num_antecendents;
+        ds & num_hydrogens;
+        ds & anchor_atom_names_[i];
+
+
+        for(std::vector<String>::iterator j = antecedent_names_[i].begin();
+            j != antecedent_names_[i].end(); ++j){
+          ds & *j;
+        }
+
+        for(std::vector<String>::iterator j = hydrogen_names_[i].begin();
+            j != hydrogen_names_[i].end(); ++j){
+          ds & *j;
+        }
+      }
+
+    }
   }
 
 private:
-  BuildingBlockPtr building_block_;
+  std::vector<String> anchor_atom_names_;
+  std::vector<std::vector<String> > antecedent_names_;
   std::vector<std::vector<String> > hydrogen_names_;
-  std::vector<std::vector<String> > anchor_atom_names_;
-  
 };