Index: src/Atom/CopyAtoms/CopyAtomsInterface.hpp
===================================================================
--- src/Atom/CopyAtoms/CopyAtomsInterface.hpp	(revision 9e1d01415f93be121370a5079d969cb2451872f0)
+++ src/Atom/CopyAtoms/CopyAtomsInterface.hpp	(revision 9e1d01415f93be121370a5079d969cb2451872f0)
@@ -0,0 +1,90 @@
+/*
+ * CopyAtomsInterface.hpp
+ *
+ *  Created on: Mar 17, 2012
+ *      Author: heber
+ */
+
+#ifndef COPYATOMSINTERFACE_HPP_
+#define COPYATOMSINTERFACE_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <vector>
+
+class atom;
+class CopyAtomsInterfaceTest;
+
+/** This class defines a general interface for functors that copy a Vector of Atoms.
+ *
+ * I.e. we can implement here multiple ways of copying a vector of atoms, with or
+ * without bonds, with or without saturation, ...
+ *
+ */
+class CopyAtomsInterface
+{
+  /// grant unit test access
+  friend class CopyAtomsInterfaceTest;
+public:
+  typedef std::vector<atom*> AtomVector;
+  typedef std::vector<const atom*> ConstAtomVector;
+
+  /** Constructor.
+   *
+   */
+  CopyAtomsInterface()
+  {}
+
+  /** Destructor.
+   *
+   */
+  virtual ~CopyAtomsInterface()
+  {}
+
+  /** Function that just stores given atoms in CopyAtomsInterface::OriginalAtoms.
+   *
+   * We reset ourselves.
+   * We initialize CopyAtomsInterface::CopiedAtoms with the size of \a _atoms
+   * but NULL entities.
+   *
+   * \note If you override this function, always first call the implementation
+   * in the original class, then continue with implementation in derived class.
+   *
+   * @param _atoms atoms to copy
+   */
+  virtual void operator()(const AtomVector &_atoms)
+  {
+    // clear ourselves
+    reset();
+    CopiedAtoms.resize(_atoms.size(), NULL);
+  }
+
+  /** Getter for CopiedAtoms to allow outside transformations.
+   *
+   * @return CopiedAtoms
+   */
+  AtomVector& getCopiedAtoms() {
+    return CopiedAtoms;
+  }
+
+private:
+  /// forbid copy cstor as it may change class behavior
+  CopyAtomsInterface(const CopyAtomsInterface &);
+
+  /** Internal helper to reset all member variables.
+   *
+   */
+  void reset()
+  {
+    CopiedAtoms.clear();
+  }
+
+protected:
+  //!> set of copied atoms, this is to allow later transformations in derived classes
+  AtomVector CopiedAtoms;
+};
+
+#endif /* COPYATOMSINTERFACE_HPP_ */
Index: src/Atom/CopyAtoms/CopyAtoms_SaturateDanglingBonds.cpp
===================================================================
--- src/Atom/CopyAtoms/CopyAtoms_SaturateDanglingBonds.cpp	(revision 9e1d01415f93be121370a5079d969cb2451872f0)
+++ src/Atom/CopyAtoms/CopyAtoms_SaturateDanglingBonds.cpp	(revision 9e1d01415f93be121370a5079d969cb2451872f0)
@@ -0,0 +1,34 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * CopyAtoms_SaturateDanglingBonds.cpp
+ *
+ *  Created on: Mar 17, 2012
+ *      Author: heber
+ */
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "CopyAtoms_SaturateDanglingBonds.hpp"
+
+#include "CodePatterns/Assert.hpp"
+
+template <class BondCopier>
+void CopyAtoms_SaturateDanglingBonds<BondCopier>::operator()(const AtomVector &_atoms)
+{
+  ASSERT( 0,
+      "CopyAtoms_SaturateDanglingBonds::operator() -  not implemented yet, see molecule::AddHydrogenReplacementAtom.");
+
+  BondCopier::operator()(_atoms);
+}
Index: src/Atom/CopyAtoms/CopyAtoms_SaturateDanglingBonds.hpp
===================================================================
--- src/Atom/CopyAtoms/CopyAtoms_SaturateDanglingBonds.hpp	(revision 9e1d01415f93be121370a5079d969cb2451872f0)
+++ src/Atom/CopyAtoms/CopyAtoms_SaturateDanglingBonds.hpp	(revision 9e1d01415f93be121370a5079d969cb2451872f0)
@@ -0,0 +1,43 @@
+/*
+ * CopyAtoms_SaturateDanglingBonds.hpp
+ *
+ *  Created on: Mar 17, 2012
+ *      Author: heber
+ */
+
+#ifndef COPYATOMS_SATURATEDANGLINGBONDS_HPP_
+#define COPYATOMS_SATURATEDANGLINGBONDS_HPP_
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Atom/CopyAtoms/CopyAtomsInterface.hpp"
+
+/** This class extends the implementation of CopyAtoms_withBonds to not only
+ * copy the atoms and their bonds but also to saturate any dangling ones with
+ * additional hydrogen atoms.
+ *
+ */
+template <class BondCopier>
+class CopyAtoms_SaturateDanglingBonds : public BondCopier, virtual public CopyAtomsInterface
+{
+public:
+  /** Destructor.
+   *
+   */
+  virtual ~CopyAtoms_SaturateDanglingBonds()
+  {}
+
+  /** Function to saturate any dangling bonds with additional hydrogen.
+   *
+   * @param _atoms vector of atoms to copy
+   */
+  virtual void operator()(const AtomVector &_atoms);
+};
+
+
+
+#endif /* COPYATOMS_SATURATEDANGLINGBONDS_HPP_ */
Index: src/Atom/CopyAtoms/CopyAtoms_Simple.hpp
===================================================================
--- src/Atom/CopyAtoms/CopyAtoms_Simple.hpp	(revision 9e1d01415f93be121370a5079d969cb2451872f0)
+++ src/Atom/CopyAtoms/CopyAtoms_Simple.hpp	(revision 9e1d01415f93be121370a5079d969cb2451872f0)
@@ -0,0 +1,51 @@
+/*
+ * CopyAtoms_Simple.hpp
+ *
+ *  Created on: Mar 17, 2012
+ *      Author: heber
+ */
+
+#ifndef COPYATOMS_SIMPLE_HPP_
+#define COPYATOMS_SIMPLE_HPP_
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <algorithm>
+#include <boost/bind.hpp>
+
+#include "Atom/atom.hpp"
+#include "Atom/CopyAtoms/CopyAtomsInterface.hpp"
+
+/** This is an implementation of CopyAtomsInterface that simply copies each atom.
+ *
+ */
+class CopyAtoms_Simple : public CopyAtomsInterface
+{
+public:
+  /** Destructor.
+   *
+   */
+  virtual ~CopyAtoms_Simple()
+  {}
+
+  /** This operator simply copies all the atoms in \a CopyAtomsInterface::atoms and
+   * translates them to the same position.
+   *
+   * @param _atoms atoms to copy
+   */
+  virtual void operator()(const AtomVector &_atoms)
+  {
+    CopyAtomsInterface::operator()(_atoms);
+
+    // copy each atom
+    std::transform(_atoms.begin(), _atoms.end(), CopiedAtoms.begin(),
+        boost::bind(&atom::clone, _1) );
+  }
+};
+
+
+#endif /* COPYATOMS_SIMPLE_HPP_ */
Index: src/Atom/CopyAtoms/CopyAtoms_withBonds.cpp
===================================================================
--- src/Atom/CopyAtoms/CopyAtoms_withBonds.cpp	(revision 9e1d01415f93be121370a5079d969cb2451872f0)
+++ src/Atom/CopyAtoms/CopyAtoms_withBonds.cpp	(revision 9e1d01415f93be121370a5079d969cb2451872f0)
@@ -0,0 +1,81 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * CopyAtoms_withBonds.cpp
+ *
+ *  Created on: Mar 17, 2012
+ *      Author: heber
+ */
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "CopyAtoms_withBonds.hpp"
+
+#include "Bond/bond.hpp"
+#include "CodePatterns/Assert.hpp"
+#include "CodePatterns/Log.hpp"
+#include "WorldTime.hpp"
+
+void CopyAtoms_withBonds::operator()(const AtomVector &_atoms)
+{
+  CopyAtoms_Simple::operator()(_atoms);
+
+  // create LookupMap
+  LookupMap_t LookupMap = createLookup(_atoms);
+  ASSERT( LookupMap.size() == _atoms.size(),
+      "CopyAtoms_withBonds::operator() - Lookupmap and original AtomVectors differ in size: "
+      +toString(LookupMap.size())+" != "+toString(_atoms.size())+".");
+  ASSERT( LookupMap.size() == CopiedAtoms.size(),
+      "CopyAtoms_withBonds::operator() - Lookupmap and copied AtomVectors differ in size.: "
+      +toString(LookupMap.size())+" != "+toString(CopiedAtoms.size())+".");
+
+  // then go through the bonds of each original atom
+  for (AtomVector::const_iterator original_iter = _atoms.begin();
+      original_iter != _atoms.end(); ++original_iter) {
+    const BondList ListOfBonds = (*original_iter)->getListOfBonds();
+    for(BondList::const_iterator iter = ListOfBonds.begin(); iter != ListOfBonds.end(); ++iter) {
+      // check both bond partners have been copied
+      const bond * const Binder = *iter;
+      if (*original_iter == Binder->leftatom) {
+        LookupMap_t::const_iterator leftiter = LookupMap.find(Binder->leftatom);
+        LookupMap_t::const_iterator rightiter = LookupMap.find(Binder->rightatom);
+        if ((leftiter !=  LookupMap.end()) && (rightiter !=  LookupMap.end())) {
+          // create new bond, copy its properties, and register with both copies
+          atom * const LeftAtom = leftiter->second;
+          atom * const RightAtom = rightiter->second;
+          bond * const NewBond = LeftAtom->addBond(WorldTime::getTime(), RightAtom);
+          LOG(3, "DEBUG: Creating copy bond between original " << Binder->leftatom->getId()
+              << " and " << Binder->rightatom->getId() << ": " << *NewBond << ".");
+          NewBond->BondDegree = Binder->BondDegree;
+          NewBond->Cyclic = Binder->Cyclic;
+          NewBond->Type = Binder->Type;
+        } else {
+          LOG(4, "DEBUG: Skipping bond between original atoms " << Binder->leftatom->getId()
+              << " and " << Binder->rightatom->getId() << " as one of them is not present in copied atoms.");
+        }
+      } else {
+        LOG(4, "DEBUG: Skipping bond between original atoms " << Binder->leftatom->getId()
+            << " and " << Binder->rightatom->getId() << " due to wrong order.");
+      }
+    }
+  }
+
+  // print copied atoms
+  if (DoLog(3))
+    for (AtomVector::const_iterator copy_iter = CopiedAtoms.begin();
+        copy_iter != CopiedAtoms.end(); ++copy_iter) {
+      const BondList ListOfBonds = (*copy_iter)->getListOfBonds();
+      LOG(3, "DEBUG: List of bonds for " << **copy_iter << ": " << ListOfBonds << ".");
+    }
+}
Index: src/Atom/CopyAtoms/CopyAtoms_withBonds.hpp
===================================================================
--- src/Atom/CopyAtoms/CopyAtoms_withBonds.hpp	(revision 9e1d01415f93be121370a5079d969cb2451872f0)
+++ src/Atom/CopyAtoms/CopyAtoms_withBonds.hpp	(revision 9e1d01415f93be121370a5079d969cb2451872f0)
@@ -0,0 +1,74 @@
+/*
+ * CopyAtoms_withBonds.hpp
+ *
+ *  Created on: Mar 17, 2012
+ *      Author: heber
+ */
+
+#ifndef COPYATOMS_WITHBONDS_HPP_
+#define COPYATOMS_WITHBONDS_HPP_
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <map>
+
+#include "Atom/CopyAtoms/CopyAtoms_Simple.hpp"
+#include "CodePatterns/Assert.hpp"
+
+class atom;
+
+/** This is an extented implementation of CopyAtoms_Simple that also copies the bonds.
+ *
+ */
+class CopyAtoms_withBonds : public CopyAtoms_Simple
+{
+public:
+  /** Destructor.
+   *
+   */
+  virtual ~CopyAtoms_withBonds()
+  {}
+
+  /** In this function we add to the copied atoms also the bonds.
+   *
+   * @param _atoms atoms to copy
+   */
+  virtual void operator()(const AtomVector &_atoms);
+
+private:
+  //!> type for lookup up man from original atoms to copied ones.
+  typedef std::map< const atom *,  atom *> LookupMap_t;
+
+  /** Internal helper to create a lookup map from original atoms to copies.
+   *
+   * This fills LookupMap.
+   *
+   * @param _atoms vector with original atoms
+   */
+  LookupMap_t createLookup(const AtomVector &_atoms)
+  {
+    LookupMap_t LookupMap;
+    AtomVector::const_iterator original_iter = _atoms.begin();
+    AtomVector::iterator copy_iter = CopiedAtoms.begin();
+    for (; original_iter != _atoms.end(); ++original_iter, ++copy_iter) {
+      ASSERT( copy_iter != CopiedAtoms.end(),
+          "CopyAtoms_withBonds::createLookup() - the number of copied atoms is insufficient.");
+  #ifndef NDEBUG
+      std::pair< LookupMap_t::iterator, bool> inserter =
+  #endif
+      LookupMap.insert( std::make_pair( *original_iter, *copy_iter ) );
+      ASSERT( (inserter.second) || (inserter.first->second == *copy_iter),
+          "CopyAtoms_withBonds::createLookup() - There is twice the same original atom for two distinct copies.");
+    }
+    ASSERT( copy_iter == CopiedAtoms.end(),
+        "CopyAtoms_withBonds::createLookup() - the number of copied atoms exceeds number of original ones.");
+    return LookupMap;
+  }
+};
+
+
+#endif /* COPYATOMS_WITHBONDS_HPP_ */
