Index: src/Actions/AtomAction/SaturateAction.cpp
===================================================================
--- src/Actions/AtomAction/SaturateAction.cpp	(revision 64cafb2cea4919e67a64a683c7bfb1682edd240f)
+++ src/Actions/AtomAction/SaturateAction.cpp	(revision cdac1dec22b8e27ee050f890677c8946a0ac6c71)
@@ -75,25 +75,58 @@
     }
     ASSERT( mol != NULL,
-        "ChangeElementAction::performCall() - mol is still NULL." );
+        "AtomSaturateAction::performCall() - mol is still NULL." );
 
-//    // add the hydrogens
-//    const Vector AtomsPosition = _atom->getPosition();
-//    double typical_distance = _atom->getType()->getHBondDistance(0);
-//    if (typical_distance == -1.)
-//      typical_distance = 1.;
-//    SphericalPointDistribution PointSphere(typical_distance);
-//    PointSphere.initSelf(_atom->getType()->getNoValenceOrbitals());
-//    for (SphericalPointDistribution::Polygon_t::const_iterator iter = PointSphere.points.begin();
-//        iter != PointSphere.points.end(); ++iter) {
-//      // for every Vector add a point relative to atom's position
-//      atom * hydrogenAtom = World::getInstance().createAtom();
-//      hydrogenAtom->setType(hydrogen);
-//      hydrogenAtom->setPosition(AtomsPosition + *iter);
-//      mol->AddAtom(hydrogenAtom);
-//      // add bond
-//      _atom->addBond(WorldTime::getTime(), hydrogenAtom);
-//      // mark down for undo state
-//      addedHydrogens.push_back(AtomicInfo(*(hydrogenAtom)));
-//    }
+    // radius of polygon on sphere
+    double typical_distance = _atom->getType()->getHBondDistance(0);
+    if (typical_distance == -1.)
+      typical_distance = 1.;
+
+    // check for any bonds and get vacant positions
+    SphericalPointDistribution::Polygon_t vacant_positions;
+    const BondList& ListOfBonds = _atom->getListOfBonds();
+    SphericalPointDistribution PointSphere(typical_distance);
+    if (ListOfBonds.size() == 0) {
+      vacant_positions = PointSphere.getSimplePolygon(_atom->getType()->getNoValenceOrbitals());
+      LOG(3, "DEBUG: Using ideal positions as " << vacant_positions);
+    } else {
+      // get ideal polygon and currently occupied positions
+      const SphericalPointDistribution::Polygon_t ideal_positions =
+          PointSphere.getSimplePolygon(_atom->getType()->getNoValenceOrbitals());
+      LOG(3, "DEBUG: ideal positions are " << ideal_positions);
+      SphericalPointDistribution::Polygon_t current_positions;
+      for (BondList::const_iterator bonditer = ListOfBonds.begin();
+          bonditer != ListOfBonds.end(); ++bonditer) {
+        const Vector position =
+            (*bonditer)->GetOtherAtom(_atom)->getPosition().getVectorToPoint(_atom->getPosition());
+        current_positions.push_back((1./position.Norm())*position);
+      }
+      LOG(3, "DEBUG: current occupied positions are " << current_positions);
+
+      // find the best matching rotated polygon
+      vacant_positions = SphericalPointDistribution::matchSphericalPointDistributions(
+          current_positions,
+          ideal_positions);
+      LOG(3, "DEBUG: Resulting vacant positions are " << vacant_positions);
+
+      // scale vacant positions to typical_distance
+      std::for_each(
+          vacant_positions.begin(), vacant_positions.end(),
+          boost::bind(&Vector::Scale, _1, boost::cref(typical_distance)));
+    }
+
+    // add the hydrogens
+    const Vector AtomsPosition = _atom->getPosition();
+    for (SphericalPointDistribution::Polygon_t::const_iterator iter = vacant_positions.begin();
+        iter != vacant_positions.end(); ++iter) {
+      // for every Vector add a point relative to atom's position
+      atom * hydrogenAtom = World::getInstance().createAtom();
+      hydrogenAtom->setType(hydrogen);
+      hydrogenAtom->setPosition(AtomsPosition + *iter);
+      mol->AddAtom(hydrogenAtom);
+      // add bond
+      _atom->addBond(WorldTime::getTime(), hydrogenAtom);
+      // mark down for undo state
+      addedHydrogens.push_back(AtomicInfo(*(hydrogenAtom)));
+    }
   }
 
