Index: src/Actions/FillAction/FillRegularGridAction.cpp
===================================================================
--- src/Actions/FillAction/FillRegularGridAction.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Actions/FillAction/FillRegularGridAction.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,191 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2010-2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * FillRegularGridAction.cpp
+ *
+ *  Created on: Jan 12, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "Atom/atom.hpp"
+#include "Atom/CopyAtoms/CopyAtoms_withBonds.hpp"
+#include "CodePatterns/Log.hpp"
+#include "Descriptors/MoleculeOrderDescriptor.hpp"
+#include "Filling/Cluster.hpp"
+#include "Filling/Filler.hpp"
+#include "Filling/Inserter/Inserter.hpp"
+#include "Filling/Inserter/RandomInserter.hpp"
+#include "Filling/Mesh/CubeMesh.hpp"
+#include "Filling/Predicates/IsInsideSurface_FillPredicate.hpp"
+#include "Filling/Predicates/IsVoidNode_FillPredicate.hpp"
+#include "Filling/Predicates/Ops_FillPredicate.hpp"
+#include "LinkedCell/linkedcell.hpp"
+#include "LinkedCell/PointCloudAdaptor.hpp"
+#include "molecule.hpp"
+#include "MoleculeListClass.hpp"
+#include "Parser/FormatParserInterface.hpp"
+#include "Parser/FormatParserStorage.hpp"
+#include "Shapes/BaseShapes.hpp"
+#include "Tesselation/tesselation.hpp"
+#include "Tesselation/BoundaryLineSet.hpp"
+#include "Tesselation/BoundaryTriangleSet.hpp"
+#include "Tesselation/CandidateForTesselation.hpp"
+#include "World.hpp"
+
+
+#include <algorithm>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include "Actions/FillAction/FillRegularGridAction.hpp"
+
+using namespace MoleCuilder;
+
+// and construct the stuff
+#include "FillRegularGridAction.def"
+#include "Action_impl_pre.hpp"
+/** =========== define the function ====================== */
+Action::state_ptr FillRegularGridAction::performCall() {
+  typedef std::vector<atom*> AtomVector;
+
+  // obtain information
+  getParametersfromValueStorage();
+
+  // get all present atoms for UndoState
+  AtomVector presentatoms = World::getInstance().getAllAtoms();
+
+  // get the filler molecule and move to origin
+  const std::vector< molecule *> molecules = World::getInstance().getSelectedMolecules();
+  if (molecules.size() != 1) {
+    ELOG(1, "No exactly one molecule selected, aborting,");
+    return Action::failure;
+  }
+  molecule *filler = *(molecules.begin());
+  LOG(1, "INFO: Chosen molecule has " << filler->size() << " atoms.");
+
+  // check for selected molecules and create surfaces from them
+  std::vector<atom *> atoms(World::getInstance().getSelectedAtoms());
+  FillPredicate * surface_predicate = NULL;
+  LinkedCell_deprecated * LC = NULL;
+  Tesselation * TesselStruct = NULL;
+  if (params.SphereRadius != 0.) {
+    if ( molecules.size() == 0) {
+      ELOG(1, "You have given a sphere radius " << params.SphereRadius
+          << " != 0, but have not select any molecules.");
+    }
+    // create adaptor for the selected atoms
+    PointCloudAdaptor< std::vector<atom *> > cloud(&atoms, std::string("Selected atoms"));
+
+    // create tesselation
+    LC = new LinkedCell_deprecated(cloud, 2.*params.SphereRadius);
+    TesselStruct = new Tesselation;
+    (*TesselStruct)(cloud, params.SphereRadius);
+
+    // and create predicate
+    surface_predicate = new FillPredicate( IsInsideSurface_FillPredicate( *TesselStruct, *LC ) );
+  }
+
+  // create predicate, mesh, and filler
+  bool successflag = false;
+  {
+    FillPredicate *voidnode_predicate = new FillPredicate(
+        IsVoidNode_FillPredicate(
+            Sphere(zeroVec, params.mindistance)
+            )
+        );
+    FillPredicate Andpredicate = (*voidnode_predicate);
+    if (surface_predicate != NULL)
+      Andpredicate = (Andpredicate) && !(*surface_predicate);
+    Mesh *mesh = new CubeMesh(params.counts, params.offset, World::getInstance().getDomain().getM());
+    Inserter *inserter = new Inserter(
+        Inserter::impl_ptr(
+            new RandomInserter(
+                params.RandAtomDisplacement,
+                params.RandMoleculeDisplacement,
+                params.DoRotate)
+            )
+        );
+
+    // fill
+    {
+      Filler *fillerFunction = new Filler(*mesh, Andpredicate, *inserter);
+      ClusterInterface::Cluster_impl cluster( new Cluster( filler->getAtomIds(), filler->getBoundingShape()) );
+      CopyAtoms_withBonds copyMethod;
+      successflag = (*fillerFunction)(copyMethod, cluster);
+      delete fillerFunction;
+    }
+
+    // remove
+    delete mesh;
+    delete inserter;
+    delete voidnode_predicate;
+    delete surface_predicate;
+    delete LC;
+    delete TesselStruct;
+  }
+
+  // generate list of newly created atoms
+  // (we can in general remove more quickly from a list than a vector)
+  AtomVector filleratoms = World::getInstance().getAllAtoms();
+//  LOG(0, filleratoms.size() << " atoms are present.");
+  std::list<atom *> filleratoms_list;
+  std::copy( filleratoms.begin(),  filleratoms.end(), std::back_inserter( filleratoms_list ));
+//  LOG(0, filleratoms_list.size() << " atoms have been copied.");
+  for (AtomVector::const_iterator iter = presentatoms.begin();
+      iter != presentatoms.end();
+      ++iter) {
+    filleratoms_list.remove(*iter);
+  }
+//  LOG(0, filleratoms_list.size() << " atoms left after removal.");
+  filleratoms.clear();
+  std::copy(filleratoms_list.begin(), filleratoms_list.end(), std::back_inserter( filleratoms ));
+
+//  LOG(0, filleratoms.size() << " atoms have been inserted.");
+
+  if (successflag)
+    return Action::state_ptr(new FillRegularGridState(filleratoms,params));
+  else
+    return Action::failure;
+}
+
+Action::state_ptr FillRegularGridAction::performUndo(Action::state_ptr _state) {
+//  FillRegularGridState *state = assert_cast<FillRegularGridState*>(_state.get());
+//
+//  BOOST_FOREACH(atom *_atom, state->filleratoms) {
+//    World::getInstance().destroyAtom(Walker);
+//  }
+//
+//  // as atoms and atoms from state are removed, we have to create a new one
+//  std::vector<atom*> filleratoms;
+//  return Action::state_ptr(new FillRegularGridState(filleratoms,state->params));
+  return Action::failure;
+}
+
+Action::state_ptr FillRegularGridAction::performRedo(Action::state_ptr _state){
+  //FillRegularGridState *state = assert_cast<FillRegularGridState*>(_state.get());
+
+  return Action::failure;
+  //return Action::state_ptr(_state);
+}
+
+bool FillRegularGridAction::canUndo() {
+  return false;
+}
+
+bool FillRegularGridAction::shouldUndo() {
+  return false;
+}
+/** =========== end of function ====================== */
Index: src/Actions/FillAction/FillRegularGridAction.def
===================================================================
--- src/Actions/FillAction/FillRegularGridAction.def	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Actions/FillAction/FillRegularGridAction.def	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,36 @@
+/*
+ * FillRegularGridAction.def
+ *
+ *  Created on: Jan 20, 2012
+ *      Author: heber
+ */
+
+// all includes and forward declarations necessary for non-integral types below
+class atom;
+
+// i.e. there is an integer with variable name Z that can be found in
+// ValueStorage by the token "Z" -> first column: int, Z, "Z"
+// "undefine" if no parameters are required, use (NODEFAULT) for each (undefined) default value
+#define paramtypes (Vector)(Vector)(double)(double)(double)(double)(bool)
+#define paramtokens ("mesh-size")("mesh-offset")("min-distance")("tesselation-radius")("random-atom-displacement")("random-molecule-displacement")("DoRotate")
+#define paramdescriptions ("number of points per axis")("offset to start of partition, must be in [0,1)")("Minimum distance to other atoms")("radius of rolling sphere in tesselating selected molecule's surfaces")("magnitude of random atom displacement")("magnitude of random molecule displacement")("whether to rotate or not")
+#define paramdefaults (NODEFAULT)("0.,0.,0.")("1.")("0.")("0.")("0.")("0")
+#define paramreferences (counts)(offset)(mindistance)(SphereRadius)(RandAtomDisplacement)(RandMoleculeDisplacement)(DoRotate)
+
+#define statetypes (std::vector<atom *>)
+#define statereferences (filleratoms)
+
+// some defines for all the names, you may use ACTION, STATE and PARAMS
+#define CATEGORY Fill
+#define MENUNAME "fill"
+#define MENUPOSITION 1
+#define ACTIONNAME RegularGrid
+#define TOKEN "fill-regular-grid"
+
+
+// finally the information stored in the ActionTrait specialization
+#define DESCRIPTION "\
+fill the domain via a regularly sparsed grid of insertion points with the \
+currently selected molecule. If atoms are selected, too, they are surrounded by \
+a tesselated surface and only outside of the tesselation is filled."
+#undef SHORTFORM
Index: src/Actions/FillAction/FillRegularGridAction.hpp
===================================================================
--- src/Actions/FillAction/FillRegularGridAction.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Actions/FillAction/FillRegularGridAction.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,22 @@
+/*
+ * FillRegularGridAction.hpp
+ *
+ *  Created on: Jan 12, 2012
+ *      Author: heber
+ */
+
+#ifndef FILLREGULARGRIDACTION_HPP
+#define FILLREGULARGRIDACTION_HPP
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include "Actions/Action.hpp"
+
+#include "FillRegularGridAction.def"
+#include "Action_impl_header.hpp"
+
+#endif // FILLREGULARGRIDACTION_HPP
Index: src/Actions/GlobalListOfActions.hpp
===================================================================
--- src/Actions/GlobalListOfActions.hpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Actions/GlobalListOfActions.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -105,5 +105,6 @@
 	(SelectionNotAllAtomsInsideCuboid) \
 	(SelectionAtomById) \
-	(FragmentationFragmentation)
+	(FragmentationFragmentation) \
+	(FillRegularGrid)
 
 #endif /* GLOBALLISTOFACTIONS_HPP_ */
Index: src/Actions/Makefile.am
===================================================================
--- src/Actions/Makefile.am	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Actions/Makefile.am	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -52,4 +52,5 @@
   ${ATOMACTIONSOURCE} \
   ${CMDACTIONSOURCE} \
+  ${FILLACTIONSOURCE} \
   ${FRAGMENTATIONACTIONSOURCE} \
   ${GRAPHACTIONSOURCE} \
@@ -67,4 +68,5 @@
   ${ATOMACTIONHEADER} \
   ${CMDACTIONHEADER} \
+  ${FILLACTIONHEADER} \
   ${FRAGMENTATIONACTIONHEADER} \
   ${GRAPHACTIONHEADER} \
@@ -82,4 +84,5 @@
   ${ATOMACTIONDEFS} \
   ${CMDACTIONDEFS} \
+  ${FILLACTIONDEFS} \
   ${FRAGMENTATIONACTIONDEFS} \
   ${GRAPHACTIONDEFS} \
@@ -173,4 +176,12 @@
   Actions/CommandAction/VersionAction.def \
   Actions/CommandAction/WarrantyAction.def
+
+FILLACTIONSOURCE = \
+	Actions/FillAction/FillRegularGridAction.cpp
+FILLACTIONHEADER = \
+	Actions/FillAction/FillRegularGridAction.hpp
+FILLACTIONDEFS = \
+	Actions/FillAction/FillRegularGridAction.def
+
 
 FRAGMENTATIONACTIONSOURCE = \
Index: src/Actions/SelectionAction/Atoms/AllAtomsInsideCuboidAction.cpp
===================================================================
--- src/Actions/SelectionAction/Atoms/AllAtomsInsideCuboidAction.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Actions/SelectionAction/Atoms/AllAtomsInsideCuboidAction.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -54,6 +54,6 @@
   LOG(1, "Selecting all atoms inside a rotated " << RotationMatrix << " cuboid at " << params.position << " and extension of " << params.extension << ".");
   Shape s = translate(transform(stretch(Cuboid(),params.extension),RotationMatrix),params.position);
-  std::vector<atom *> selectedAtoms = World::getInstance().getAllAtoms(AtomsBySelection() && AtomByShape(s));
-  World::getInstance().selectAllAtoms(AtomByShape(s));
+  std::vector<atom *> selectedAtoms = World::getInstance().getAllAtoms(AtomsBySelection() && AtomsByShape(s));
+  World::getInstance().selectAllAtoms(AtomsByShape(s));
   LOG(0, World::getInstance().countSelectedAtoms() << " atoms selected.");
   return Action::state_ptr(new SelectionAllAtomsInsideCuboidState(selectedAtoms, s, params));
@@ -63,5 +63,5 @@
   SelectionAllAtomsInsideCuboidState *state = assert_cast<SelectionAllAtomsInsideCuboidState*>(_state.get());
 
-  World::getInstance().unselectAllAtoms(AtomByShape(state->s));
+  World::getInstance().unselectAllAtoms(AtomsByShape(state->s));
   BOOST_FOREACH(atom *_atom, state->selectedAtoms)
     World::getInstance().selectAtom(_atom);
@@ -74,5 +74,5 @@
   RealSpaceMatrix RotationMatrix;
 
-  World::getInstance().selectAllAtoms(AtomByShape(state->s));
+  World::getInstance().selectAllAtoms(AtomsByShape(state->s));
 
   return Action::state_ptr(_state);
Index: src/Actions/SelectionAction/Atoms/AllAtomsInsideSphereAction.cpp
===================================================================
--- src/Actions/SelectionAction/Atoms/AllAtomsInsideSphereAction.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Actions/SelectionAction/Atoms/AllAtomsInsideSphereAction.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -49,6 +49,6 @@
   LOG(1, "Selecting all atoms inside a sphere at " << params.position << " with radius " << params.radius << ".");
   Shape s = translate(resize(Sphere(),params.radius),params.position);
-  std::vector<atom *> selectedAtoms = World::getInstance().getAllAtoms(AtomsBySelection() && AtomByShape(s));
-  World::getInstance().selectAllAtoms(AtomByShape(s));
+  std::vector<atom *> selectedAtoms = World::getInstance().getAllAtoms(AtomsBySelection() && AtomsByShape(s));
+  World::getInstance().selectAllAtoms(AtomsByShape(s));
   LOG(0, World::getInstance().countSelectedAtoms() << " atoms selected.");
   return Action::state_ptr(new SelectionAllAtomsInsideSphereState(selectedAtoms, s, params));
@@ -58,5 +58,5 @@
   SelectionAllAtomsInsideSphereState *state = assert_cast<SelectionAllAtomsInsideSphereState*>(_state.get());
 
-  World::getInstance().unselectAllAtoms(AtomByShape(state->s));
+  World::getInstance().unselectAllAtoms(AtomsByShape(state->s));
   BOOST_FOREACH(atom *_atom, state->selectedAtoms)
     World::getInstance().selectAtom(_atom);
@@ -68,5 +68,5 @@
   SelectionAllAtomsInsideSphereState *state = assert_cast<SelectionAllAtomsInsideSphereState*>(_state.get());
 
-  World::getInstance().selectAllAtoms(AtomByShape(state->s));
+  World::getInstance().selectAllAtoms(AtomsByShape(state->s));
 
   return Action::state_ptr(_state);
Index: src/Actions/SelectionAction/Atoms/NotAllAtomsInsideCuboidAction.cpp
===================================================================
--- src/Actions/SelectionAction/Atoms/NotAllAtomsInsideCuboidAction.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Actions/SelectionAction/Atoms/NotAllAtomsInsideCuboidAction.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -53,6 +53,6 @@
   LOG(1, "Unselecting all atoms inside a rotated " << RotationMatrix << " cuboid at " << params.position << " and extension of " << params.extension << ".");
   Shape s = translate(transform(stretch(Cuboid(),params.extension),RotationMatrix),params.position);
-  std::vector<atom *> unselectedAtoms = World::getInstance().getAllAtoms((!AtomsBySelection()) && AtomByShape(s));
-  World::getInstance().unselectAllAtoms(AtomByShape(s));
+  std::vector<atom *> unselectedAtoms = World::getInstance().getAllAtoms((!AtomsBySelection()) && AtomsByShape(s));
+  World::getInstance().unselectAllAtoms(AtomsByShape(s));
   LOG(0, World::getInstance().countSelectedAtoms() << " atoms remain selected.");
   return Action::state_ptr(new SelectionNotAllAtomsInsideCuboidState(unselectedAtoms, s, params));
@@ -62,5 +62,5 @@
   SelectionNotAllAtomsInsideCuboidState *state = assert_cast<SelectionNotAllAtomsInsideCuboidState*>(_state.get());
 
-  World::getInstance().selectAllAtoms(AtomByShape(state->s));
+  World::getInstance().selectAllAtoms(AtomsByShape(state->s));
   BOOST_FOREACH(atom *_atom, state->unselectedAtoms)
     World::getInstance().unselectAtom(_atom);
@@ -73,5 +73,5 @@
   RealSpaceMatrix RotationMatrix;
 
-  World::getInstance().unselectAllAtoms(AtomByShape(state->s));
+  World::getInstance().unselectAllAtoms(AtomsByShape(state->s));
 
   return Action::state_ptr(_state);
Index: src/Actions/SelectionAction/Atoms/NotAllAtomsInsideSphereAction.cpp
===================================================================
--- src/Actions/SelectionAction/Atoms/NotAllAtomsInsideSphereAction.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Actions/SelectionAction/Atoms/NotAllAtomsInsideSphereAction.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -49,6 +49,6 @@
   LOG(1, "Unselecting all atoms inside a sphere at " << params.position << " with radius " << params.radius << ".");
   Shape s = translate(resize(Sphere(),params.radius),params.position);
-  std::vector<atom *> unselectedAtoms = World::getInstance().getAllAtoms((!AtomsBySelection()) && AtomByShape(s));
-  World::getInstance().unselectAllAtoms(AtomByShape(s));
+  std::vector<atom *> unselectedAtoms = World::getInstance().getAllAtoms((!AtomsBySelection()) && AtomsByShape(s));
+  World::getInstance().unselectAllAtoms(AtomsByShape(s));
   LOG(0, World::getInstance().countSelectedAtoms() << " atoms remain selected.");
   return Action::state_ptr(new SelectionNotAllAtomsInsideSphereState(unselectedAtoms, s, params));
@@ -58,5 +58,5 @@
   SelectionNotAllAtomsInsideSphereState *state = assert_cast<SelectionNotAllAtomsInsideSphereState*>(_state.get());
 
-  World::getInstance().selectAllAtoms(AtomByShape(state->s));
+  World::getInstance().selectAllAtoms(AtomsByShape(state->s));
   BOOST_FOREACH(atom *_atom, state->unselectedAtoms)
     World::getInstance().unselectAtom(_atom);
@@ -68,5 +68,5 @@
   SelectionNotAllAtomsInsideSphereState *state = assert_cast<SelectionNotAllAtomsInsideSphereState*>(_state.get());
 
-  World::getInstance().unselectAllAtoms(AtomByShape(state->s));
+  World::getInstance().unselectAllAtoms(AtomsByShape(state->s));
 
   return Action::state_ptr(_state);
Index: src/Atom/CopyAtoms/CopyAtomsInterface.hpp
===================================================================
--- src/Atom/CopyAtoms/CopyAtomsInterface.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Atom/CopyAtoms/CopyAtomsInterface.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -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 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Atom/CopyAtoms/CopyAtoms_SaturateDanglingBonds.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -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 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Atom/CopyAtoms/CopyAtoms_SaturateDanglingBonds.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -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 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Atom/CopyAtoms/CopyAtoms_Simple.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -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 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Atom/CopyAtoms/CopyAtoms_withBonds.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -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 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Atom/CopyAtoms/CopyAtoms_withBonds.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -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_ */
Index: src/Atom/Makefile.am
===================================================================
--- src/Atom/Makefile.am	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Atom/Makefile.am	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -29,9 +29,18 @@
   Atom/TesselPoint.hpp
 
+COPYATOMSSOURCE = \
+	Atom/CopyAtoms/CopyAtoms_SaturateDanglingBonds.cpp \
+	Atom/CopyAtoms/CopyAtoms_withBonds.cpp
+
+COPYATOMSHEADER = \
+	Atom/CopyAtoms/CopyAtoms_SaturateDanglingBonds.hpp \
+	Atom/CopyAtoms/CopyAtoms_Simple.hpp \
+	Atom/CopyAtoms/CopyAtoms_withBonds.hpp \
+	Atom/CopyAtoms/CopyAtomsInterface.hpp
 
 noinst_LTLIBRARIES += libMolecuilderAtom.la
 libMolecuilderAtom_la_includedir = $(includedir)/MoleCuilder/Atom/
 
-nobase_libMolecuilderAtom_la_include_HEADERS = ${ATOMHEADER}
+nobase_libMolecuilderAtom_la_include_HEADERS = $(ATOMHEADER) $(COPYATOMSHEADER) 
 
 ## Define the source file list for the "libexample-@MOLECUILDER_API_VERSION@.la"
@@ -43,5 +52,5 @@
 ## from each source file.  Note that it is not necessary to list header files
 ## which are already listed elsewhere in a _HEADERS variable assignment.
-libMolecuilderAtom_la_SOURCES = ${ATOMSOURCE}
+libMolecuilderAtom_la_SOURCES = $(ATOMSOURCE) $(COPYATOMSSOURCE)
 
 ## Instruct libtool to include ABI version information in the generated shared
Index: src/Atom/unittests/CopyAtomsInterfaceUnitTest.cpp
===================================================================
--- src/Atom/unittests/CopyAtomsInterfaceUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Atom/unittests/CopyAtomsInterfaceUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+/*
+ * CopyAtomsInterfaceUnitTest.cpp
+ *
+ *  Created on: Mar 17, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CopyAtomsInterfaceUnitTest.hpp"
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <iostream>
+
+#include "CodePatterns/Log.hpp"
+
+#include "Atom/atom.hpp"
+#include "Atom/CopyAtoms/CopyAtomsInterface.hpp"
+#include "Atom/CopyAtoms/CopyAtoms_Simple.hpp"
+#include "Atom/CopyAtoms/CopyAtoms_withBonds.hpp"
+#include "Bond/bond.hpp"
+#include "World.hpp"
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+/********************************************** Test classes **************************************/
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( CopyAtomsInterfaceTest );
+
+// set up and tear down
+void CopyAtomsInterfaceTest::setUp()
+{
+  setVerbosity(5);
+
+  for(int i=0;i<ATOM_COUNT;++i){
+    atoms[i]= World::getInstance().createAtom();
+    atomIds[i]= atoms[i]->getId();
+  }
+}
+
+void CopyAtomsInterfaceTest::tearDown()
+{
+  World::purgeInstance();
+}
+
+/** Unit test on whether CopyAtomsInterface::operator() works as expected.
+ *
+ */
+void CopyAtomsInterfaceTest::CopyAtomsInterfaceOperatorTest()
+{
+  CopyAtomsInterface copyMethod;
+  CopyAtomsInterface::AtomVector atomVec(atoms, atoms+ATOM_COUNT);
+
+  copyMethod(atomVec);
+
+  CPPUNIT_ASSERT_EQUAL( (size_t)2, World::getInstance().getAllAtoms().size() );
+  CPPUNIT_ASSERT_EQUAL( (size_t)2, atomVec.size() );
+  CPPUNIT_ASSERT_EQUAL( (size_t)2, copyMethod.CopiedAtoms.size() );
+  CPPUNIT_ASSERT_EQUAL( (atom *) NULL, copyMethod.CopiedAtoms[0] );
+}
+
+/** Unit test on whether CopyAtoms_Simple::operator() works as expected.
+ *
+ */
+void CopyAtomsInterfaceTest::CopyAtoms_SimpleOperatorTest()
+{
+  CopyAtoms_Simple copyMethod;
+  CopyAtomsInterface::AtomVector atomVec(atoms, atoms+ATOM_COUNT);
+
+  copyMethod(atomVec);
+
+  CPPUNIT_ASSERT_EQUAL( (size_t)4, World::getInstance().getAllAtoms().size() );
+  CPPUNIT_ASSERT_EQUAL( (size_t)2, atomVec.size() );
+  CPPUNIT_ASSERT_EQUAL( (size_t)2, copyMethod.CopiedAtoms.size() );
+  CPPUNIT_ASSERT( copyMethod.CopiedAtoms[0] != NULL );
+}
+
+/** Unit test on whether CopyAtoms_withBonds::operator() works as expected.
+ *
+ */
+void CopyAtomsInterfaceTest::CopyAtoms_withBondsOperatorTest()
+{
+  CopyAtoms_withBonds copyMethod;
+  {
+    CopyAtomsInterface::AtomVector atomVec(atoms, atoms+ATOM_COUNT);
+    CPPUNIT_ASSERT_EQUAL( (size_t)2, atomVec.size() );
+
+    copyMethod(atomVec);
+
+    CPPUNIT_ASSERT_EQUAL( (size_t)4, World::getInstance().getAllAtoms().size() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)2, copyMethod.CopiedAtoms.size() );
+    CPPUNIT_ASSERT( copyMethod.CopiedAtoms[0] != NULL );
+    CPPUNIT_ASSERT( copyMethod.CopiedAtoms[1] != NULL );
+    CPPUNIT_ASSERT_EQUAL( copyMethod.CopiedAtoms, copyMethod.getCopiedAtoms() );
+  }
+
+  // create bonds
+  {
+    atoms[0]->addBond( (size_t)0, atoms[1]);
+    const BondList & ListOfBonds = atoms[0]->getListOfBonds();
+    CPPUNIT_ASSERT( !ListOfBonds.empty() );
+    const bond * const _bond = *ListOfBonds.begin();
+    CPPUNIT_ASSERT( _bond->GetOtherAtom(atoms[0]) == atoms[1] );
+  }
+  {
+    CopyAtomsInterface::AtomVector atomVec(atoms, atoms+ATOM_COUNT);
+    CPPUNIT_ASSERT_EQUAL( (size_t)2, atomVec.size() );
+
+    copyMethod(atomVec);
+
+    CPPUNIT_ASSERT_EQUAL( (size_t)6, World::getInstance().getAllAtoms().size() );
+    CPPUNIT_ASSERT_EQUAL( (size_t)2, copyMethod.CopiedAtoms.size() );
+    CPPUNIT_ASSERT( copyMethod.CopiedAtoms[0] != NULL );
+    CPPUNIT_ASSERT( copyMethod.CopiedAtoms[1] != NULL );
+    const BondList & ListOfBonds = copyMethod.CopiedAtoms[0]->getListOfBonds();
+    CPPUNIT_ASSERT( !ListOfBonds.empty() );
+    const bond * const _bond = *ListOfBonds.begin();
+    CPPUNIT_ASSERT( _bond->GetOtherAtom(copyMethod.CopiedAtoms[0]) == copyMethod.CopiedAtoms[1] );
+  }
+}
+
+
Index: src/Atom/unittests/CopyAtomsInterfaceUnitTest.hpp
===================================================================
--- src/Atom/unittests/CopyAtomsInterfaceUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Atom/unittests/CopyAtomsInterfaceUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,47 @@
+/*
+ * CopyAtomsInterfaceUnitTest.hpp
+ *
+ *  Created on: Mar 17, 2012
+ *      Author: heber
+ */
+
+#ifndef COPYATOMSINTERFACEUNITTEST_HPP_
+#define COPYATOMSINTERFACEUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "types.hpp"
+
+// we prefer enum over define
+enum { ATOM_COUNT = 2 };
+
+class atom;
+
+class CopyAtomsInterfaceTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( CopyAtomsInterfaceTest );
+  CPPUNIT_TEST ( CopyAtomsInterfaceOperatorTest );
+  CPPUNIT_TEST ( CopyAtoms_SimpleOperatorTest );
+  CPPUNIT_TEST ( CopyAtoms_withBondsOperatorTest );
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+  void setUp();
+  void tearDown();
+
+  void CopyAtomsInterfaceOperatorTest();
+  void CopyAtoms_SimpleOperatorTest();
+  void CopyAtoms_withBondsOperatorTest();
+
+private:
+  atom *atoms [ATOM_COUNT];
+  atomId_t atomIds [ATOM_COUNT];
+};
+
+#endif /* COPYATOMSINTERFACEUNITTEST_HPP_ */
Index: src/Atom/unittests/Makefile.am
===================================================================
--- src/Atom/unittests/Makefile.am	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Atom/unittests/Makefile.am	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -4,12 +4,15 @@
 ATOMTESTSSOURCES = \
 	../Atom/unittests/AtomObserverUnitTest.cpp \
+	../Atom/unittests/CopyAtomsInterfaceUnitTest.cpp \
 	stubs/ObserverStub.cpp
 
 ATOMTESTSHEADERS = \
 	../Atom/unittests/AtomObserverUnitTest.hpp \
+	../Atom/unittests/CopyAtomsInterfaceUnitTest.hpp \
 	stubs/ObserverStub.hpp
 
 ATOMTESTS = \
-  AtomObserverUnitTest
+  AtomObserverUnitTest \
+  CopyAtomsInterfaceUnitTest
 
 TESTS += $(ATOMTESTS)
@@ -35,4 +38,8 @@
 AtomObserverUnitTest_LDADD = ${ATOMTESTLIBS}
 
+CopyAtomsInterfaceUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+	../Atom/unittests/CopyAtomsInterfaceUnitTest.cpp \
+	../Atom/unittests/CopyAtomsInterfaceUnitTest.hpp
+CopyAtomsInterfaceUnitTest_LDADD = ${ATOMTESTLIBS}
 
 
Index: src/AtomIdSet.cpp
===================================================================
--- src/AtomIdSet.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/AtomIdSet.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+/*
+ * AtomIdSet.cpp
+ *
+ *  Created on: Feb 21, 2012
+ *      Author: heber
+ */
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "AtomIdSet.hpp"
+
+#include <boost/foreach.hpp>
+
+#include "Atom/atom.hpp"
+#include "Descriptors/AtomIdDescriptor.hpp"
+#include "World.hpp"
+
+atom * FromIdToAtom::operator()(atomId_t id) const {
+  return World::getInstance().getAtom(AtomById(id));
+}
+
+/** Constructor for class AtomIdSet.
+ *
+ * @param _atoms atoms to put into this set
+ */
+AtomIdSet::AtomIdSet(const atomIdSet &_atoms) :
+    atoms(_atoms)
+{}
+
+/** Constructor for class AtomIdSet.
+ *
+ * @param _atoms atoms to put into this set
+ */
+AtomIdSet::AtomIdSet(const std::vector<atom *> &_atoms)
+{
+  BOOST_FOREACH(const atom * _atom, _atoms) {
+    insert(_atom->getId());
+  }
+}
+
+/** Constructor for class AtomIdSet.
+ *
+ */
+AtomIdSet::AtomIdSet()
+{}
+
+/** Destructor for class AtomIdSet.
+ *
+ */
+AtomIdSet::~AtomIdSet()
+{}
+
+/** Returns iterator to first atim via a transform_iterator.
+ *
+ * @return iterator to first atom in this set
+ */
+AtomIdSet::iterator AtomIdSet::begin(){
+  return iterator(atoms.begin(), FromIdToAtom());
+}
+
+/** Returns constant iterator to first atim via a transform_iterator.
+ *
+ * @return const iterator to first atom in this set
+ */
+AtomIdSet::const_iterator AtomIdSet::begin() const{
+  return const_iterator(atoms.begin(), FromIdToAtom());
+}
+
+/** Returns iterator to one beyond last atom via a transform_iterator.
+ *
+ * @return iterator to one beyond last atom in this set
+ */
+AtomIdSet::iterator AtomIdSet::end(){
+  return iterator(atoms.end(), FromIdToAtom());
+}
+
+/** Returns constant iterator to one beyond last atom via a transform_iterator.
+ *
+ * @return const iterator to one beyond last atom in this set
+ */
+AtomIdSet::const_iterator AtomIdSet::end() const{
+  return const_iterator(atoms.end(), FromIdToAtom());
+}
+
+/** Returns true if this set is empty.
+ *
+ * @return true - set is empty, false - there is at least one atom
+ */
+bool AtomIdSet::empty() const
+{
+  return (atoms.empty());
+}
+
+/** Returns the number of members of this set.
+ *
+ * @return number of members in set
+ */
+size_t AtomIdSet::size() const
+{
+  // set has unique members, hence just return its size
+  return atoms.size();
+}
+
+/** Returns the iterator to the atom \a *key.
+ *
+ * @param key atom to find
+ * @return iterator to atom if found, to end() - else
+ */
+AtomIdSet::const_iterator AtomIdSet::find(const atom * const key) const
+{
+  return const_iterator(atoms.find(key->getId()), FromIdToAtom());
+}
+
+/** Returns the iterator to the atom \a *key.
+ *
+ * @param id atomic id to find
+ * @return iterator to atom if found, to end() - else
+ */
+AtomIdSet::const_iterator AtomIdSet::find(const atomId_t &id) const
+{
+  return const_iterator(atoms.find(id), FromIdToAtom());
+}
+
+/** Inserts a given atom into the set.
+ *
+ * @param key atom to insert
+ * @return pair of iterator and bool that states whether element is already present (true) or not (false)
+ */
+std::pair<AtomIdSet::iterator, bool> AtomIdSet::insert(const atom * const key)
+{
+  std::pair<atomIdSet::iterator, bool> iter =
+      atoms.insert(key->getId());
+  std::pair<iterator, bool> retiter (std::make_pair(iterator(iter.first), iter.second));
+
+  return retiter;
+}
+
+/** Inserts a given atom into the set.
+ *
+ * @param id atomic id to insert
+ * @return pair of iterator and bool that states whether element is already present (true) or not (false)
+ */
+std::pair<AtomIdSet::iterator, bool> AtomIdSet::insert(const atomId_t &id)
+{
+  std::pair<atomIdSet::iterator, bool> iter =
+      atoms.insert(id);
+  std::pair<iterator, bool> retiter (std::make_pair(iterator(iter.first), iter.second));
+
+  return retiter;
+}
+
+AtomIdSet::const_iterator AtomIdSet::erase(AtomIdSet::const_iterator &loc)
+{
+  const_iterator iter = loc;
+  ++iter;
+  atom * const _atom = const_cast<atom *>(*loc);
+  atoms.erase( _atom->getId() );
+  return iter;
+}
+
+/** Erase an atom from the list.
+ *
+ * @param *key key to atom in list
+ * @return iterator to just after removed item (compliant with standard)
+ */
+AtomIdSet::const_iterator AtomIdSet::erase(const atom * const key)
+{
+  const_iterator iter = find(key);
+  if (iter != end()){
+    ++iter;
+    atoms.erase( key->getId() );
+  }
+  return iter;
+}
+
+/** Erase an atom from the list.
+ *
+ * @param id atomic id atom in list to erase
+ * @return iterator to just after removed item (compliant with standard)
+ */
+AtomIdSet::const_iterator AtomIdSet::erase(const atomId_t &id)
+{
+  atomIdSet::const_iterator iter = atoms.find(id);
+  if (iter != atoms.end()){
+    ++iter;
+    atoms.erase( id );
+  }
+  return iterator(iter, FromIdToAtom());
+}
Index: src/AtomIdSet.hpp
===================================================================
--- src/AtomIdSet.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/AtomIdSet.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,76 @@
+/*
+ * AtomIdSet.hpp
+ *
+ *  Created on: Feb 21, 2012
+ *      Author: heber
+ */
+
+#ifndef ATOMIDSET_HPP_
+#define ATOMIDSET_HPP_
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <boost/iterator/transform_iterator.hpp>
+
+#include <set>
+#include <vector>
+
+#include "types.hpp"
+
+class atom;
+struct FromIdToAtom :
+  public std::unary_function<atom *, atomId_t>
+{
+    atom * operator()(atomId_t id) const;
+};
+
+/** AtomIdSet is a set of atomic ids that however behave as a set of atoms.
+ *
+ * This class represents an iterable set of atoms that is however only stored as
+ * ids internally.
+ */
+class AtomIdSet
+{
+public:
+  typedef std::set<atomId_t> atomIdSet;
+  typedef boost::transform_iterator<FromIdToAtom, atomIdSet::iterator, atom *, atomId_t> iterator;
+  typedef boost::transform_iterator<FromIdToAtom, atomIdSet::const_iterator, const atom *, atomId_t const &> const_iterator;
+
+  AtomIdSet(const atomIdSet &_atoms);
+  AtomIdSet(const std::vector<atom *> &_atoms);
+  AtomIdSet();
+  ~AtomIdSet();
+
+  iterator begin();
+  const_iterator begin() const;
+  iterator end();
+  const_iterator end() const;
+  bool empty() const;
+  size_t size() const;
+  const_iterator find(const atom * const key) const;
+  const_iterator find(const atomId_t &id) const;
+  std::pair<iterator, bool> insert(const atom * const key);
+  std::pair<iterator, bool> insert(const atomId_t &id);
+  const_iterator erase(const_iterator &loc);
+  const_iterator erase(const atom * const key);
+  const_iterator erase(const atomId_t &id);
+
+  /** Getter for internal set of atoms.
+   *
+   * @return set of atomic ids
+   */
+  const atomIdSet & getAtomIds() const {
+    return atoms;
+  }
+
+private:
+  //!> internal atoms stored by their ids
+  atomIdSet atoms;
+};
+
+
+#endif /* ATOMIDSET_HPP_ */
Index: src/Descriptors/AtomShapeDescriptor.cpp
===================================================================
--- src/Descriptors/AtomShapeDescriptor.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Descriptors/AtomShapeDescriptor.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -35,6 +35,29 @@
 }
 
+atom* AtomShapeDescriptor_impl::find(){
+  LinkedCell::LinkedCell_View view = World::getInstance().getLinkedCell(shape.getRadius());
+  LinkedCell::LinkedList list = view.getPointsInsideSphere(shape.getRadius(), shape.getCenter());
+  for (LinkedCell::LinkedList::iterator iter = list.begin(); iter != list.end(); ++iter) {
+    atom * const _atom = static_cast<atom *>(const_cast<TesselPoint *>(*iter));
+    if (shape.isInside(_atom->getPosition()))
+      return _atom;
+  }
+  return NULL;
+}
 
-AtomDescriptor AtomByShape(const Shape &shape){
+std::vector<atom*> AtomShapeDescriptor_impl::findAll(){
+  LinkedCell::LinkedCell_View view = World::getInstance().getLinkedCell(shape.getRadius());
+  LinkedCell::LinkedList list = view.getPointsInsideSphere(shape.getRadius(), shape.getCenter());
+  std::vector<atom*> res;
+  for (LinkedCell::LinkedList::iterator iter = list.begin(); iter != list.end(); ++iter) {
+    atom * const _atom = static_cast<atom *>(const_cast<TesselPoint *>(*iter));
+    if (shape.isInside(_atom->getPosition()))
+      res.push_back(_atom);
+  }
+  return res;
+}
+
+
+AtomDescriptor AtomsByShape(const Shape &shape){
   return AtomDescriptor(AtomDescriptor::impl_ptr(new AtomShapeDescriptor_impl(shape)));
 }
Index: src/Descriptors/AtomShapeDescriptor.hpp
===================================================================
--- src/Descriptors/AtomShapeDescriptor.hpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Descriptors/AtomShapeDescriptor.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -20,5 +20,5 @@
 class Shape;
 
-AtomDescriptor AtomByShape(const Shape &shape);
+AtomDescriptor AtomsByShape(const Shape &shape);
 
 #endif /* ATOMSHAPEDESCRIPTOR_HPP_ */
Index: src/Descriptors/AtomShapeDescriptor_impl.hpp
===================================================================
--- src/Descriptors/AtomShapeDescriptor_impl.hpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Descriptors/AtomShapeDescriptor_impl.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -27,4 +27,7 @@
   bool predicate(std::pair<atomId_t,atom*> atom);
 private:
+  virtual atom* find();
+  virtual std::vector<atom*> findAll();
+
   Shape shape;
 };
Index: src/Filling/Cluster.cpp
===================================================================
--- src/Filling/Cluster.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Cluster.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,225 @@
+/*
+ * 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.
+ */
+
+/*
+ * Cluster.cpp
+ *
+ *  Created on: Jan 16, 2012
+ *      Author: heber
+ */
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include <algorithm>
+#include <boost/bind.hpp>
+#include <boost/foreach.hpp>
+
+#include "Cluster.hpp"
+
+#include "CodePatterns/Assert.hpp"
+#include "CodePatterns/Log.hpp"
+
+#include "Atom/atom.hpp"
+#include "Descriptors/AtomIdDescriptor.hpp"
+#include "LinearAlgebra/RealSpaceMatrix.hpp"
+#include "LinearAlgebra/Vector.hpp"
+#include "Shapes/ShapeOps.hpp"
+#include "World.hpp"
+
+/** Constructor for class Cluster.
+ *
+ * @param _s Shape of this Cluster
+ */
+Cluster::Cluster(const Shape & _s) :
+    s(_s)
+{}
+
+/** Copy Constructor for class Cluster.
+ *
+ * Here, we do not check whether we atomds reside in the Shape or not, as
+ * this should have been validated in the instance to copy \a _cluster.
+ *
+ * @param _cluster instance to copy
+ */
+Cluster::Cluster(const Cluster & _cluster) :
+    atoms(_cluster.atoms),
+    s(_cluster.s)
+{}
+
+/** Constructor for class Cluster.
+ *
+ * @param _atoms list of atoms to place in this cluster
+ * @param _s Shape of this Cluster
+ */
+Cluster::Cluster(const atomIdSet & _atoms, const Shape & _s) :
+    s(_s)
+{
+  // make sure only those atoms are in Cluster that are also inside its Shape
+  std::vector<atomId_t> tempIds(_atoms.size(), (size_t)-1);
+  std::vector<atomId_t>::iterator iter =
+      std::remove_copy_if( _atoms.begin(), _atoms.end(), tempIds.begin(),
+          !boost::bind(&Cluster::IsInShape, this, _1) );
+  tempIds.erase( iter, tempIds.end() );
+  ASSERT( tempIds.size() == _atoms.size(),
+      "Cluster::Cluster() - at least one atom is not inside the Shape.");
+  atoms.insert( tempIds.begin(), tempIds.end() );
+  LOG(1, "INFO: New cluster has " << atoms.size() << " atoms.");
+}
+
+
+/** Destructor for class Cluster.
+ *
+ */
+Cluster::~Cluster()
+{}
+
+/** Inserts an atomic by its \a id into the Cluster.
+ *
+ * We check whether the atom is inside the given Shape \a s.
+ *
+ * @param id id to insert
+ */
+void Cluster::insert(const atomId_t id)
+{
+  const bool status = IsInShape(id);
+  ASSERT(status,
+      "Cluster::insert() - atomic id "+toString(id)+" is not contained in Shape.");
+  if (status) {
+    std::pair<atomIdSet::iterator, bool> inserter = atoms.insert(id);
+    ASSERT(inserter.second,
+        "Cluster::insert() - atomic id "+toString(id)+" is already present.");
+  }
+}
+
+/** Remove atom by its \a id from the cluster.
+ *
+ * @param id atom to remove
+ */
+void Cluster::erase(const atomId_t id)
+{
+  atomIdSet::iterator iter = atoms.find(id);
+  ASSERT(iter != atoms.end(),
+      "Cluster::erase() - atomic id "+toString(id)+" unknown in this Cluster.");
+  if (iter != atoms.end())
+    atoms.erase(iter);
+}
+
+/** Checks whether a given atom is within the shape \a s.
+ *
+ * @param id atomic id to check
+ * @return true - is in Shape, false - is not contained (or does not exist)
+ */
+bool Cluster::IsInShape(const atomId_t id) const
+{
+  const atom * const _atom = getAtomById(id);
+  if (_atom != NULL)
+    return s.isInside(_atom->getPosition());
+  else
+    return false;
+}
+
+/** Helper function for looking up atomic reference by its id.
+ *
+ * @param id id to look up
+ * @return reference to atom with this id
+ */
+atom * const Cluster::getAtomById(const atomId_t id) const
+{
+  atom * const _atom = World::getInstance().getAtom(AtomById(id));
+  ASSERT(_atom != NULL,
+      "Cluster::getAtomById() - id "+toString(id)+" is unknown to World.");
+  return _atom;
+}
+
+bool isNullAtom(const atom* _atom) {
+  return _atom == NULL;
+}
+
+/** Getter for the underlying true atoms refs.
+ *
+ * @return AtomVector filled with looked-up atom references
+ */
+Cluster::AtomVector Cluster::getAtomRefs() const
+{
+  AtomVector atomVector;
+  atomVector.reserve(atoms.size());
+  BOOST_FOREACH(atomId_t _id, atoms) {
+    atom * const _atom = World::getInstance().getAtom(AtomById(_id));
+    if (_atom != NULL)
+      atomVector.push_back( _atom );
+    else
+      ASSERT( false, "Cluster::getAtomRefs() - unknown id "+toString(_id)+".");
+  }
+  return atomVector;
+}
+
+/** Clone function for this instance.
+ *
+ * @param copyMethod functor that knows how to copy atoms
+ * @param offset Vector to translate new cluster relative to old one
+ * @return another instance with newly allocated atoms
+ */
+ClusterInterface::Cluster_impl Cluster::clone(
+    CopyAtomsInterface& copyMethod,
+    const Vector &offset) const
+{
+  LOG(2, "INFO: Clone this cluster with " << atoms.size() << " atoms.");
+  /// get another cluster instance
+  Cluster * clonedInstance = new Cluster(::translate(getShape(), offset));
+
+  /// copy and move atoms
+  copyMethod(getAtomRefs());
+  AtomVector CopiedAtoms = copyMethod.getCopiedAtoms();
+  BOOST_FOREACH( atom *_atom, CopiedAtoms) {
+    _atom->setPosition( _atom->getPosition() + offset );
+  }
+
+  /// fill copied atoms into new instance
+  // dont use a set here, makes life hard with STL algos
+  std::vector<atomId_t> Copies(CopiedAtoms.size(), (size_t)-1);
+  std::transform(CopiedAtoms.begin(), CopiedAtoms.end(), Copies.begin(),
+      boost::bind(&atom::getId, _1) );
+  clonedInstance->atoms.insert(Copies.begin(), Copies.end());
+
+  return ClusterInterface::Cluster_impl(clonedInstance);
+}
+
+/** Translate atoms inside Cluster and Shape.
+ *
+ * @param offset offset to translate by
+ */
+void Cluster::translate(const Vector &offset)
+{
+  // move atoms
+  AtomVector atomVector = getAtomRefs();
+  BOOST_FOREACH(atom *_atom, atomVector) {
+    _atom->setPosition(_atom->getPosition()+offset);
+  }
+  // translate shape
+  s = ::translate(s, offset);
+}
+
+/** Transform atoms inside Cluster and Shape.
+ *
+ * @param M transformation matrix
+ */
+void Cluster::transform(const RealSpaceMatrix &M)
+{
+  // transform atoms
+  AtomVector atomVector = getAtomRefs();
+  BOOST_FOREACH(atom *_atom, atomVector) {
+    _atom->setPosition( M * _atom->getPosition() );
+  }
+  // translate shape
+  s = ::transform(s, M);
+}
Index: src/Filling/Cluster.hpp
===================================================================
--- src/Filling/Cluster.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Cluster.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,89 @@
+/*
+ * Cluster.hpp
+ *
+ *  Created on: Jan 16, 2012
+ *      Author: heber
+ */
+
+#ifndef CLUSTER_HPP_
+#define CLUSTER_HPP_
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "types.hpp"
+
+#include <set>
+
+#include "ClusterInterface.hpp"
+
+#include "Atom/CopyAtoms/CopyAtomsInterface.hpp"
+#include "LinearAlgebra/Vector.hpp"
+#include "Shapes/Shape.hpp"
+
+class atom;
+class RealSpaceMatrix;
+
+/** A Cluster is a set of atoms within a given Shape that contains them.
+ *
+ */
+class Cluster : public ClusterInterface
+{
+  //!> grant unit test access
+  friend class ClusterTest;
+public:
+  typedef std::set<atomId_t> atomIdSet;
+  typedef std::vector<atom *> AtomVector;
+
+  Cluster(const Cluster & _cluster);
+  Cluster(const Shape &s);
+  Cluster(const atomIdSet &atoms, const Shape &s);
+  ~Cluster();
+
+  void insert(const atomId_t id);
+  void erase(const atomId_t id);
+
+  /** Getter for the internal set of atomic ids.
+   *
+   * @return atomIdSet with \a atoms
+   */
+  const atomIdSet & getAtomIds() const { return atoms; }
+
+  Cluster_impl clone(CopyAtomsInterface& copyMethod, const Vector &offset = zeroVec) const;
+
+  void translate(const Vector &offset);
+
+  void transform(const RealSpaceMatrix &M);
+
+  bool isInside(const atomId_t id) const {
+    return IsInShape(id);
+  }
+
+  /** Getter for the internal Shape.
+   *
+   * @return Shape \a s
+   */
+  const Shape& getShape() const { return s; }
+
+private:
+  /** Getter for the contained atoms.
+   *
+   * @return vector of atomic refs
+   */
+  AtomVector getAtomRefs() const;
+
+  //!> do not allow Cluster without Shape
+  Cluster();
+
+  bool IsInShape(const atomId_t id) const;
+  atom * const getAtomById(const atomId_t id) const;
+
+  atomIdSet atoms;
+  Shape s;
+};
+
+
+#endif /* CLUSTER_HPP_ */
Index: src/Filling/ClusterInterface.hpp
===================================================================
--- src/Filling/ClusterInterface.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/ClusterInterface.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,108 @@
+/*
+ * ClusterInterface.hpp
+ *
+ *  Created on: Jan 20, 2012
+ *      Author: heber
+ */
+
+#ifndef CLUSTERINTERFACE_HPP_
+#define CLUSTERINTERFACE_HPP_
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <boost/shared_ptr.hpp>
+#include <set>
+
+#include "AtomIdSet.hpp"
+#include "types.hpp"
+
+class atom;
+class CopyAtomsInterface;
+class RealSpaceMatrix;
+class Shape;
+class Vector;
+
+/** This is the interface class for clusters.
+ *
+ * Clusters are containers for \refAtomIdSet that make sure that within a given
+ * shape each of the atoms in the \ref AtomIdSet is contained and none else.
+ *
+ * We need this ClusterInterface to allow for ClusterInterface::clone() to not
+ * return a pointer but a boost::shared_ptr which is much cleaner in terms of
+ * memory management.
+ *
+ */
+class ClusterInterface
+{
+public:
+  //!> typedef for pointer to ClusterInterface-compatible instances
+  typedef boost::shared_ptr<ClusterInterface> Cluster_impl;
+  typedef AtomIdSet::atomIdSet atomIdSet;
+
+  virtual ~ClusterInterface() {}
+
+  /** Getter for the set of atomic ids associated to the cluster.
+   *
+   * @return set of atomic ids
+   */
+  virtual const atomIdSet & getAtomIds() const=0;
+
+  /** Getter for the set of atoms associated to the cluster.
+   *
+   * @return set of atoms
+   */
+  AtomIdSet getAtoms() const
+  {
+    return AtomIdSet(getAtomIds());
+  }
+
+  /** Getter for the cluster's Shape.
+   *
+   * @return Shape \a s
+   */
+  virtual const Shape& getShape() const=0;
+
+  /** Clones this cluster.
+   *
+   * We copy the shape and we copy all contained atoms in such a way as
+   * functor \a copyMethod does. We also translate atoms by \a offset
+   * eventually.
+   *
+   * @param copyMethod functor that knows how to copy the atoms
+   * @param offset translational offset for contained atoms
+   * @return reference to the clone cluster
+   */
+  virtual Cluster_impl clone(CopyAtomsInterface& copyMethod, const Vector &offset) const =0;
+
+  /** Move a cluster.
+   *
+   * This moves both all contained atoms associated to the cluster and the
+   * shape itself
+   *
+   * @param offset translation vector
+   */
+  virtual void translate(const Vector &offset)=0;
+
+  /** Transforms a cluster.
+   *
+   * This transforms both all contained atoms associated to the cluster and the
+   * shape itself with respect to their spatial positions.
+   *
+   * @param M transformation matrix
+   */
+  virtual void transform(const RealSpaceMatrix &M)=0;
+
+  /** Check whether the given atom is inside the Cluster's shape.
+   *
+   * @param id atom id to check
+   * @return true - is inside cluster's shape, false - else
+   */
+  virtual bool isInside(const atomId_t id) const = 0;
+};
+
+
+#endif /* CLUSTERINTERFACE_HPP_ */
Index: src/Filling/Filler.cpp
===================================================================
--- src/Filling/Filler.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Filler.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+
+/*
+ * Filler.cpp
+ *
+ *  Created on: Jan 16, 2012
+ *      Author: heber
+ */
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include <algorithm>
+#include <boost/bind.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <sstream>
+#include <vector>
+
+#include "Filler.hpp"
+
+#include "CodePatterns/Assert.hpp"
+#include "CodePatterns/Log.hpp"
+
+#include "Atom/atom.hpp"
+#include "Box.hpp"
+#include "ClusterInterface.hpp"
+#include "Descriptors/AtomIdDescriptor.hpp"
+#include "Inserter/Inserter.hpp"
+#include "LinearAlgebra/RealSpaceMatrix.hpp"
+#include "LinearAlgebra/Vector.hpp"
+#include "NodeTypes.hpp"
+#include "Predicates/FillPredicate.hpp"
+#include "Predicates/Ops_FillPredicate.hpp"
+#include "World.hpp"
+
+
+/** Constructor for class Filler.
+ *
+ * \note We store inverted \a _predicate because we need it only for
+ * remove_copy_if which works in this inverted way as desired.
+ *
+ * @param _mesh Mesh with a NodeSet that fills its Shape
+ * @param _predicate predicate construct to check at each Node
+ * @param _inserter inserter which places the cloned cluster
+ */
+Filler::Filler(const Mesh &_mesh, const FillPredicate &_predicate, const Inserter &_inserter) :
+  mesh(_mesh),
+  predicate(!_predicate),
+  inserter(_inserter)
+{}
+
+/** Destructor for class Filler.
+ *
+ */
+Filler::~Filler()
+{}
+
+/** Fill in the desired Cluster at each remaining node.
+ *
+ * \note The cluster is non-const because it is moved to the first vacant node.
+ *
+ * @param copyMethod functor that knows how to copy atoms.
+ * @param cluster set of atomic ids contained in a specific Shape to fill each Node with
+ * @return true - at least one node has been filled, false - no node filled
+ */
+bool Filler::operator()(
+    CopyAtomsInterface &copyMethod,
+    ClusterInterface::Cluster_impl cluster) const
+{
+  const NodeSet &nodes = mesh.getNodes();
+  std::stringstream output;
+  std::for_each( nodes.begin(), nodes.end(), output << boost::lambda::_1 << " ");
+  LOG(3, "DEBUG: Listing nodes to check: " << output.str());
+  if (nodes.size() == 0)
+    return false;
+  NodeSet FillNodes(nodes.size(), zeroVec);
+
+  // move filler cluster's atoms out of domain such that it does not disturb the predicate.
+  // we only move the atoms as otherwise two translate ShapeOps will be on top of the Shape
+  // which is subsequently copied to all other cloned Clusters ...
+  Vector BoxDiagonal;
+  {
+    const RealSpaceMatrix &M = World::getInstance().getDomain().getM();
+    BoxDiagonal = (M * Vector(1.,1.,1.));
+    BoxDiagonal -= cluster->getShape().getCenter();
+    BoxDiagonal *= 1. + 2.*cluster->getShape().getRadius()/BoxDiagonal.Norm(); // extend it a little further
+    AtomIdSet atoms = cluster->getAtoms();
+    for (AtomIdSet::iterator iter = atoms.begin(); iter != atoms.end(); ++iter)
+      (*iter)->setPosition( (*iter)->getPosition() + BoxDiagonal );
+    LOG(1, "INFO: Translating original cluster's atoms by " << BoxDiagonal << ".");
+  }
+
+  // evaluate predicate and gather into new set
+  NodeSet::iterator transform_end  =
+      std::remove_copy_if(nodes.begin(), nodes.end(), FillNodes.begin(), predicate );
+  FillNodes.erase(transform_end, FillNodes.end());
+
+  // shift cluster back to original place
+  {
+    AtomIdSet atoms = cluster->getAtoms();
+    for (AtomIdSet::iterator iter = atoms.begin(); iter != atoms.end(); ++iter)
+      (*iter)->setPosition( (*iter)->getPosition() - BoxDiagonal );
+    LOG(1, "INFO: Translating original cluster's atoms back.");
+  }
+
+  if (FillNodes.size() == 0) {
+    ELOG(2, "For none of the nodes did the predicate return true.");
+    return false;
+  } else {
+    LOG(1, "INFO: " << FillNodes.size() << " out of " << nodes.size() << " returned true from predicate.");
+  }
+
+  // clone clusters
+  std::vector<ClusterInterface::Cluster_impl> clusters(FillNodes.size());
+  std::vector<ClusterInterface::Cluster_impl>::iterator clusteriter = clusters.begin();
+  *clusteriter = cluster;
+  clusteriter++;
+  std::generate_n(clusteriter, FillNodes.size()-1,
+      boost::bind(&ClusterInterface::clone, boost::cref(cluster), boost::ref(copyMethod), zeroVec) );
+
+  // insert each cluster by abusing std::search a bit:
+  // we look for the subsequence of FillNodes inside clusters. If Inserter always
+  // returns true, we'll have the iterator pointing at first cluster
+  std::vector<ClusterInterface::Cluster_impl>::const_iterator inserteriter =
+    std::search(clusters.begin(), clusters.end(), FillNodes.begin(), FillNodes.end(),
+        boost::bind(&Inserter::operator(), boost::cref(inserter), _1, _2));
+  if( inserteriter != clusters.begin()) {
+    ELOG(1, "Not all cloned clusters could be successfully inserted.");
+    return false;
+  }
+
+  // give final statment on whether at least \a single cluster has been placed
+  if ( FillNodes.size() != 0)
+    return true;
+  else
+    return false;
+}
+
Index: src/Filling/Filler.hpp
===================================================================
--- src/Filling/Filler.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Filler.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,49 @@
+/*
+ * Filler.hpp
+ *
+ *  Created on: Jan 16, 2012
+ *      Author: heber
+ */
+
+#ifndef FILLER_HPP_
+#define FILLER_HPP_
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Cluster.hpp"
+#include "Predicates/FillPredicate.hpp"
+#include "Mesh/Mesh.hpp"
+#include "NodeTypes.hpp"
+
+class CopyAtomsInterface;
+class FillPredicate;
+class Inserter;
+class Mesh;
+
+/** This class operators on a set of nodes (Vector's), checks which fulfill some
+ * given predicate, and fills these position with a given molecule lateron.
+ *
+ */
+class Filler
+{
+public:
+  Filler(const Mesh &_mesh, const FillPredicate &_predicate, const Inserter &_inserter);
+  ~Filler();
+
+  bool operator()(CopyAtomsInterface &copyMethod, ClusterInterface::Cluster_impl cluster) const;
+
+private:
+  //!> mesh is the set of points filling a Shape
+  const Mesh mesh;
+  //!> the predicate is evaluted whether a Node in the NodeSet of mesh is filled or not
+  const FillPredicate predicate;
+  //!> Inserter function to allow for some changes when placing the cluster at the node
+  const Inserter &inserter;
+};
+
+
+#endif /* FILLER_HPP_ */
Index: src/Filling/Generators/NodeGenerator.cpp
===================================================================
--- src/Filling/Generators/NodeGenerator.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Generators/NodeGenerator.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+/*
+ * NodeGenerator.cpp
+ *
+ *
+ *  Created on: Jan 16, 2012
+ *      Author: heber
+ */
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "NodeGenerator.hpp"
+
+#include <cmath>
+#include <vector>
+
+#include "Shapes/Shape.hpp"
+#include "Shapes/ShapeOps.hpp"
+
+/** Constructor for NodeGenerator.
+ *
+ * @param _shape Shape which is to be filled with nodes
+ */
+NodeGenerator::NodeGenerator(const Shape &_shape) :
+	shape(_shape)
+{}
+
+/** Destructor for NodeGenerator.
+ *
+ */
+NodeGenerator::~NodeGenerator()
+{}
+
+/** Returns a set of points contained in the \a NodeGenerator::_shape
+ * with a homogeneous density.
+ *
+ * The central idea of the algorithm is to make use of the present function
+ * for obtaining homogeneously distributed points on all surfaces of
+ * presently implemented Shape's.
+ *
+ * The given \a _shape is shrinked such that eventually the volume is filled
+ * with points. Points filled in that actually reside outside the given
+ * Shape are eventually extracted as all are checked for inclusion.
+ *
+ * \note Although a certain density of points given as it has to be converted
+ * to an discrete regime this density can in general be matched only
+ * approximately.
+ *
+ * @param density desired density of points, the unit is the inverse of the
+ * required volume per point
+ * @return set of nodes
+ */
+NodeSet  NodeGenerator::operator()(const double density)
+{
+	// calculate volume and surface of the given Shape
+	const double volume = shape.getVolume();
+	const double surface = shape.getSurfaceArea();
+
+	// calculate the number of shrinking operations
+	const double radius = shape.getRadius();
+	const double fraction = surface/volume;
+	const int factor = floor(radius * fraction);
+
+	// calculate correction for surface density due to discrete number of layers
+	const double surfaceDensity = volume/(double)factor;
+
+	// fill the shrinking vector
+	std::vector<double> shrinking_factors;
+	for(int f=0; f < factor; ++f)
+		shrinking_factors.push_back(radius*((double)f/(double)factor));
+
+	// go through the shrinking operations
+	NodeSet nodes;
+	for (std::vector<double>::const_iterator iter = shrinking_factors.begin();
+			iter != shrinking_factors.end(); ++iter) {
+		const Shape currentShape = resize(shape, *iter);
+		std::vector<Vector> pointsOnSurface =
+				currentShape.getHomogeneousPointsOnSurface(surfaceDensity);
+		nodes.insert(nodes.end(), pointsOnSurface.begin(), pointsOnSurface.end());
+	}
+
+	// check each point whether its inside the surface
+	return filterOutsidePoints(nodes);
+}
+
+/** Filters out all points that are not contained inside NodeGenerator::shape.
+ *
+ * @param nodes nodes to check
+ * @return subset of nodes that fulfill Shape::isInisde().
+ */
+NodeSet NodeGenerator::filterOutsidePoints(const NodeSet &nodes) const
+{
+	NodeSet return_nodes;
+	return_nodes.reserve(nodes.size());
+	for (NodeSet::const_iterator iter = nodes.begin(); iter != nodes.end(); ++iter) {
+		if (shape.isInside(*iter))
+			return_nodes.push_back(*iter);
+	}
+
+	return return_nodes;
+}
Index: src/Filling/Generators/NodeGenerator.hpp
===================================================================
--- src/Filling/Generators/NodeGenerator.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Generators/NodeGenerator.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,42 @@
+/*
+ * NodeGenerator.hpp
+ *
+ *  Created on: Jan 16, 2012
+ *      Author: heber
+ */
+
+#ifndef NODEGENERATOR_HPP_
+#define NODEGENERATOR_HPP_
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Filling/NodeTypes.hpp"
+
+#include "Shapes/Shape.hpp"
+
+/** The class NodeGenerator is an interface to routines that generate points
+ * within a domain used for subsequent traversal and test as possible filling
+ * positions.
+ *
+ */
+class NodeGenerator
+{
+public:
+
+  NodeGenerator(const Shape &_shape);
+  ~NodeGenerator();
+
+  NodeSet operator()(const double density);
+
+private:
+  NodeSet filterOutsidePoints(const NodeSet &nodes) const;
+
+  Shape shape;
+};
+
+
+#endif /* NODEGENERATOR_HPP_ */
Index: src/Filling/Inserter/Inserter.cpp
===================================================================
--- src/Filling/Inserter/Inserter.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Inserter/Inserter.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/*
+ * Inserter.cpp
+ *
+ *  Created on: Feb 21, 2012
+ *      Author: heber
+ */
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "Inserter.hpp"
+
+#include "InserterBase.hpp"
+
+/** Constructor for class Inserter.
+ *
+ * @param _impl implementation to wrap
+ */
+Inserter::Inserter(Inserter::impl_ptr _impl) :
+    impl(_impl)
+{}
+
+/** Copy Constructor for class Inserter.
+ *
+ */
+Inserter::Inserter(const Inserter &ptr) :
+    impl(ptr.getImpl())
+{}
+
+/** Destructor for class Inserter.
+ *
+ */
+Inserter::~Inserter()
+{}
+
+bool Inserter::operator()(ClusterInterface::Cluster_impl cluster, const Vector &offset) const
+{
+  return impl->operator()(cluster, offset);
+}
+
+Inserter::impl_ptr Inserter::getImpl() const {
+  return impl;
+}
Index: src/Filling/Inserter/Inserter.hpp
===================================================================
--- src/Filling/Inserter/Inserter.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Inserter/Inserter.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,51 @@
+/*
+ * Inserter.hpp
+ *
+ *  Created on: Feb 21, 2012
+ *      Author: heber
+ */
+
+#ifndef INSERTER_HPP_
+#define INSERTER_HPP_
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <boost/shared_ptr.hpp>
+
+#include "Filling/ClusterInterface.hpp"
+
+class Vector;
+
+class InserterBase;
+
+/** This class defines the interface for all derived classes.
+ *
+ * This is just a functor of an inserter function.
+ *
+ */
+class Inserter
+{
+public:
+  typedef boost::shared_ptr<InserterBase> impl_ptr;
+  friend impl_ptr getInserterImpl(const Inserter&);
+
+  Inserter(const Inserter &ptr);
+  Inserter(impl_ptr);
+  ~Inserter();
+  bool operator()(ClusterInterface::Cluster_impl cluster, const Vector &offset) const;
+
+protected:
+  impl_ptr getImpl() const;
+
+private:
+  impl_ptr impl;
+};
+
+Inserter::impl_ptr getInserterImpl(const Inserter &f);
+
+
+#endif /* INSERTER_HPP_ */
Index: src/Filling/Inserter/InserterBase.hpp
===================================================================
--- src/Filling/Inserter/InserterBase.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Inserter/InserterBase.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,35 @@
+/*
+ * InserterBase.hpp
+ *
+ *  Created on: Feb 21, 2012
+ *      Author: heber
+ */
+
+#ifndef INSERTERBASE_HPP_
+#define INSERTERBASE_HPP_
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Filling/ClusterInterface.hpp"
+
+class Vector;
+
+/** Inserter defines the interface to all classes that handle insertion of \a
+ * Cluster into the World at a specific position.
+ */
+class InserterBase
+{
+public:
+  InserterBase() {}
+  virtual ~InserterBase() {}
+
+  virtual bool operator()(ClusterInterface::Cluster_impl cluster, const Vector &offset) const = 0;
+
+};
+
+
+#endif /* INSERTERBASE_HPP_ */
Index: src/Filling/Inserter/RandomInserter.cpp
===================================================================
--- src/Filling/Inserter/RandomInserter.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Inserter/RandomInserter.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,220 @@
+/*
+ * 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.
+ */
+
+/*
+ * RandomInserter.cpp
+ *
+ *  Created on: Feb 21, 2012
+ *      Author: heber
+ */
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "RandomInserter.hpp"
+
+#include <algorithm>
+
+#include "Atom/atom.hpp"
+#include "CodePatterns/Log.hpp"
+#include "LinearAlgebra/RealSpaceMatrix.hpp"
+#include "RandomNumbers/RandomNumberGeneratorFactory.hpp"
+#include "RandomNumbers/RandomNumberGenerator.hpp"
+
+
+size_t RandomInserter::Max_Attempts = 10;
+
+/** Sets given 3x3 matrix to a random rotation matrix.
+ *
+ * @param a matrix to set
+ */
+inline void setRandomRotation(RealSpaceMatrix &a)
+{
+  double phi[NDIM];
+  RandomNumberGenerator &random = RandomNumberGeneratorFactory::getInstance().makeRandomNumberGenerator();
+  const double rng_min = random.min();
+  const double rng_max = random.max();
+
+  for (int i=0;i<NDIM;i++) {
+    phi[i] = (random()/(rng_max-rng_min))*(2.*M_PI);
+    LOG(4, "DEBUG: Random angle is " << phi[i] << ".");
+  }
+
+  a.setRotation(phi);
+}
+
+/** Constructor for class RandomInserter.
+ *
+ * @param _MaxAtomComponent maximum component for random atom translations
+ * @param _MaxMoleculeComponent maximum component for random molecule translations
+ * @param  _DoRandomRotation whether to do random rotations
+ */
+RandomInserter::RandomInserter(
+    const double _MaxAtomComponent,
+    const double _MaxMoleculeComponent,
+    const bool _DoRandomRotation) :
+   random(RandomNumberGeneratorFactory::getInstance().makeRandomNumberGenerator()),
+   rng_min(random.min()),
+   rng_max(random.max()),
+   MaxAtomComponent(_MaxAtomComponent),
+   MaxMoleculeComponent(_MaxMoleculeComponent),
+   DoRandomRotation(_DoRandomRotation)
+{}
+
+/** Destructor for class RandomInserter.
+ *
+ */
+RandomInserter::~RandomInserter()
+{}
+
+/** Checks whether all atoms currently are inside the cluster's shape.
+ *
+ * @param cluster cluster to check
+ * @return true - all atoms are inside cluster's shape, false - else
+ */
+bool RandomInserter::AreClustersAtomsInside(ClusterInterface::Cluster_impl cluster) const
+{
+  ClusterInterface::atomIdSet atoms = cluster->getAtomIds();
+  bool status = true;
+
+  for (ClusterInterface::atomIdSet::const_iterator iter = atoms.begin();
+      iter != atoms.end();
+      ++iter)
+    status = status && cluster->isInside(*iter);
+
+  return status;
+}
+
+/** Perform the given random translations and rotations on a cluster.
+ *
+ * @param cluster cluster to translate and rotate
+ * @param Rotations random rotation matrix
+ * @param RandomAtomTranslations vector with random translation for each atom in cluster
+ * @param RandomMoleculeTranslation vector with random translation for cluster
+ * @param offset vector with offset for cluster
+ */
+void RandomInserter::doTranslation(
+    ClusterInterface::Cluster_impl cluster,
+    const RealSpaceMatrix &Rotations,
+    const std::vector<Vector> &RandomAtomTranslations,
+    const Vector &RandomMoleculeTranslation) const
+{
+  AtomIdSet atoms = cluster->getAtoms();
+
+  ASSERT( atoms.size() <=  RandomAtomTranslations.size(),
+      "RandomInserter::doTranslation() - insufficient random atom translations given.");
+
+  cluster->transform(Rotations);
+  cluster->translate(RandomMoleculeTranslation);
+  AtomIdSet::iterator miter = atoms.begin();
+  std::vector<Vector>::const_iterator aiter = RandomAtomTranslations.begin();
+  for(;miter != atoms.end(); ++miter, ++aiter)
+    (*miter)->setPosition((*miter)->getPosition() + *aiter);
+}
+
+/** Undos a given random translations and rotations on a cluster.
+ *
+ * @param cluster cluster to translate and rotate
+ * @param Rotations random rotation matrix
+ * @param RandomAtomTranslations vector with random translation for each atom in cluster
+ * @param RandomMoleculeTranslations vector with random translation for cluster
+ * @param offset vector with offset for cluster
+ */
+void RandomInserter::undoTranslation(
+    ClusterInterface::Cluster_impl cluster,
+    const RealSpaceMatrix &Rotations,
+    const std::vector<Vector> &RandomAtomTranslations,
+    const Vector &RandomMoleculeTranslation) const
+{
+  AtomIdSet atoms = cluster->getAtoms();
+  ASSERT( atoms.size() <=  RandomAtomTranslations.size(),
+      "RandomInserter::doTranslation() - insufficient random atom translations given.");
+
+  // get inverse rotation
+  RealSpaceMatrix inverseRotations = Rotations.invert();
+
+  AtomIdSet::iterator miter = atoms.begin();
+  std::vector<Vector>::const_iterator aiter = RandomAtomTranslations.begin();
+  for(;miter != atoms.end(); ++miter, ++aiter) {
+    (*miter)->setPosition((*miter)->getPosition() - *aiter);
+  }
+  cluster->translate(zeroVec-RandomMoleculeTranslation);
+  cluster->transform(inverseRotations);
+}
+
+/** Creates a random vector
+ *
+ * @param range range of components, i.e. \f$ v[i] \in [0,range)\f$
+ * @param offset offset for each component
+ * @return \a range * rnd() + \a offset
+ */
+Vector RandomInserter::getRandomVector(const double range, const double offset) const
+{
+  Vector returnVector;
+  for (size_t i=0; i<NDIM; ++i)
+    returnVector[i] = (range*random()/((rng_max-rng_min)/2.)) + offset;
+  return returnVector;
+}
+
+/** Inserter operator that randomly translates and rotates the Cluster.
+ *
+ * \note we assume that clusters are always cloned at origin.
+ *
+ * @param offset
+ * @return true - random translations and rotations did not violate bounding shape, false - else
+ */
+bool RandomInserter::operator()(ClusterInterface::Cluster_impl cluster, const Vector &offset) const
+{
+  // calculate center
+  AtomIdSet atoms = cluster->getAtoms();
+  Vector center;
+  center.Zero();
+  for(AtomIdSet::iterator miter = atoms.begin();miter != atoms.end(); ++miter)
+    center += (*miter)->getPosition();
+  center *= 1./atoms.size();
+
+  // shift cluster to center
+  cluster->translate(zeroVec-center);
+
+  size_t attempt = 0;
+  for (;attempt < Max_Attempts; ++attempt) {
+    // generate random rotation matrix
+    RealSpaceMatrix Rotations;
+    if (DoRandomRotation)
+      setRandomRotation(Rotations);
+    else
+      Rotations.setIdentity();
+
+    // generate random molecule translation vector
+    Vector RandomMoleculeTranslation(getRandomVector(MaxMoleculeComponent, -MaxMoleculeComponent));
+
+    // generate random atom translation vector
+    std::vector<Vector> RandomAtomTranslations(atoms.size(), zeroVec);
+    std::generate_n(RandomAtomTranslations.begin(), atoms.size(),
+        boost::bind(&RandomInserter::getRandomVector, boost::cref(this), MaxAtomComponent, -MaxAtomComponent));
+
+    // apply!
+    doTranslation(cluster, Rotations, RandomAtomTranslations, RandomMoleculeTranslation);
+
+    // ... and check
+    if (!AreClustersAtomsInside(cluster)) {
+      undoTranslation(cluster, Rotations, RandomAtomTranslations, RandomMoleculeTranslation);
+    } else {
+      break;
+    }
+  }
+
+  // and move to final position
+  cluster->translate(offset+center);
+
+  return attempt != Max_Attempts;
+}
Index: src/Filling/Inserter/RandomInserter.hpp
===================================================================
--- src/Filling/Inserter/RandomInserter.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Inserter/RandomInserter.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,77 @@
+/*
+ * RandomInserter.hpp
+ *
+ *  Created on: Feb 21, 2012
+ *      Author: heber
+ */
+
+#ifndef RANDOMINSERTER_HPP_
+#define RANDOMINSERTER_HPP_
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "InserterBase.hpp"
+
+#include <vector>
+
+#include "LinearAlgebra/Vector.hpp"
+
+class RandomNumberGenerator;
+class RealSpaceMatrix;
+
+/** RandomInserter implements Inserter interface such that the given \a Cluster
+ * is inserted at the position with a slight random variation.
+ *
+ * \warning As the RandomInserter rotates the molecule, the only bounding shape in
+ * Cluster that makes sense is a sphere. Otherwise, RandomInserter::Max_Attempts
+ * attempts are made at finding a lucky shot where all atoms, though rotated
+ * and randomly translated, remain inside but after that the cluster is inserted
+ * as it is.
+ */
+class RandomInserter : public InserterBase
+{
+public:
+  RandomInserter(const double _MaxAtomComponent, const double _MaxMoleculeComponent, const bool _DoRandomRotation);
+  ~RandomInserter();
+
+  bool operator()(ClusterInterface::Cluster_impl cluster, const Vector &offset) const;
+
+private:
+  bool AreClustersAtomsInside(ClusterInterface::Cluster_impl cluster) const;
+  Vector getRandomVector(const double range, const double offset) const;
+
+  void doTranslation(
+      ClusterInterface::Cluster_impl cluster,
+      const RealSpaceMatrix &Rotations,
+      const std::vector<Vector> &RandomAtomTranslations,
+      const Vector &RandomMoleculeTranslations) const;
+  void undoTranslation(
+      ClusterInterface::Cluster_impl cluster,
+      const RealSpaceMatrix &Rotations,
+      const std::vector<Vector> &RandomAtomTranslations,
+      const Vector &RandomMoleculeTranslations) const;
+
+private:
+  //!> internal random number generator
+  RandomNumberGenerator &random;
+  //!> minimum value of the random number distribution
+  const double rng_min;
+  //!> maximum value of the random number distribution
+  const double rng_max;
+  //!> range is maximum component for atom translations
+  const double MaxAtomComponent;
+  //!> range is maximum component for molecule translations
+  const double MaxMoleculeComponent;
+  //!> whether to randomly rotate or not
+  const bool DoRandomRotation;
+
+  //!> maximum number of tries to find a suitable randomized position
+  static size_t Max_Attempts;
+};
+
+
+#endif /* RANDOMINSERTER_HPP_ */
Index: src/Filling/Inserter/SimpleInserter.cpp
===================================================================
--- src/Filling/Inserter/SimpleInserter.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Inserter/SimpleInserter.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/*
+ * SimpleInserter.cpp
+ *
+ *  Created on: Feb 21, 2012
+ *      Author: heber
+ */
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "SimpleInserter.hpp"
+
+/** Constructor for class SimpleInserter.
+ *
+ */
+SimpleInserter::SimpleInserter()
+{}
+
+/** Destructor for class SimpleInserter.
+ *
+ */
+SimpleInserter::~SimpleInserter()
+{}
+
+/** Inserter operator that simply enacts ClusterInterface::clone().
+ *
+ * @param offset
+ * @return always true
+ */
+bool SimpleInserter::operator()(ClusterInterface::Cluster_impl cluster, const Vector &offset) const
+{
+  cluster->translate(offset);
+
+  return true;
+}
Index: src/Filling/Inserter/SimpleInserter.hpp
===================================================================
--- src/Filling/Inserter/SimpleInserter.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Inserter/SimpleInserter.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,33 @@
+/*
+ * SimpleInserter.hpp
+ *
+ *  Created on: Feb 21, 2012
+ *      Author: heber
+ */
+
+#ifndef SIMPLEINSERTER_HPP_
+#define SIMPLEINSERTER_HPP_
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Filling/Inserter/InserterBase.hpp"
+
+/** SimpleInserter implements Inserter interface such that the given \a Cluster
+ * is simply inserted at the given position.
+ */
+class SimpleInserter : public InserterBase
+{
+public:
+  SimpleInserter();
+  ~SimpleInserter();
+
+  bool operator()(ClusterInterface::Cluster_impl cluster, const Vector &offset) const;
+};
+
+
+
+#endif /* SIMPLEINSERTER_HPP_ */
Index: src/Filling/Makefile.am
===================================================================
--- src/Filling/Makefile.am	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Makefile.am	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,84 @@
+# PLEASE adhere to the alphabetical ordering in this Makefile!
+# Also indentation by a single tab
+
+FILLINGSOURCE = \
+	Filling/Cluster.cpp \
+	Filling/Mesh/CubeMesh.cpp \
+	Filling/Mesh/Mesh.cpp \
+	Filling/Filler.cpp \
+	Filling/Generators/NodeGenerator.cpp \
+	Filling/Inserter/Inserter.cpp \
+	Filling/Inserter/RandomInserter.cpp \
+	Filling/Inserter/SimpleInserter.cpp \
+	Filling/Predicates/AnyFillPredicate.cpp \
+	Filling/Predicates/FillPredicate.cpp \
+	Filling/Predicates/IsInsideDomain_FillPredicate.cpp \
+	Filling/Predicates/IsInsideSurface_FillPredicate.cpp \
+	Filling/Predicates/IsValidInDomain_FillPredicate.cpp \
+	Filling/Predicates/IsVoidNode_FillPredicate.cpp \
+	Filling/Predicates/Ops_FillPredicate.cpp
+	
+FILLINGHEADER = \
+	Filling/Cluster.hpp \
+	Filling/ClusterInterface.hpp \
+	Filling/Mesh/CubeMesh.hpp \
+	Filling/Mesh/Mesh.hpp \
+	Filling/Filler.hpp \
+	Filling/Generators/NodeGenerator.hpp \
+	Filling/Inserter/Inserter.hpp \
+	Filling/Inserter/InserterBase.hpp \
+	Filling/Inserter/RandomInserter.hpp \
+	Filling/Inserter/SimpleInserter.hpp \
+	Filling/NodeTypes.hpp \
+	Filling/Predicates/AnyFillPredicate.hpp \
+	Filling/Predicates/FillPredicate.hpp \
+	Filling/Predicates/FillPredicateBase.hpp \
+	Filling/Predicates/FillPredicate_impl.hpp \
+	Filling/Predicates/IsInsideDomain_FillPredicate.hpp \
+	Filling/Predicates/IsInsideSurface_FillPredicate.hpp \
+	Filling/Predicates/IsValidInDomain_FillPredicate.hpp \
+	Filling/Predicates/IsVoidNode_FillPredicate.hpp \
+	Filling/Predicates/Ops_FillPredicate.hpp \
+	Filling/Predicates/Ops_FillPredicate_impl.hpp
+				  
+
+noinst_LTLIBRARIES += libMolecuilderFilling.la
+libMolecuilderFilling_la_includedir = $(includedir)/MoleCuilder/Filling/
+
+nobase_libMolecuilderFilling_la_include_HEADERS = ${FILLINGHEADER}
+
+## Define the source file list for the "libexample-@MOLECUILDER_API_VERSION@.la"
+## target.  Note that @MOLECUILDER_API_VERSION@ is not interpreted by Automake and
+## will therefore be treated as if it were literally part of the target name,
+## and the variable name derived from that.
+## The file extension .cc is recognized by Automake, and makes it produce
+## rules which invoke the C++ compiler to produce a libtool object file (.lo)
+## from each source file.  Note that it is not necessary to list header files
+## which are already listed elsewhere in a _HEADERS variable assignment.
+libMolecuilderFilling_la_SOURCES = ${FILLINGSOURCE}
+
+## Instruct libtool to include ABI version information in the generated shared
+## library file (.so).  The library ABI version is defined in configure.ac, so
+## that all version information is kept in one place.
+#libMolecuilderFilling_la_LDFLAGS = -version-info $(MOLECUILDER_SO_VERSION)
+
+## The generated configuration header is installed in its own subdirectory of
+## $(libdir).  The reason for this is that the configuration information put
+## into this header file describes the target platform the installed library
+## has been built for.  Thus the file must not be installed into a location
+## intended for architecture-independent files, as defined by the Filesystem
+## Hierarchy Standard (FHS).
+## The nodist_ prefix instructs Automake to not generate rules for including
+## the listed files in the distribution on 'make dist'.  Files that are listed
+## in _HEADERS variables are normally included in the distribution, but the
+## configuration header file is generated at configure time and should not be
+## shipped with the source tarball.
+#libMolecuilderFilling_libincludedir = $(libdir)/MoleCuilder/include
+#nodist_libMolecuilderFilling_libinclude_HEADERS = $(top_builddir)/libmolecuilder_config.h
+
+## Install the generated pkg-config file (.pc) into the expected location for
+## architecture-dependent package configuration information.  Occasionally,
+## pkg-config files are also used for architecture-independent data packages,
+## in which case the correct install location would be $(datadir)/pkgconfig.
+#pkgconfigdir = $(libdir)/pkgconfig
+#pkgconfig_DATA = $(top_builddir)/MoleCuilder.pc
Index: src/Filling/Mesh/CubeMesh.cpp
===================================================================
--- src/Filling/Mesh/CubeMesh.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Mesh/CubeMesh.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+/*
+ * CubeMesh.cpp
+ *
+ *  Created on: Jan 20, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include <boost/lambda/lambda.hpp>
+#include <cmath>
+
+#include "CodePatterns/Log.hpp"
+#include "CubeMesh.hpp"
+#include "LinearAlgebra/RealSpaceMatrix.hpp"
+#include "LinearAlgebra/Vector.hpp"
+
+/** Constructor for class CubeMesh.
+ *
+ * Here, we generate nodes homogeneously distributed over a cuboid.
+ *
+ * \a offset shifts the coordinates, e.g. if counts = 2, we would set nodes at
+ * 0 and 0.5 with offset = 0 and 0.4999... and 0.9999.. with offset = 0.999...
+ *
+ * @param counts number of points per axis
+ * @param offset offset Vector (coordinates in [0,1))
+ * @param M matrix to transform the default cuboid from (0,0,0) to (1,1,1).
+ */
+CubeMesh::CubeMesh(const Vector &counts, const Vector &offset, const RealSpaceMatrix &M)
+{
+  RealSpaceMatrix partition;
+  int n[NDIM];
+
+#ifndef NDEBUG
+  for (size_t i=0;i<NDIM;++i) {
+    ASSERT((offset[i] >= 0.) && (offset[i] < 1.),
+        "CubeMesh::CubeMesh() - offset coordinates must be in [0,1) but offset["
+        +toString(i)+"] is "+toString(offset[i])+".");
+    ASSERT(counts[i] != 0.,
+        "CubeMesh::CubeMesh() - counts["+toString(i)+"] must be != "+toString(counts[i])+".");
+  }
+#endif
+
+  partition.setZero();
+  for(int i=0;i<NDIM;i++)
+    partition.at(i,i) =  1./(double)counts[i];
+  LOG(1, "INFO: partition is " << partition << ".");
+
+
+  // go over [0,1]^3 filler grid
+  for (n[0] = 0; n[0] < counts[0]; n[0]++)
+    for (n[1] = 0; n[1] < counts[1]; n[1]++)
+      for (n[2] = 0; n[2] < counts[2]; n[2]++) {
+        const Vector CurrentPosition((double)n[0], (double)n[1], (double)n[2]);
+        nodes.push_back(M * partition * (CurrentPosition + offset));
+      }
+}
+
+/** Destructor for class CubeMesh.
+ *
+ */
+CubeMesh::~CubeMesh()
+{}
Index: src/Filling/Mesh/CubeMesh.hpp
===================================================================
--- src/Filling/Mesh/CubeMesh.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Mesh/CubeMesh.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,31 @@
+/*
+ * CubeMesh.hpp
+ *
+ *  Created on: Jan 20, 2012
+ *      Author: heber
+ */
+
+#ifndef CUBEMESH_HPP_
+#define CUBEMESH_HPP_
+
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Filling/NodeTypes.hpp"
+#include "Mesh.hpp"
+
+class Vector;
+
+class CubeMesh : public Mesh
+{
+public:
+  CubeMesh(const Vector &counts, const Vector &offset, const RealSpaceMatrix &M);
+  virtual ~CubeMesh();
+
+};
+
+#endif /* CUBEMESH_HPP_ */
Index: src/Filling/Mesh/Mesh.cpp
===================================================================
--- src/Filling/Mesh/Mesh.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Mesh/Mesh.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+/*
+ * Mesh.cpp
+ *
+ *  Created on: Jan 19, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "Mesh.hpp"
+
+#include "CodePatterns/Assert.hpp"
+
+/** Constructor for class Mesh.
+ *
+ */
+Mesh::Mesh()
+{}
+
+/** Copy constructor for class Mesh.
+ *
+ * @param mesh instance to copy
+ */
+Mesh::Mesh(const Mesh &mesh) :
+    nodes(mesh.getNodes())
+{
+  ASSERT( nodes.size() == mesh.getNodes().size(),
+      "Mesh::Mesh() - copied nodes contains not the same number.");
+}
+
+/** Destructor for class Mesh.
+ *
+ */
+Mesh::~Mesh()
+{}
+
+const NodeSet & Mesh::getNodes() const
+{
+  return nodes;
+}
Index: src/Filling/Mesh/Mesh.hpp
===================================================================
--- src/Filling/Mesh/Mesh.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Mesh/Mesh.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,33 @@
+/*
+ * Mesh.hpp
+ *
+ *  Created on: Jan 19, 2012
+ *      Author: heber
+ */
+
+#ifndef MESH_HPP_
+#define MESH_HPP_
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Filling/NodeTypes.hpp"
+
+class Mesh
+{
+public:
+  Mesh();
+  Mesh(const Mesh &mesh);
+  virtual ~Mesh();
+
+  const NodeSet &getNodes() const;
+
+protected:
+  NodeSet nodes;
+};
+
+
+#endif /* MESH_HPP_ */
Index: src/Filling/NodeTypes.hpp
===================================================================
--- src/Filling/NodeTypes.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/NodeTypes.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,23 @@
+/*
+ * NodeTypes.hpp
+ *
+ *  Created on: 17.01.2012
+ *      Author: heber
+ */
+
+#ifndef NODETYPES_HPP_
+#define NODETYPES_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <vector>
+
+#include "LinearAlgebra/Vector.hpp"
+
+typedef Vector Node;
+typedef std::vector<Vector> NodeSet;
+
+#endif /* NODETYPES_HPP_ */
Index: src/Filling/Predicates/AnyFillPredicate.cpp
===================================================================
--- src/Filling/Predicates/AnyFillPredicate.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Predicates/AnyFillPredicate.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+/*
+ * AnyFillPredicate.cpp
+ *
+ *  Created on: Jan 19, 2012
+ *      Author: heber
+ */
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "AnyFillPredicate.hpp"
+
+/** Constructor for class AnyFillPredicate.
+ *
+ * @param _function function to use as predicate
+ */
+AnyFillPredicate::AnyFillPredicate(FillPredicator &_function) :
+  function(_function)
+{}
+
+/** Destructor for class AnyFillPredicate
+ *
+ */
+AnyFillPredicate::~AnyFillPredicate()
+{}
+
+/** Predicate implementation that simply calls upon \a AnyFillPredicate::function.
+ *
+ * @param n Node for which the predicate is to check
+ * @return true - predicate results as true, false - predicate results as false
+ */
+bool AnyFillPredicate::operator()(const Node&n) const {
+  return function(n);
+}
Index: src/Filling/Predicates/AnyFillPredicate.hpp
===================================================================
--- src/Filling/Predicates/AnyFillPredicate.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Predicates/AnyFillPredicate.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,41 @@
+/*
+ * AnyFillPredicate.hpp
+ *
+ *  Created on: Jan 19, 2012
+ *      Author: heber
+ */
+
+#ifndef ANYFILLPREDICATE_HPP_
+#define ANYFILLPREDICATE_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <boost/function.hpp>
+
+#include "FillPredicateBase.hpp"
+#include "types.hpp"
+
+
+/** Allows arbitrarily bound boolean functions to represent a predicate.
+ *
+ */
+class AnyFillPredicate : public FillPredicateBase
+{
+public:
+  //!> specific type of the predicate function
+  typedef boost::function<bool(const Node&)> FillPredicator;
+
+  AnyFillPredicate(FillPredicator &_function);
+  virtual ~AnyFillPredicate();
+
+  bool operator()(const Node&n) const;
+
+private:
+  FillPredicator function;
+};
+
+
+#endif /* ANYFILLPREDICATE_HPP_ */
Index: src/Filling/Predicates/FillPredicate.cpp
===================================================================
--- src/Filling/Predicates/FillPredicate.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Predicates/FillPredicate.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+/*
+ * FillPredicate.cpp
+ *
+ *  Created on: Jan 19, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "FillPredicate.hpp"
+
+#include "FillPredicateBase.hpp"
+#include "FillPredicate_impl.hpp"
+
+/** Constructor for class FillPredicate.
+ *
+ * @param _impl implementation to wrap
+ */
+FillPredicate::FillPredicate(FillPredicate::impl_ptr _impl) :
+    impl(_impl)
+{}
+
+/** Copy Constructor for class FillPredicate.
+ *
+ */
+FillPredicate::FillPredicate(const FillPredicate &ptr) :
+    impl(ptr.getImpl())
+{}
+
+/** Destructor for class FillPredicate.
+ *
+ */
+FillPredicate::~FillPredicate()
+{}
+
+bool FillPredicate::operator()(const Node &n) const
+{
+  return impl->operator()(n);
+}
+
+FillPredicate::impl_ptr FillPredicate::getImpl() const {
+  return impl;
+}
+
+FillPredicate AlwaysFillPredicate()
+{
+  static FillPredicate::impl_ptr impl = FillPredicate::impl_ptr(new AlwaysFillPredicate_impl());
+  return FillPredicate(impl);
+}
+
+FillPredicate NeverFillPredicate()
+{
+  static FillPredicate::impl_ptr impl = FillPredicate::impl_ptr(new NeverFillPredicate_impl());
+  return FillPredicate(impl);
+}
+
+// allows arbitrary friendship, but only if implementation is known
+FillPredicate::impl_ptr getFillPredicateImpl(const FillPredicate &f){
+  return f.getImpl();
+}
Index: src/Filling/Predicates/FillPredicate.hpp
===================================================================
--- src/Filling/Predicates/FillPredicate.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Predicates/FillPredicate.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,51 @@
+/*
+ * FillPredicate.hpp
+ *
+ *  Created on: Jan 16, 2012
+ *      Author: heber
+ */
+
+#ifndef FILLPREDICATE_HPP_
+#define FILLPREDICATE_HPP_
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Filling/NodeTypes.hpp"
+
+#include <boost/shared_ptr.hpp>
+
+class FillPredicateBase;
+
+/** This class defines the interface for all derived classes.
+ *
+ * This is just a functor of a predicate function.
+ *
+ */
+class FillPredicate
+{
+public:
+  typedef boost::shared_ptr<FillPredicateBase> impl_ptr;
+  friend impl_ptr getFillPredicateImpl(const FillPredicate&);
+
+  FillPredicate(const FillPredicate &ptr);
+  FillPredicate(impl_ptr);
+  ~FillPredicate();
+  bool operator()(const Node &n) const;
+
+protected:
+  impl_ptr getImpl() const;
+
+private:
+  impl_ptr impl;
+};
+
+FillPredicate AlwaysFillPredicate();
+FillPredicate NeverFillPredicate();
+
+FillPredicate::impl_ptr getFillPredicateImpl(const FillPredicate &f);
+
+#endif /* FILLPREDICATE_HPP_ */
Index: src/Filling/Predicates/FillPredicateBase.hpp
===================================================================
--- src/Filling/Predicates/FillPredicateBase.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Predicates/FillPredicateBase.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,31 @@
+/*
+ * FillPredicateBase.hpp
+ *
+ *  Created on: Jan 19, 2012
+ *      Author: heber
+ */
+
+#ifndef FILLPREDICATEBASE_HPP_
+#define FILLPREDICATEBASE_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Filling/NodeTypes.hpp"
+
+/** This class defines the interface for all derived classes.
+ *
+ * This is just a functor of a predicate function.
+ *
+ */
+struct FillPredicateBase
+{
+  FillPredicateBase(){};
+  virtual ~FillPredicateBase(){};
+  virtual bool operator()(const Node &n) const=0;
+};
+
+
+#endif /* FILLPREDICATEBASE_HPP_ */
Index: src/Filling/Predicates/FillPredicate_impl.hpp
===================================================================
--- src/Filling/Predicates/FillPredicate_impl.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Predicates/FillPredicate_impl.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,33 @@
+/*
+ * FillPredicate_impl.hpp
+ *
+ *  Created on: Jan 19, 2012
+ *      Author: heber
+ */
+
+#ifndef FILLPREDICATE_IMPL_HPP_
+#define FILLPREDICATE_IMPL_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "FillPredicateBase.hpp"
+#include "types.hpp"
+
+class AlwaysFillPredicate_impl : public FillPredicateBase {
+public:
+  virtual bool operator()(const Node&n) const{
+    return true;
+  }
+};
+
+class NeverFillPredicate_impl : public FillPredicateBase {
+public:
+  virtual bool operator()(const Node&n) const{
+    return false;
+  }
+};
+
+#endif /* FILLPREDICATE_IMPL_HPP_ */
Index: src/Filling/Predicates/IsInsideDomain_FillPredicate.cpp
===================================================================
--- src/Filling/Predicates/IsInsideDomain_FillPredicate.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Predicates/IsInsideDomain_FillPredicate.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/*
+ * IsInsideDomain_FillPredicate.cpp
+ *
+ *  Created on: Jan 19, 2012
+ *      Author: heber
+ */
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include <boost/bind.hpp>
+
+#include "IsInsideDomain_FillPredicate.hpp"
+
+#include "AnyFillPredicate.hpp"
+#include "Box.hpp"
+#include "FillPredicate.hpp"
+
+FillPredicate IsInsideDomain_FillPredicate(const Box &domain)
+{
+  AnyFillPredicate::FillPredicator function = boost::bind(&Box::isInside, &domain, _1);
+  FillPredicate::impl_ptr impl(new AnyFillPredicate(function));
+  return FillPredicate(impl);
+}
Index: src/Filling/Predicates/IsInsideDomain_FillPredicate.hpp
===================================================================
--- src/Filling/Predicates/IsInsideDomain_FillPredicate.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Predicates/IsInsideDomain_FillPredicate.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,22 @@
+/*
+ * IsInsideDomain_FillPredicate.hpp
+ *
+ *  Created on: Jan 19, 2012
+ *      Author: heber
+ */
+
+#ifndef ISINSIDEDOMAIN_FILLPREDICATE_HPP_
+#define ISINSIDEDOMAIN_FILLPREDICATE_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "FillPredicate.hpp"
+
+class Box;
+
+FillPredicate IsInsideDomain_FillPredicate(const Box &domain);
+
+#endif /* ISINSIDEDOMAIN_FILLPREDICATE_HPP_ */
Index: src/Filling/Predicates/IsInsideSurface_FillPredicate.cpp
===================================================================
--- src/Filling/Predicates/IsInsideSurface_FillPredicate.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Predicates/IsInsideSurface_FillPredicate.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/*
+ * IsInsideSurface_FillPredicate.cpp
+ *
+ *  Created on: Jan 16, 2012
+ *      Author: heber
+ */
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include <boost/bind.hpp>
+
+#include "IsInsideSurface_FillPredicate.hpp"
+
+#include "AnyFillPredicate.hpp"
+#include "FillPredicate.hpp"
+#include "Tesselation/tesselation.hpp"
+
+FillPredicate IsInsideSurface_FillPredicate(const Tesselation &_tess, const LinkedCell_deprecated &_LC)
+{
+  AnyFillPredicate::FillPredicator function = boost::bind(&Tesselation::IsInnerPoint, &_tess, _1, &_LC);
+  FillPredicate::impl_ptr impl(new AnyFillPredicate(function));
+  return FillPredicate(impl);
+}
Index: src/Filling/Predicates/IsInsideSurface_FillPredicate.hpp
===================================================================
--- src/Filling/Predicates/IsInsideSurface_FillPredicate.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Predicates/IsInsideSurface_FillPredicate.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,25 @@
+/*
+ * IsInsideSurface_FillPredicate.hpp
+ *
+ *  Created on: Jan 16, 2012
+ *      Author: heber
+ */
+
+#ifndef ISINSIDESURFACE_FILLPREDICATE_HPP_
+#define ISINSIDESURFACE_FILLPREDICATE_HPP_
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "FillPredicate.hpp"
+
+class LinkedCell_deprecated;
+class Tesselation;
+
+
+FillPredicate IsInsideSurface_FillPredicate(const Tesselation &_tess, const LinkedCell_deprecated &_LC);
+
+#endif /* ISINSIDESURFACE_FILLPREDICATE_HPP_ */
Index: src/Filling/Predicates/IsValidInDomain_FillPredicate.cpp
===================================================================
--- src/Filling/Predicates/IsValidInDomain_FillPredicate.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Predicates/IsValidInDomain_FillPredicate.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+/*
+ * IsValidInDomain_FillPredicate.cpp
+ *
+ *  Created on: Jan 16, 2012
+ *      Author: heber
+ */
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include <boost/bind.hpp>
+
+#include "IsValidInDomain_FillPredicate.hpp"
+
+#include "AnyFillPredicate.hpp"
+#include "Box.hpp"
+#include "FillPredicate.hpp"
+
+
+FillPredicate IsValidInDomain_FillPredicate(const Box &domain)
+{
+  AnyFillPredicate::FillPredicator function = boost::bind(&Box::isValid, &domain, _1);
+  FillPredicate::impl_ptr impl(new AnyFillPredicate(function));
+  return FillPredicate(impl);
+}
Index: src/Filling/Predicates/IsValidInDomain_FillPredicate.hpp
===================================================================
--- src/Filling/Predicates/IsValidInDomain_FillPredicate.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Predicates/IsValidInDomain_FillPredicate.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,22 @@
+/*
+ * IsValidInDomain_FillPredicate.hpp
+ *
+ *  Created on: Jan 16, 2012
+ *      Author: heber
+ */
+
+#ifndef ISVALIDINDOMAIN_FILLPREDICATE_HPP_
+#define ISVALIDINDOMAIN_FILLPREDICATE_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "FillPredicate.hpp"
+
+class Box;
+
+FillPredicate IsValidInDomain_FillPredicate(const Box &domain);
+
+#endif /* ISVALIDINDOMAIN_FILLPREDICATE_HPP_ */
Index: src/Filling/Predicates/IsVoidNode_FillPredicate.cpp
===================================================================
--- src/Filling/Predicates/IsVoidNode_FillPredicate.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Predicates/IsVoidNode_FillPredicate.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+/*
+ * IsVoidNode_FillPredicate.cpp
+ *
+ *  Created on: Jan 16, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include <boost/bind.hpp>
+
+#include "IsVoidNode_FillPredicate.hpp"
+
+#include "CodePatterns/Log.hpp"
+
+#include "Atom/TesselPoint.hpp"
+#include "LinkedCell/LinkedCell_View.hpp"
+#include "Shapes/ShapeOps.hpp"
+#include "Tesselation/tesselation.hpp"
+#include "World.hpp"
+
+#include "AnyFillPredicate.hpp"
+#include "FillPredicate.hpp"
+
+/** Checks whether a given node \a n in the domain is empty with respect to the
+ * given \a shape.
+ *
+ * @param LC View of a linked cell structure for finding neighbors quickly
+ * @param shape shape as a sort of placeholder
+ * @param n point where to center the placeholder
+ * @return true - placeholder at node contains no points,
+ *         false - there is at least one point contained
+ */
+bool IsVoidNode(const LinkedCell::LinkedCell_View &LC, const Shape &shape, const Node &n)
+{
+  LOG(3, "DEBUG: Node is " << n << ".");
+  LOG(3, "DEBUG: Original shape is at " << shape.getCenter() << " with radius of "
+      << shape.getRadius() << ".");
+  const Shape shapeAtn = translate(shape, n);
+  LOG(3, "DEBUG: Translated shape is at " << shapeAtn.getCenter() << ".");
+  LinkedCell::LinkedList neighborlist = LC.getAllNeighbors(
+      shapeAtn.getRadius(), shapeAtn.getCenter());
+  LOG(3, "DEBUG: we have " << neighborlist.size() << " possible neighbors.");
+  LinkedCell::LinkedList::const_iterator neighboriter =
+      std::find_if(neighborlist.begin(), neighborlist.end(),
+          boost::bind(&Shape::isInside, shapeAtn,
+              boost::bind(&TesselPoint::getPosition, _1) ));
+  return neighboriter == neighborlist.end();
+}
+
+FillPredicate IsVoidNode_FillPredicate(const Shape &_shape)
+{
+  // copy _shape !
+  const LinkedCell::LinkedCell_View LC = World::getInstance().getLinkedCell(_shape.getRadius());
+  AnyFillPredicate::FillPredicator function = boost::bind(&IsVoidNode, LC, _shape, _1);
+  LOG(2, "DEBUG: Create IsVoidNode_FillPredicate from shape at "
+      << _shape.getCenter() << " and radius " << _shape.getRadius() << ".");
+  FillPredicate::impl_ptr impl(new AnyFillPredicate(function));
+  return FillPredicate(impl);
+}
Index: src/Filling/Predicates/IsVoidNode_FillPredicate.hpp
===================================================================
--- src/Filling/Predicates/IsVoidNode_FillPredicate.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Predicates/IsVoidNode_FillPredicate.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,25 @@
+/*
+ * IsVoidNode_FillPredicate.hpp
+ *
+ *  Created on: Jan 16, 2012
+ *      Author: heber
+ */
+
+#ifndef ISVOIDNODE_FILLPREDICATE_HPP_
+#define ISVOIDNODE_FILLPREDICATE_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "FillPredicate.hpp"
+
+namespace LinkedCell {
+  class LinkedCell_View;
+}
+class Shape;
+
+FillPredicate IsVoidNode_FillPredicate(const Shape &_shape);
+
+#endif /* ISVOIDNODE_FILLPREDICATE_HPP_ */
Index: src/Filling/Predicates/Ops_FillPredicate.cpp
===================================================================
--- src/Filling/Predicates/Ops_FillPredicate.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Predicates/Ops_FillPredicate.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/*
+ * Ops_FillPredicate.cpp
+ *
+ *  Created on: 17.01.2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "Ops_FillPredicate.hpp"
+#include "Ops_FillPredicate_impl.hpp"
+
+FillPredicate operator&&(const FillPredicate &a, const FillPredicate &b)
+{
+  FillPredicate::impl_ptr impl_ptr = FillPredicate::impl_ptr(
+      new And_FillPredicate(getFillPredicateImpl(a),getFillPredicateImpl(b)));
+	return FillPredicate(impl_ptr);
+}
+
+FillPredicate operator||(const FillPredicate &a, const FillPredicate &b)
+{
+  FillPredicate::impl_ptr impl_ptr = FillPredicate::impl_ptr(
+      new Or_FillPredicate(getFillPredicateImpl(a),getFillPredicateImpl(b)));
+  return FillPredicate(impl_ptr);
+}
+
+FillPredicate operator!(const FillPredicate &a)
+{
+  FillPredicate::impl_ptr impl_ptr = FillPredicate::impl_ptr(
+      new Not_FillPredicate(getFillPredicateImpl(a)));
+  return FillPredicate(impl_ptr);
+}
Index: src/Filling/Predicates/Ops_FillPredicate.hpp
===================================================================
--- src/Filling/Predicates/Ops_FillPredicate.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Predicates/Ops_FillPredicate.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,24 @@
+/*
+ * Ops_FillPredicate.hpp
+ *
+ *  Created on: 17.01.2012
+ *      Author: heber
+ */
+
+#ifndef OPS_FILLPREDICATE_HPP_
+#define OPS_FILLPREDICATE_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "FillPredicate.hpp"
+
+
+FillPredicate operator&&(const FillPredicate &a, const FillPredicate &b);
+FillPredicate operator||(const FillPredicate &a, const FillPredicate &b);
+FillPredicate operator!(const FillPredicate &a);
+
+
+#endif /* OPS_FILLPREDICATE_HPP_ */
Index: src/Filling/Predicates/Ops_FillPredicate_impl.hpp
===================================================================
--- src/Filling/Predicates/Ops_FillPredicate_impl.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/Predicates/Ops_FillPredicate_impl.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,80 @@
+/*
+ * Ops_FillPredicate_impl.hpp
+ *
+ *  Created on: 17.01.2012
+ *      Author: heber
+ */
+
+#ifndef OPS_FILLPREDICATE_IMPL_HPP_
+#define OPS_FILLPREDICATE_IMPL_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "FillPredicateBase.hpp"
+
+/** Logical AND composition of two FillPredicate's.
+ *
+ */
+class And_FillPredicate : public FillPredicateBase
+{
+public:
+	And_FillPredicate(const FillPredicate::impl_ptr &_a, const FillPredicate::impl_ptr &_b) :
+		a(_a), b(_b)
+	{}
+	virtual ~And_FillPredicate()
+	{}
+
+	bool operator()(const Node &n) const {
+		return (*a)(n) && (*b)(n);
+	}
+
+private:
+	FillPredicate::impl_ptr a;
+	FillPredicate::impl_ptr b;
+};
+
+/** Logical OR composition of two FillPredicate's.
+ *
+ */
+class Or_FillPredicate : public FillPredicateBase
+{
+public:
+	Or_FillPredicate(const FillPredicate::impl_ptr &_a, const FillPredicate::impl_ptr &_b) :
+		a(_a), b(_b)
+	{}
+	virtual ~Or_FillPredicate()
+	{}
+
+	bool operator()(const Node &n) const {
+		return (*a)(n) || (*b)(n);
+	}
+
+private:
+	FillPredicate::impl_ptr a;
+	FillPredicate::impl_ptr b;
+};
+
+/** Logical NOT composition of two FillPredicate's.
+ *
+ */
+class Not_FillPredicate : public FillPredicateBase
+{
+public:
+	Not_FillPredicate(const FillPredicate::impl_ptr &_a) :
+		a(_a)
+	{}
+	virtual ~Not_FillPredicate()
+	{}
+
+	bool operator()(const Node &n) const {
+		return !(*a)(n);
+	}
+
+private:
+	FillPredicate::impl_ptr a;
+};
+
+#endif /* OPS_FILLPREDICATE_IMPL_HPP_ */
Index: src/Filling/unittests/ClusterUnitTest.cpp
===================================================================
--- src/Filling/unittests/ClusterUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/unittests/ClusterUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,312 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2010-2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * ClusterUnitTest.cpp
+ *
+ *  Created on: Jan 17, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include "CodePatterns/Assert.hpp"
+
+#include "Atom/CopyAtoms/CopyAtoms_Simple.hpp"
+#include "Descriptors/AtomIdDescriptor.hpp"
+#include "Element/periodentafel.hpp"
+#include "Filling/Cluster.hpp"
+#include "LinearAlgebra/Vector.hpp"
+#include "LinearAlgebra/RealSpaceMatrix.hpp"
+#include "Shapes/BaseShapes.hpp"
+#include "Shapes/Shape.hpp"
+#include "World.hpp"
+#include "WorldTime.hpp"
+
+#include "ClusterUnitTest.hpp"
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+/********************************************** Test classes **************************************/
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( ClusterTest );
+
+
+void ClusterTest::setUp()
+{
+  // failing asserts should be thrown
+  ASSERT_DO(Assert::Throw);
+
+  // this must not compile: private default Cstor
+  // cluster = new Cluster();
+
+  shape  = new Shape(Sphere());
+
+  // create an atom
+  _atom = World::getInstance().createAtom();
+  const element * hydrogen = World::getInstance().getPeriode()->FindElement(1);
+  CPPUNIT_ASSERT(hydrogen != NULL);
+  _atom->setType(hydrogen);
+  _atom->setPosition(Vector(0.,0.,0.));
+  _atomId = _atom->getId();
+
+  cluster = new Cluster(*shape);
+}
+
+
+void ClusterTest::tearDown()
+{
+  delete cluster;
+
+  World::purgeInstance();
+  WorldTime::purgeInstance();
+}
+
+/** Test whether setting and getting works
+ *
+ */
+void ClusterTest::insert_eraseTest()
+{
+  // check for empty cluster
+  CPPUNIT_ASSERT_EQUAL( (size_t)0, cluster->getAtomIds().size() );
+
+  // Shape is sphere at (0,0,0) with radius 1
+
+  {
+    // insert present atom at center of shape
+#ifndef NDEBUG
+    CPPUNIT_ASSERT_NO_THROW( cluster->insert(_atomId) );
+#else
+    cluster->insert(_atomId);
+#endif
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cluster->getAtomIds().size() );
+#ifndef NDEBUG
+    CPPUNIT_ASSERT_NO_THROW( cluster->erase(_atomId) );
+#else
+    cluster->erase(_atomId);
+#endif
+  }
+
+  {
+    // erase non-existing atom
+    const atomId_t falseId = _atomId+1;
+    CPPUNIT_ASSERT_EQUAL( (atom *)NULL, World::getInstance().getAtom(AtomById(falseId)) );
+#ifndef NDEBUG
+    std::cout << "The following Assertion is intended and does not present a failure of the test." << std::endl;
+    CPPUNIT_ASSERT_THROW( cluster->erase(falseId), Assert::AssertionFailure );
+#else
+    cluster->erase(falseId);
+#endif
+  }
+
+  {
+    // erase non-present atom
+#ifndef NDEBUG
+    std::cout << "The following Assertion is intended and does not present a failure of the test." << std::endl;
+    CPPUNIT_ASSERT_THROW( cluster->erase(_atomId), Assert::AssertionFailure );
+#else
+    cluster->erase(_atomId);
+#endif
+  }
+
+  {
+    // insert present atom within shape
+    _atom->setPosition(Vector(.5,.5,.5));
+#ifndef NDEBUG
+    CPPUNIT_ASSERT_NO_THROW( cluster->insert(_atomId) );
+#else
+    cluster->insert(_atomId);
+#endif
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cluster->getAtomIds().size() );
+#ifndef NDEBUG
+    CPPUNIT_ASSERT_NO_THROW( cluster->erase(_atomId) );
+#else
+    cluster->erase(_atomId);
+#endif
+    _atom->setPosition(Vector(0.,0.,0.));
+  }
+
+  {
+    // insert present atom outside shape
+    _atom->setPosition(Vector(2.,0.,0.));
+#ifndef NDEBUG
+    std::cout << "The following Assertion is intended and does not present a failure of the test." << std::endl;
+    CPPUNIT_ASSERT_THROW( cluster->insert(_atomId), Assert::AssertionFailure );
+#else
+    cluster->insert(_atomId);
+#endif
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cluster->getAtomIds().size() );
+    _atom->setPosition(Vector(0.,0.,0.));
+  }
+
+  {
+    // insert present atom on boundary shape
+    _atom->setPosition(Vector(1.,0.,0.));
+#ifndef NDEBUG
+    CPPUNIT_ASSERT_NO_THROW( cluster->insert(_atomId) );
+#else
+    cluster->insert(_atomId);
+#endif
+    CPPUNIT_ASSERT_EQUAL( (size_t)1, cluster->getAtomIds().size() );
+#ifndef NDEBUG
+    CPPUNIT_ASSERT_NO_THROW( cluster->erase(_atomId) );
+#else
+    cluster->erase(_atomId);
+#endif
+    _atom->setPosition(Vector(0.,0.,0.));
+  }
+
+  {
+    // insert non-existing atom
+    const atomId_t falseId = _atomId+1;
+    CPPUNIT_ASSERT_EQUAL( (atom *)NULL, World::getInstance().getAtom(AtomById(falseId)) );
+#ifndef NDEBUG
+    std::cout << "The following Assertion is intended and does not present a failure of the test." << std::endl;
+    CPPUNIT_ASSERT_THROW( cluster->insert(falseId), Assert::AssertionFailure );
+#else
+    cluster->insert(falseId);
+#endif
+    CPPUNIT_ASSERT_EQUAL( (size_t)0, cluster->getAtomIds().size() );
+  }
+}
+
+/** Test whether setting and getting works
+ *
+ */
+void ClusterTest::setter_getterTest()
+{
+  CPPUNIT_ASSERT( *shape == cluster->getShape() );
+
+  CPPUNIT_ASSERT( cluster->atoms == cluster->getAtomIds() );
+}
+
+/** Test whether translate() works
+ *
+ */
+void ClusterTest::translateTest()
+{
+  // insert
+  cluster->insert(_atomId);
+  CPPUNIT_ASSERT_EQUAL( (size_t)1, cluster->getAtomIds().size() );
+
+  // check we are at origin
+  CPPUNIT_ASSERT_EQUAL( Vector(0.,0.,0.), cluster->getShape().getCenter() );
+  const atom * _atom = NULL;
+  CPPUNIT_ASSERT_NO_THROW( _atom = cluster->getAtomById(_atomId) );
+  CPPUNIT_ASSERT( _atom != NULL );
+  CPPUNIT_ASSERT_EQUAL( Vector(0.,0.,0.), _atom->getPosition() );
+
+  // move
+  cluster->translate( Vector(1.,0.,0.) );
+
+  CPPUNIT_ASSERT_EQUAL( Vector(1.,0.,0.), cluster->getShape().getCenter() );
+  CPPUNIT_ASSERT_EQUAL( Vector(1.,0.,0.), cluster->getAtomById(_atomId)->getPosition() );
+}
+
+
+/** Test whether transform() works
+ *
+ */
+void ClusterTest::transformTest()
+{
+  // insert
+  cluster->insert(_atomId);
+  CPPUNIT_ASSERT_EQUAL( (size_t)1, cluster->getAtomIds().size() );
+
+  // check we are at origin
+  CPPUNIT_ASSERT_EQUAL( Vector(0.,0.,0.), cluster->getShape().getCenter() );
+  const atom * _atom = NULL;
+  CPPUNIT_ASSERT_NO_THROW( _atom = cluster->getAtomById(_atomId) );
+  CPPUNIT_ASSERT( _atom != NULL );
+  CPPUNIT_ASSERT_EQUAL( Vector(0.,0.,0.), _atom->getPosition() );
+
+  // transform
+  RealSpaceMatrix M;
+  M.setIdentity();
+  cluster->transform( M );
+
+  CPPUNIT_ASSERT_EQUAL( Vector(0.,0.,0.), cluster->getShape().getCenter() );
+  CPPUNIT_ASSERT_EQUAL( Vector(0.,0.,0.), cluster->getAtomById(_atomId)->getPosition() );
+}
+
+/** Test whether IsInShape() works
+ *
+ */
+void ClusterTest::IsInShapeTest()
+{
+  // at origin we are inside
+  CPPUNIT_ASSERT( shape->isInside(_atom->getPosition() ) );
+  CPPUNIT_ASSERT( cluster->IsInShape(_atomId) );
+
+  // at boundary we are inside
+  _atom->setPosition( Vector(1.,0.,0.) );
+  CPPUNIT_ASSERT( shape->isInside(_atom->getPosition() ) );
+  CPPUNIT_ASSERT( cluster->IsInShape(_atomId) );
+
+  // now we are outside
+  _atom->setPosition( Vector(2.,0.,0.) );
+  CPPUNIT_ASSERT( !shape->isInside(_atom->getPosition() ) );
+  CPPUNIT_ASSERT( !cluster->IsInShape(_atomId) );
+}
+
+/** Test whether clone() works
+ *
+ */
+void ClusterTest::cloneTest()
+{
+  // insert atom ...
+  cluster->insert(_atomId);
+
+  // ... and clone
+  CopyAtoms_Simple copyMethod;
+  ClusterInterface::Cluster_impl clonedCluster = cluster->clone(copyMethod);
+
+  // check for present atom
+  CPPUNIT_ASSERT_EQUAL( (size_t)1, clonedCluster->getAtomIds().size() );
+
+  // check for different ids
+  CPPUNIT_ASSERT_EQUAL( (size_t)2, World::getInstance().getAllAtoms().size() );
+  CPPUNIT_ASSERT( *(cluster->getAtomIds().begin()) != *(clonedCluster->getAtomIds().begin()) );
+  // check for same position
+  atomId_t id = *(clonedCluster->getAtomIds().begin());
+  const atom * const _atom = World::getInstance().getAtom(AtomById(id));
+  CPPUNIT_ASSERT( _atom != NULL );
+  CPPUNIT_ASSERT( (*cluster->getAtomRefs().begin())->getPosition() ==_atom->getPosition() );
+
+  // check that shape is the same
+  CPPUNIT_ASSERT( cluster->getShape() == clonedCluster->getShape() );
+  CPPUNIT_ASSERT( cluster->getShape().getCenter() == clonedCluster->getShape().getCenter() );
+  CPPUNIT_ASSERT( cluster->getShape().getRadius() == clonedCluster->getShape().getRadius() );
+}
+
+/** Test whether getAtomRefs() works
+ *
+ */
+void ClusterTest::getAtomRefsTest()
+{
+  Cluster::AtomVector Atomvec;
+
+  // check with empty cluster
+  CPPUNIT_ASSERT_EQUAL( Atomvec, cluster->getAtomRefs() );
+
+  // insert into both ...
+  Atomvec.push_back(_atom);
+  cluster->insert(_atomId);
+
+  // ...and check again
+  CPPUNIT_ASSERT_EQUAL( Atomvec, cluster->getAtomRefs() );
+}
Index: src/Filling/unittests/ClusterUnitTest.hpp
===================================================================
--- src/Filling/unittests/ClusterUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/unittests/ClusterUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,57 @@
+/*
+ * ClusterUnitTest.hpp
+ *
+ *  Created on: Jan 17, 2012
+ *      Author: heber
+ */
+
+#ifndef CLUSTERUNITTEST_HPP_
+#define CLUSTERUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "types.hpp"
+
+class atom;
+class Cluster;
+class Shape;
+
+/********************************************** Test classes **************************************/
+
+class ClusterTest : public CppUnit::TestFixture
+{
+    CPPUNIT_TEST_SUITE( ClusterTest) ;
+    CPPUNIT_TEST ( insert_eraseTest );
+    CPPUNIT_TEST ( setter_getterTest );
+    CPPUNIT_TEST ( IsInShapeTest );
+    CPPUNIT_TEST ( getAtomRefsTest );
+    CPPUNIT_TEST ( translateTest );
+    CPPUNIT_TEST ( transformTest );
+    CPPUNIT_TEST ( cloneTest );
+    CPPUNIT_TEST_SUITE_END();
+
+public:
+      void setUp();
+      void tearDown();
+      void insert_eraseTest();
+      void setter_getterTest();
+      void IsInShapeTest();
+      void getAtomRefsTest();
+      void translateTest();
+      void transformTest();
+      void cloneTest();
+
+private:
+      Cluster *cluster;
+      Shape *shape;
+      atom * _atom;
+      atomId_t _atomId;
+};
+
+#endif /* CLUSTERUNITTEST_HPP_ */
Index: src/Filling/unittests/FillerUnitTest.cpp
===================================================================
--- src/Filling/unittests/FillerUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/unittests/FillerUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,121 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2010-2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * FillerUnitTest.cpp
+ *
+ *  Created on: Jan 19, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include "CodePatterns/Assert.hpp"
+
+#include "Atom/atom.hpp"
+#include "Atom/CopyAtoms/CopyAtoms_Simple.hpp"
+#include "Descriptors/AtomIdDescriptor.hpp"
+#include "Element/periodentafel.hpp"
+#include "Filling/Cluster.hpp"
+#include "Filling/Filler.hpp"
+#include "Filling/Inserter/Inserter.hpp"
+#include "Filling/Inserter/SimpleInserter.hpp"
+#include "Filling/Mesh/Mesh.hpp"
+#include "Filling/Predicates/FillPredicate.hpp"
+#include "LinearAlgebra/Vector.hpp"
+#include "molecule.hpp"
+#include "Shapes/BaseShapes.hpp"
+#include "Shapes/Shape.hpp"
+#include "World.hpp"
+#include "WorldTime.hpp"
+
+#include "FillerUnitTest.hpp"
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+/********************************************** Test classes **************************************/
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( FillerTest );
+
+
+class MeshStub : public Mesh
+{
+  public:
+  MeshStub() {
+    nodes.reserve(5);
+    for (double i=1; i<6.; ++i)
+      nodes.push_back(Vector(i,0.,0.));
+  }
+  virtual ~MeshStub()
+  {}
+};
+
+void FillerTest::setUp()
+{
+  // failing asserts should be thrown
+  ASSERT_DO(Assert::Throw);
+
+  predicate = new FillPredicate(AlwaysFillPredicate());
+  mesh = new MeshStub();
+  inserter = new Inserter(Inserter::impl_ptr(new SimpleInserter()));
+  CPPUNIT_ASSERT_EQUAL( (size_t)5, mesh->getNodes().size() );
+  filler = new Filler(*mesh, *predicate, *inserter);
+  s = new Shape(Sphere( Vector(0.,0.,0.05), 0.1));
+
+  Cluster::atomIdSet atoms;
+
+  // create an atom
+  hydrogen = World::getInstance().getPeriode()->FindElement(1);
+  CPPUNIT_ASSERT(hydrogen != NULL);
+  _atom = World::getInstance().createAtom();
+  _atom->setType(hydrogen);
+  _atom->setPosition( zeroVec );
+  atoms.insert(_atom->getId());
+  _atom = World::getInstance().createAtom();
+  _atom->setType(hydrogen);
+  _atom->setPosition( Vector(0.,0.,0.1) );
+  atoms.insert(_atom->getId());
+
+  CPPUNIT_ASSERT( s->isInside(_atom->getPosition()) );
+  cluster = new ClusterInterface::Cluster_impl(new Cluster(atoms, *s));
+}
+
+
+void FillerTest::tearDown()
+{
+  hydrogen = NULL;
+  delete cluster;
+  delete filler;
+  delete mesh;
+  delete predicate;
+  delete inserter;
+
+  World::purgeInstance();
+  WorldTime::purgeInstance();
+}
+
+/** Test whether operator() works
+ *
+ */
+void FillerTest::operatorTest()
+{
+  CopyAtoms_Simple copyMethod;
+  (*filler)(copyMethod, *cluster);
+
+  // one atom at 5 nodes added
+  CPPUNIT_ASSERT_EQUAL( mesh->getNodes().size()*2, World::getInstance().getAllAtoms().size() );
+}
Index: src/Filling/unittests/FillerUnitTest.hpp
===================================================================
--- src/Filling/unittests/FillerUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/unittests/FillerUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,57 @@
+/*
+ * FillerUnitTest.hpp
+ *
+ *  Created on: Jan 19, 2012
+ *      Author: heber
+ */
+
+#ifndef FILLERUNITTEST_HPP_
+#define FILLERUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <boost/shared_ptr.hpp>
+
+#include "types.hpp"
+
+class atom;
+class Cluster;
+class Filler;
+class FillPredicate;
+class Inserter;
+class Mesh;
+class Shape;
+class ClusterInterface;
+typedef boost::shared_ptr<ClusterInterface> Cluster_impl;
+
+/********************************************** Test classes **************************************/
+
+class FillerTest : public CppUnit::TestFixture
+{
+    CPPUNIT_TEST_SUITE( FillerTest) ;
+    CPPUNIT_TEST ( operatorTest );
+    CPPUNIT_TEST_SUITE_END();
+
+public:
+      void setUp();
+      void tearDown();
+      void operatorTest();
+
+private:
+      FillPredicate *predicate;
+      Mesh *mesh;
+      Inserter *inserter;
+      Filler *filler;
+      atom * _atom;
+      Shape *s;
+      const element * hydrogen;
+      Cluster_impl *cluster;
+};
+
+#endif /* FILLERUNITTEST_HPP_ */
Index: src/Filling/unittests/IsInsideDomain_FillPredicateUnitTest.cpp
===================================================================
--- src/Filling/unittests/IsInsideDomain_FillPredicateUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/unittests/IsInsideDomain_FillPredicateUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,88 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2010-2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * IsInsideDomain_FillPredicateUnitTest.cpp
+ *
+ *  Created on: Jan 19, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include "CodePatterns/Assert.hpp"
+
+#include "Box.hpp"
+#include "Filling/Predicates/IsInsideDomain_FillPredicate.hpp"
+#include "LinearAlgebra/RealSpaceMatrix.hpp"
+#include "Filling/NodeTypes.hpp"
+
+#include "IsInsideDomain_FillPredicateUnitTest.hpp"
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+/********************************************** Test classes **************************************/
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( IsInsideDomain_FillPredicateTest );
+
+
+void IsInsideDomain_FillPredicateTest::setUp()
+{
+  // failing asserts should be thrown
+  ASSERT_DO(Assert::Throw);
+
+  M = new RealSpaceMatrix;
+  M->setIdentity();
+  (*M) *= 20.;
+
+  domain = new Box(*M);
+
+  predicate = new FillPredicate(IsInsideDomain_FillPredicate(*domain));
+}
+
+
+void IsInsideDomain_FillPredicateTest::tearDown()
+{
+  delete predicate;
+  delete domain;
+  delete M;
+}
+
+/** Test whether operator() returns as desired
+ *
+ */
+void IsInsideDomain_FillPredicateTest::operatorTest()
+{
+  Node origin(0.,0.,0.);
+  Node center(10.,10.,10.);
+  Node corner(20.,20.,20.);
+  Node outside(30.,30.,30.);
+
+  {
+    // origin is inside
+    CPPUNIT_ASSERT( (*predicate)(origin) );
+
+    // center is inside
+    CPPUNIT_ASSERT( (*predicate)(center) );
+
+    // corner is inside
+    CPPUNIT_ASSERT( (*predicate)(corner) );
+
+    // outside is outside
+    CPPUNIT_ASSERT( !(*predicate)(outside) );
+  }
+}
Index: src/Filling/unittests/IsInsideDomain_FillPredicateUnitTest.hpp
===================================================================
--- src/Filling/unittests/IsInsideDomain_FillPredicateUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/unittests/IsInsideDomain_FillPredicateUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,42 @@
+/*
+ * IsInsideDomain_FillPredicateUnitTest.hpp
+ *
+ *  Created on: Jan 19, 2012
+ *      Author: heber
+ */
+
+#ifndef ISINSIDEDOMAIN_FILLPREDICATEUNITTEST_HPP_
+#define ISINSIDEDOMAIN_FILLPREDICATEUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class Box;
+class RealSpaceMatrix;
+class FillPredicate;
+
+/********************************************** Test classes **************************************/
+
+class IsInsideDomain_FillPredicateTest : public CppUnit::TestFixture
+{
+    CPPUNIT_TEST_SUITE( IsInsideDomain_FillPredicateTest) ;
+    CPPUNIT_TEST ( operatorTest );
+    CPPUNIT_TEST_SUITE_END();
+
+public:
+      void setUp();
+      void tearDown();
+      void operatorTest();
+
+private:
+      RealSpaceMatrix *M;
+      Box *domain;
+      FillPredicate *predicate;
+};
+
+#endif /* ISINSIDEDOMAIN_FILLPREDICATEUNITTEST_HPP_ */
Index: src/Filling/unittests/IsInsideSurface_FillPredicateUnitTest.cpp
===================================================================
--- src/Filling/unittests/IsInsideSurface_FillPredicateUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/unittests/IsInsideSurface_FillPredicateUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,129 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2010-2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * IsInsideSurface_FillPredicateUnitTest.cpp
+ *
+ *  Created on: Jan 18, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include "CodePatterns/Assert.hpp"
+#include "CodePatterns/Log.hpp"
+
+#include "Atom/TesselPoint.hpp"
+#include "LinkedCell/PointCloudAdaptor.hpp"
+#include "Filling/Predicates/IsInsideSurface_FillPredicate.hpp"
+#include "Filling/NodeTypes.hpp"
+#include "LinearAlgebra/Vector.hpp"
+#include "Tesselation/BoundaryLineSet.hpp"
+#include "Tesselation/BoundaryTriangleSet.hpp"
+#include "Tesselation/CandidateForTesselation.hpp"
+#include "Tesselation/tesselation.hpp"
+
+#include "IsInsideSurface_FillPredicateUnitTest.hpp"
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+const double IsInsideSurface_FillPredicateTest::SPHERERADIUS=2.;
+
+/********************************************** Test classes **************************************/
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( IsInsideSurface_FillPredicateTest );
+
+
+void IsInsideSurface_FillPredicateTest::setUp()
+{
+  // failing asserts should be thrown
+  ASSERT_DO(Assert::Throw);
+
+  // create corners
+  class TesselPoint *Walker;
+  Walker = new TesselPoint;
+  Walker->setPosition(Vector(1., 0., -1.));
+  Walker->setName("1");
+  Walker->setNr(1);
+  Corners.push_back(Walker);
+  Walker = new TesselPoint;
+  Walker->setPosition(Vector(-1., 1., -1.));
+  Walker->setName("2");
+  Walker->setNr(2);
+  Corners.push_back(Walker);
+  Walker = new TesselPoint;
+  Walker->setPosition(Vector(-1., -1., -1.));
+  Walker->setName("3");
+  Walker->setNr(3);
+  Corners.push_back(Walker);
+  Walker = new TesselPoint;
+  Walker->setPosition(Vector(-1., 0., 1.));
+  Walker->setName("4");
+  Walker->setNr(4);
+  Corners.push_back(Walker);
+
+  // create linkedcell
+  PointCloudAdaptor<TesselPointSTLList> cloud(&Corners, "TesselPointSTLList");
+  LinkedList = new LinkedCell_deprecated(cloud, 2.*SPHERERADIUS);
+
+  // create tesselation
+  TesselStruct = new Tesselation;
+  (*TesselStruct)(cloud, SPHERERADIUS);
+
+  // create predicate
+  predicate = new FillPredicate(IsInsideSurface_FillPredicate(*TesselStruct, *LinkedList));
+}
+
+
+void IsInsideSurface_FillPredicateTest::tearDown()
+{
+  delete predicate;
+
+  delete(LinkedList);
+  delete(TesselStruct);
+  for (TesselPointSTLList::iterator Runner = Corners.begin(); Runner != Corners.end(); Runner++)
+    delete(*Runner);
+  Corners.clear();
+  logger::purgeInstance();
+  errorLogger::purgeInstance();
+
+}
+
+/** Test whether operator() returns as desired
+ *
+ */
+void IsInsideSurface_FillPredicateTest::operatorTest()
+{
+  Node center(0.,0.,0.);
+  Node corner(1.,0.,-1.);
+  Node outside(2.,0.,0.);
+
+  {
+    // center is inside
+    CPPUNIT_ASSERT( (*predicate)(center) );
+  }
+
+  {
+    // corner is inside
+    CPPUNIT_ASSERT( (*predicate)(corner) );
+  }
+
+  {
+    // outside is outside
+    CPPUNIT_ASSERT( !(*predicate)(outside) );
+  }
+}
Index: src/Filling/unittests/IsInsideSurface_FillPredicateUnitTest.hpp
===================================================================
--- src/Filling/unittests/IsInsideSurface_FillPredicateUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/unittests/IsInsideSurface_FillPredicateUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,47 @@
+/*
+ * IsInsideSurface_FillPredicateUnitTest.hpp
+ *
+ *  Created on: Jan 18, 2012
+ *      Author: heber
+ */
+
+#ifndef ISINSIDESURFACE_FILLPREDICATEUNITTEST_HPP_
+#define ISINSIDESURFACE_FILLPREDICATEUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "LinkedCell/linkedcell.hpp"
+
+class FillPredicate;
+class LinkedCell_deprecated;
+class Tesselation;
+
+/********************************************** Test classes **************************************/
+
+class IsInsideSurface_FillPredicateTest : public CppUnit::TestFixture
+{
+    CPPUNIT_TEST_SUITE( IsInsideSurface_FillPredicateTest) ;
+    CPPUNIT_TEST ( operatorTest );
+    CPPUNIT_TEST_SUITE_END();
+
+public:
+      void setUp();
+      void tearDown();
+      void operatorTest();
+
+private:
+      static const double SPHERERADIUS;
+
+      TesselPointSTLList Corners;
+      Tesselation *TesselStruct;
+      LinkedCell_deprecated *LinkedList;
+      FillPredicate *predicate;
+};
+
+#endif /* ISINSIDESURFACE_FILLPREDICATEUNITTEST_HPP_ */
Index: src/Filling/unittests/IsValidInDomain_FillPredicateUnitTest.cpp
===================================================================
--- src/Filling/unittests/IsValidInDomain_FillPredicateUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/unittests/IsValidInDomain_FillPredicateUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,126 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2010-2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * IsValidInDomain_FillPredicateUnitTest.cpp
+ *
+ *  Created on: Jan 18, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include "CodePatterns/Assert.hpp"
+
+#include "Box.hpp"
+#include "Filling/Predicates/IsValidInDomain_FillPredicate.hpp"
+#include "LinearAlgebra/RealSpaceMatrix.hpp"
+#include "Filling/NodeTypes.hpp"
+
+#include "IsValidInDomain_FillPredicateUnitTest.hpp"
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+/********************************************** Test classes **************************************/
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( IsValidInDomain_FillPredicateTest );
+
+
+void IsValidInDomain_FillPredicateTest::setUp()
+{
+  // failing asserts should be thrown
+  ASSERT_DO(Assert::Throw);
+
+  M = new RealSpaceMatrix;
+  M->setIdentity();
+  (*M) *= 20.;
+
+  domain = new Box(*M);
+
+  predicate = new FillPredicate(IsValidInDomain_FillPredicate(*domain));
+}
+
+
+void IsValidInDomain_FillPredicateTest::tearDown()
+{
+  delete predicate;
+  delete domain;
+  delete M;
+}
+
+/** Test whether operator() returns as desired
+ *
+ */
+void IsValidInDomain_FillPredicateTest::operatorTest()
+{
+  Node origin(0.,0.,0.);
+  Node center(10.,10.,10.);
+  Node corner(20.,20.,20.);
+  Node outside(30.,30.,30.);
+
+  for (size_t i=0;i<NDIM;++i)
+    domain->setCondition(i, BoundaryConditions::Wrap);
+
+  // boundary conditions: Wrap
+  {
+    // origin is inside
+    CPPUNIT_ASSERT( (*predicate)(origin) );
+
+    // center is inside
+    CPPUNIT_ASSERT( (*predicate)(center) );
+
+    // corner is inside
+    CPPUNIT_ASSERT( (*predicate)(corner) );
+
+    // outside is outside
+    CPPUNIT_ASSERT( (*predicate)(outside) );
+  }
+
+  // boundary conditions: Bounce
+  {
+    domain->setCondition(0, BoundaryConditions::Bounce);
+    // origin is inside
+    CPPUNIT_ASSERT( (*predicate)(origin) );
+
+    // center is inside
+    CPPUNIT_ASSERT( (*predicate)(center) );
+
+    // corner is inside
+    CPPUNIT_ASSERT( (*predicate)(corner) );
+
+    // outside is outside
+    CPPUNIT_ASSERT( (*predicate)(outside) );
+    domain->setCondition(0, BoundaryConditions::Wrap);
+  }
+
+  // boundary conditions: Ignore
+  {
+    domain->setCondition(0, BoundaryConditions::Ignore);
+    // origin is inside
+    CPPUNIT_ASSERT( (*predicate)(origin) );
+
+    // center is inside
+    CPPUNIT_ASSERT( (*predicate)(center) );
+
+    // corner is inside
+    CPPUNIT_ASSERT( (*predicate)(corner) );
+
+    // outside is outside
+    CPPUNIT_ASSERT( !(*predicate)(outside) );
+    domain->setCondition(0, BoundaryConditions::Wrap);
+  }
+}
Index: src/Filling/unittests/IsValidInDomain_FillPredicateUnitTest.hpp
===================================================================
--- src/Filling/unittests/IsValidInDomain_FillPredicateUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/unittests/IsValidInDomain_FillPredicateUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,42 @@
+/*
+ * IsValidInDomain_FillPredicateUnitTest.hpp
+ *
+ *  Created on: Jan 18, 2012
+ *      Author: heber
+ */
+
+#ifndef ISVALIDINDOMAIN_FILLPREDICATEUNITTEST_HPP_
+#define ISVALIDINDOMAIN_FILLPREDICATEUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class Box;
+class RealSpaceMatrix;
+class FillPredicate;
+
+/********************************************** Test classes **************************************/
+
+class IsValidInDomain_FillPredicateTest : public CppUnit::TestFixture
+{
+    CPPUNIT_TEST_SUITE( IsValidInDomain_FillPredicateTest) ;
+    CPPUNIT_TEST ( operatorTest );
+    CPPUNIT_TEST_SUITE_END();
+
+public:
+      void setUp();
+      void tearDown();
+      void operatorTest();
+
+private:
+      RealSpaceMatrix *M;
+      Box *domain;
+      FillPredicate *predicate;
+};
+
+#endif /* ISVALIDINDOMAIN_FILLPREDICATEUNITTEST_HPP_ */
Index: src/Filling/unittests/IsVoidNode_FillPredicateUnitTest.cpp
===================================================================
--- src/Filling/unittests/IsVoidNode_FillPredicateUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/unittests/IsVoidNode_FillPredicateUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,126 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2010-2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * IsVoidNode_FillPredicateUnitTest.cpp
+ *
+ *  Created on: Jan 18, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include <algorithm>
+#include <boost/bind.hpp>
+#include <iostream>
+
+#include "CodePatterns/Assert.hpp"
+
+#include "Atom/atom.hpp"
+#include "Box.hpp"
+#include "Filling/Predicates/IsVoidNode_FillPredicate.hpp"
+#include "LinearAlgebra/RealSpaceMatrix.hpp"
+#include "Filling/NodeTypes.hpp"
+#include "Shapes/BaseShapes.hpp"
+#include "Shapes/Shape.hpp"
+#include "World.hpp"
+
+#include "IsVoidNode_FillPredicateUnitTest.hpp"
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+/********************************************** Test classes **************************************/
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( IsVoidNode_FillPredicateTest );
+
+void DoSomething(atom * const _atom)
+{
+  _atom->setPosition( Vector((double)_atom->getId(), 0., 0.) );
+}
+
+void IsVoidNode_FillPredicateTest::setUp()
+{
+  // failing asserts should be thrown
+  ASSERT_DO(Assert::Throw);
+
+  // set default BCs to ignore
+  World::getInstance().getDomain().setConditions(
+      BoundaryConditions::Conditions_t(3, BoundaryConditions::Ignore)
+  );
+
+  // create some atoms as "neighbours"
+  atoms.resize((size_t)5, NULL);
+  std::generate_n(atoms.begin(), (size_t)5, boost::bind(&World::createAtom, World::getPointer()) );
+
+  // position them
+  std::for_each(atoms.begin(), atoms.end(), &DoSomething);
+
+  predicate = new FillPredicate(IsVoidNode_FillPredicate(Sphere()));
+}
+
+
+void IsVoidNode_FillPredicateTest::tearDown()
+{
+  delete predicate;
+
+  World::purgeInstance();
+}
+
+/** Test whether operator() returns as desired
+ *
+ */
+void IsVoidNode_FillPredicateTest::operatorTest()
+{
+#ifndef NDEBUG
+  std::cout << "The following Assertion is intended and does not represent a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( (*predicate)( Vector(-2.,0.,0.)), Assert::AssertionFailure );
+#else
+  CPPUNIT_ASSERT( (*predicate)( Vector(-2.,0.,0.)) );
+#endif
+  for (double i = 0; i < 5.; ++i) {
+    CPPUNIT_ASSERT( !(*predicate)( Vector(i, 0., 0.)) );
+    CPPUNIT_ASSERT( !(*predicate)( Vector(i, 1., 0.)) );
+#ifndef NDEBUG
+  std::cout << "The following Assertion is intended and does not represent a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( (*predicate)( Vector(i, -1., 0.)), Assert::AssertionFailure );
+#else
+  CPPUNIT_ASSERT( !(*predicate)( Vector(i, -1., 0.)) );
+#endif
+    CPPUNIT_ASSERT( !(*predicate)( Vector(i, 0., 1.)) );
+#ifndef NDEBUG
+  std::cout << "The following Assertion is intended and does not represent a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( (*predicate)( Vector(i, 0., -1.)), Assert::AssertionFailure );
+#else
+  CPPUNIT_ASSERT( !(*predicate)( Vector(i, 0., -1.)) );
+#endif
+  }
+  CPPUNIT_ASSERT( (*predicate)( Vector(5.,1.,0.)) );
+#ifndef NDEBUG
+  std::cout << "The following Assertion is intended and does not represent a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW(  (*predicate)( Vector(5.,-1.,0.)), Assert::AssertionFailure );
+#else
+  CPPUNIT_ASSERT( (*predicate)( Vector(5.,-1.,0.)) );
+#endif
+  CPPUNIT_ASSERT( (*predicate)( Vector(5.,0.,1.)) );
+#ifndef NDEBUG
+  std::cout << "The following Assertion is intended and does not represent a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( (*predicate)( Vector(5.,0.,-1.)), Assert::AssertionFailure );
+#else
+  CPPUNIT_ASSERT( (*predicate)( Vector(5.,0.,-1.)) );
+#endif
+  CPPUNIT_ASSERT( (*predicate)( Vector(6.,0.,0.)) );
+}
Index: src/Filling/unittests/IsVoidNode_FillPredicateUnitTest.hpp
===================================================================
--- src/Filling/unittests/IsVoidNode_FillPredicateUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/unittests/IsVoidNode_FillPredicateUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,42 @@
+/*
+ * IsVoidNode_FillPredicateUnitTest.hpp
+ *
+ *  Created on: Jan 18, 2012
+ *      Author: heber
+ */
+
+#ifndef ISVOIDNODE_FILLPREDICATEUNITTEST_HPP_
+#define ISVOIDNODE_FILLPREDICATEUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <vector>
+
+class atom;
+class FillPredicate;
+
+/********************************************** Test classes **************************************/
+
+class IsVoidNode_FillPredicateTest : public CppUnit::TestFixture
+{
+    CPPUNIT_TEST_SUITE( IsVoidNode_FillPredicateTest) ;
+    CPPUNIT_TEST ( operatorTest );
+    CPPUNIT_TEST_SUITE_END();
+
+public:
+      void setUp();
+      void tearDown();
+      void operatorTest();
+
+private:
+      std::vector<atom *> atoms;
+      FillPredicate *predicate;
+};
+
+#endif /* ISVOIDNODE_FILLPREDICATEUNITTEST_HPP_ */
Index: src/Filling/unittests/Makefile.am
===================================================================
--- src/Filling/unittests/Makefile.am	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/unittests/Makefile.am	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,115 @@
+# PLEASE adhere to the alphabetical ordering in this Makefile!
+# Also indentation by a single tab
+
+FILLINGTESTSSOURCES = \
+  ../Filling/unittests/ClusterUnitTest.cpp \
+  ../Filling/unittests/FillerUnitTest.cpp \
+  ../Filling/unittests/IsInsideDomain_FillPredicateUnitTest.cpp \
+  ../Filling/unittests/IsInsideSurface_FillPredicateUnitTest.cpp \
+  ../Filling/unittests/IsValidInDomain_FillPredicateUnitTest.cpp \
+  ../Filling/unittests/IsVoidNode_FillPredicateUnitTest.cpp \
+  ../Filling/unittests/Ops_FillPredicateUnitTest.cpp
+
+FILLINGTESTSHEADERS = \
+  ../Filling/unittests/ClusterUnitTest.hpp \
+  ../Filling/unittests/FillerUnitTest.hpp \
+  ../Filling/unittests/IsInsideDomain_FillPredicateUnitTest.hpp \
+  ../Filling/unittests/IsInsideSurface_FillPredicateUnitTest.hpp \
+  ../Filling/unittests/IsValidInDomain_FillPredicateUnitTest.hpp \
+  ../Filling/unittests/IsVoidNode_FillPredicateUnitTest.hpp \
+  ../Filling/unittests/Ops_FillPredicateUnitTest.hpp
+
+FILLINGTESTS = \
+  ClusterUnitTest \
+  FillerUnitTest \
+  IsInsideDomain_FillPredicateUnitTest \
+  IsInsideSurface_FillPredicateUnitTest \
+  IsValidInDomain_FillPredicateUnitTest \
+  IsVoidNode_FillPredicateUnitTest \
+  Ops_FillPredicateUnitTest
+  
+TESTS += $(FILLINGTESTS)
+check_PROGRAMS += $(FILLINGTESTS) 
+noinst_PROGRAMS += $(FILLINGTESTS)
+
+FILLINGLIBS =
+
+ClusterUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+	../Filling/unittests/ClusterUnitTest.cpp \
+	../Filling/unittests/ClusterUnitTest.hpp
+ClusterUnitTest_LDADD = \
+	../libMolecuilderFilling.la \
+	../libMolecuilderUI.la \
+	../libMolecuilder.la \
+	$(top_builddir)/LinearAlgebra/src/LinearAlgebra/libLinearAlgebra.la \
+	${CodePatterns_LIBS} \
+	$(BOOST_LIBS)
+
+FillerUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+	../Filling/unittests/FillerUnitTest.cpp \
+	../Filling/unittests/FillerUnitTest.hpp
+FillerUnitTest_LDADD = \
+	../libMolecuilderFilling.la \
+	../libMolecuilderUI.la \
+	../libMolecuilder.la \
+	$(top_builddir)/LinearAlgebra/src/LinearAlgebra/libLinearAlgebra.la \
+	${CodePatterns_LIBS} \
+	$(BOOST_LIBS)
+
+IsInsideDomain_FillPredicateUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+	../Filling/unittests/IsInsideDomain_FillPredicateUnitTest.cpp \
+	../Filling/unittests/IsInsideDomain_FillPredicateUnitTest.hpp
+IsInsideDomain_FillPredicateUnitTest_LDADD = \
+	../libMolecuilderFilling.la \
+	../libMolecuilderUI.la \
+	../libMolecuilder.la \
+	$(top_builddir)/LinearAlgebra/src/LinearAlgebra/libLinearAlgebra.la \
+	${CodePatterns_LIBS} \
+	$(BOOST_LIBS)
+
+IsInsideSurface_FillPredicateUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+	../Filling/unittests/IsInsideSurface_FillPredicateUnitTest.cpp \
+	../Filling/unittests/IsInsideSurface_FillPredicateUnitTest.hpp
+IsInsideSurface_FillPredicateUnitTest_LDADD = \
+	../libMolecuilderFilling.la \
+	../libMolecuilderUI.la \
+	../libMolecuilder.la \
+	$(top_builddir)/LinearAlgebra/src/LinearAlgebra/libLinearAlgebra.la \
+	${CodePatterns_LIBS} \
+	$(BOOST_LIBS)
+
+IsValidInDomain_FillPredicateUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+	../Filling/unittests/IsValidInDomain_FillPredicateUnitTest.cpp \
+	../Filling/unittests/IsValidInDomain_FillPredicateUnitTest.hpp
+IsValidInDomain_FillPredicateUnitTest_LDADD = \
+	../libMolecuilderFilling.la \
+	../libMolecuilderUI.la \
+	../libMolecuilder.la \
+	$(top_builddir)/LinearAlgebra/src/LinearAlgebra/libLinearAlgebra.la \
+	${CodePatterns_LIBS} \
+	$(BOOST_LIBS)
+
+IsVoidNode_FillPredicateUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+	../Filling/unittests/IsVoidNode_FillPredicateUnitTest.cpp \
+	../Filling/unittests/IsVoidNode_FillPredicateUnitTest.hpp
+IsVoidNode_FillPredicateUnitTest_LDADD = \
+	../libMolecuilderFilling.la \
+	../libMolecuilderUI.la \
+	../libMolecuilder.la \
+	$(top_builddir)/LinearAlgebra/src/LinearAlgebra/libLinearAlgebra.la \
+	${CodePatterns_LIBS} \
+	$(BOOST_LIBS)
+
+Ops_FillPredicateUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+	../Filling/unittests/Ops_FillPredicateUnitTest.cpp \
+	../Filling/unittests/Ops_FillPredicateUnitTest.hpp
+Ops_FillPredicateUnitTest_LDADD = \
+	../libMolecuilderFilling.la \
+	../libMolecuilderUI.la \
+	../libMolecuilder.la \
+	$(top_builddir)/LinearAlgebra/src/LinearAlgebra/libLinearAlgebra.la \
+	${CodePatterns_LIBS} \
+	$(BOOST_LIBS)
+
+
+#AUTOMAKE_OPTIONS = parallel-tests
Index: src/Filling/unittests/Ops_FillPredicateUnitTest.cpp
===================================================================
--- src/Filling/unittests/Ops_FillPredicateUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/unittests/Ops_FillPredicateUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,272 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2010-2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * Ops_FillPredicateUnitTest.cpp
+ *
+ *  Created on: Jan 19, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include "CodePatterns/Assert.hpp"
+
+#include "Atom/atom.hpp"
+#include "Box.hpp"
+#include "Filling/Predicates/IsValidInDomain_FillPredicate.hpp"
+#include "Filling/Predicates/IsVoidNode_FillPredicate.hpp"
+#include "Filling/Predicates/Ops_FillPredicate.hpp"
+#include "LinearAlgebra/RealSpaceMatrix.hpp"
+#include "Filling/NodeTypes.hpp"
+#include "Shapes/BaseShapes.hpp"
+#include "World.hpp"
+
+#include "Ops_FillPredicateUnitTest.hpp"
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+/********************************************** Test classes **************************************/
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( Ops_FillPredicateTest );
+
+void DoSomething(atom * const _atom)
+{
+  _atom->setPosition( Vector((double)_atom->getId(), 0., 0.) );
+}
+
+void Ops_FillPredicateTest::setUp()
+{
+  // failing asserts should be thrown
+  ASSERT_DO(Assert::Throw);
+
+  // set default BCs to ignore
+  World::getInstance().getDomain().setConditions(
+      BoundaryConditions::Conditions_t(3, BoundaryConditions::Ignore)
+  );
+
+  Domainpredicate = new FillPredicate(IsValidInDomain_FillPredicate(World::getInstance().getDomain()));
+
+  // create some atoms as "neighbours"
+  atoms.resize((size_t)5, NULL);
+  std::generate_n(atoms.begin(), (size_t)5, boost::bind(&World::createAtom, World::getPointer()) );
+
+  // position them
+  std::for_each(atoms.begin(), atoms.end(), &DoSomething);
+
+  Voidpredicate = new FillPredicate(IsVoidNode_FillPredicate(Sphere()));
+}
+
+
+void Ops_FillPredicateTest::tearDown()
+{
+  delete Domainpredicate;
+  delete Voidpredicate;
+
+  World::purgeInstance();
+}
+
+/** Test whether operator() returns as desired
+ *
+ */
+void Ops_FillPredicateTest::AndTest()
+{
+	FillPredicate Andpredicate = (*Domainpredicate) && (*Voidpredicate);
+
+	CPPUNIT_ASSERT( !Andpredicate( Vector(-1.,1.,0.)) );
+  CPPUNIT_ASSERT( !Andpredicate( Vector(-2.,0.,0.)) );
+	CPPUNIT_ASSERT( Andpredicate( Vector(5.,1.,0.)) );
+  CPPUNIT_ASSERT( Andpredicate( Vector(5.,0.,1.)) );
+  for (double i = 0; i < 5.; ++i) {
+    CPPUNIT_ASSERT( !Andpredicate( Vector(i, 0., 0.)) );
+    CPPUNIT_ASSERT( !Andpredicate( Vector(i, 1., 0.)) );
+    CPPUNIT_ASSERT( !Andpredicate( Vector(i, -1., 0.)) );
+    CPPUNIT_ASSERT( !Andpredicate( Vector(i, 0., 1.)) );
+    CPPUNIT_ASSERT( !Andpredicate( Vector(i, 0., -1.)) );
+  }
+  CPPUNIT_ASSERT( !Andpredicate( Vector(5.,-1.,0.)) );
+  CPPUNIT_ASSERT( Andpredicate( Vector(5.,0.,1.)) );
+  CPPUNIT_ASSERT( !Andpredicate( Vector(5.,0.,-1.)) );
+  CPPUNIT_ASSERT( Andpredicate( Vector(6.,0.,0.)) );
+}
+/** Test whether operator() returns as desired
+ *
+ */
+void Ops_FillPredicateTest::OrTest()
+{
+  FillPredicate Orpredicate = (*Domainpredicate) || (*Voidpredicate);
+
+  // in OR case: Voidpredicate will always throw because it internally checks
+  // whether Linked Cell structure gets correct index to cell, which fails under
+  // Ignore boundary conditions
+#ifndef NDEBUG
+  std::cout << "The following Assertion is intended and does not represent a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( Orpredicate( Vector(-1.,1.,0.)), Assert::AssertionFailure );
+#else
+  CPPUNIT_ASSERT( Orpredicate( Vector(-1.,1.,0.)) );
+#endif
+	CPPUNIT_ASSERT( Orpredicate( Vector(5.,1.,0.)) );
+#ifndef NDEBUG
+  std::cout << "The following Assertion is intended and does not represent a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( Orpredicate( Vector(-2.,0.,0.)), Assert::AssertionFailure );
+#else
+  CPPUNIT_ASSERT( Orpredicate( Vector(-2.,0.,0.)) );
+#endif
+  for (double i = 0; i < 5.; ++i) {
+    CPPUNIT_ASSERT( Orpredicate( Vector(i, 0., 0.)) );
+    CPPUNIT_ASSERT( Orpredicate( Vector(i, 1., 0.)) );
+#ifndef NDEBUG
+  std::cout << "The following Assertion is intended and does not represent a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( Orpredicate( Vector(i, -1., 0.)), Assert::AssertionFailure );
+#else
+  CPPUNIT_ASSERT( !Orpredicate( Vector(i, -1., 0.)) );
+#endif
+    CPPUNIT_ASSERT( Orpredicate( Vector(i, 0., 1.)) );
+#ifndef NDEBUG
+  std::cout << "The following Assertion is intended and does not represent a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( Orpredicate( Vector(i, 0., -1.)), Assert::AssertionFailure );
+#else
+  CPPUNIT_ASSERT( !Orpredicate( Vector(i, 0., -1.)) );
+#endif
+  }
+  CPPUNIT_ASSERT( Orpredicate( Vector(5.,1.,0.)) );
+#ifndef NDEBUG
+  std::cout << "The following Assertion is intended and does not represent a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( Orpredicate( Vector(5.,-1.,0.)), Assert::AssertionFailure );
+#else
+  CPPUNIT_ASSERT( Orpredicate( Vector(5.,-1.,0.)) );
+#endif
+  CPPUNIT_ASSERT( Orpredicate( Vector(5.,0.,1.)) );
+#ifndef NDEBUG
+  std::cout << "The following Assertion is intended and does not represent a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( Orpredicate( Vector(5.,0.,-1.)), Assert::AssertionFailure );
+#else
+  CPPUNIT_ASSERT( Orpredicate( Vector(5.,0.,-1.)) );
+#endif
+  CPPUNIT_ASSERT( Orpredicate( Vector(6.,0.,0.)) );
+}
+
+/** Test whether operator!() returns as desired
+ *
+ */
+void Ops_FillPredicateTest::NotTest()
+{
+  Box &domain = World::getInstance().getDomain();
+  Node origin(0.,0.,0.);
+  Node center(10.,10.,10.);
+  Node corner(20.,20.,20.);
+  Node outside(30.,30.,30.);
+
+  FillPredicate Notpredicate = !(*Domainpredicate);
+  FillPredicate Notpredicate2 = !(*Voidpredicate);
+
+  domain.setConditions(
+      BoundaryConditions::Conditions_t(3, BoundaryConditions::Wrap)
+  );
+  // boundary conditions: Wrap
+  {
+    // origin is inside
+    CPPUNIT_ASSERT( !Notpredicate(origin) );
+
+    // center is inside
+    CPPUNIT_ASSERT( !Notpredicate(center) );
+
+    // corner is inside
+    CPPUNIT_ASSERT( !Notpredicate(corner) );
+
+    // outside is outside
+    CPPUNIT_ASSERT( !Notpredicate(outside) );
+  }
+
+  // boundary conditions: Bounce
+  {
+    domain.setCondition(0, BoundaryConditions::Bounce);
+    // origin is inside
+    CPPUNIT_ASSERT( !Notpredicate(origin) );
+
+    // center is inside
+    CPPUNIT_ASSERT( !Notpredicate(center) );
+
+    // corner is inside
+    CPPUNIT_ASSERT( !Notpredicate(corner) );
+
+    // outside is outside
+    CPPUNIT_ASSERT( !Notpredicate(outside) );
+    domain.setCondition(0, BoundaryConditions::Wrap);
+  }
+
+  // boundary conditions: Ignore
+  {
+    domain.setCondition(0, BoundaryConditions::Ignore);
+    // origin is inside
+    CPPUNIT_ASSERT( !Notpredicate(origin) );
+
+    // center is inside
+    CPPUNIT_ASSERT( !Notpredicate(center) );
+
+    // corner is inside
+    CPPUNIT_ASSERT( !Notpredicate(corner) );
+
+    // outside is outside
+    CPPUNIT_ASSERT( Notpredicate(outside) );
+    domain.setCondition(0, BoundaryConditions::Wrap);
+  }
+
+  // set BCs back to default Ignore
+  domain.setConditions(
+      BoundaryConditions::Conditions_t(3, BoundaryConditions::Ignore)
+  );
+	// check on not void
+#ifndef NDEBUG
+  std::cout << "The following Assertion is intended and does not represent a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( Notpredicate2( Vector(-2.,0.,0.)), Assert::AssertionFailure );
+#else
+  CPPUNIT_ASSERT( !Notpredicate2( Vector(-2.,0.,0.)) );
+#endif
+  for (double i = 0; i < 5.; ++i) {
+    CPPUNIT_ASSERT( Notpredicate2( Vector(i, 0., 0.)) );
+    CPPUNIT_ASSERT( Notpredicate2( Vector(i, 1., 0.)) );
+#ifndef NDEBUG
+  std::cout << "The following Assertion is intended and does not represent a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( Notpredicate2( Vector(i, -1., 0.)), Assert::AssertionFailure );
+#else
+  CPPUNIT_ASSERT( Notpredicate2( Vector(i, -1., 0.)) );
+#endif
+    CPPUNIT_ASSERT( Notpredicate2( Vector(i, 0., 1.)) );
+#ifndef NDEBUG
+  std::cout << "The following Assertion is intended and does not represent a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( Notpredicate2( Vector(i, 0., -1.)), Assert::AssertionFailure );
+#else
+  CPPUNIT_ASSERT( Notpredicate2( Vector(i, 0., -1.)) );
+#endif
+  }
+  CPPUNIT_ASSERT( !Notpredicate2( Vector(5.,1.,0.)) );
+#ifndef NDEBUG
+  std::cout << "The following Assertion is intended and does not represent a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( Notpredicate2( Vector(5.,-1.,0.)), Assert::AssertionFailure );
+#else
+  CPPUNIT_ASSERT( !Notpredicate2( Vector(5.,-1.,0.)) );
+#endif
+  CPPUNIT_ASSERT( !Notpredicate2( Vector(5.,0.,1.)) );
+#ifndef NDEBUG
+  std::cout << "The following Assertion is intended and does not represent a failure of the test." << std::endl;
+  CPPUNIT_ASSERT_THROW( Notpredicate2( Vector(5.,0.,-1.)), Assert::AssertionFailure );
+#else
+  CPPUNIT_ASSERT( !Notpredicate2( Vector(5.,0.,-1.)) );
+#endif
+  CPPUNIT_ASSERT( !Notpredicate2( Vector(6.,0.,0.)) );
+}
Index: src/Filling/unittests/Ops_FillPredicateUnitTest.hpp
===================================================================
--- src/Filling/unittests/Ops_FillPredicateUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Filling/unittests/Ops_FillPredicateUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,50 @@
+/*
+ * Ops_FillPredicateUnitTest.hpp
+ *
+ *  Created on: Jan 19, 2012
+ *      Author: heber
+ */
+
+#ifndef OPS_FILLPREDICATEUNITTEST_HPP_
+#define OPS_FILLPREDICATEUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <vector>
+
+class atom;
+class Box;
+class RealSpaceMatrix;
+class FillPredicate;
+
+/********************************************** Test classes **************************************/
+
+class Ops_FillPredicateTest : public CppUnit::TestFixture
+{
+    CPPUNIT_TEST_SUITE( Ops_FillPredicateTest) ;
+    CPPUNIT_TEST ( AndTest );
+    CPPUNIT_TEST ( OrTest );
+    CPPUNIT_TEST ( NotTest );
+    CPPUNIT_TEST_SUITE_END();
+
+public:
+      void setUp();
+      void tearDown();
+      void AndTest();
+      void OrTest();
+      void NotTest();
+
+private:
+      std::vector<atom *> atoms;
+
+      FillPredicate *Voidpredicate;
+      FillPredicate *Domainpredicate;
+};
+
+#endif /* OPS_FILLPREDICATEUNITTEST_HPP_ */
Index: src/Fragmentation/Fragmentation.cpp
===================================================================
--- src/Fragmentation/Fragmentation.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Fragmentation/Fragmentation.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -27,4 +27,5 @@
 #include "Atom/atom.hpp"
 #include "Bond/bond.hpp"
+#include "Descriptors/MoleculeDescriptor.hpp"
 #include "Element/element.hpp"
 #include "Element/periodentafel.hpp"
Index: src/Graph/DepthFirstSearchAnalysis.cpp
===================================================================
--- src/Graph/DepthFirstSearchAnalysis.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Graph/DepthFirstSearchAnalysis.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -32,4 +32,5 @@
 #include "CodePatterns/Verbose.hpp"
 #include "Descriptors/AtomDescriptor.hpp"
+#include "Descriptors/MoleculeDescriptor.hpp"
 #include "molecule.hpp"
 #include "MoleculeLeafClass.hpp"
Index: src/IdPool_impl.hpp
===================================================================
--- src/IdPool_impl.hpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/IdPool_impl.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -96,5 +96,5 @@
     return;
   }
-  LOG(1, "STATUS: Defragmenting id pool.");
+  LOG(3, "DEBUG: Defragmenting id pool.");
   for(typename IdPool_t::iterator iter = pool.begin();iter!=pool.end();) {
     // see if this range is adjacent to the next one
Index: src/LinkedCell/Makefile.am
===================================================================
--- src/LinkedCell/Makefile.am	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/LinkedCell/Makefile.am	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -20,4 +20,5 @@
   LinkedCell/LinkedCell_Model.hpp \
   LinkedCell/LinkedCell_Model_changeModel.hpp \
+  LinkedCell/LinkedCell_Model_inline.hpp \
   LinkedCell/LinkedCell_Model_LinkedCellArrayCache.hpp \
   LinkedCell/LinkedCell_Model_Update.hpp \
Index: src/LinkedCell/unittests/Makefile.am
===================================================================
--- src/LinkedCell/unittests/Makefile.am	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/LinkedCell/unittests/Makefile.am	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -53,10 +53,10 @@
 	../LinkedCell/unittests/LinkedCell_ControllerUnitTest.hpp \
 	../LinkedCell/unittests/defs.hpp \
-	../LinkedCell/unittests/stubs/AtomStub.cpp \
+	stubs/AtomStub.cpp \
 	../LinkedCell/unittests/stubs/AtomObserverStub.cpp \
 	../LinkedCell/unittests/stubs/ObserverBoxStub.cpp \
 	../LinkedCell/unittests/stubs/TesselPointStub.cpp \
-	../LinkedCell/unittests/stubs/WorldStub.cpp \
 	../LinkedCell/unittests/stubs/WorldTimeStub.cpp \
+	stubs/WorldStub.cpp \
 	../LinkedCell/PointCloudAdaptor.hpp \
 	../Box_BoundaryConditions.cpp \
Index: src/LinkedCell/unittests/stubs/AtomStub.cpp
===================================================================
--- src/LinkedCell/unittests/stubs/AtomStub.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ 	(revision )
@@ -1,26 +1,0 @@
-/*
- * 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.
- */
-
-/*
- * AtomStub.cpp
- *
- *  Created on: Dec 22, 2011
- *      Author: heber
- */
-
-// include config.h
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "CodePatterns/MemDebug.hpp"
-
-#include "Atom/atom.hpp"
-
-int atom::getNr() const {
-  return 0;
-}
Index: src/LinkedCell/unittests/stubs/WorldStub.cpp
===================================================================
--- src/LinkedCell/unittests/stubs/WorldStub.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ 	(revision )
@@ -1,58 +1,0 @@
-/*
- * 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.
- */
-
-/*
- * WorldStub.cpp
- *
- *  Created on: Dec 22, 2011
- *      Author: heber
- */
-
-// include config.h
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "CodePatterns/MemDebug.hpp"
-
-#include "World.hpp"
-
-#include "CodePatterns/Observer/Channels.hpp"
-#include "CodePatterns/Observer/Notification.hpp"
-#include "CodePatterns/Observer/ObservedContainer_impl.hpp"
-#include "CodePatterns/Singleton_impl.hpp"
-
-#include "IdPool_impl.hpp"
-
-atom* World::_lastchangedatom = NULL;
-
-World::World() :
-    Observable("World"),
-    atoms(this),
-    selectedAtoms(this),
-    atomIdPool(0, 20, 100),
-    molecules(this),
-    selectedMolecules(this),
-    moleculeIdPool(0, 20,100)
-{
-  // observable stuff
-  Channels *OurChannel = new Channels;
-  NotificationChannels.insert( std::make_pair(this, OurChannel) );
-  // add instance for each notification type
-  OurChannel->addChannel(World::AtomInserted);
-  OurChannel->addChannel(World::AtomRemoved);
-}
-
-World::~World()
-{
-  // observable stuff
-  std::map<Observable *, Channels*>::iterator iter = NotificationChannels.find(this);
-  delete iter->second;
-  NotificationChannels.erase(iter);
-}
-
-CONSTRUCT_SINGLETON(World);
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Makefile.am	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -13,4 +13,5 @@
 include Atom/Makefile.am
 include Element/Makefile.am
+include Filling/Makefile.am
 include Fragmentation/Makefile.am
 include Graph/Makefile.am
@@ -124,4 +125,6 @@
 
 TESSELATIONSOURCE = \
+  Tesselation/ApproximateShapeArea.cpp \
+  Tesselation/ApproximateShapeVolume.cpp \
   Tesselation/boundary.cpp \
   Tesselation/BoundaryLineSet.cpp \
@@ -136,4 +139,6 @@
   
 TESSELATIONHEADER = \
+  Tesselation/ApproximateShapeArea.hpp \
+  Tesselation/ApproximateShapeVolume.hpp \
   Tesselation/boundary.hpp \
   Tesselation/BoundaryLineSet.hpp \
@@ -154,4 +159,5 @@
   ${THERMOSTATSOURCE} \
   ${TESSELATIONSOURCE} \
+  AtomIdSet.cpp \
   Box.cpp \
   Box_BoundaryConditions.cpp \
@@ -175,4 +181,5 @@
   ${THERMOSTATHEADER} \
   ${TESSELATIONHEADER} \
+  AtomIdSet.hpp \
   Box.hpp \
   Box_BoundaryConditions.hpp \
Index: src/Shapes/BaseShapes.cpp
===================================================================
--- src/Shapes/BaseShapes.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Shapes/BaseShapes.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -37,13 +37,13 @@
 #include <algorithm>
 
-bool Sphere_impl::isInside(const Vector &point){
-  return point.NormSquared()<=1;
-}
-
-bool Sphere_impl::isOnSurface(const Vector &point){
-  return fabs(point.NormSquared()-1)<MYEPSILON;
-}
-
-Vector Sphere_impl::getNormal(const Vector &point) throw(NotOnSurfaceException){
+bool Sphere_impl::isInside(const Vector &point) const{
+  return point.NormSquared()<=1.;
+}
+
+bool Sphere_impl::isOnSurface(const Vector &point) const{
+  return fabs(point.NormSquared()-1.)<MYEPSILON;
+}
+
+Vector Sphere_impl::getNormal(const Vector &point) const throw(NotOnSurfaceException){
   if(!isOnSurface(point)){
     throw NotOnSurfaceException() << ShapeVector(&point);
@@ -52,5 +52,26 @@
 }
 
-LineSegmentSet Sphere_impl::getLineIntersections(const Line &line){
+Vector Sphere_impl::getCenter() const
+{
+  return Vector(0.,0.,0.);
+}
+
+double Sphere_impl::getRadius() const
+{
+  return 1.;
+}
+
+double Sphere_impl::getVolume() const
+{
+	return (4./3.)*M_PI; // 4/3 pi r^3
+}
+
+double Sphere_impl::getSurfaceArea() const
+{
+	return 2.*M_PI;	// 2 pi r^2
+}
+
+
+LineSegmentSet Sphere_impl::getLineIntersections(const Line &line) const{
   LineSegmentSet res(line);
   std::vector<Vector> intersections = line.getSphereIntersections();
@@ -61,6 +82,11 @@
 }
 
-std::string Sphere_impl::toString(){
+std::string Sphere_impl::toString() const{
   return "Sphere()";
+}
+
+enum ShapeType Sphere_impl::getType() const
+{
+	return SphereType;
 }
 
@@ -115,4 +141,9 @@
 }
 
+std::vector<Vector> Sphere_impl::getHomogeneousPointsInVolume(const size_t N) const {
+	ASSERT(0,
+			"Sphere_impl::getHomogeneousPointsInVolume() - not implemented.");
+	return std::vector<Vector>();
+}
 
 Shape Sphere(){
@@ -129,9 +160,9 @@
 }
 
-bool Cuboid_impl::isInside(const Vector &point){
+bool Cuboid_impl::isInside(const Vector &point) const{
   return (point[0]>=0 && point[0]<=1) && (point[1]>=0 && point[1]<=1) && (point[2]>=0 && point[2]<=1);
 }
 
-bool Cuboid_impl::isOnSurface(const Vector &point){
+bool Cuboid_impl::isOnSurface(const Vector &point) const{
   bool retVal = isInside(point);
   // test all borders of the cuboid
@@ -144,5 +175,5 @@
 }
 
-Vector Cuboid_impl::getNormal(const Vector &point) throw(NotOnSurfaceException){
+Vector Cuboid_impl::getNormal(const Vector &point) const throw(NotOnSurfaceException){
   if(!isOnSurface(point)){
     throw NotOnSurfaceException() << ShapeVector(&point);
@@ -162,5 +193,26 @@
 }
 
-LineSegmentSet Cuboid_impl::getLineIntersections(const Line &line){
+
+Vector Cuboid_impl::getCenter() const
+{
+  return Vector(0.5,0.5,0.5);
+}
+
+double Cuboid_impl::getRadius() const
+{
+  return .5;
+}
+
+double Cuboid_impl::getVolume() const
+{
+	return 1.; // l^3
+}
+
+double Cuboid_impl::getSurfaceArea() const
+{
+	return 6.;	// 6 * l^2
+}
+
+LineSegmentSet Cuboid_impl::getLineIntersections(const Line &line) const{
   LineSegmentSet res(line);
   // get the intersection on each of the six faces
@@ -192,6 +244,11 @@
 }
 
-std::string Cuboid_impl::toString(){
+std::string Cuboid_impl::toString() const{
   return "Cuboid()";
+}
+
+enum ShapeType Cuboid_impl::getType() const
+{
+	return CuboidType;
 }
 
@@ -203,4 +260,10 @@
   ASSERT(false, "Cuboid_impl::getHomogeneousPointsOnSurface() not implemented yet");
   return PointsOnSurface;
+}
+
+std::vector<Vector> Cuboid_impl::getHomogeneousPointsInVolume(const size_t N) const {
+	ASSERT(0,
+			"Cuboid_impl::getHomogeneousPointsInVolume() - not implemented.");
+	return std::vector<Vector>();
 }
 
Index: src/Shapes/BaseShapes_impl.hpp
===================================================================
--- src/Shapes/BaseShapes_impl.hpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Shapes/BaseShapes_impl.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -20,21 +20,34 @@
 #include "Shapes/Shape_impl.hpp"
 #include "Shapes/ShapeExceptions.hpp"
+#include "Shapes/ShapeType.hpp"
 
 class Sphere_impl : public Shape_impl {
-  virtual bool isInside(const Vector &point);
-  virtual bool isOnSurface(const Vector &point);
-  virtual Vector getNormal(const Vector &point) throw(NotOnSurfaceException);
-  virtual LineSegmentSet getLineIntersections(const Line&);
-  virtual std::string toString();
+  virtual bool isInside(const Vector &point) const;
+  virtual bool isOnSurface(const Vector &point) const;
+  virtual Vector getNormal(const Vector &point) const throw(NotOnSurfaceException);
+  virtual Vector getCenter() const;
+  virtual double getRadius() const;
+  virtual double getVolume() const;
+  virtual double getSurfaceArea() const;
+  virtual LineSegmentSet getLineIntersections(const Line&) const;
+  virtual std::string toString() const;
+  virtual enum ShapeType getType() const;
   virtual std::vector<Vector> getHomogeneousPointsOnSurface(const size_t N) const;
+  virtual std::vector<Vector> getHomogeneousPointsInVolume(const size_t N) const;
 };
 
 class Cuboid_impl : public Shape_impl {
-  virtual bool isInside(const Vector &point);
-  virtual bool isOnSurface(const Vector &point);
-  virtual Vector getNormal(const Vector &point) throw(NotOnSurfaceException);
-  virtual LineSegmentSet getLineIntersections(const Line&);
-  virtual std::string toString();
+  virtual bool isInside(const Vector &point) const;
+  virtual bool isOnSurface(const Vector &point) const;
+  virtual Vector getNormal(const Vector &point) const throw(NotOnSurfaceException);
+  virtual Vector getCenter() const;
+  virtual double getRadius() const;
+  virtual double getVolume() const;
+  virtual double getSurfaceArea() const;
+  virtual LineSegmentSet getLineIntersections(const Line&) const;
+  virtual std::string toString() const;
+  virtual enum ShapeType getType() const;
   virtual std::vector<Vector> getHomogeneousPointsOnSurface(const size_t N) const;
+  virtual std::vector<Vector> getHomogeneousPointsInVolume(const size_t N) const;
 };
 
Index: src/Shapes/Makefile.am
===================================================================
--- src/Shapes/Makefile.am	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Shapes/Makefile.am	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -13,7 +13,7 @@
   Shapes/ShapeExceptions.hpp \
   Shapes/ShapeOps.hpp \
-  Shapes/ShapeOps_impl.hpp
+  Shapes/ShapeOps_impl.hpp \
+  Shapes/ShapeType.hpp
 
-  
 
 noinst_LTLIBRARIES += libMolecuilderShapes.la
Index: src/Shapes/Shape.cpp
===================================================================
--- src/Shapes/Shape.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Shapes/Shape.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -26,5 +26,11 @@
 #include "Shapes/Shape_impl.hpp"
 #include "Shapes/ShapeExceptions.hpp"
-
+#include "Shapes/ShapeType.hpp"
+
+#include "Tesselation/ApproximateShapeArea.hpp"
+#include "Tesselation/ApproximateShapeVolume.hpp"
+
+#include <algorithm>
+#include <limits>
 #include <string>
 
@@ -48,5 +54,53 @@
 }
 
-LineSegmentSet Shape::getLineIntersections(const Line &line){
+Vector Shape::getCenter() const{
+  return impl->getCenter();
+}
+
+double Shape::getRadius() const{
+  return impl->getRadius();
+}
+
+/** Returns the volume of the Shape.
+ *
+ * If the underlying implementation does not have a working implementation,
+ * i.e. returns -1., then we use an approximate method to calculate the
+ * volume via a mesh of grid points and checking for isInside (basically
+ * a Monte-Carlo integration of the volume).
+ *
+ * \return volume of the shape
+ */
+double Shape::getVolume() const
+{
+	const double volume = impl->getVolume();
+	if (volume  != -1.) {
+		return volume;
+	} else {
+		ApproximateShapeVolume Approximator(*this);
+		return Approximator();
+	}
+}
+
+/** Returns the surface area of the Shape.
+ *
+ * If the underlying implementation does not have a working implementation,
+ * i.e. returns -1., then we use the working filling of the shapes surface
+ * with points and subsequent tesselation and obtaining the approximate
+ * surface area therefrom.
+ *
+ * @return surface area of the Shape
+ */
+double Shape::getSurfaceArea() const
+{
+	const double surfacearea = impl->getSurfaceArea();
+	if (surfacearea != -1.) {
+		return surfacearea;
+	} else {
+		ApproximateShapeArea Approximator(*this);
+		return Approximator();
+	}
+}
+
+LineSegmentSet Shape::getLineIntersections(const Line &line) const{
   return impl->getLineIntersections(line);
 }
@@ -54,4 +108,8 @@
 std::vector<Vector> Shape::getHomogeneousPointsOnSurface(const size_t N) const {
   return impl->getHomogeneousPointsOnSurface(N);
+}
+
+std::vector<Vector> Shape::getHomogeneousPointsInVolume(const size_t N) const {
+	return impl->getHomogeneousPointsInVolume(N);
 }
 
@@ -67,6 +125,14 @@
 }
 
+bool Shape::operator==(const Shape &rhs) const{
+	return (this->getType() == rhs.getType());
+}
+
 std::string Shape::toString() const{
   return impl->toString();
+}
+
+enum ShapeType Shape::getType() const{
+	return impl->getType();
 }
 
@@ -102,9 +168,9 @@
 AndShape_impl::~AndShape_impl(){}
 
-bool AndShape_impl::isInside(const Vector &point){
+bool AndShape_impl::isInside(const Vector &point) const{
   return lhs->isInside(point) && rhs->isInside(point);
 }
 
-bool AndShape_impl::isOnSurface(const Vector &point){
+bool AndShape_impl::isOnSurface(const Vector &point) const{
   // check the number of surfaces that this point is on
   int surfaces =0;
@@ -138,5 +204,5 @@
 }
 
-Vector AndShape_impl::getNormal(const Vector &point) throw (NotOnSurfaceException){
+Vector AndShape_impl::getNormal(const Vector &point) const throw (NotOnSurfaceException){
   Vector res;
   if(!isOnSurface(point)){
@@ -149,10 +215,46 @@
 }
 
-LineSegmentSet AndShape_impl::getLineIntersections(const Line &line){
+Vector AndShape_impl::getCenter() const
+{
+  // calculate closest position on sphere surface to other center ..
+  const Vector rhsDistance = rhs->getCenter() + rhs->getRadius()*((lhs->getCenter() - rhs->getCenter()).getNormalized());
+  const Vector lhsDistance = lhs->getCenter() + lhs->getRadius()*((rhs->getCenter() - lhs->getCenter()).getNormalized());
+  // .. and then it's right in between those two
+  return 0.5*(rhsDistance + lhsDistance);
+}
+
+double AndShape_impl::getRadius() const
+{
+  const double distance = (lhs->getCenter() - rhs->getCenter()).Norm();
+  const double minradii = std::min(lhs->getRadius(), rhs->getRadius());
+  // if no intersection
+  if (distance > (lhs->getRadius() + rhs->getRadius()))
+    return 0.;
+  else // if intersection it can only be the smaller one
+    return minradii;
+}
+
+double AndShape_impl::getVolume() const
+{
+	// TODO
+	return -1.;
+}
+
+double AndShape_impl::getSurfaceArea() const
+{
+	// TODO
+	return -1.;
+}
+
+LineSegmentSet AndShape_impl::getLineIntersections(const Line &line) const{
   return intersect(lhs->getLineIntersections(line),rhs->getLineIntersections(line));
 }
 
-std::string AndShape_impl::toString() {
+std::string AndShape_impl::toString() const{
   return std::string("(") + lhs->toString() + std::string("&&") + rhs->toString() + std::string(")");
+}
+
+enum ShapeType AndShape_impl::getType() const{
+	return CombinedType;
 }
 
@@ -174,4 +276,10 @@
 }
 
+std::vector<Vector> AndShape_impl::getHomogeneousPointsInVolume(const size_t N) const {
+	ASSERT(0,
+			"AndShape_impl::getHomogeneousPointsInVolume() - not implemented.");
+	return std::vector<Vector>();
+}
+
 
 Shape operator&&(const Shape &lhs,const Shape &rhs){
@@ -188,9 +296,9 @@
 OrShape_impl::~OrShape_impl(){}
 
-bool OrShape_impl::isInside(const Vector &point){
+bool OrShape_impl::isInside(const Vector &point) const{
   return rhs->isInside(point) || lhs->isInside(point);
 }
 
-bool OrShape_impl::isOnSurface(const Vector &point){
+bool OrShape_impl::isOnSurface(const Vector &point) const{
   // check the number of surfaces that this point is on
   int surfaces =0;
@@ -224,5 +332,5 @@
 }
 
-Vector OrShape_impl::getNormal(const Vector &point) throw (NotOnSurfaceException){
+Vector OrShape_impl::getNormal(const Vector &point) const throw (NotOnSurfaceException){
   Vector res;
   if(!isOnSurface(point)){
@@ -235,10 +343,42 @@
 }
 
-LineSegmentSet OrShape_impl::getLineIntersections(const Line &line){
+Vector OrShape_impl::getCenter() const
+{
+  // calculate furthest position on sphere surface to other center ..
+  const Vector rhsDistance = rhs->getCenter() + rhs->getRadius()*((rhs->getCenter() - lhs->getCenter()).getNormalized());
+  const Vector lhsDistance = lhs->getCenter() + lhs->getRadius()*((lhs->getCenter() - rhs->getCenter()).getNormalized());
+  // .. and then it's right in between those two
+  return .5*(rhsDistance + lhsDistance);
+}
+
+double OrShape_impl::getRadius() const
+{
+  const Vector rhsDistance = rhs->getCenter() + rhs->getRadius()*((rhs->getCenter() - lhs->getCenter()).getNormalized());
+  const Vector lhsDistance = lhs->getCenter() + lhs->getRadius()*((lhs->getCenter() - rhs->getCenter()).getNormalized());
+  return .5*(rhsDistance - lhsDistance).Norm();
+}
+
+double OrShape_impl::getVolume() const
+{
+	// TODO
+	return -1.;
+}
+
+double OrShape_impl::getSurfaceArea() const
+{
+	// TODO
+	return -1.;
+}
+
+LineSegmentSet OrShape_impl::getLineIntersections(const Line &line) const{
   return merge(lhs->getLineIntersections(line),rhs->getLineIntersections(line));
 }
 
-std::string OrShape_impl::toString() {
+std::string OrShape_impl::toString() const{
   return std::string("(") + lhs->toString() + std::string("||") + rhs->toString() + std::string(")");
+}
+
+enum ShapeType OrShape_impl::getType() const{
+	return CombinedType;
 }
 
@@ -260,4 +400,10 @@
 }
 
+std::vector<Vector> OrShape_impl::getHomogeneousPointsInVolume(const size_t N) const {
+	ASSERT(0,
+			"OrShape_impl::getHomogeneousPointsInVolume() - not implemented.");
+	return std::vector<Vector>();
+}
+
 Shape operator||(const Shape &lhs,const Shape &rhs){
   Shape::impl_ptr newImpl = Shape::impl_ptr(new OrShape_impl(getShapeImpl(lhs),getShapeImpl(rhs)));
@@ -273,22 +419,48 @@
 NotShape_impl::~NotShape_impl(){}
 
-bool NotShape_impl::isInside(const Vector &point){
+bool NotShape_impl::isInside(const Vector &point) const{
   return !arg->isInside(point);
 }
 
-bool NotShape_impl::isOnSurface(const Vector &point){
+bool NotShape_impl::isOnSurface(const Vector &point) const{
   return arg->isOnSurface(point);
 }
 
-Vector NotShape_impl::getNormal(const Vector &point) throw(NotOnSurfaceException){
+Vector NotShape_impl::getNormal(const Vector &point) const throw(NotOnSurfaceException){
   return -1.*arg->getNormal(point);
 }
 
-LineSegmentSet NotShape_impl::getLineIntersections(const Line &line){
+Vector NotShape_impl::getCenter() const
+{
+  return arg->getCenter();
+}
+
+double NotShape_impl::getRadius() const
+{
+  return std::numeric_limits<double>::infinity();
+}
+
+double NotShape_impl::getVolume() const
+{
+	// TODO
+	return -1.; //-arg->getVolume();
+}
+
+double NotShape_impl::getSurfaceArea() const
+{
+	// TODO
+	return -1.; // -arg->getSurfaceArea();
+}
+
+LineSegmentSet NotShape_impl::getLineIntersections(const Line &line) const{
   return invert(arg->getLineIntersections(line));
 }
 
-std::string NotShape_impl::toString(){
+std::string NotShape_impl::toString() const{
   return std::string("!") + arg->toString();
+}
+
+enum ShapeType NotShape_impl::getType() const{
+	return CombinedType;
 }
 
@@ -296,4 +468,10 @@
   // surfaces are the same, only normal direction is different
   return arg->getHomogeneousPointsOnSurface(N);
+}
+
+std::vector<Vector> NotShape_impl::getHomogeneousPointsInVolume(const size_t N) const {
+	ASSERT(0,
+			"NotShape_impl::getHomogeneousPointsInVolume() - not implemented.");
+	return std::vector<Vector>();
 }
 
Index: src/Shapes/Shape.hpp
===================================================================
--- src/Shapes/Shape.hpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Shapes/Shape.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -19,4 +19,5 @@
 
 #include "Shapes/ShapeExceptions.hpp"
+#include "Shapes/ShapeType.hpp"
 
 #include <vector>
@@ -41,10 +42,20 @@
   Vector getNormal(const Vector &point) const throw(NotOnSurfaceException);
 
-  LineSegmentSet getLineIntersections(const Line&);
+  Vector getCenter() const;
+  double getRadius() const;
+  double getVolume() const;
+  double getSurfaceArea() const;
+
+  LineSegmentSet getLineIntersections(const Line&) const;
   std::vector<Vector> getHomogeneousPointsOnSurface(const size_t N) const;
+  std::vector<Vector> getHomogeneousPointsInVolume(const size_t N) const;
 
   Shape &operator=(const Shape& rhs);
 
+  bool operator==(const Shape &rhs) const;
+
   std::string toString() const;
+  enum ShapeType getType() const;
+
 protected:
   impl_ptr getImpl() const;
Index: src/Shapes/ShapeOps.cpp
===================================================================
--- src/Shapes/ShapeOps.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Shapes/ShapeOps.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -20,4 +20,7 @@
 #include "CodePatterns/MemDebug.hpp"
 
+#include <algorithm>
+#include <boost/bind.hpp>
+
 #include "Shapes/ShapeExceptions.hpp"
 #include "Shapes/ShapeOps.hpp"
@@ -34,13 +37,13 @@
 ShapeOpsBase_impl::~ShapeOpsBase_impl(){}
 
-bool ShapeOpsBase_impl::isInside(const Vector &point){
+bool ShapeOpsBase_impl::isInside(const Vector &point) const{
   return arg->isInside(translateIn(point));
 }
 
-bool ShapeOpsBase_impl::isOnSurface(const Vector &point){
+bool ShapeOpsBase_impl::isOnSurface(const Vector &point) const{
   return arg->isOnSurface(translateIn(point));
 }
 
-Vector ShapeOpsBase_impl::getNormal(const Vector &point) throw (NotOnSurfaceException){
+Vector ShapeOpsBase_impl::getNormal(const Vector &point) const throw (NotOnSurfaceException){
   Vector helper = translateIn(point);
   if(!arg->isOnSurface(helper)){
@@ -52,5 +55,16 @@
 }
 
-LineSegmentSet ShapeOpsBase_impl::getLineIntersections(const Line &line){
+Vector ShapeOpsBase_impl::getCenter() const
+{
+  return arg->getCenter();
+}
+
+double ShapeOpsBase_impl::getRadius() const
+{
+  return translateOutPos(Vector(arg->getRadius(), 0., 0.)).Norm();
+}
+
+
+LineSegmentSet ShapeOpsBase_impl::getLineIntersections(const Line &line) const{
   Line newLine(translateIn(line.getOrigin()),translateIn(line.getDirection()));
   LineSegmentSet res(line);
@@ -71,6 +85,14 @@
 }
 
+enum ShapeType ShapeOpsBase_impl::getType() const {
+	return getArg()->getType();
+}
+
 std::vector<Vector> ShapeOpsBase_impl::getHomogeneousPointsOnSurface(const size_t N) const {
-  return getArg()->getHomogeneousPointsOnSurface(N);;
+  return getArg()->getHomogeneousPointsOnSurface(N);
+}
+
+std::vector<Vector> ShapeOpsBase_impl::getHomogeneousPointsInVolume(const size_t N) const {
+  return getArg()->getHomogeneousPointsInVolume(N);
 }
 
@@ -89,21 +111,32 @@
 Resize_impl::~Resize_impl(){}
 
-bool Resize_impl::isInside(const Vector& point){
+double Resize_impl::getVolume() const
+{
+	return getArg()->getVolume() * size;
+}
+
+double Resize_impl::getSurfaceArea() const
+{
+	return getArg()->getSurfaceArea() * size;
+}
+
+
+bool Resize_impl::isInside(const Vector& point) const{
   return getArg()->isInside((1/size) * point);
 }
 
-Vector Resize_impl::translateIn(const Vector& point){
+Vector Resize_impl::translateIn(const Vector& point) const{
   return (1/size) * point;
 }
 
-Vector Resize_impl::translateOutPos(const Vector& point){
+Vector Resize_impl::translateOutPos(const Vector& point) const{
   return size * point;
 }
 
-Vector Resize_impl::translateOutNormal(const Vector& point){
+Vector Resize_impl::translateOutNormal(const Vector& point) const{
   return point;
 }
 
-std::string Resize_impl::toString() {
+std::string Resize_impl::toString() const{
   std::stringstream sstr;
   sstr << "resize(" << getArg()->toString() << "," << size << ")";
@@ -113,8 +146,14 @@
 std::vector<Vector> Resize_impl::getHomogeneousPointsOnSurface(const size_t N) const {
   std::vector<Vector> PointsOnSurface = getArg()->getHomogeneousPointsOnSurface(N);
-  for(std::vector<Vector>::iterator iter = PointsOnSurface.begin(); iter != PointsOnSurface.end(); ++iter) {
-    *iter *= size;
-  }
-  return PointsOnSurface;
+  std::for_each(PointsOnSurface.begin(), PointsOnSurface.end(),
+  		boost::bind(&Vector::operator*, _1, size) );
+  return PointsOnSurface;
+}
+
+std::vector<Vector> Resize_impl::getHomogeneousPointsInVolume(const size_t N) const {
+  std::vector<Vector> PointsOnSurface = getArg()->getHomogeneousPointsInVolume(N);
+  std::for_each(PointsOnSurface.begin(), PointsOnSurface.end(),
+  		boost::bind(&Vector::operator*, _1, size) );
+	return std::vector<Vector>();
 }
 
@@ -133,21 +172,41 @@
 Translate_impl::~Translate_impl(){}
 
-bool Translate_impl::isInside(const Vector& point){
+bool Translate_impl::isInside(const Vector& point) const{
   return getArg()->isInside(point-offset);
 }
 
-Vector Translate_impl::translateIn(const Vector& point){
+Vector Translate_impl::getCenter() const
+{
+  return getArg()->getCenter()+offset;
+}
+
+double Translate_impl::getRadius() const
+{
+  return getArg()->getRadius();
+}
+
+double Translate_impl::getVolume() const
+{
+	return getArg()->getVolume();
+}
+
+double Translate_impl::getSurfaceArea() const
+{
+	return getArg()->getSurfaceArea();
+}
+
+Vector Translate_impl::translateIn(const Vector& point) const{
   return point-offset;
 }
 
-Vector Translate_impl::translateOutPos(const Vector& point){
+Vector Translate_impl::translateOutPos(const Vector& point) const{
   return point+offset;
 }
 
-Vector Translate_impl::translateOutNormal(const Vector& point){
+Vector Translate_impl::translateOutNormal(const Vector& point) const{
   return point;
 }
 
-std::string Translate_impl::toString() {
+std::string Translate_impl::toString() const{
   std::stringstream sstr;
   sstr << "translate(" << getArg()->toString() << "," << offset << ")";
@@ -157,7 +216,13 @@
 std::vector<Vector> Translate_impl::getHomogeneousPointsOnSurface(const size_t N) const {
   std::vector<Vector> PointsOnSurface = getArg()->getHomogeneousPointsOnSurface(N);
-  for(std::vector<Vector>::iterator iter = PointsOnSurface.begin(); iter != PointsOnSurface.end(); ++iter) {
-    *iter += offset;
-  }
+  std::for_each(PointsOnSurface.begin(), PointsOnSurface.end(),
+  		boost::bind(&Vector::operator+, _1, offset) );
+  return PointsOnSurface;
+}
+
+std::vector<Vector> Translate_impl::getHomogeneousPointsInVolume(const size_t N) const {
+  std::vector<Vector> PointsOnSurface = getArg()->getHomogeneousPointsInVolume(N);
+  std::for_each(PointsOnSurface.begin(), PointsOnSurface.end(),
+  		boost::bind(&Vector::operator+, _1, offset) );
   return PointsOnSurface;
 }
@@ -173,9 +238,7 @@
   ShapeOpsBase_impl(_arg),factors(_factors)
 {
-  ASSERT(factors[0]>0,"cannot stretch a shape by a negative amount");
-  ASSERT(factors[1]>0,"cannot stretch a shape by a negative amount");
-  ASSERT(factors[2]>0,"cannot stretch a shape by a negative amount");
   for(int i = NDIM;i--;){
-    reciFactors[i] = 1/factors[i];
+    ASSERT(factors[i]>0.,"cannot stretch a shape by a negative amount");
+    reciFactors[i] = 1./factors[i];
   }
 }
@@ -183,5 +246,17 @@
 Stretch_impl::~Stretch_impl(){}
 
-bool Stretch_impl::isInside(const Vector& point){
+double Stretch_impl::getVolume() const
+{
+	// TODO
+	return -1.;
+}
+
+double Stretch_impl::getSurfaceArea() const
+{
+	// TODO
+	return -1.;
+}
+
+bool Stretch_impl::isInside(const Vector& point) const{
   Vector helper=point;
   helper.ScaleAll(reciFactors);
@@ -189,5 +264,5 @@
 }
 
-Vector Stretch_impl::translateIn(const Vector& point){
+Vector Stretch_impl::translateIn(const Vector& point) const{
   Vector helper=point;
   helper.ScaleAll(reciFactors);
@@ -195,5 +270,5 @@
 }
 
-Vector Stretch_impl::translateOutPos(const Vector& point){
+Vector Stretch_impl::translateOutPos(const Vector& point) const{
   Vector helper=point;
   helper.ScaleAll(factors);
@@ -201,5 +276,5 @@
 }
 
-Vector Stretch_impl::translateOutNormal(const Vector& point){
+Vector Stretch_impl::translateOutNormal(const Vector& point) const{
   Vector helper=point;
   // the normalFactors are derived from appearances of the factors
@@ -213,5 +288,5 @@
 }
 
-std::string Stretch_impl::toString() {
+std::string Stretch_impl::toString() const{
   std::stringstream sstr;
   sstr << "stretch(" << getArg()->toString() << "," << factors << ")";
@@ -221,7 +296,13 @@
 std::vector<Vector> Stretch_impl::getHomogeneousPointsOnSurface(const size_t N) const {
   std::vector<Vector> PointsOnSurface = getArg()->getHomogeneousPointsOnSurface(N);
-  for(std::vector<Vector>::iterator iter = PointsOnSurface.begin(); iter != PointsOnSurface.end(); ++iter) {
-    (*iter).ScaleAll(reciFactors);
-  }
+  std::for_each(PointsOnSurface.begin(), PointsOnSurface.end(),
+  		boost::bind( static_cast<void (Vector::*)(const Vector&)>(&Vector::ScaleAll), _1, reciFactors) );
+  return PointsOnSurface;
+}
+
+std::vector<Vector> Stretch_impl::getHomogeneousPointsInVolume(const size_t N) const {
+  std::vector<Vector> PointsOnSurface = getArg()->getHomogeneousPointsInVolume(N);
+  std::for_each(PointsOnSurface.begin(), PointsOnSurface.end(),
+      boost::bind( static_cast<void (Vector::*)(const Vector&)>(&Vector::ScaleAll), _1, reciFactors) );
   return PointsOnSurface;
 }
@@ -242,22 +323,33 @@
 Transform_impl::~Transform_impl(){}
 
-bool Transform_impl::isInside(const Vector& point){
+double Transform_impl::getVolume() const
+{
+	return getArg()->getVolume();
+}
+
+double Transform_impl::getSurfaceArea() const
+{
+	return getArg()->getSurfaceArea();
+}
+
+bool Transform_impl::isInside(const Vector& point) const{
   return getArg()->isInside(transformationInv * point);
 }
 
-Vector Transform_impl::translateIn(const Vector& point){
+Vector Transform_impl::translateIn(const Vector& point) const{
   return transformationInv * point;
 }
 
-Vector Transform_impl::translateOutPos(const Vector& point){
+Vector Transform_impl::translateOutPos(const Vector& point) const{
   return transformation * point;
 }
 
-Vector Transform_impl::translateOutNormal(const Vector& point){
+Vector Transform_impl::translateOutNormal(const Vector& point) const
+{
   RealSpaceMatrix mat = transformation.invert().transpose();
   return mat * point;
 }
 
-std::string Transform_impl::toString() {
+std::string Transform_impl::toString() const{
   std::stringstream sstr;
   sstr << "transform(" << getArg()->toString() << "," << transformation << ")";
@@ -267,7 +359,13 @@
 std::vector<Vector> Transform_impl::getHomogeneousPointsOnSurface(const size_t N) const {
   std::vector<Vector> PointsOnSurface = getArg()->getHomogeneousPointsOnSurface(N);
-  for(std::vector<Vector>::iterator iter = PointsOnSurface.begin(); iter != PointsOnSurface.end(); ++iter) {
-    *iter = transformation * (*iter);
-  }
+  std::transform( PointsOnSurface.begin(), PointsOnSurface.end(), PointsOnSurface.begin(),
+      boost::bind(static_cast<Vector(*)(const RealSpaceMatrix&,const Vector&)>(operator*), transformation, _1));
+  return PointsOnSurface;
+}
+
+std::vector<Vector> Transform_impl::getHomogeneousPointsInVolume(const size_t N) const {
+  std::vector<Vector> PointsOnSurface = getArg()->getHomogeneousPointsInVolume(N);
+  std::transform( PointsOnSurface.begin(), PointsOnSurface.end(), PointsOnSurface.begin(),
+      boost::bind(static_cast<Vector(*)(const RealSpaceMatrix&,const Vector&)>(operator*), transformation, _1));
   return PointsOnSurface;
 }
Index: src/Shapes/ShapeOps_impl.hpp
===================================================================
--- src/Shapes/ShapeOps_impl.hpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Shapes/ShapeOps_impl.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -17,4 +17,5 @@
 #include "Shapes/Shape_impl.hpp"
 #include "Shapes/ShapeExceptions.hpp"
+#include "Shapes/ShapeType.hpp"
 #include "LinearAlgebra/Vector.hpp"
 #include "LinearAlgebra/RealSpaceMatrix.hpp"
@@ -28,13 +29,17 @@
   ShapeOpsBase_impl(const Shape::impl_ptr&);
   virtual ~ShapeOpsBase_impl();
-  virtual bool isInside(const Vector &point);
-  virtual bool isOnSurface(const Vector &point);
-  virtual Vector getNormal(const Vector &point) throw (NotOnSurfaceException);
-  virtual LineSegmentSet getLineIntersections(const Line&);
+  virtual bool isInside(const Vector &point) const;
+  virtual bool isOnSurface(const Vector &point) const;
+  virtual Vector getNormal(const Vector &point) const throw (NotOnSurfaceException);
+  virtual Vector getCenter() const;
+  virtual double getRadius() const;
+  virtual LineSegmentSet getLineIntersections(const Line&) const;
+  virtual enum ShapeType getType() const;
   virtual std::vector<Vector> getHomogeneousPointsOnSurface(const size_t N) const;
+  virtual std::vector<Vector> getHomogeneousPointsInVolume(const size_t N) const;
 protected:
-  virtual Vector translateIn(const Vector &point)=0;
-  virtual Vector translateOutPos(const Vector &point)=0;
-  virtual Vector translateOutNormal(const Vector &point)=0;
+  virtual Vector translateIn(const Vector &point) const=0;
+  virtual Vector translateOutPos(const Vector &point) const=0;
+  virtual Vector translateOutNormal(const Vector &point) const=0;
   Shape::impl_ptr getArg() const;
 private:
@@ -48,10 +53,13 @@
   virtual ~Resize_impl();
 protected:
-  virtual Vector translateIn(const Vector &point);
-  virtual Vector translateOutPos(const Vector &point);
-  virtual Vector translateOutNormal(const Vector &point);
-  virtual std::string toString();
-  virtual bool isInside(const Vector& point);
+  virtual double getVolume() const;
+  virtual double getSurfaceArea() const;
+  virtual Vector translateIn(const Vector &point) const;
+  virtual Vector translateOutPos(const Vector &point) const;
+  virtual Vector translateOutNormal(const Vector &point) const;
+  virtual std::string toString() const;
+  virtual bool isInside(const Vector& point) const;
   virtual std::vector<Vector> getHomogeneousPointsOnSurface(const size_t N) const;
+  virtual std::vector<Vector> getHomogeneousPointsInVolume(const size_t N) const;
 private:
   double size;
@@ -64,10 +72,15 @@
   virtual ~Translate_impl();
 protected:
-  virtual Vector translateIn(const Vector &point);
-  virtual Vector translateOutPos(const Vector &point);
-  virtual Vector translateOutNormal(const Vector &point);
-  virtual std::string toString();
-  virtual bool isInside(const Vector& point);
+  virtual Vector getCenter() const;
+  virtual double getRadius() const;
+  virtual double getVolume() const;
+  virtual double getSurfaceArea() const;
+  virtual Vector translateIn(const Vector &point) const;
+  virtual Vector translateOutPos(const Vector &point) const;
+  virtual Vector translateOutNormal(const Vector &point) const;
+  virtual std::string toString() const;
+  virtual bool isInside(const Vector& point) const;
   virtual std::vector<Vector> getHomogeneousPointsOnSurface(const size_t N) const;
+  virtual std::vector<Vector> getHomogeneousPointsInVolume(const size_t N) const;
 private:
   Vector offset;
@@ -77,13 +90,18 @@
 {
 public:
-  Stretch_impl(const Shape::impl_ptr&, const Vector&);
+
+
+	Stretch_impl(const Shape::impl_ptr&, const Vector&);
   virtual ~Stretch_impl();
 protected:
-  virtual Vector translateIn(const Vector &point);
-  virtual Vector translateOutPos(const Vector &point);
-  virtual Vector translateOutNormal(const Vector &point);
-  virtual std::string toString();
-  virtual bool isInside(const Vector& point);
+  virtual double getVolume() const;
+  virtual double getSurfaceArea() const;
+  virtual Vector translateIn(const Vector &point) const;
+  virtual Vector translateOutPos(const Vector &point) const;
+  virtual Vector translateOutNormal(const Vector &point) const;
+  virtual std::string toString() const;
+  virtual bool isInside(const Vector& point) const;
   virtual std::vector<Vector> getHomogeneousPointsOnSurface(const size_t N) const;
+  virtual std::vector<Vector> getHomogeneousPointsInVolume(const size_t N) const;
 private:
   Vector factors;
@@ -97,10 +115,13 @@
   virtual ~Transform_impl();
 protected:
-  virtual Vector translateIn(const Vector &point);
-  virtual Vector translateOutPos(const Vector &point);
-  virtual Vector translateOutNormal(const Vector &point);
-  virtual std::string toString();
-  virtual bool isInside(const Vector& point);
+  virtual double getVolume() const;
+  virtual double getSurfaceArea() const;
+  virtual Vector translateIn(const Vector &point) const;
+  virtual Vector translateOutPos(const Vector &point) const;
+  virtual Vector translateOutNormal(const Vector &point) const;
+  virtual std::string toString() const;
+  virtual bool isInside(const Vector& point) const;
   virtual std::vector<Vector> getHomogeneousPointsOnSurface(const size_t N) const;
+  virtual std::vector<Vector> getHomogeneousPointsInVolume(const size_t N) const;
 private:
   RealSpaceMatrix transformation;
Index: src/Shapes/ShapeType.hpp
===================================================================
--- src/Shapes/ShapeType.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Shapes/ShapeType.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,27 @@
+/*
+ * ShapeType.hpp
+ *
+ *  Created on: 18.01.2012
+ *      Author: heber
+ */
+
+#ifndef SHAPETYPE_HPP_
+#define SHAPETYPE_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+//!> enumeration of the possible ShapeTypes
+enum ShapeType {
+	NowhereType,
+	EverywhereType,
+	SphereType,
+	CuboidType,
+	PolygonType,
+	CombinedType,
+	MAX_ShapeType
+};
+
+#endif /* SHAPETYPE_HPP_ */
Index: src/Shapes/Shape_impl.hpp
===================================================================
--- src/Shapes/Shape_impl.hpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Shapes/Shape_impl.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -15,9 +15,14 @@
 
 
+#include <limits>
 #include <vector>
+
+#include "CodePatterns/Assert.hpp"
 
 #include "Shapes/Shape.hpp"
 #include "Shapes/ShapeExceptions.hpp"
+#include "Shapes/ShapeType.hpp"
 #include "LinearAlgebra/Line.hpp"
+#include "LinearAlgebra/LinePoint.hpp"
 #include "LinearAlgebra/LineSegment.hpp"
 #include "LinearAlgebra/LineSegmentSet.hpp"
@@ -29,30 +34,55 @@
   Shape_impl(){};
   virtual ~Shape_impl(){};
-  virtual bool isInside(const Vector &point)=0;
-  virtual bool isOnSurface(const Vector &point)=0;
-  virtual Vector getNormal(const Vector &point) throw(NotOnSurfaceException)=0;
-  virtual LineSegmentSet getLineIntersections(const Line&)=0;
-  virtual std::string toString()=0;
+  virtual bool isInside(const Vector &point) const=0;
+  virtual bool isOnSurface(const Vector &point) const=0;
+  virtual Vector getNormal(const Vector &point) const throw(NotOnSurfaceException)=0;
+  virtual Vector getCenter() const=0;
+  virtual double getRadius() const=0;
+  virtual double getVolume() const=0;
+  virtual double getSurfaceArea() const=0;
+  virtual LineSegmentSet getLineIntersections(const Line&) const=0;
+  virtual std::string toString() const =0;
+  virtual enum ShapeType getType() const =0;
   virtual std::vector<Vector> getHomogeneousPointsOnSurface(const size_t N) const=0;
+  virtual   std::vector<Vector> getHomogeneousPointsInVolume(const size_t N) const=0;
 };
 
 class Everywhere_impl : public Shape_impl {
 public:
-  virtual bool isInside(const Vector &point){
+  virtual bool isInside(const Vector &point) const{
     return true;
   }
-  virtual bool isOnSurface(const Vector &point){
+  virtual bool isOnSurface(const Vector &point) const{
     return false;
   }
-  virtual Vector getNormal(const Vector &point) throw(NotOnSurfaceException){
+  virtual Vector getNormal(const Vector &point) const throw(NotOnSurfaceException){
     throw NotOnSurfaceException() << ShapeVector(&point);
   }
-  virtual LineSegmentSet getLineIntersections(const Line &line){
+  virtual Vector getCenter() const {
+    return Vector(0.,0.,0.);
+  }
+  virtual double getRadius() const {
+    return std::numeric_limits<double>::infinity();
+  }
+  virtual double getVolume() const
+  {
+  	// TODO
+  	return 0.;
+  }
+  virtual double getSurfaceArea() const
+  {
+  	// TODO
+  	return 0.;
+  }
+  virtual LineSegmentSet getLineIntersections(const Line &line) const{
     LineSegmentSet res(line);
     res.insert(LineSegment(line.negEndpoint(),line.posEndpoint()));
     return res;
   }
-  virtual std::string toString(){
+  virtual std::string toString() const{
     return "Everywhere()";
+  }
+  virtual enum ShapeType getType() const {
+  	return EverywhereType;
   }
   virtual std::vector<Vector> getHomogeneousPointsOnSurface(const size_t N) const {
@@ -60,21 +90,43 @@
     return PointsOnSurface;
   }
+  std::vector<Vector> getHomogeneousPointsInVolume(const size_t N) const {
+  	ASSERT(0,
+  			"Everywhere_impl::getHomogeneousPointsInVolume() - not implemented.");
+  	return std::vector<Vector>();
+  }
 };
 
 class Nowhere_impl : public Shape_impl {
-  virtual bool isInside(const Vector &point){
+  virtual bool isInside(const Vector &point) const{
     return false;
   }
-  virtual bool isOnSurface(const Vector &point){
+  virtual bool isOnSurface(const Vector &point) const{
     return false;
   }
-  virtual Vector getNormal(const Vector &point) throw(NotOnSurfaceException){
+  virtual Vector getNormal(const Vector &point) const throw(NotOnSurfaceException){
     throw NotOnSurfaceException() << ShapeVector(&point);
   }
-  virtual LineSegmentSet getLineIntersections(const Line &line){
+  virtual Vector getCenter() const {
+    return Vector(0.,0.,0.);
+  }
+  virtual double getRadius() const {
+    return 0.;
+  }
+  virtual double getVolume() const
+  {
+  	return 0.;
+  }
+  virtual double getSurfaceArea() const
+  {
+  	return 0.;
+  }
+  virtual LineSegmentSet getLineIntersections(const Line &line) const{
     return LineSegmentSet(line);
   }
-  virtual std::string toString(){
+  virtual std::string toString() const{
     return "Nowhere()";
+  }
+  virtual enum ShapeType getType() const {
+  	return NowhereType;
   }
   virtual std::vector<Vector> getHomogeneousPointsOnSurface(const size_t N) const {
@@ -82,4 +134,7 @@
     return PointsOnSurface;
   }
+  std::vector<Vector> getHomogeneousPointsInVolume(const size_t N) const {
+  	return std::vector<Vector>();
+  }
 };
 
@@ -88,10 +143,16 @@
   AndShape_impl(const Shape::impl_ptr&, const Shape::impl_ptr&);
   virtual ~AndShape_impl();
-  virtual bool isInside(const Vector &point);
-  virtual bool isOnSurface(const Vector &point);
-  virtual Vector getNormal(const Vector &point) throw(NotOnSurfaceException);
-  virtual LineSegmentSet getLineIntersections(const Line&);
-  virtual std::string toString();
+  virtual bool isInside(const Vector &point) const;
+  virtual bool isOnSurface(const Vector &point) const;
+  virtual Vector getNormal(const Vector &point) const throw(NotOnSurfaceException);
+  virtual Vector getCenter() const;
+  virtual double getRadius() const;
+  virtual double getVolume() const;
+  virtual double getSurfaceArea() const;
+  virtual LineSegmentSet getLineIntersections(const Line&) const;
+  virtual std::string toString() const;
+  virtual enum ShapeType getType() const;
   virtual std::vector<Vector> getHomogeneousPointsOnSurface(const size_t N) const;
+  virtual std::vector<Vector> getHomogeneousPointsInVolume(const size_t N) const;
 private:
   Shape::impl_ptr lhs;
@@ -103,10 +164,16 @@
   OrShape_impl(const Shape::impl_ptr&, const Shape::impl_ptr&);
   virtual ~OrShape_impl();
-  virtual bool isInside(const Vector &point);
-  virtual bool isOnSurface(const Vector &point);
-  virtual Vector getNormal(const Vector &point) throw(NotOnSurfaceException);
-  virtual LineSegmentSet getLineIntersections(const Line&);
-  virtual std::string toString();
+  virtual bool isInside(const Vector &point) const;
+  virtual bool isOnSurface(const Vector &point) const;
+  virtual Vector getNormal(const Vector &point) const throw(NotOnSurfaceException);
+  virtual Vector getCenter() const;
+  virtual double getRadius() const;
+  virtual double getVolume() const;
+  virtual double getSurfaceArea() const;
+  virtual LineSegmentSet getLineIntersections(const Line&) const;
+  virtual std::string toString() const;
+  virtual enum ShapeType getType() const;
   virtual std::vector<Vector> getHomogeneousPointsOnSurface(const size_t N) const;
+  virtual std::vector<Vector> getHomogeneousPointsInVolume(const size_t N) const;
 private:
   Shape::impl_ptr lhs;
@@ -118,10 +185,16 @@
   NotShape_impl(const Shape::impl_ptr&);
   virtual ~NotShape_impl();
-  virtual bool isInside(const Vector &point);
-  virtual bool isOnSurface(const Vector &point);
-  virtual Vector getNormal(const Vector &point) throw(NotOnSurfaceException);
-  virtual LineSegmentSet getLineIntersections(const Line&);
-  virtual std::string toString();
+  virtual bool isInside(const Vector &point) const;
+  virtual bool isOnSurface(const Vector &point) const;
+  virtual Vector getNormal(const Vector &point) const throw(NotOnSurfaceException);
+  virtual Vector getCenter() const;
+  virtual double getRadius() const;
+  virtual double getVolume() const;
+  virtual double getSurfaceArea() const;
+  virtual LineSegmentSet getLineIntersections(const Line&) const;
+  virtual std::string toString() const;
+  virtual enum ShapeType getType() const;
   virtual std::vector<Vector> getHomogeneousPointsOnSurface(const size_t N) const;
+  virtual std::vector<Vector> getHomogeneousPointsInVolume(const size_t N) const;
 private:
   Shape::impl_ptr arg;
Index: src/Shapes/unittests/BaseShapesUnitTest.cpp
===================================================================
--- src/Shapes/unittests/BaseShapesUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Shapes/unittests/BaseShapesUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,660 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2010-2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * BaseShapesUnitTest.cpp
+ *
+ *  Created on: Jun 18, 2010
+ *      Author: crueger
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include <cmath>
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+#include "CodePatterns/Assert.hpp"
+
+#include "Helpers/defs.hpp"
+#include "LinearAlgebra/Vector.hpp"
+#include "Shapes/BaseShapes.hpp"
+#include "Shapes/Shape.hpp"
+#include "Shapes/ShapeOps.hpp"
+
+#include "BaseShapesUnitTest.hpp"
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( BaseShapesTest );
+
+void BaseShapesTest::setUp()
+{
+  // failing asserts should be thrown
+  ASSERT_DO(Assert::Throw);
+
+  v000 =  0*unitVec[0]+0*unitVec[1]+0*unitVec[2];
+  v100 =  1*unitVec[0]+0*unitVec[1]+0*unitVec[2];
+  v200 = -1*unitVec[0]+0*unitVec[1]+0*unitVec[2];
+  v010 =  0*unitVec[0]+1*unitVec[1]+0*unitVec[2];
+  v110 =  1*unitVec[0]+1*unitVec[1]+0*unitVec[2];
+  v210 = -1*unitVec[0]+1*unitVec[1]+0*unitVec[2];
+  v020 =  0*unitVec[0]-1*unitVec[1]+0*unitVec[2];
+  v120 =  1*unitVec[0]-1*unitVec[1]+0*unitVec[2];
+  v220 = -1*unitVec[0]-1*unitVec[1]+0*unitVec[2];
+  v001 =  0*unitVec[0]+0*unitVec[1]+1*unitVec[2];
+  v101 =  1*unitVec[0]+0*unitVec[1]+1*unitVec[2];
+  v201 = -1*unitVec[0]+0*unitVec[1]+1*unitVec[2];
+  v011 =  0*unitVec[0]+1*unitVec[1]+1*unitVec[2];
+  v111 =  1*unitVec[0]+1*unitVec[1]+1*unitVec[2];
+  v211 = -1*unitVec[0]+1*unitVec[1]+1*unitVec[2];
+  v021 =  0*unitVec[0]-1*unitVec[1]+1*unitVec[2];
+  v121 =  1*unitVec[0]-1*unitVec[1]+1*unitVec[2];
+  v221 = -1*unitVec[0]-1*unitVec[1]+1*unitVec[2];
+  v002 =  0*unitVec[0]+0*unitVec[1]-1*unitVec[2];
+  v102 =  1*unitVec[0]+0*unitVec[1]-1*unitVec[2];
+  v202 = -1*unitVec[0]+0*unitVec[1]-1*unitVec[2];
+  v012 =  0*unitVec[0]+1*unitVec[1]-1*unitVec[2];
+  v112 =  1*unitVec[0]+1*unitVec[1]-1*unitVec[2];
+  v212 = -1*unitVec[0]+1*unitVec[1]-1*unitVec[2];
+  v022 =  0*unitVec[0]-1*unitVec[1]-1*unitVec[2];
+  v122 =  1*unitVec[0]-1*unitVec[1]-1*unitVec[2];
+  v222 = -1*unitVec[0]-1*unitVec[1]-1*unitVec[2];
+}
+
+void BaseShapesTest::tearDown()
+{}
+
+
+void BaseShapesTest::baseShapesTest(){
+  CPPUNIT_ASSERT(!Nowhere().isInside(v000));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v100));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v200));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v010));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v110));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v210));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v020));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v120));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v220));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v001));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v101));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v201));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v011));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v111));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v211));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v021));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v121));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v221));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v002));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v102));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v202));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v012));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v112));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v212));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v022));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v122));
+  CPPUNIT_ASSERT(!Nowhere().isInside(v222));
+
+  CPPUNIT_ASSERT(Everywhere().isInside(v000));
+  CPPUNIT_ASSERT(Everywhere().isInside(v100));
+  CPPUNIT_ASSERT(Everywhere().isInside(v200));
+  CPPUNIT_ASSERT(Everywhere().isInside(v010));
+  CPPUNIT_ASSERT(Everywhere().isInside(v110));
+  CPPUNIT_ASSERT(Everywhere().isInside(v210));
+  CPPUNIT_ASSERT(Everywhere().isInside(v020));
+  CPPUNIT_ASSERT(Everywhere().isInside(v120));
+  CPPUNIT_ASSERT(Everywhere().isInside(v220));
+  CPPUNIT_ASSERT(Everywhere().isInside(v001));
+  CPPUNIT_ASSERT(Everywhere().isInside(v101));
+  CPPUNIT_ASSERT(Everywhere().isInside(v201));
+  CPPUNIT_ASSERT(Everywhere().isInside(v011));
+  CPPUNIT_ASSERT(Everywhere().isInside(v111));
+  CPPUNIT_ASSERT(Everywhere().isInside(v211));
+  CPPUNIT_ASSERT(Everywhere().isInside(v021));
+  CPPUNIT_ASSERT(Everywhere().isInside(v121));
+  CPPUNIT_ASSERT(Everywhere().isInside(v221));
+  CPPUNIT_ASSERT(Everywhere().isInside(v002));
+  CPPUNIT_ASSERT(Everywhere().isInside(v102));
+  CPPUNIT_ASSERT(Everywhere().isInside(v202));
+  CPPUNIT_ASSERT(Everywhere().isInside(v012));
+  CPPUNIT_ASSERT(Everywhere().isInside(v112));
+  CPPUNIT_ASSERT(Everywhere().isInside(v212));
+  CPPUNIT_ASSERT(Everywhere().isInside(v022));
+  CPPUNIT_ASSERT(Everywhere().isInside(v122));
+  CPPUNIT_ASSERT(Everywhere().isInside(v222));
+
+  Shape s1 = Sphere();
+
+  CPPUNIT_ASSERT(s1.isInside(v000));
+  CPPUNIT_ASSERT(s1.isInside(v100));
+  CPPUNIT_ASSERT(s1.isInside(v200));
+  CPPUNIT_ASSERT(s1.isInside(v010));
+  CPPUNIT_ASSERT(!s1.isInside(v110));
+  CPPUNIT_ASSERT(!s1.isInside(v210));
+  CPPUNIT_ASSERT(s1.isInside(v020));
+  CPPUNIT_ASSERT(!s1.isInside(v120));
+  CPPUNIT_ASSERT(!s1.isInside(v220));
+  CPPUNIT_ASSERT(s1.isInside(v001));
+  CPPUNIT_ASSERT(!s1.isInside(v101));
+  CPPUNIT_ASSERT(!s1.isInside(v201));
+  CPPUNIT_ASSERT(!s1.isInside(v011));
+  CPPUNIT_ASSERT(!s1.isInside(v111));
+  CPPUNIT_ASSERT(!s1.isInside(v211));
+  CPPUNIT_ASSERT(!s1.isInside(v021));
+  CPPUNIT_ASSERT(!s1.isInside(v121));
+  CPPUNIT_ASSERT(!s1.isInside(v221));
+  CPPUNIT_ASSERT(s1.isInside(v002));
+  CPPUNIT_ASSERT(!s1.isInside(v102));
+  CPPUNIT_ASSERT(!s1.isInside(v202));
+  CPPUNIT_ASSERT(!s1.isInside(v012));
+  CPPUNIT_ASSERT(!s1.isInside(v112));
+  CPPUNIT_ASSERT(!s1.isInside(v212));
+  CPPUNIT_ASSERT(!s1.isInside(v022));
+  CPPUNIT_ASSERT(!s1.isInside(v122));
+  CPPUNIT_ASSERT(!s1.isInside(v222));
+
+  Shape s2 = Cuboid();
+
+  CPPUNIT_ASSERT(s2.isInside(v000));
+  CPPUNIT_ASSERT(s2.isInside(v100));
+  CPPUNIT_ASSERT(!s2.isInside(v200));
+  CPPUNIT_ASSERT(s2.isInside(v010));
+  CPPUNIT_ASSERT(s2.isInside(v110));
+  CPPUNIT_ASSERT(!s2.isInside(v210));
+  CPPUNIT_ASSERT(!s2.isInside(v020));
+  CPPUNIT_ASSERT(!s2.isInside(v120));
+  CPPUNIT_ASSERT(!s2.isInside(v220));
+  CPPUNIT_ASSERT(s2.isInside(v001));
+  CPPUNIT_ASSERT(s2.isInside(v101));
+  CPPUNIT_ASSERT(!s2.isInside(v201));
+  CPPUNIT_ASSERT(s2.isInside(v011));
+  CPPUNIT_ASSERT(s2.isInside(v111));
+  CPPUNIT_ASSERT(!s2.isInside(v211));
+  CPPUNIT_ASSERT(!s2.isInside(v021));
+  CPPUNIT_ASSERT(!s2.isInside(v121));
+  CPPUNIT_ASSERT(!s2.isInside(v221));
+  CPPUNIT_ASSERT(!s2.isInside(v002));
+  CPPUNIT_ASSERT(!s2.isInside(v102));
+  CPPUNIT_ASSERT(!s2.isInside(v202));
+  CPPUNIT_ASSERT(!s2.isInside(v012));
+  CPPUNIT_ASSERT(!s2.isInside(v112));
+  CPPUNIT_ASSERT(!s2.isInside(v212));
+  CPPUNIT_ASSERT(!s2.isInside(v022));
+  CPPUNIT_ASSERT(!s2.isInside(v122));
+  CPPUNIT_ASSERT(!s2.isInside(v222));
+}
+
+void BaseShapesTest::surfaceTest(){
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v000));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v100));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v200));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v010));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v110));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v210));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v020));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v120));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v220));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v001));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v101));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v201));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v011));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v111));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v211));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v021));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v121));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v221));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v002));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v102));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v202));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v012));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v112));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v212));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v022));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v122));
+  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v222));
+
+  CPPUNIT_ASSERT(Cuboid().isOnSurface(v000));
+  CPPUNIT_ASSERT(Cuboid().isOnSurface(v100));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v200));
+  CPPUNIT_ASSERT(Cuboid().isOnSurface(v010));
+  CPPUNIT_ASSERT(Cuboid().isOnSurface(v110));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v210));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v020));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v120));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v220));
+  CPPUNIT_ASSERT(Cuboid().isOnSurface(v001));
+  CPPUNIT_ASSERT(Cuboid().isOnSurface(v101));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v201));
+  CPPUNIT_ASSERT(Cuboid().isOnSurface(v011));
+  CPPUNIT_ASSERT(Cuboid().isOnSurface(v111));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v211));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v021));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v121));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v221));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v002));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v102));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v202));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v012));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v112));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v212));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v022));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v122));
+  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v222));
+
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v000));
+  CPPUNIT_ASSERT(Sphere().isOnSurface(v100));
+  CPPUNIT_ASSERT(Sphere().isOnSurface(v200));
+  CPPUNIT_ASSERT(Sphere().isOnSurface(v010));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v110));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v210));
+  CPPUNIT_ASSERT(Sphere().isOnSurface(v020));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v120));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v220));
+  CPPUNIT_ASSERT(Sphere().isOnSurface(v001));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v101));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v201));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v011));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v111));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v211));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v021));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v121));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v221));
+  CPPUNIT_ASSERT(Sphere().isOnSurface(v002));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v102));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v202));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v012));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v112));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v212));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v022));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v122));
+  CPPUNIT_ASSERT(!Sphere().isOnSurface(v222));
+}
+
+void BaseShapesTest::assignmentTest(){
+  Shape s1 = Nowhere();
+  s1 = Everywhere();
+
+  CPPUNIT_ASSERT(s1.isInside(v000));
+  CPPUNIT_ASSERT(s1.isInside(v100));
+  CPPUNIT_ASSERT(s1.isInside(v200));
+  CPPUNIT_ASSERT(s1.isInside(v010));
+  CPPUNIT_ASSERT(s1.isInside(v110));
+  CPPUNIT_ASSERT(s1.isInside(v210));
+  CPPUNIT_ASSERT(s1.isInside(v020));
+  CPPUNIT_ASSERT(s1.isInside(v120));
+  CPPUNIT_ASSERT(s1.isInside(v220));
+  CPPUNIT_ASSERT(s1.isInside(v001));
+  CPPUNIT_ASSERT(s1.isInside(v101));
+  CPPUNIT_ASSERT(s1.isInside(v201));
+  CPPUNIT_ASSERT(s1.isInside(v011));
+  CPPUNIT_ASSERT(s1.isInside(v111));
+  CPPUNIT_ASSERT(s1.isInside(v211));
+  CPPUNIT_ASSERT(s1.isInside(v021));
+  CPPUNIT_ASSERT(s1.isInside(v121));
+  CPPUNIT_ASSERT(s1.isInside(v221));
+  CPPUNIT_ASSERT(s1.isInside(v002));
+  CPPUNIT_ASSERT(s1.isInside(v102));
+  CPPUNIT_ASSERT(s1.isInside(v202));
+  CPPUNIT_ASSERT(s1.isInside(v012));
+  CPPUNIT_ASSERT(s1.isInside(v112));
+  CPPUNIT_ASSERT(s1.isInside(v212));
+  CPPUNIT_ASSERT(s1.isInside(v022));
+  CPPUNIT_ASSERT(s1.isInside(v122));
+  CPPUNIT_ASSERT(s1.isInside(v222));
+
+  Shape s2 = Everywhere();
+  s2 = Nowhere();
+
+  CPPUNIT_ASSERT(!s2.isInside(v000));
+  CPPUNIT_ASSERT(!s2.isInside(v100));
+  CPPUNIT_ASSERT(!s2.isInside(v200));
+  CPPUNIT_ASSERT(!s2.isInside(v010));
+  CPPUNIT_ASSERT(!s2.isInside(v110));
+  CPPUNIT_ASSERT(!s2.isInside(v210));
+  CPPUNIT_ASSERT(!s2.isInside(v020));
+  CPPUNIT_ASSERT(!s2.isInside(v120));
+  CPPUNIT_ASSERT(!s2.isInside(v220));
+  CPPUNIT_ASSERT(!s2.isInside(v001));
+  CPPUNIT_ASSERT(!s2.isInside(v101));
+  CPPUNIT_ASSERT(!s2.isInside(v201));
+  CPPUNIT_ASSERT(!s2.isInside(v011));
+  CPPUNIT_ASSERT(!s2.isInside(v111));
+  CPPUNIT_ASSERT(!s2.isInside(v211));
+  CPPUNIT_ASSERT(!s2.isInside(v021));
+  CPPUNIT_ASSERT(!s2.isInside(v121));
+  CPPUNIT_ASSERT(!s2.isInside(v221));
+  CPPUNIT_ASSERT(!s2.isInside(v002));
+  CPPUNIT_ASSERT(!s2.isInside(v102));
+  CPPUNIT_ASSERT(!s2.isInside(v202));
+  CPPUNIT_ASSERT(!s2.isInside(v012));
+  CPPUNIT_ASSERT(!s2.isInside(v112));
+  CPPUNIT_ASSERT(!s2.isInside(v212));
+  CPPUNIT_ASSERT(!s2.isInside(v022));
+  CPPUNIT_ASSERT(!s2.isInside(v122));
+  CPPUNIT_ASSERT(!s2.isInside(v222));
+
+}
+
+void BaseShapesTest::operatorTest(){
+  {
+    Shape s1 = !Nowhere();
+    CPPUNIT_ASSERT(s1.isInside(v000));
+    CPPUNIT_ASSERT(s1.isInside(v100));
+    CPPUNIT_ASSERT(s1.isInside(v200));
+    CPPUNIT_ASSERT(s1.isInside(v010));
+    CPPUNIT_ASSERT(s1.isInside(v110));
+    CPPUNIT_ASSERT(s1.isInside(v210));
+    CPPUNIT_ASSERT(s1.isInside(v020));
+    CPPUNIT_ASSERT(s1.isInside(v120));
+    CPPUNIT_ASSERT(s1.isInside(v220));
+    CPPUNIT_ASSERT(s1.isInside(v001));
+    CPPUNIT_ASSERT(s1.isInside(v101));
+    CPPUNIT_ASSERT(s1.isInside(v201));
+    CPPUNIT_ASSERT(s1.isInside(v011));
+    CPPUNIT_ASSERT(s1.isInside(v111));
+    CPPUNIT_ASSERT(s1.isInside(v211));
+    CPPUNIT_ASSERT(s1.isInside(v021));
+    CPPUNIT_ASSERT(s1.isInside(v121));
+    CPPUNIT_ASSERT(s1.isInside(v221));
+    CPPUNIT_ASSERT(s1.isInside(v002));
+    CPPUNIT_ASSERT(s1.isInside(v102));
+    CPPUNIT_ASSERT(s1.isInside(v202));
+    CPPUNIT_ASSERT(s1.isInside(v012));
+    CPPUNIT_ASSERT(s1.isInside(v112));
+    CPPUNIT_ASSERT(s1.isInside(v212));
+    CPPUNIT_ASSERT(s1.isInside(v022));
+    CPPUNIT_ASSERT(s1.isInside(v122));
+    CPPUNIT_ASSERT(s1.isInside(v222));
+
+    Shape s2 = !Everywhere();
+    CPPUNIT_ASSERT(!s2.isInside(v000));
+    CPPUNIT_ASSERT(!s2.isInside(v100));
+    CPPUNIT_ASSERT(!s2.isInside(v200));
+    CPPUNIT_ASSERT(!s2.isInside(v010));
+    CPPUNIT_ASSERT(!s2.isInside(v110));
+    CPPUNIT_ASSERT(!s2.isInside(v210));
+    CPPUNIT_ASSERT(!s2.isInside(v020));
+    CPPUNIT_ASSERT(!s2.isInside(v120));
+    CPPUNIT_ASSERT(!s2.isInside(v220));
+    CPPUNIT_ASSERT(!s2.isInside(v001));
+    CPPUNIT_ASSERT(!s2.isInside(v101));
+    CPPUNIT_ASSERT(!s2.isInside(v201));
+    CPPUNIT_ASSERT(!s2.isInside(v011));
+    CPPUNIT_ASSERT(!s2.isInside(v111));
+    CPPUNIT_ASSERT(!s2.isInside(v211));
+    CPPUNIT_ASSERT(!s2.isInside(v021));
+    CPPUNIT_ASSERT(!s2.isInside(v121));
+    CPPUNIT_ASSERT(!s2.isInside(v221));
+    CPPUNIT_ASSERT(!s2.isInside(v002));
+    CPPUNIT_ASSERT(!s2.isInside(v102));
+    CPPUNIT_ASSERT(!s2.isInside(v202));
+    CPPUNIT_ASSERT(!s2.isInside(v012));
+    CPPUNIT_ASSERT(!s2.isInside(v112));
+    CPPUNIT_ASSERT(!s2.isInside(v212));
+    CPPUNIT_ASSERT(!s2.isInside(v022));
+    CPPUNIT_ASSERT(!s2.isInside(v122));
+    CPPUNIT_ASSERT(!s2.isInside(v222));
+  }
+
+  {
+    Shape s1 = Nowhere() || Everywhere();
+    CPPUNIT_ASSERT(s1.isInside(v000));
+    CPPUNIT_ASSERT(s1.isInside(v100));
+    CPPUNIT_ASSERT(s1.isInside(v200));
+    CPPUNIT_ASSERT(s1.isInside(v010));
+    CPPUNIT_ASSERT(s1.isInside(v110));
+    CPPUNIT_ASSERT(s1.isInside(v210));
+    CPPUNIT_ASSERT(s1.isInside(v020));
+    CPPUNIT_ASSERT(s1.isInside(v120));
+    CPPUNIT_ASSERT(s1.isInside(v220));
+    CPPUNIT_ASSERT(s1.isInside(v001));
+    CPPUNIT_ASSERT(s1.isInside(v101));
+    CPPUNIT_ASSERT(s1.isInside(v201));
+    CPPUNIT_ASSERT(s1.isInside(v011));
+    CPPUNIT_ASSERT(s1.isInside(v111));
+    CPPUNIT_ASSERT(s1.isInside(v211));
+    CPPUNIT_ASSERT(s1.isInside(v021));
+    CPPUNIT_ASSERT(s1.isInside(v121));
+    CPPUNIT_ASSERT(s1.isInside(v221));
+    CPPUNIT_ASSERT(s1.isInside(v002));
+    CPPUNIT_ASSERT(s1.isInside(v102));
+    CPPUNIT_ASSERT(s1.isInside(v202));
+    CPPUNIT_ASSERT(s1.isInside(v012));
+    CPPUNIT_ASSERT(s1.isInside(v112));
+    CPPUNIT_ASSERT(s1.isInside(v212));
+    CPPUNIT_ASSERT(s1.isInside(v022));
+    CPPUNIT_ASSERT(s1.isInside(v122));
+    CPPUNIT_ASSERT(s1.isInside(v222));
+
+    Shape s2 = Nowhere() && Everywhere();
+    CPPUNIT_ASSERT(!s2.isInside(v000));
+    CPPUNIT_ASSERT(!s2.isInside(v100));
+    CPPUNIT_ASSERT(!s2.isInside(v200));
+    CPPUNIT_ASSERT(!s2.isInside(v010));
+    CPPUNIT_ASSERT(!s2.isInside(v110));
+    CPPUNIT_ASSERT(!s2.isInside(v210));
+    CPPUNIT_ASSERT(!s2.isInside(v020));
+    CPPUNIT_ASSERT(!s2.isInside(v120));
+    CPPUNIT_ASSERT(!s2.isInside(v220));
+    CPPUNIT_ASSERT(!s2.isInside(v001));
+    CPPUNIT_ASSERT(!s2.isInside(v101));
+    CPPUNIT_ASSERT(!s2.isInside(v201));
+    CPPUNIT_ASSERT(!s2.isInside(v011));
+    CPPUNIT_ASSERT(!s2.isInside(v111));
+    CPPUNIT_ASSERT(!s2.isInside(v211));
+    CPPUNIT_ASSERT(!s2.isInside(v021));
+    CPPUNIT_ASSERT(!s2.isInside(v121));
+    CPPUNIT_ASSERT(!s2.isInside(v221));
+    CPPUNIT_ASSERT(!s2.isInside(v002));
+    CPPUNIT_ASSERT(!s2.isInside(v102));
+    CPPUNIT_ASSERT(!s2.isInside(v202));
+    CPPUNIT_ASSERT(!s2.isInside(v012));
+    CPPUNIT_ASSERT(!s2.isInside(v112));
+    CPPUNIT_ASSERT(!s2.isInside(v212));
+    CPPUNIT_ASSERT(!s2.isInside(v022));
+    CPPUNIT_ASSERT(!s2.isInside(v122));
+    CPPUNIT_ASSERT(!s2.isInside(v222));
+  }
+
+  {
+    Shape s1 = Everywhere() || Nowhere();
+    CPPUNIT_ASSERT(s1.isInside(v000));
+    CPPUNIT_ASSERT(s1.isInside(v100));
+    CPPUNIT_ASSERT(s1.isInside(v200));
+    CPPUNIT_ASSERT(s1.isInside(v010));
+    CPPUNIT_ASSERT(s1.isInside(v110));
+    CPPUNIT_ASSERT(s1.isInside(v210));
+    CPPUNIT_ASSERT(s1.isInside(v020));
+    CPPUNIT_ASSERT(s1.isInside(v120));
+    CPPUNIT_ASSERT(s1.isInside(v220));
+    CPPUNIT_ASSERT(s1.isInside(v001));
+    CPPUNIT_ASSERT(s1.isInside(v101));
+    CPPUNIT_ASSERT(s1.isInside(v201));
+    CPPUNIT_ASSERT(s1.isInside(v011));
+    CPPUNIT_ASSERT(s1.isInside(v111));
+    CPPUNIT_ASSERT(s1.isInside(v211));
+    CPPUNIT_ASSERT(s1.isInside(v021));
+    CPPUNIT_ASSERT(s1.isInside(v121));
+    CPPUNIT_ASSERT(s1.isInside(v221));
+    CPPUNIT_ASSERT(s1.isInside(v002));
+    CPPUNIT_ASSERT(s1.isInside(v102));
+    CPPUNIT_ASSERT(s1.isInside(v202));
+    CPPUNIT_ASSERT(s1.isInside(v012));
+    CPPUNIT_ASSERT(s1.isInside(v112));
+    CPPUNIT_ASSERT(s1.isInside(v212));
+    CPPUNIT_ASSERT(s1.isInside(v022));
+    CPPUNIT_ASSERT(s1.isInside(v122));
+    CPPUNIT_ASSERT(s1.isInside(v222));
+
+    Shape s2 = Everywhere() && Nowhere();
+    CPPUNIT_ASSERT(!s2.isInside(v000));
+    CPPUNIT_ASSERT(!s2.isInside(v100));
+    CPPUNIT_ASSERT(!s2.isInside(v200));
+    CPPUNIT_ASSERT(!s2.isInside(v010));
+    CPPUNIT_ASSERT(!s2.isInside(v110));
+    CPPUNIT_ASSERT(!s2.isInside(v210));
+    CPPUNIT_ASSERT(!s2.isInside(v020));
+    CPPUNIT_ASSERT(!s2.isInside(v120));
+    CPPUNIT_ASSERT(!s2.isInside(v220));
+    CPPUNIT_ASSERT(!s2.isInside(v001));
+    CPPUNIT_ASSERT(!s2.isInside(v101));
+    CPPUNIT_ASSERT(!s2.isInside(v201));
+    CPPUNIT_ASSERT(!s2.isInside(v011));
+    CPPUNIT_ASSERT(!s2.isInside(v111));
+    CPPUNIT_ASSERT(!s2.isInside(v211));
+    CPPUNIT_ASSERT(!s2.isInside(v021));
+    CPPUNIT_ASSERT(!s2.isInside(v121));
+    CPPUNIT_ASSERT(!s2.isInside(v221));
+    CPPUNIT_ASSERT(!s2.isInside(v002));
+    CPPUNIT_ASSERT(!s2.isInside(v102));
+    CPPUNIT_ASSERT(!s2.isInside(v202));
+    CPPUNIT_ASSERT(!s2.isInside(v012));
+    CPPUNIT_ASSERT(!s2.isInside(v112));
+    CPPUNIT_ASSERT(!s2.isInside(v212));
+    CPPUNIT_ASSERT(!s2.isInside(v022));
+    CPPUNIT_ASSERT(!s2.isInside(v122));
+    CPPUNIT_ASSERT(!s2.isInside(v222));
+  }
+
+  {
+    Shape s1 = Sphere() && Cuboid(); // Sphere in upper place
+
+    CPPUNIT_ASSERT(s1.isInside(v000));
+    CPPUNIT_ASSERT(s1.isInside(v100));
+    CPPUNIT_ASSERT(!s1.isInside(v200));
+    CPPUNIT_ASSERT(s1.isInside(v010));
+    CPPUNIT_ASSERT(!s1.isInside(v110));
+    CPPUNIT_ASSERT(!s1.isInside(v210));
+    CPPUNIT_ASSERT(!s1.isInside(v020));
+    CPPUNIT_ASSERT(!s1.isInside(v120));
+    CPPUNIT_ASSERT(!s1.isInside(v220));
+    CPPUNIT_ASSERT(s1.isInside(v001));
+    CPPUNIT_ASSERT(!s1.isInside(v101));
+    CPPUNIT_ASSERT(!s1.isInside(v201));
+    CPPUNIT_ASSERT(!s1.isInside(v011));
+    CPPUNIT_ASSERT(!s1.isInside(v111));
+    CPPUNIT_ASSERT(!s1.isInside(v211));
+    CPPUNIT_ASSERT(!s1.isInside(v021));
+    CPPUNIT_ASSERT(!s1.isInside(v121));
+    CPPUNIT_ASSERT(!s1.isInside(v221));
+    CPPUNIT_ASSERT(!s1.isInside(v002));
+    CPPUNIT_ASSERT(!s1.isInside(v102));
+    CPPUNIT_ASSERT(!s1.isInside(v202));
+    CPPUNIT_ASSERT(!s1.isInside(v012));
+    CPPUNIT_ASSERT(!s1.isInside(v112));
+    CPPUNIT_ASSERT(!s1.isInside(v212));
+    CPPUNIT_ASSERT(!s1.isInside(v022));
+    CPPUNIT_ASSERT(!s1.isInside(v122));
+    CPPUNIT_ASSERT(!s1.isInside(v222));
+
+    CPPUNIT_ASSERT(s1.isOnSurface(v000));
+    CPPUNIT_ASSERT(s1.isOnSurface(v100));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v200));
+    CPPUNIT_ASSERT(s1.isOnSurface(v010));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v110));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v210));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v020));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v120));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v220));
+    CPPUNIT_ASSERT(s1.isOnSurface(v001));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v101));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v201));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v011));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v111));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v211));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v021));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v121));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v221));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v002));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v102));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v202));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v012));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v112));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v212));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v022));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v122));
+    CPPUNIT_ASSERT(!s1.isOnSurface(v222));
+
+
+    Shape s2 = Sphere() || Cuboid(); // Should be same as Cuboid
+
+    CPPUNIT_ASSERT(s2.isInside(v000));
+    CPPUNIT_ASSERT(s2.isInside(v100));
+    CPPUNIT_ASSERT(s2.isInside(v200));
+    CPPUNIT_ASSERT(s2.isInside(v010));
+    CPPUNIT_ASSERT(s2.isInside(v110));
+    CPPUNIT_ASSERT(!s2.isInside(v210));
+    CPPUNIT_ASSERT(s2.isInside(v020));
+    CPPUNIT_ASSERT(!s2.isInside(v120));
+    CPPUNIT_ASSERT(!s2.isInside(v220));
+    CPPUNIT_ASSERT(s2.isInside(v001));
+    CPPUNIT_ASSERT(s2.isInside(v101));
+    CPPUNIT_ASSERT(!s2.isInside(v201));
+    CPPUNIT_ASSERT(s2.isInside(v011));
+    CPPUNIT_ASSERT(s2.isInside(v111));
+    CPPUNIT_ASSERT(!s2.isInside(v211));
+    CPPUNIT_ASSERT(!s2.isInside(v021));
+    CPPUNIT_ASSERT(!s2.isInside(v121));
+    CPPUNIT_ASSERT(!s2.isInside(v221));
+    CPPUNIT_ASSERT(s2.isInside(v002));
+    CPPUNIT_ASSERT(!s2.isInside(v102));
+    CPPUNIT_ASSERT(!s2.isInside(v202));
+    CPPUNIT_ASSERT(!s2.isInside(v012));
+    CPPUNIT_ASSERT(!s2.isInside(v112));
+    CPPUNIT_ASSERT(!s2.isInside(v212));
+    CPPUNIT_ASSERT(!s2.isInside(v022));
+    CPPUNIT_ASSERT(!s2.isInside(v122));
+    CPPUNIT_ASSERT(!s2.isInside(v222));
+
+    CPPUNIT_ASSERT(!s2.isOnSurface(v000));
+    CPPUNIT_ASSERT(s2.isOnSurface(v100));
+    CPPUNIT_ASSERT(s2.isOnSurface(v200));
+    CPPUNIT_ASSERT(s2.isOnSurface(v010));
+    CPPUNIT_ASSERT(s2.isOnSurface(v110));
+    CPPUNIT_ASSERT(!s2.isOnSurface(v210));
+    CPPUNIT_ASSERT(s2.isOnSurface(v020));
+    CPPUNIT_ASSERT(!s2.isOnSurface(v120));
+    CPPUNIT_ASSERT(!s2.isOnSurface(v220));
+    CPPUNIT_ASSERT(s2.isOnSurface(v001));
+    CPPUNIT_ASSERT(s2.isOnSurface(v101));
+    CPPUNIT_ASSERT(!s2.isOnSurface(v201));
+    CPPUNIT_ASSERT(s2.isOnSurface(v011));
+    CPPUNIT_ASSERT(s2.isOnSurface(v111));
+    CPPUNIT_ASSERT(!s2.isOnSurface(v211));
+    CPPUNIT_ASSERT(!s2.isOnSurface(v021));
+    CPPUNIT_ASSERT(!s2.isOnSurface(v121));
+    CPPUNIT_ASSERT(!s2.isOnSurface(v221));
+    CPPUNIT_ASSERT(s2.isOnSurface(v002));
+    CPPUNIT_ASSERT(!s2.isOnSurface(v102));
+    CPPUNIT_ASSERT(!s2.isOnSurface(v202));
+    CPPUNIT_ASSERT(!s2.isOnSurface(v012));
+    CPPUNIT_ASSERT(!s2.isOnSurface(v112));
+    CPPUNIT_ASSERT(!s2.isOnSurface(v212));
+    CPPUNIT_ASSERT(!s2.isOnSurface(v022));
+    CPPUNIT_ASSERT(!s2.isOnSurface(v122));
+    CPPUNIT_ASSERT(!s2.isOnSurface(v222));
+  }
+
+}
+
+void BaseShapesTest::PointsOnSurfaceTest(){
+  Shape s = Sphere();
+  const size_t N = 200;
+  std::vector<Vector> PointsOnSurface = s.getHomogeneousPointsOnSurface(N);
+  for (std::vector<Vector>::const_iterator iter = PointsOnSurface.begin(); iter != PointsOnSurface.end(); ++iter) {
+    CPPUNIT_ASSERT(fabs(1. - (*iter).NormSquared()) < MYEPSILON);
+  }
+  CPPUNIT_ASSERT_EQUAL((size_t)194, PointsOnSurface.size());
+}
Index: src/Shapes/unittests/BaseShapesUnitTest.hpp
===================================================================
--- src/Shapes/unittests/BaseShapesUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Shapes/unittests/BaseShapesUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,76 @@
+/*
+ * BaseShapesUnitTest.hpp
+ *
+ *  Created on: Jun 18, 2010
+ *      Author: crueger
+ */
+
+#ifndef BASESHAPESUNITTEST_HPP_
+#define BASESHAPESUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class Shape;
+class Vector;
+
+#include "LinearAlgebra/Vector.hpp"
+
+class BaseShapesTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( BaseShapesTest) ;
+  CPPUNIT_TEST ( baseShapesTest );
+  CPPUNIT_TEST ( surfaceTest );
+  CPPUNIT_TEST ( assignmentTest );
+  CPPUNIT_TEST ( operatorTest );
+  CPPUNIT_TEST ( PointsOnSurfaceTest );
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+  void setUp();
+  void tearDown();
+
+  void baseShapesTest();
+  void surfaceTest();
+  void assignmentTest();
+  void operatorTest();
+  void PointsOnSurfaceTest();
+
+  // a lot of vectors.
+  // these define all the edges of a box around -1 +1 on each axis
+  // 0 is 0, 1 is 1 and 2 is -1
+  Vector v000;
+  Vector v100;
+  Vector v200;
+  Vector v010;
+  Vector v110;
+  Vector v210;
+  Vector v020;
+  Vector v120;
+  Vector v220;
+  Vector v001;
+  Vector v101;
+  Vector v201;
+  Vector v011;
+  Vector v111;
+  Vector v211;
+  Vector v021;
+  Vector v121;
+  Vector v221;
+  Vector v002;
+  Vector v102;
+  Vector v202;
+  Vector v012;
+  Vector v112;
+  Vector v212;
+  Vector v022;
+  Vector v122;
+  Vector v222;
+};
+
+#endif /* BASESHAPESUNITTEST_HPP_ */
Index: src/Shapes/unittests/Makefile.am
===================================================================
--- src/Shapes/unittests/Makefile.am	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Shapes/unittests/Makefile.am	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -4,11 +4,17 @@
 
 SHAPETESTSSOURCES = \
-	../Shapes/unittests/ShapeUnitTest.cpp
+	../Shapes/unittests/BaseShapesUnitTest.cpp \
+	../Shapes/unittests/ShapeOpsUnitTest.cpp \
+	../Shapes/unittests/Shape_HomogeneousPointsUnitTest.cpp
 
 SHAPETESTSHEADERS= \
-	../Shapes/unittests/ShapeUnitTest.hpp
+	../Shapes/unittests/BaseShapesUnitTest.hpp \
+	../Shapes/unittests/ShapeOpsUnitTest.hpp \
+	../Shapes/unittests/Shape_HomogeneousPointsUnitTest.cpp
 
 SHAPETESTS = \
-  ShapeUnittest
+  BaseShapesUnitTest \
+  ShapeOpsUnitTest \
+  Shape_HomogeneousPointsUnitTest
   
 TESTS += $(SHAPETESTS)
@@ -22,11 +28,31 @@
 #	$(BOOST_LIB)
 
-ShapeUnittest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
-	../Shapes/unittests/ShapeUnitTest.cpp \
-	../Shapes/unittests/ShapeUnitTest.hpp
-nodist_ShapeUnittest_SOURCES = \
+BaseShapesUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+	../Shapes/unittests/BaseShapesUnitTest.cpp \
+	../Shapes/unittests/BaseShapesUnitTest.hpp \
+	../Shapes/unittests/stubs/ApproximateShapeAreaStub.cpp \
+	../Shapes/unittests/stubs/ApproximateShapeVolumeStub.cpp
+nodist_BaseShapesUnitTest_SOURCES = \
 	../Helpers/defs.hpp \
 	../Helpers/defs.cpp
-ShapeUnittest_LDADD = $(SHAPELIBS)
+BaseShapesUnitTest_LDADD = $(SHAPELIBS)
+
+ShapeOpsUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+	../Shapes/unittests/ShapeOpsUnitTest.cpp \
+	../Shapes/unittests/ShapeOpsUnitTest.hpp \
+	../Shapes/unittests/stubs/ApproximateShapeAreaStub.cpp \
+	../Shapes/unittests/stubs/ApproximateShapeVolumeStub.cpp
+nodist_ShapeOpsUnitTest_SOURCES = \
+	../Helpers/defs.hpp \
+	../Helpers/defs.cpp
+ShapeOpsUnitTest_LDADD = $(SHAPELIBS)
+
+Shape_HomogeneousPointsUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+	../Shapes/unittests/Shape_HomogeneousPointsUnitTest.cpp \
+	../Shapes/unittests/Shape_HomogeneousPointsUnitTest.hpp
+nodist_Shape_HomogeneousPointsUnitTest_SOURCES = \
+	../Helpers/defs.hpp \
+	../Helpers/defs.cpp
+Shape_HomogeneousPointsUnitTest_LDADD = $(SHAPELIBS)
 
 
Index: src/Shapes/unittests/ShapeOpsUnitTest.cpp
===================================================================
--- src/Shapes/unittests/ShapeOpsUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Shapes/unittests/ShapeOpsUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,265 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2010-2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * ShapeOpsUnitTest.cpp
+ *
+ *  Created on: Jun 18, 2010
+ *      Author: crueger
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include <cmath>
+#include <limits>
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+#include "CodePatterns/Assert.hpp"
+
+#include "Helpers/defs.hpp"
+#include "LinearAlgebra/RealSpaceMatrix.hpp"
+#include "LinearAlgebra/Vector.hpp"
+#include "Shapes/BaseShapes.hpp"
+#include "Shapes/Shape.hpp"
+#include "Shapes/ShapeOps.hpp"
+
+#include "ShapeOpsUnitTest.hpp"
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( ShapeOpsTest );
+
+void ShapeOpsTest::setUp()
+{
+  // failing asserts should be thrown
+  ASSERT_DO(Assert::Throw);
+}
+
+void ShapeOpsTest::tearDown()
+{}
+
+void ShapeOpsTest::resizeTest()
+{
+  Shape s = resize(Sphere(), 2.);
+
+  CPPUNIT_ASSERT( s.isInside( Vector(1.5,0.,0.) ) );
+  CPPUNIT_ASSERT( s.isInside( Vector(0.,1.5,0.) ) );
+  CPPUNIT_ASSERT( s.isInside( Vector(0.,0.,1.5) ) );
+  CPPUNIT_ASSERT( s.isOnSurface( Vector(2.,0.,0.) ) );
+  CPPUNIT_ASSERT( s.isOnSurface( Vector(0.,2.,0.) ) );
+  CPPUNIT_ASSERT( s.isOnSurface( Vector(0.,0.,2.) ) );
+}
+
+void ShapeOpsTest::translateTest()
+{
+  Shape s = translate(Sphere(), Vector(1.,0.,0.));
+
+  CPPUNIT_ASSERT( s.isInside( Vector(1.5,0.,0.) ) );
+  CPPUNIT_ASSERT( s.isInside( Vector(1.,.5,0.) ) );
+  CPPUNIT_ASSERT( s.isInside( Vector(1.,0.,.5) ) );
+  CPPUNIT_ASSERT( s.isOnSurface( Vector(2.,0.,0.) ) );
+  CPPUNIT_ASSERT( s.isOnSurface( Vector(1.,1.,0.) ) );
+  CPPUNIT_ASSERT( s.isOnSurface( Vector(1.,0.,1.) ) );
+  CPPUNIT_ASSERT( !s.isInside( Vector(-.5,0.,0.) ) );
+  CPPUNIT_ASSERT( !s.isInside( Vector(0.,-.5,0.) ) );
+  CPPUNIT_ASSERT( !s.isInside( Vector(0.,0.,-.5) ) );
+}
+
+void ShapeOpsTest::stretchTest()
+{
+#ifndef NDEBUG
+  CPPUNIT_ASSERT_THROW( Shape test = stretch(Sphere(), Vector(-2.,0.,0.)), Assert::AssertionFailure );
+#endif
+  Shape s = stretch(Sphere(), Vector(2.,1.,1.));
+
+  CPPUNIT_ASSERT( s.isInside( Vector(1.5,0.,0.) ) );
+  CPPUNIT_ASSERT( !s.isInside( Vector(0.,1.5,0.) ) );
+  CPPUNIT_ASSERT( !s.isInside( Vector(0.,0.,1.5) ) );
+  CPPUNIT_ASSERT( s.isOnSurface( Vector(2.,0.,0.) ) );
+  CPPUNIT_ASSERT( s.isOnSurface( Vector(0.,1.,0.) ) );
+  CPPUNIT_ASSERT( s.isOnSurface( Vector(0.,1.,0.) ) );
+}
+
+void ShapeOpsTest::transformTest()
+{
+  RealSpaceMatrix M;
+  M.setRotation(45., 0., 0.);
+  Shape s = transform(Sphere(), M);
+
+  CPPUNIT_ASSERT( s.isInside( Vector(.5,0.,0.) ) );
+  CPPUNIT_ASSERT( s.isInside( Vector(0.,.5,0.) ) );
+  CPPUNIT_ASSERT( s.isInside( Vector(0.,0.,.5) ) );
+  CPPUNIT_ASSERT( s.isOnSurface( Vector(1.,0.,0.) ) );
+  CPPUNIT_ASSERT( s.isOnSurface( Vector(0.,1.,0.) ) );
+  CPPUNIT_ASSERT( s.isOnSurface( Vector(0.,0.,1.) ) );
+}
+
+void ShapeOpsTest::getCenterTest()
+{
+  Shape s = Sphere();
+  Shape t = Sphere(Vector(2.,0.,0.),1.);
+  Vector offset(1.,0.,0);
+  RealSpaceMatrix M;
+  M.setRotation(45.,0.,0.);
+
+  // Sphere
+  {
+    // sphere at origin
+    CPPUNIT_ASSERT_EQUAL( Vector(0.,0.,0), s.getCenter() );
+
+    // translated sphere
+    CPPUNIT_ASSERT_EQUAL( offset, translate(s, offset).getCenter() );
+
+    // resized sphere
+    CPPUNIT_ASSERT_EQUAL( Vector(0.,0.,0), resize(s, 2.).getCenter() );
+
+    // stretched sphere
+    CPPUNIT_ASSERT_EQUAL( Vector(0.,0.,0), stretch(s, Vector(2.,1.,1.)).getCenter() );
+
+    // transformed sphere
+    CPPUNIT_ASSERT_EQUAL( Vector(0.,0.,0), transform(s, M).getCenter() );
+
+    // resized and translated sphere
+    CPPUNIT_ASSERT_EQUAL( offset, translate(resize(s, 2.), offset).getCenter() );
+  }
+
+  // AND spheres
+  {
+    // sphere at origin
+    CPPUNIT_ASSERT_EQUAL( Vector(1.,0.,0), (s && t).getCenter() );
+
+    // translated sphere
+    CPPUNIT_ASSERT_EQUAL( Vector(2.,0.,0), translate((s && t), offset).getCenter() );
+
+    // resized sphere
+    CPPUNIT_ASSERT_EQUAL( Vector(1.,0.,0), resize((s && t), 2.).getCenter() );
+
+    // stretched sphere
+    CPPUNIT_ASSERT_EQUAL( Vector(1.5,0.,0), (stretch(s, Vector(2.,1.,1.)) && t).getCenter() );
+
+    // transformed sphere
+    CPPUNIT_ASSERT_EQUAL( Vector(1.,0.,0), (transform(s, M) && t).getCenter() );
+
+    // resized and translated sphere
+    CPPUNIT_ASSERT_EQUAL( Vector(2.,0.,0), translate(resize((s && t), 2.), offset).getCenter() );
+  }
+
+  // OR spheres
+  {
+    // sphere at origin
+    CPPUNIT_ASSERT_EQUAL( Vector(1.,0.,0), (s || t).getCenter() );
+
+    // translated sphere
+    CPPUNIT_ASSERT_EQUAL( Vector(2.,0.,0), translate((s || t), offset).getCenter() );
+
+    // resized sphere
+    CPPUNIT_ASSERT_EQUAL( Vector(1.,0.,0), resize((s || t), 2.).getCenter() );
+
+    // stretched sphere
+    CPPUNIT_ASSERT_EQUAL( Vector(0.5,0.,0), (stretch(s, Vector(2.,1.,1.)) || t).getCenter() );
+
+    // transformed sphere
+    CPPUNIT_ASSERT_EQUAL( Vector(1.,0.,0), (transform(s, M) || t).getCenter() );
+
+    // resized and translated sphere
+    CPPUNIT_ASSERT_EQUAL( Vector(2.,0.,0), translate(resize((s || t), 2.), offset).getCenter() );
+  }
+
+  // NOT spheres
+  {
+    // sphere at origin
+    CPPUNIT_ASSERT_EQUAL( Vector(0.,0.,0), (!s).getCenter() );
+  }
+}
+
+void ShapeOpsTest::getRadiusTest()
+{
+  Shape s = Sphere();
+  Shape t = Sphere(Vector(2.,0.,0.),1.);
+  Vector offset(1.,0.,0);
+  RealSpaceMatrix M;
+  M.setRotation(45.,0.,0.);
+
+  // Sphere
+  {
+    // sphere at origin
+    CPPUNIT_ASSERT_EQUAL( 1., s.getRadius() );
+
+    // translated sphere
+    CPPUNIT_ASSERT_EQUAL( 1., translate(s, offset).getRadius() );
+
+    // resized sphere
+    CPPUNIT_ASSERT_EQUAL( 2., resize(s, 2.).getRadius() );
+
+    // stretched sphere
+    CPPUNIT_ASSERT_EQUAL( 2., stretch(s, Vector(2.,1.,1.)).getRadius() );
+
+    // transformed sphere
+    CPPUNIT_ASSERT_EQUAL( 1., transform(s, M).getRadius() );
+
+    // resized and translated sphere
+    CPPUNIT_ASSERT_EQUAL( 2., translate(resize(s, 2.), offset).getRadius() );
+  }
+
+  // AND spheres
+  {
+    // sphere at origin
+    CPPUNIT_ASSERT_EQUAL( 1., (s && t).getRadius() );
+
+    // translated sphere
+    CPPUNIT_ASSERT_EQUAL( 1., translate((s && t), offset).getRadius() );
+
+    // resized sphere
+    CPPUNIT_ASSERT_EQUAL( 2., resize((s && t), 2.).getRadius() );
+
+    // stretched sphere
+    CPPUNIT_ASSERT_EQUAL( 1., (stretch(s, Vector(2.,1.,1.)) && t).getRadius() );
+
+    // transformed sphere
+    CPPUNIT_ASSERT_EQUAL( 1., (transform(s, M) && t).getRadius() );
+
+    // resized and translated sphere
+    CPPUNIT_ASSERT_EQUAL( 2., translate(resize((s && t), 2.), offset).getRadius() );
+  }
+
+  // OR spheres
+  {
+    // sphere at origin
+    CPPUNIT_ASSERT_EQUAL( 2., (s || t).getRadius() );
+
+    // translated sphere
+    CPPUNIT_ASSERT_EQUAL( 2., translate((s || t), offset).getRadius() );
+
+    // resized sphere
+    CPPUNIT_ASSERT_EQUAL( 4., resize((s || t), 2.).getRadius() );
+
+    // stretched sphere
+    CPPUNIT_ASSERT_EQUAL( 2.5, (stretch(s, Vector(2.,1.,1.)) || t).getRadius() );
+
+    // transformed sphere
+    CPPUNIT_ASSERT_EQUAL( 2., (transform(s, M) || t).getRadius() );
+
+    // resized and translated sphere
+    CPPUNIT_ASSERT_EQUAL( 4., translate(resize((s || t), 2.), offset).getRadius() );
+  }
+
+  // NOT spheres
+  {
+    // sphere at origin
+    CPPUNIT_ASSERT_EQUAL( std::numeric_limits<double>::infinity(), (!s).getRadius() );
+  }
+}
+
Index: src/Shapes/unittests/ShapeOpsUnitTest.hpp
===================================================================
--- src/Shapes/unittests/ShapeOpsUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Shapes/unittests/ShapeOpsUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,42 @@
+/*
+ * ShapeOpsUnitTest.hpp
+ *
+ *  Created on: Jun 18, 2010
+ *      Author: crueger
+ */
+
+#ifndef SHAPEOPSUNITTEST_HPP_
+#define SHAPEOPSUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class ShapeOpsTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( ShapeOpsTest) ;
+  CPPUNIT_TEST ( resizeTest );
+  CPPUNIT_TEST ( translateTest );
+  CPPUNIT_TEST ( stretchTest );
+  CPPUNIT_TEST ( transformTest );
+  CPPUNIT_TEST ( getCenterTest );
+  CPPUNIT_TEST ( getRadiusTest );
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+  void setUp();
+  void tearDown();
+
+  void resizeTest();
+  void translateTest();
+  void stretchTest();
+  void transformTest();
+  void getCenterTest();
+  void getRadiusTest();
+};
+
+#endif /* SHAPEOPSUNITTEST_HPP_ */
Index: src/Shapes/unittests/ShapeUnitTest.cpp
===================================================================
--- src/Shapes/unittests/ShapeUnitTest.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ 	(revision )
@@ -1,655 +1,0 @@
-/*
- * Project: MoleCuilder
- * Description: creates and alters molecular systems
- * Copyright (C)  2010-2012 University of Bonn. All rights reserved.
- * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
- */
-
-/*
- * ShapeUnittest.cpp
- *
- *  Created on: Jun 18, 2010
- *      Author: crueger
- */
-
-// include config.h
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <cppunit/CompilerOutputter.h>
-#include <cppunit/extensions/TestFactoryRegistry.h>
-#include <cppunit/ui/text/TestRunner.h>
-
-#include <cmath>
-
-#ifdef HAVE_TESTRUNNER
-#include "UnitTestMain.hpp"
-#endif /*HAVE_TESTRUNNER*/
-
-#include "Helpers/defs.hpp"
-#include "LinearAlgebra/Vector.hpp"
-#include "Shapes/BaseShapes.hpp"
-#include "Shapes/Shape.hpp"
-
-#include "ShapeUnitTest.hpp"
-
-// Registers the fixture into the 'registry'
-CPPUNIT_TEST_SUITE_REGISTRATION( ShapeUnittest );
-
-void ShapeUnittest::setUp()
-{
-  v000 =  0*unitVec[0]+0*unitVec[1]+0*unitVec[2];
-  v100 =  1*unitVec[0]+0*unitVec[1]+0*unitVec[2];
-  v200 = -1*unitVec[0]+0*unitVec[1]+0*unitVec[2];
-  v010 =  0*unitVec[0]+1*unitVec[1]+0*unitVec[2];
-  v110 =  1*unitVec[0]+1*unitVec[1]+0*unitVec[2];
-  v210 = -1*unitVec[0]+1*unitVec[1]+0*unitVec[2];
-  v020 =  0*unitVec[0]-1*unitVec[1]+0*unitVec[2];
-  v120 =  1*unitVec[0]-1*unitVec[1]+0*unitVec[2];
-  v220 = -1*unitVec[0]-1*unitVec[1]+0*unitVec[2];
-  v001 =  0*unitVec[0]+0*unitVec[1]+1*unitVec[2];
-  v101 =  1*unitVec[0]+0*unitVec[1]+1*unitVec[2];
-  v201 = -1*unitVec[0]+0*unitVec[1]+1*unitVec[2];
-  v011 =  0*unitVec[0]+1*unitVec[1]+1*unitVec[2];
-  v111 =  1*unitVec[0]+1*unitVec[1]+1*unitVec[2];
-  v211 = -1*unitVec[0]+1*unitVec[1]+1*unitVec[2];
-  v021 =  0*unitVec[0]-1*unitVec[1]+1*unitVec[2];
-  v121 =  1*unitVec[0]-1*unitVec[1]+1*unitVec[2];
-  v221 = -1*unitVec[0]-1*unitVec[1]+1*unitVec[2];
-  v002 =  0*unitVec[0]+0*unitVec[1]-1*unitVec[2];
-  v102 =  1*unitVec[0]+0*unitVec[1]-1*unitVec[2];
-  v202 = -1*unitVec[0]+0*unitVec[1]-1*unitVec[2];
-  v012 =  0*unitVec[0]+1*unitVec[1]-1*unitVec[2];
-  v112 =  1*unitVec[0]+1*unitVec[1]-1*unitVec[2];
-  v212 = -1*unitVec[0]+1*unitVec[1]-1*unitVec[2];
-  v022 =  0*unitVec[0]-1*unitVec[1]-1*unitVec[2];
-  v122 =  1*unitVec[0]-1*unitVec[1]-1*unitVec[2];
-  v222 = -1*unitVec[0]-1*unitVec[1]-1*unitVec[2];
-}
-
-void ShapeUnittest::tearDown()
-{}
-
-
-void ShapeUnittest::baseShapesTest(){
-  CPPUNIT_ASSERT(!Nowhere().isInside(v000));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v100));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v200));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v010));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v110));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v210));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v020));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v120));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v220));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v001));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v101));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v201));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v011));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v111));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v211));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v021));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v121));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v221));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v002));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v102));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v202));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v012));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v112));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v212));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v022));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v122));
-  CPPUNIT_ASSERT(!Nowhere().isInside(v222));
-
-  CPPUNIT_ASSERT(Everywhere().isInside(v000));
-  CPPUNIT_ASSERT(Everywhere().isInside(v100));
-  CPPUNIT_ASSERT(Everywhere().isInside(v200));
-  CPPUNIT_ASSERT(Everywhere().isInside(v010));
-  CPPUNIT_ASSERT(Everywhere().isInside(v110));
-  CPPUNIT_ASSERT(Everywhere().isInside(v210));
-  CPPUNIT_ASSERT(Everywhere().isInside(v020));
-  CPPUNIT_ASSERT(Everywhere().isInside(v120));
-  CPPUNIT_ASSERT(Everywhere().isInside(v220));
-  CPPUNIT_ASSERT(Everywhere().isInside(v001));
-  CPPUNIT_ASSERT(Everywhere().isInside(v101));
-  CPPUNIT_ASSERT(Everywhere().isInside(v201));
-  CPPUNIT_ASSERT(Everywhere().isInside(v011));
-  CPPUNIT_ASSERT(Everywhere().isInside(v111));
-  CPPUNIT_ASSERT(Everywhere().isInside(v211));
-  CPPUNIT_ASSERT(Everywhere().isInside(v021));
-  CPPUNIT_ASSERT(Everywhere().isInside(v121));
-  CPPUNIT_ASSERT(Everywhere().isInside(v221));
-  CPPUNIT_ASSERT(Everywhere().isInside(v002));
-  CPPUNIT_ASSERT(Everywhere().isInside(v102));
-  CPPUNIT_ASSERT(Everywhere().isInside(v202));
-  CPPUNIT_ASSERT(Everywhere().isInside(v012));
-  CPPUNIT_ASSERT(Everywhere().isInside(v112));
-  CPPUNIT_ASSERT(Everywhere().isInside(v212));
-  CPPUNIT_ASSERT(Everywhere().isInside(v022));
-  CPPUNIT_ASSERT(Everywhere().isInside(v122));
-  CPPUNIT_ASSERT(Everywhere().isInside(v222));
-
-  Shape s1 = Sphere();
-
-  CPPUNIT_ASSERT(s1.isInside(v000));
-  CPPUNIT_ASSERT(s1.isInside(v100));
-  CPPUNIT_ASSERT(s1.isInside(v200));
-  CPPUNIT_ASSERT(s1.isInside(v010));
-  CPPUNIT_ASSERT(!s1.isInside(v110));
-  CPPUNIT_ASSERT(!s1.isInside(v210));
-  CPPUNIT_ASSERT(s1.isInside(v020));
-  CPPUNIT_ASSERT(!s1.isInside(v120));
-  CPPUNIT_ASSERT(!s1.isInside(v220));
-  CPPUNIT_ASSERT(s1.isInside(v001));
-  CPPUNIT_ASSERT(!s1.isInside(v101));
-  CPPUNIT_ASSERT(!s1.isInside(v201));
-  CPPUNIT_ASSERT(!s1.isInside(v011));
-  CPPUNIT_ASSERT(!s1.isInside(v111));
-  CPPUNIT_ASSERT(!s1.isInside(v211));
-  CPPUNIT_ASSERT(!s1.isInside(v021));
-  CPPUNIT_ASSERT(!s1.isInside(v121));
-  CPPUNIT_ASSERT(!s1.isInside(v221));
-  CPPUNIT_ASSERT(s1.isInside(v002));
-  CPPUNIT_ASSERT(!s1.isInside(v102));
-  CPPUNIT_ASSERT(!s1.isInside(v202));
-  CPPUNIT_ASSERT(!s1.isInside(v012));
-  CPPUNIT_ASSERT(!s1.isInside(v112));
-  CPPUNIT_ASSERT(!s1.isInside(v212));
-  CPPUNIT_ASSERT(!s1.isInside(v022));
-  CPPUNIT_ASSERT(!s1.isInside(v122));
-  CPPUNIT_ASSERT(!s1.isInside(v222));
-
-  Shape s2 = Cuboid();
-
-  CPPUNIT_ASSERT(s2.isInside(v000));
-  CPPUNIT_ASSERT(s2.isInside(v100));
-  CPPUNIT_ASSERT(!s2.isInside(v200));
-  CPPUNIT_ASSERT(s2.isInside(v010));
-  CPPUNIT_ASSERT(s2.isInside(v110));
-  CPPUNIT_ASSERT(!s2.isInside(v210));
-  CPPUNIT_ASSERT(!s2.isInside(v020));
-  CPPUNIT_ASSERT(!s2.isInside(v120));
-  CPPUNIT_ASSERT(!s2.isInside(v220));
-  CPPUNIT_ASSERT(s2.isInside(v001));
-  CPPUNIT_ASSERT(s2.isInside(v101));
-  CPPUNIT_ASSERT(!s2.isInside(v201));
-  CPPUNIT_ASSERT(s2.isInside(v011));
-  CPPUNIT_ASSERT(s2.isInside(v111));
-  CPPUNIT_ASSERT(!s2.isInside(v211));
-  CPPUNIT_ASSERT(!s2.isInside(v021));
-  CPPUNIT_ASSERT(!s2.isInside(v121));
-  CPPUNIT_ASSERT(!s2.isInside(v221));
-  CPPUNIT_ASSERT(!s2.isInside(v002));
-  CPPUNIT_ASSERT(!s2.isInside(v102));
-  CPPUNIT_ASSERT(!s2.isInside(v202));
-  CPPUNIT_ASSERT(!s2.isInside(v012));
-  CPPUNIT_ASSERT(!s2.isInside(v112));
-  CPPUNIT_ASSERT(!s2.isInside(v212));
-  CPPUNIT_ASSERT(!s2.isInside(v022));
-  CPPUNIT_ASSERT(!s2.isInside(v122));
-  CPPUNIT_ASSERT(!s2.isInside(v222));
-}
-
-void ShapeUnittest::surfaceTest(){
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v000));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v100));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v200));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v010));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v110));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v210));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v020));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v120));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v220));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v001));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v101));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v201));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v011));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v111));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v211));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v021));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v121));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v221));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v002));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v102));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v202));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v012));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v112));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v212));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v022));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v122));
-  CPPUNIT_ASSERT(!Nowhere().isOnSurface(v222));
-
-  CPPUNIT_ASSERT(Cuboid().isOnSurface(v000));
-  CPPUNIT_ASSERT(Cuboid().isOnSurface(v100));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v200));
-  CPPUNIT_ASSERT(Cuboid().isOnSurface(v010));
-  CPPUNIT_ASSERT(Cuboid().isOnSurface(v110));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v210));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v020));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v120));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v220));
-  CPPUNIT_ASSERT(Cuboid().isOnSurface(v001));
-  CPPUNIT_ASSERT(Cuboid().isOnSurface(v101));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v201));
-  CPPUNIT_ASSERT(Cuboid().isOnSurface(v011));
-  CPPUNIT_ASSERT(Cuboid().isOnSurface(v111));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v211));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v021));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v121));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v221));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v002));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v102));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v202));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v012));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v112));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v212));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v022));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v122));
-  CPPUNIT_ASSERT(!Cuboid().isOnSurface(v222));
-
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v000));
-  CPPUNIT_ASSERT(Sphere().isOnSurface(v100));
-  CPPUNIT_ASSERT(Sphere().isOnSurface(v200));
-  CPPUNIT_ASSERT(Sphere().isOnSurface(v010));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v110));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v210));
-  CPPUNIT_ASSERT(Sphere().isOnSurface(v020));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v120));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v220));
-  CPPUNIT_ASSERT(Sphere().isOnSurface(v001));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v101));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v201));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v011));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v111));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v211));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v021));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v121));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v221));
-  CPPUNIT_ASSERT(Sphere().isOnSurface(v002));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v102));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v202));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v012));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v112));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v212));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v022));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v122));
-  CPPUNIT_ASSERT(!Sphere().isOnSurface(v222));
-}
-
-void ShapeUnittest::assignmentTest(){
-  Shape s1 = Nowhere();
-  s1 = Everywhere();
-
-  CPPUNIT_ASSERT(s1.isInside(v000));
-  CPPUNIT_ASSERT(s1.isInside(v100));
-  CPPUNIT_ASSERT(s1.isInside(v200));
-  CPPUNIT_ASSERT(s1.isInside(v010));
-  CPPUNIT_ASSERT(s1.isInside(v110));
-  CPPUNIT_ASSERT(s1.isInside(v210));
-  CPPUNIT_ASSERT(s1.isInside(v020));
-  CPPUNIT_ASSERT(s1.isInside(v120));
-  CPPUNIT_ASSERT(s1.isInside(v220));
-  CPPUNIT_ASSERT(s1.isInside(v001));
-  CPPUNIT_ASSERT(s1.isInside(v101));
-  CPPUNIT_ASSERT(s1.isInside(v201));
-  CPPUNIT_ASSERT(s1.isInside(v011));
-  CPPUNIT_ASSERT(s1.isInside(v111));
-  CPPUNIT_ASSERT(s1.isInside(v211));
-  CPPUNIT_ASSERT(s1.isInside(v021));
-  CPPUNIT_ASSERT(s1.isInside(v121));
-  CPPUNIT_ASSERT(s1.isInside(v221));
-  CPPUNIT_ASSERT(s1.isInside(v002));
-  CPPUNIT_ASSERT(s1.isInside(v102));
-  CPPUNIT_ASSERT(s1.isInside(v202));
-  CPPUNIT_ASSERT(s1.isInside(v012));
-  CPPUNIT_ASSERT(s1.isInside(v112));
-  CPPUNIT_ASSERT(s1.isInside(v212));
-  CPPUNIT_ASSERT(s1.isInside(v022));
-  CPPUNIT_ASSERT(s1.isInside(v122));
-  CPPUNIT_ASSERT(s1.isInside(v222));
-
-  Shape s2 = Everywhere();
-  s2 = Nowhere();
-
-  CPPUNIT_ASSERT(!s2.isInside(v000));
-  CPPUNIT_ASSERT(!s2.isInside(v100));
-  CPPUNIT_ASSERT(!s2.isInside(v200));
-  CPPUNIT_ASSERT(!s2.isInside(v010));
-  CPPUNIT_ASSERT(!s2.isInside(v110));
-  CPPUNIT_ASSERT(!s2.isInside(v210));
-  CPPUNIT_ASSERT(!s2.isInside(v020));
-  CPPUNIT_ASSERT(!s2.isInside(v120));
-  CPPUNIT_ASSERT(!s2.isInside(v220));
-  CPPUNIT_ASSERT(!s2.isInside(v001));
-  CPPUNIT_ASSERT(!s2.isInside(v101));
-  CPPUNIT_ASSERT(!s2.isInside(v201));
-  CPPUNIT_ASSERT(!s2.isInside(v011));
-  CPPUNIT_ASSERT(!s2.isInside(v111));
-  CPPUNIT_ASSERT(!s2.isInside(v211));
-  CPPUNIT_ASSERT(!s2.isInside(v021));
-  CPPUNIT_ASSERT(!s2.isInside(v121));
-  CPPUNIT_ASSERT(!s2.isInside(v221));
-  CPPUNIT_ASSERT(!s2.isInside(v002));
-  CPPUNIT_ASSERT(!s2.isInside(v102));
-  CPPUNIT_ASSERT(!s2.isInside(v202));
-  CPPUNIT_ASSERT(!s2.isInside(v012));
-  CPPUNIT_ASSERT(!s2.isInside(v112));
-  CPPUNIT_ASSERT(!s2.isInside(v212));
-  CPPUNIT_ASSERT(!s2.isInside(v022));
-  CPPUNIT_ASSERT(!s2.isInside(v122));
-  CPPUNIT_ASSERT(!s2.isInside(v222));
-
-}
-
-void ShapeUnittest::operatorTest(){
-  {
-    Shape s1 = !Nowhere();
-    CPPUNIT_ASSERT(s1.isInside(v000));
-    CPPUNIT_ASSERT(s1.isInside(v100));
-    CPPUNIT_ASSERT(s1.isInside(v200));
-    CPPUNIT_ASSERT(s1.isInside(v010));
-    CPPUNIT_ASSERT(s1.isInside(v110));
-    CPPUNIT_ASSERT(s1.isInside(v210));
-    CPPUNIT_ASSERT(s1.isInside(v020));
-    CPPUNIT_ASSERT(s1.isInside(v120));
-    CPPUNIT_ASSERT(s1.isInside(v220));
-    CPPUNIT_ASSERT(s1.isInside(v001));
-    CPPUNIT_ASSERT(s1.isInside(v101));
-    CPPUNIT_ASSERT(s1.isInside(v201));
-    CPPUNIT_ASSERT(s1.isInside(v011));
-    CPPUNIT_ASSERT(s1.isInside(v111));
-    CPPUNIT_ASSERT(s1.isInside(v211));
-    CPPUNIT_ASSERT(s1.isInside(v021));
-    CPPUNIT_ASSERT(s1.isInside(v121));
-    CPPUNIT_ASSERT(s1.isInside(v221));
-    CPPUNIT_ASSERT(s1.isInside(v002));
-    CPPUNIT_ASSERT(s1.isInside(v102));
-    CPPUNIT_ASSERT(s1.isInside(v202));
-    CPPUNIT_ASSERT(s1.isInside(v012));
-    CPPUNIT_ASSERT(s1.isInside(v112));
-    CPPUNIT_ASSERT(s1.isInside(v212));
-    CPPUNIT_ASSERT(s1.isInside(v022));
-    CPPUNIT_ASSERT(s1.isInside(v122));
-    CPPUNIT_ASSERT(s1.isInside(v222));
-
-    Shape s2 = !Everywhere();
-    CPPUNIT_ASSERT(!s2.isInside(v000));
-    CPPUNIT_ASSERT(!s2.isInside(v100));
-    CPPUNIT_ASSERT(!s2.isInside(v200));
-    CPPUNIT_ASSERT(!s2.isInside(v010));
-    CPPUNIT_ASSERT(!s2.isInside(v110));
-    CPPUNIT_ASSERT(!s2.isInside(v210));
-    CPPUNIT_ASSERT(!s2.isInside(v020));
-    CPPUNIT_ASSERT(!s2.isInside(v120));
-    CPPUNIT_ASSERT(!s2.isInside(v220));
-    CPPUNIT_ASSERT(!s2.isInside(v001));
-    CPPUNIT_ASSERT(!s2.isInside(v101));
-    CPPUNIT_ASSERT(!s2.isInside(v201));
-    CPPUNIT_ASSERT(!s2.isInside(v011));
-    CPPUNIT_ASSERT(!s2.isInside(v111));
-    CPPUNIT_ASSERT(!s2.isInside(v211));
-    CPPUNIT_ASSERT(!s2.isInside(v021));
-    CPPUNIT_ASSERT(!s2.isInside(v121));
-    CPPUNIT_ASSERT(!s2.isInside(v221));
-    CPPUNIT_ASSERT(!s2.isInside(v002));
-    CPPUNIT_ASSERT(!s2.isInside(v102));
-    CPPUNIT_ASSERT(!s2.isInside(v202));
-    CPPUNIT_ASSERT(!s2.isInside(v012));
-    CPPUNIT_ASSERT(!s2.isInside(v112));
-    CPPUNIT_ASSERT(!s2.isInside(v212));
-    CPPUNIT_ASSERT(!s2.isInside(v022));
-    CPPUNIT_ASSERT(!s2.isInside(v122));
-    CPPUNIT_ASSERT(!s2.isInside(v222));
-  }
-
-  {
-    Shape s1 = Nowhere() || Everywhere();
-    CPPUNIT_ASSERT(s1.isInside(v000));
-    CPPUNIT_ASSERT(s1.isInside(v100));
-    CPPUNIT_ASSERT(s1.isInside(v200));
-    CPPUNIT_ASSERT(s1.isInside(v010));
-    CPPUNIT_ASSERT(s1.isInside(v110));
-    CPPUNIT_ASSERT(s1.isInside(v210));
-    CPPUNIT_ASSERT(s1.isInside(v020));
-    CPPUNIT_ASSERT(s1.isInside(v120));
-    CPPUNIT_ASSERT(s1.isInside(v220));
-    CPPUNIT_ASSERT(s1.isInside(v001));
-    CPPUNIT_ASSERT(s1.isInside(v101));
-    CPPUNIT_ASSERT(s1.isInside(v201));
-    CPPUNIT_ASSERT(s1.isInside(v011));
-    CPPUNIT_ASSERT(s1.isInside(v111));
-    CPPUNIT_ASSERT(s1.isInside(v211));
-    CPPUNIT_ASSERT(s1.isInside(v021));
-    CPPUNIT_ASSERT(s1.isInside(v121));
-    CPPUNIT_ASSERT(s1.isInside(v221));
-    CPPUNIT_ASSERT(s1.isInside(v002));
-    CPPUNIT_ASSERT(s1.isInside(v102));
-    CPPUNIT_ASSERT(s1.isInside(v202));
-    CPPUNIT_ASSERT(s1.isInside(v012));
-    CPPUNIT_ASSERT(s1.isInside(v112));
-    CPPUNIT_ASSERT(s1.isInside(v212));
-    CPPUNIT_ASSERT(s1.isInside(v022));
-    CPPUNIT_ASSERT(s1.isInside(v122));
-    CPPUNIT_ASSERT(s1.isInside(v222));
-
-    Shape s2 = Nowhere() && Everywhere();
-    CPPUNIT_ASSERT(!s2.isInside(v000));
-    CPPUNIT_ASSERT(!s2.isInside(v100));
-    CPPUNIT_ASSERT(!s2.isInside(v200));
-    CPPUNIT_ASSERT(!s2.isInside(v010));
-    CPPUNIT_ASSERT(!s2.isInside(v110));
-    CPPUNIT_ASSERT(!s2.isInside(v210));
-    CPPUNIT_ASSERT(!s2.isInside(v020));
-    CPPUNIT_ASSERT(!s2.isInside(v120));
-    CPPUNIT_ASSERT(!s2.isInside(v220));
-    CPPUNIT_ASSERT(!s2.isInside(v001));
-    CPPUNIT_ASSERT(!s2.isInside(v101));
-    CPPUNIT_ASSERT(!s2.isInside(v201));
-    CPPUNIT_ASSERT(!s2.isInside(v011));
-    CPPUNIT_ASSERT(!s2.isInside(v111));
-    CPPUNIT_ASSERT(!s2.isInside(v211));
-    CPPUNIT_ASSERT(!s2.isInside(v021));
-    CPPUNIT_ASSERT(!s2.isInside(v121));
-    CPPUNIT_ASSERT(!s2.isInside(v221));
-    CPPUNIT_ASSERT(!s2.isInside(v002));
-    CPPUNIT_ASSERT(!s2.isInside(v102));
-    CPPUNIT_ASSERT(!s2.isInside(v202));
-    CPPUNIT_ASSERT(!s2.isInside(v012));
-    CPPUNIT_ASSERT(!s2.isInside(v112));
-    CPPUNIT_ASSERT(!s2.isInside(v212));
-    CPPUNIT_ASSERT(!s2.isInside(v022));
-    CPPUNIT_ASSERT(!s2.isInside(v122));
-    CPPUNIT_ASSERT(!s2.isInside(v222));
-  }
-
-  {
-    Shape s1 = Everywhere() || Nowhere();
-    CPPUNIT_ASSERT(s1.isInside(v000));
-    CPPUNIT_ASSERT(s1.isInside(v100));
-    CPPUNIT_ASSERT(s1.isInside(v200));
-    CPPUNIT_ASSERT(s1.isInside(v010));
-    CPPUNIT_ASSERT(s1.isInside(v110));
-    CPPUNIT_ASSERT(s1.isInside(v210));
-    CPPUNIT_ASSERT(s1.isInside(v020));
-    CPPUNIT_ASSERT(s1.isInside(v120));
-    CPPUNIT_ASSERT(s1.isInside(v220));
-    CPPUNIT_ASSERT(s1.isInside(v001));
-    CPPUNIT_ASSERT(s1.isInside(v101));
-    CPPUNIT_ASSERT(s1.isInside(v201));
-    CPPUNIT_ASSERT(s1.isInside(v011));
-    CPPUNIT_ASSERT(s1.isInside(v111));
-    CPPUNIT_ASSERT(s1.isInside(v211));
-    CPPUNIT_ASSERT(s1.isInside(v021));
-    CPPUNIT_ASSERT(s1.isInside(v121));
-    CPPUNIT_ASSERT(s1.isInside(v221));
-    CPPUNIT_ASSERT(s1.isInside(v002));
-    CPPUNIT_ASSERT(s1.isInside(v102));
-    CPPUNIT_ASSERT(s1.isInside(v202));
-    CPPUNIT_ASSERT(s1.isInside(v012));
-    CPPUNIT_ASSERT(s1.isInside(v112));
-    CPPUNIT_ASSERT(s1.isInside(v212));
-    CPPUNIT_ASSERT(s1.isInside(v022));
-    CPPUNIT_ASSERT(s1.isInside(v122));
-    CPPUNIT_ASSERT(s1.isInside(v222));
-
-    Shape s2 = Everywhere() && Nowhere();
-    CPPUNIT_ASSERT(!s2.isInside(v000));
-    CPPUNIT_ASSERT(!s2.isInside(v100));
-    CPPUNIT_ASSERT(!s2.isInside(v200));
-    CPPUNIT_ASSERT(!s2.isInside(v010));
-    CPPUNIT_ASSERT(!s2.isInside(v110));
-    CPPUNIT_ASSERT(!s2.isInside(v210));
-    CPPUNIT_ASSERT(!s2.isInside(v020));
-    CPPUNIT_ASSERT(!s2.isInside(v120));
-    CPPUNIT_ASSERT(!s2.isInside(v220));
-    CPPUNIT_ASSERT(!s2.isInside(v001));
-    CPPUNIT_ASSERT(!s2.isInside(v101));
-    CPPUNIT_ASSERT(!s2.isInside(v201));
-    CPPUNIT_ASSERT(!s2.isInside(v011));
-    CPPUNIT_ASSERT(!s2.isInside(v111));
-    CPPUNIT_ASSERT(!s2.isInside(v211));
-    CPPUNIT_ASSERT(!s2.isInside(v021));
-    CPPUNIT_ASSERT(!s2.isInside(v121));
-    CPPUNIT_ASSERT(!s2.isInside(v221));
-    CPPUNIT_ASSERT(!s2.isInside(v002));
-    CPPUNIT_ASSERT(!s2.isInside(v102));
-    CPPUNIT_ASSERT(!s2.isInside(v202));
-    CPPUNIT_ASSERT(!s2.isInside(v012));
-    CPPUNIT_ASSERT(!s2.isInside(v112));
-    CPPUNIT_ASSERT(!s2.isInside(v212));
-    CPPUNIT_ASSERT(!s2.isInside(v022));
-    CPPUNIT_ASSERT(!s2.isInside(v122));
-    CPPUNIT_ASSERT(!s2.isInside(v222));
-  }
-
-  {
-    Shape s1 = Sphere() && Cuboid(); // Sphere in upper place
-
-    CPPUNIT_ASSERT(s1.isInside(v000));
-    CPPUNIT_ASSERT(s1.isInside(v100));
-    CPPUNIT_ASSERT(!s1.isInside(v200));
-    CPPUNIT_ASSERT(s1.isInside(v010));
-    CPPUNIT_ASSERT(!s1.isInside(v110));
-    CPPUNIT_ASSERT(!s1.isInside(v210));
-    CPPUNIT_ASSERT(!s1.isInside(v020));
-    CPPUNIT_ASSERT(!s1.isInside(v120));
-    CPPUNIT_ASSERT(!s1.isInside(v220));
-    CPPUNIT_ASSERT(s1.isInside(v001));
-    CPPUNIT_ASSERT(!s1.isInside(v101));
-    CPPUNIT_ASSERT(!s1.isInside(v201));
-    CPPUNIT_ASSERT(!s1.isInside(v011));
-    CPPUNIT_ASSERT(!s1.isInside(v111));
-    CPPUNIT_ASSERT(!s1.isInside(v211));
-    CPPUNIT_ASSERT(!s1.isInside(v021));
-    CPPUNIT_ASSERT(!s1.isInside(v121));
-    CPPUNIT_ASSERT(!s1.isInside(v221));
-    CPPUNIT_ASSERT(!s1.isInside(v002));
-    CPPUNIT_ASSERT(!s1.isInside(v102));
-    CPPUNIT_ASSERT(!s1.isInside(v202));
-    CPPUNIT_ASSERT(!s1.isInside(v012));
-    CPPUNIT_ASSERT(!s1.isInside(v112));
-    CPPUNIT_ASSERT(!s1.isInside(v212));
-    CPPUNIT_ASSERT(!s1.isInside(v022));
-    CPPUNIT_ASSERT(!s1.isInside(v122));
-    CPPUNIT_ASSERT(!s1.isInside(v222));
-
-    CPPUNIT_ASSERT(s1.isOnSurface(v000));
-    CPPUNIT_ASSERT(s1.isOnSurface(v100));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v200));
-    CPPUNIT_ASSERT(s1.isOnSurface(v010));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v110));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v210));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v020));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v120));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v220));
-    CPPUNIT_ASSERT(s1.isOnSurface(v001));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v101));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v201));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v011));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v111));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v211));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v021));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v121));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v221));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v002));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v102));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v202));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v012));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v112));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v212));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v022));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v122));
-    CPPUNIT_ASSERT(!s1.isOnSurface(v222));
-
-
-    Shape s2 = Sphere() || Cuboid(); // Should be same as Cuboid
-
-    CPPUNIT_ASSERT(s2.isInside(v000));
-    CPPUNIT_ASSERT(s2.isInside(v100));
-    CPPUNIT_ASSERT(s2.isInside(v200));
-    CPPUNIT_ASSERT(s2.isInside(v010));
-    CPPUNIT_ASSERT(s2.isInside(v110));
-    CPPUNIT_ASSERT(!s2.isInside(v210));
-    CPPUNIT_ASSERT(s2.isInside(v020));
-    CPPUNIT_ASSERT(!s2.isInside(v120));
-    CPPUNIT_ASSERT(!s2.isInside(v220));
-    CPPUNIT_ASSERT(s2.isInside(v001));
-    CPPUNIT_ASSERT(s2.isInside(v101));
-    CPPUNIT_ASSERT(!s2.isInside(v201));
-    CPPUNIT_ASSERT(s2.isInside(v011));
-    CPPUNIT_ASSERT(s2.isInside(v111));
-    CPPUNIT_ASSERT(!s2.isInside(v211));
-    CPPUNIT_ASSERT(!s2.isInside(v021));
-    CPPUNIT_ASSERT(!s2.isInside(v121));
-    CPPUNIT_ASSERT(!s2.isInside(v221));
-    CPPUNIT_ASSERT(s2.isInside(v002));
-    CPPUNIT_ASSERT(!s2.isInside(v102));
-    CPPUNIT_ASSERT(!s2.isInside(v202));
-    CPPUNIT_ASSERT(!s2.isInside(v012));
-    CPPUNIT_ASSERT(!s2.isInside(v112));
-    CPPUNIT_ASSERT(!s2.isInside(v212));
-    CPPUNIT_ASSERT(!s2.isInside(v022));
-    CPPUNIT_ASSERT(!s2.isInside(v122));
-    CPPUNIT_ASSERT(!s2.isInside(v222));
-
-    CPPUNIT_ASSERT(!s2.isOnSurface(v000));
-    CPPUNIT_ASSERT(s2.isOnSurface(v100));
-    CPPUNIT_ASSERT(s2.isOnSurface(v200));
-    CPPUNIT_ASSERT(s2.isOnSurface(v010));
-    CPPUNIT_ASSERT(s2.isOnSurface(v110));
-    CPPUNIT_ASSERT(!s2.isOnSurface(v210));
-    CPPUNIT_ASSERT(s2.isOnSurface(v020));
-    CPPUNIT_ASSERT(!s2.isOnSurface(v120));
-    CPPUNIT_ASSERT(!s2.isOnSurface(v220));
-    CPPUNIT_ASSERT(s2.isOnSurface(v001));
-    CPPUNIT_ASSERT(s2.isOnSurface(v101));
-    CPPUNIT_ASSERT(!s2.isOnSurface(v201));
-    CPPUNIT_ASSERT(s2.isOnSurface(v011));
-    CPPUNIT_ASSERT(s2.isOnSurface(v111));
-    CPPUNIT_ASSERT(!s2.isOnSurface(v211));
-    CPPUNIT_ASSERT(!s2.isOnSurface(v021));
-    CPPUNIT_ASSERT(!s2.isOnSurface(v121));
-    CPPUNIT_ASSERT(!s2.isOnSurface(v221));
-    CPPUNIT_ASSERT(s2.isOnSurface(v002));
-    CPPUNIT_ASSERT(!s2.isOnSurface(v102));
-    CPPUNIT_ASSERT(!s2.isOnSurface(v202));
-    CPPUNIT_ASSERT(!s2.isOnSurface(v012));
-    CPPUNIT_ASSERT(!s2.isOnSurface(v112));
-    CPPUNIT_ASSERT(!s2.isOnSurface(v212));
-    CPPUNIT_ASSERT(!s2.isOnSurface(v022));
-    CPPUNIT_ASSERT(!s2.isOnSurface(v122));
-    CPPUNIT_ASSERT(!s2.isOnSurface(v222));
-  }
-
-}
-
-void ShapeUnittest::PointsOnSurfaceTest(){
-  Shape s = Sphere();
-  const size_t N = 200;
-  std::vector<Vector> PointsOnSurface = s.getHomogeneousPointsOnSurface(N);
-  for (std::vector<Vector>::const_iterator iter = PointsOnSurface.begin(); iter != PointsOnSurface.end(); ++iter) {
-    CPPUNIT_ASSERT(fabs(1. - (*iter).NormSquared()) < MYEPSILON);
-  }
-  CPPUNIT_ASSERT_EQUAL((size_t)194, PointsOnSurface.size());
-}
-
Index: src/Shapes/unittests/ShapeUnitTest.hpp
===================================================================
--- src/Shapes/unittests/ShapeUnitTest.hpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ 	(revision )
@@ -1,76 +1,0 @@
-/*
- * ShapeUnittest.hpp
- *
- *  Created on: Jun 18, 2010
- *      Author: crueger
- */
-
-#ifndef SHAPEUNITTEST_HPP_
-#define SHAPEUNITTEST_HPP_
-
-// include config.h
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-
-#include <cppunit/extensions/HelperMacros.h>
-
-class Shape;
-class Vector;
-
-#include "LinearAlgebra/Vector.hpp"
-
-class ShapeUnittest : public CppUnit::TestFixture
-{
-  CPPUNIT_TEST_SUITE( ShapeUnittest) ;
-  CPPUNIT_TEST ( baseShapesTest );
-  CPPUNIT_TEST ( surfaceTest );
-  CPPUNIT_TEST ( assignmentTest );
-  CPPUNIT_TEST ( operatorTest );
-  CPPUNIT_TEST ( PointsOnSurfaceTest );
-  CPPUNIT_TEST_SUITE_END();
-
-public:
-  void setUp();
-  void tearDown();
-
-  void baseShapesTest();
-  void surfaceTest();
-  void assignmentTest();
-  void operatorTest();
-  void PointsOnSurfaceTest();
-
-  // a lot of vectors.
-  // these define all the edges of a box around -1 +1 on each axis
-  // 0 is 0, 1 is 1 and 2 is -1
-  Vector v000;
-  Vector v100;
-  Vector v200;
-  Vector v010;
-  Vector v110;
-  Vector v210;
-  Vector v020;
-  Vector v120;
-  Vector v220;
-  Vector v001;
-  Vector v101;
-  Vector v201;
-  Vector v011;
-  Vector v111;
-  Vector v211;
-  Vector v021;
-  Vector v121;
-  Vector v221;
-  Vector v002;
-  Vector v102;
-  Vector v202;
-  Vector v012;
-  Vector v112;
-  Vector v212;
-  Vector v022;
-  Vector v122;
-  Vector v222;
-};
-
-#endif /* SHAPEUNITTEST_HPP_ */
Index: src/Shapes/unittests/Shape_HomogeneousPointsUnitTest.cpp
===================================================================
--- src/Shapes/unittests/Shape_HomogeneousPointsUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Shapes/unittests/Shape_HomogeneousPointsUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,64 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2010-2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * Shape_HomogeneousPointsUnitTest.cpp
+ *
+ *  Created on: Jun 19, 2010
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include <cmath>
+#include <limits>
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+#include "CodePatterns/Assert.hpp"
+
+#include "Shapes/BaseShapes.hpp"
+#include "Shapes/Shape.hpp"
+
+#include "Shape_HomogeneousPointsUnitTest.hpp"
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( Shape_HomogeneousPointsTest );
+
+void Shape_HomogeneousPointsTest::setUp()
+{
+  // failing asserts should be thrown
+  ASSERT_DO(Assert::Throw);
+}
+
+void Shape_HomogeneousPointsTest::tearDown()
+{}
+
+/** Unit test for points on Shape's surface.
+ *
+ */
+void Shape_HomogeneousPointsTest::surfaceTest()
+{
+	CPPUNIT_ASSERT(true);
+}
+
+/** Unit test for points in Shape's volume.
+ *
+ */
+void Shape_HomogeneousPointsTest::volumeTest()
+{
+	CPPUNIT_ASSERT(true);
+}
Index: src/Shapes/unittests/Shape_HomogeneousPointsUnitTest.hpp
===================================================================
--- src/Shapes/unittests/Shape_HomogeneousPointsUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Shapes/unittests/Shape_HomogeneousPointsUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,34 @@
+/*
+ * Shape_HomogeneousPointsUnitTest.hpp
+ *
+ *  Created on: Jun 19, 2010
+ *      Author: heber
+ */
+
+#ifndef SHAPE_HOMOGENEOUSPOINTSUNITTEST_HPP_
+#define SHAPE_HOMOGENEOUSPOINTSUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class Shape_HomogeneousPointsTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( Shape_HomogeneousPointsTest) ;
+  CPPUNIT_TEST ( surfaceTest );
+  CPPUNIT_TEST ( volumeTest );
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+  void setUp();
+  void tearDown();
+
+  void surfaceTest();
+  void volumeTest();
+};
+
+#endif /* SHAPE_HOMOGENEOUSPOINTSUNITTEST_HPP_ */
Index: src/Shapes/unittests/stubs/ApproximateShapeAreaStub.cpp
===================================================================
--- src/Shapes/unittests/stubs/ApproximateShapeAreaStub.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Shapes/unittests/stubs/ApproximateShapeAreaStub.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -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.
+ */
+
+/*
+ * ApproximateShapeArea.cpp
+ *
+ *  Created on: Jan 30, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "Tesselation/ApproximateShapeArea.hpp"
+
+ApproximateShapeArea::ApproximateShapeArea(const Shape &_shape) :
+		shape(_shape)
+{}
+
+ApproximateShapeArea::~ApproximateShapeArea()
+{}
+
+double ApproximateShapeArea::operator()() const
+{
+	return 0.;
+}
Index: src/Shapes/unittests/stubs/ApproximateShapeVolumeStub.cpp
===================================================================
--- src/Shapes/unittests/stubs/ApproximateShapeVolumeStub.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Shapes/unittests/stubs/ApproximateShapeVolumeStub.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -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.
+ */
+
+/*
+ * ApproximateShapeVolume.cpp
+ *
+ *  Created on: Jan 30, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "Tesselation/ApproximateShapeVolume.hpp"
+
+ApproximateShapeVolume::ApproximateShapeVolume(const Shape &_shape) :
+		shape(_shape)
+{}
+
+ApproximateShapeVolume::~ApproximateShapeVolume()
+{}
+
+double ApproximateShapeVolume::operator()() const
+{
+	return 0.;
+}
Index: src/Tesselation/ApproximateShapeArea.cpp
===================================================================
--- src/Tesselation/ApproximateShapeArea.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Tesselation/ApproximateShapeArea.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+/*
+ * ApproximateShapeArea.cpp
+ *
+ *  Created on: Jan 30, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include <cmath>
+#include <set>
+#include <vector>
+
+#include "Atom/TesselPoint.hpp"
+#include "LinkedCell/PointCloudAdaptor.hpp"
+#include "ApproximateShapeArea.hpp"
+#include "Tesselation/tesselation.hpp"
+
+/** Constructor of class ApproximateShapeArea.
+ *
+ * @param _shape shape to calculate the surface area approximately
+ */
+ApproximateShapeArea::ApproximateShapeArea(const Shape &_shape) :
+		shape(_shape)
+{}
+
+/** Destructor of class ApproximateShapeArea.
+ *
+ */
+ApproximateShapeArea::~ApproximateShapeArea()
+{}
+
+/** Calculate the approximate surface area of the given \a shape.
+ *
+ * @return surface area approximated
+ */
+double ApproximateShapeArea::operator()() const
+{
+  const double distance = 2.;
+  const double min_area = distance*distance*distance;
+  const double radius = shape.getRadius();
+  const double surfacearea_upperbound = 4.*M_PI * radius*radius;
+  const size_t N = (int)(surfacearea_upperbound/min_area);
+  // get surface points
+  std::vector<Vector> SurfacePoints =
+      shape.getHomogeneousPointsOnSurface(N);
+  typedef std::set<TesselPoint *> NodeSet;
+  NodeSet SurfaceNodes;
+  for (size_t i=0;i<SurfacePoints.size();++i) {
+    TesselPoint * Walker = new TesselPoint();
+    Walker->setName(std::string("SurfaceNode")+toString(i));
+    Walker->setPosition(SurfacePoints[i]);
+    SurfaceNodes.insert(Walker);
+  }
+
+  // tesselate
+  PointCloudAdaptor<NodeSet> cloud(&SurfaceNodes, "TesselPointSTLList");
+  Tesselation *tesselator = new Tesselation;
+  (*tesselator)(cloud, distance);
+
+  // obtain surface area (assume angstroem)
+  const double surfacearea = tesselator->getAreaOfEnvelope(true);
+
+  // clear up
+  delete tesselator;
+  for (NodeSet::iterator iter = SurfaceNodes.begin();
+      !SurfaceNodes.empty(); iter = SurfaceNodes.begin()) {
+    delete *iter;
+    SurfaceNodes.erase(iter);
+  }
+
+  return surfacearea;
+}
+
Index: src/Tesselation/ApproximateShapeArea.hpp
===================================================================
--- src/Tesselation/ApproximateShapeArea.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Tesselation/ApproximateShapeArea.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,36 @@
+/*
+ * ApproximateShapeArea.hpp
+ *
+ *  Created on: Jan 30, 2012
+ *      Author: heber
+ */
+
+#ifndef APPROXIMATESHAPEAREA_HPP_
+#define APPROXIMATESHAPEAREA_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Shapes/Shape.hpp"
+
+/** Functor for the approximate surface are of a shape.
+ *
+ * This class is just an intermediate until we have implemented a better way
+ * to calculate the surface area within the constructuve solid geometry method.
+ */
+class ApproximateShapeArea
+{
+public:
+	ApproximateShapeArea(const Shape &_shape);
+	~ApproximateShapeArea();
+
+	double operator()() const;
+
+private:
+	Shape shape;
+};
+
+
+#endif /* APPROXIMATESHAPEAREA_HPP_ */
Index: src/Tesselation/ApproximateShapeVolume.cpp
===================================================================
--- src/Tesselation/ApproximateShapeVolume.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Tesselation/ApproximateShapeVolume.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+/*
+ * ApproximateShapeVolume.cpp
+ *
+ *  Created on: Jan 30, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "ApproximateShapeVolume.hpp"
+
+#include <boost/bind.hpp>
+#include <vector>
+
+#include "Box.hpp"
+#include "Filling/Mesh/CubeMesh.hpp"
+#include "Filling/NodeTypes.hpp"
+#include "LinearAlgebra/RealSpaceMatrix.hpp"
+#include "LinearAlgebra/Vector.hpp"
+#include "World.hpp"
+
+/** Constructor of class ApproximateShapeVolume.
+ *
+ * @param _shape shape to calculate the volume approximately
+ */
+ApproximateShapeVolume::ApproximateShapeVolume(const Shape &_shape) :
+		shape(_shape)
+{}
+
+/** Destructor of class ApproximateShapeVolume.
+ *
+ */
+ApproximateShapeVolume::~ApproximateShapeVolume()
+{}
+
+/** Calculate the approximate volume of the given \a shape.
+ *
+ * @return surface volume approximated
+ */
+double ApproximateShapeVolume::operator()() const
+{
+	// TODO
+	// generate mesh of points to "integrate"
+	const double min_distance = 10.;
+	Vector distance(min_distance,min_distance,min_distance);
+	const RealSpaceMatrix &M = World::getInstance().getDomain().getM();
+	Mesh *mesh = new CubeMesh(distance, Vector(0.5,0.5,0.5), M );
+	NodeSet nodes = mesh->getNodes();
+
+	// fill with grid points and count whether isInside
+	const size_t total = nodes.size();
+	size_t inside = 0;
+	for (NodeSet::const_iterator iter = nodes.begin();
+			iter != nodes.end(); ++iter) {
+		if (shape.isInside(*iter))
+			++inside;
+	}
+
+	// calculate volume of box
+	const double volume = M.determinant();
+
+	// return fraction that is inside
+	return volume*((double)inside/(double)total);
+}
Index: src/Tesselation/ApproximateShapeVolume.hpp
===================================================================
--- src/Tesselation/ApproximateShapeVolume.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/Tesselation/ApproximateShapeVolume.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,36 @@
+/*
+ * ApproximateShapeVolume.hpp
+ *
+ *  Created on: Jan 30, 2012
+ *      Author: heber
+ */
+
+#ifndef APPROXIMATESHAPEVOLUME_HPP_
+#define APPROXIMATESHAPEVOLUME_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Shapes/Shape.hpp"
+
+/** Functor for the approximate volume of a shape.
+ *
+ * This class is just an intermediate until we have implemented a better way
+ * to calculate the volume within the constructuve solid geometry method.
+ */
+class ApproximateShapeVolume
+{
+public:
+	ApproximateShapeVolume(const Shape &_shape);
+	~ApproximateShapeVolume();
+
+	double operator()() const;
+
+private:
+	Shape shape;
+};
+
+
+#endif /* APPROXIMATESHAPEVOLUME_HPP_ */
Index: src/Tesselation/BoundaryTriangleSet.cpp
===================================================================
--- src/Tesselation/BoundaryTriangleSet.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Tesselation/BoundaryTriangleSet.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -230,52 +230,53 @@
   Vector Direction;
 
-  // 1. get intersection with plane
+  // 1. get intersection with plane and place in ClosestPoint
   LOG(1, "INFO: Looking for closest point of triangle " << *this << " to " << x << ".");
-  GetCenter(Direction);
+  LOG(1, "INFO: endpoints are " << endpoints[0]->node->getPosition() << ","
+      << endpoints[1]->node->getPosition() << ", and " << endpoints[2]->node->getPosition() << ".");
   try {
-    Line l = makeLineThrough(x, Direction);
-    ClosestPoint = Plane(NormalVector, (endpoints[0]->node->getPosition())).GetIntersection(l);
+    ClosestPoint = Plane(NormalVector, (endpoints[0]->node->getPosition())).getClosestPoint(x);
   }
   catch (LinearAlgebraException &excp) {
     (ClosestPoint) = (x);
   }
+  Vector InPlane(ClosestPoint); // points from plane intersection to straight-down point
 
   // 2. Calculate in plane part of line (x, intersection)
-  Vector InPlane = (x) - (ClosestPoint); // points from plane intersection to straight-down point
-  InPlane.ProjectOntoPlane(NormalVector);
-  InPlane += ClosestPoint;
-
-  LOG(2, "INFO: Triangle is " << *this << ".");
-  LOG(2, "INFO: Line is from " << Direction << " to " << x << ".");
-  LOG(2, "INFO: In-plane part is " << InPlane << ".");
+  LOG(2, "INFO: Closest point on triangle plane is " << ClosestPoint << ".");
 
   // Calculate cross point between one baseline and the desired point such that distance is shortest
-  double ShortestDistance = -1.;
-  bool InsideFlag = false;
   Vector CrossDirection[3];
   Vector CrossPoint[3];
-  Vector helper;
   for (int i = 0; i < 3; i++) {
-    // treat direction of line as normal of a (cut)plane and the desired point x as the plane offset, the intersect line with point
-    Direction = (endpoints[(i+1)%3]->node->getPosition()) - (endpoints[i%3]->node->getPosition());
+    const Vector Direction = (endpoints[i%3]->node->getPosition()) - (endpoints[(i+1)%3]->node->getPosition());
     // calculate intersection, line can never be parallel to Direction (is the same vector as PlaneNormal);
     Line l = makeLineThrough((endpoints[i%3]->node->getPosition()), (endpoints[(i+1)%3]->node->getPosition()));
-    CrossPoint[i] = Plane(Direction, InPlane).GetIntersection(l);
-    CrossDirection[i] = CrossPoint[i] - InPlane;
-    CrossPoint[i] -= (endpoints[i%3]->node->getPosition());  // cross point was returned as absolute vector
+    CrossPoint[i] = l.getClosestPoint(InPlane);
+    // NOTE: direction of line is normalized, hence s must not necessarily be in [0,1] for the baseline
+    LOG(2, "INFO: Closest point on line from " << (endpoints[(i+1)%3]->node->getPosition())
+        << " to " << (endpoints[i%3]->node->getPosition()) << " is " << CrossPoint[i] << ".");
+    CrossPoint[i] -= (endpoints[(i+1)%3]->node->getPosition());  // cross point was returned as absolute vector
     const double s = CrossPoint[i].ScalarProduct(Direction)/Direction.NormSquared();
     LOG(2, "INFO: Factor s is " << s << ".");
     if ((s >= -MYEPSILON) && ((s-1.) <= MYEPSILON)) {
-          CrossPoint[i] += (endpoints[i%3]->node->getPosition());  // make cross point absolute again
-      LOG(2, "INFO: Crosspoint is " << CrossPoint[i] << ", intersecting BoundaryLine between " << endpoints[i % 3]->node->getPosition() << " and " << endpoints[(i + 1) % 3]->node->getPosition() << ".");
-      const double distance = CrossPoint[i].DistanceSquared(x);
-      if ((ShortestDistance < 0.) || (ShortestDistance > distance)) {
-        ShortestDistance = distance;
-        (ClosestPoint) = CrossPoint[i];
-      }
-    } else
-      CrossPoint[i].Zero();
-  }
-  InsideFlag = true;
+      CrossPoint[i] += (endpoints[(i+1)%3]->node->getPosition());  // make cross point absolute again
+      LOG(2, "INFO: Crosspoint is " << CrossPoint[i] << ", intersecting BoundaryLine between "
+          << endpoints[i % 3]->node->getPosition() << " and "
+          << endpoints[(i + 1) % 3]->node->getPosition() << ".");
+    } else {
+      // set to either endpoint of BoundaryLine
+      if (s < -MYEPSILON)
+        CrossPoint[i] = (endpoints[(i+1)%3]->node->getPosition());
+      else
+        CrossPoint[i] = (endpoints[i%3]->node->getPosition());
+      LOG(2, "INFO: Crosspoint is " << CrossPoint[i] << ", intersecting outside of BoundaryLine between "
+          << endpoints[i % 3]->node->getPosition() << " and "
+          << endpoints[(i + 1) % 3]->node->getPosition() << ".");
+    }
+    CrossDirection[i] = CrossPoint[i] - InPlane;
+  }
+
+  bool InsideFlag = true;
+  double ShortestDistance = -1.;
   for (int i = 0; i < 3; i++) {
     const double sign = CrossDirection[i].ScalarProduct(CrossDirection[(i + 1) % 3]);
@@ -284,17 +285,17 @@
     if ((sign > -MYEPSILON) && (othersign > -MYEPSILON)) // have different sign
       InsideFlag = false;
-  }
+    // update current best candidate
+    const double distance = CrossPoint[i].DistanceSquared(x);
+    if ((ShortestDistance < 0.) || (ShortestDistance > distance)) {
+      ShortestDistance = distance;
+      (ClosestPoint) = CrossPoint[i];
+    }
+  }
+
   if (InsideFlag) {
     (ClosestPoint) = InPlane;
     ShortestDistance = InPlane.DistanceSquared(x);
-  } else { // also check endnodes
-    for (int i = 0; i < 3; i++) {
-      const double distance = x.DistanceSquared(endpoints[i]->node->getPosition());
-      if ((ShortestDistance < 0.) || (ShortestDistance > distance)) {
-        ShortestDistance = distance;
-        (ClosestPoint) = (endpoints[i]->node->getPosition());
-      }
-    }
-  }
+  }
+
   LOG(1, "INFO: Closest Point is " << ClosestPoint << " with shortest squared distance is " << ShortestDistance << ".");
   return ShortestDistance;
@@ -370,4 +371,79 @@
 }
 ;
+
+/** Checks whether a given point is inside the plane of the triangle and inside the
+ * bounds defined by its BoundaryLineSet's.
+ *
+ * @param point point to check
+ * @return true - point is inside place and inside all BoundaryLine's
+ */
+bool BoundaryTriangleSet::IsInsideTriangle(const Vector &point) const
+{
+  Info FunctionInfo(__func__);
+
+  // check if it's inside the plane
+  try {
+    Plane trianglePlane(
+        endpoints[0]->node->getPosition(),
+        endpoints[1]->node->getPosition(),
+        endpoints[2]->node->getPosition());
+    if (!trianglePlane.isContained(point)) {
+      LOG(1, "INFO: Point " << point << " is not inside plane " << trianglePlane << " by "
+          << trianglePlane.distance(point) << ".");
+      return false;
+    }
+  } catch(LinearDependenceException) {
+    // triangle is degenerated, it's just a line (i.e. one endpoint is right in between two others
+    for (size_t i = 0; i < NDIM; ++i) {
+      try {
+        Line l = makeLineThrough(
+            lines[i]->endpoints[0]->node->getPosition(),
+            lines[i]->endpoints[1]->node->getPosition());
+        if (l.isContained(GetThirdEndpoint(lines[i])->node->getPosition())) {
+          // we have the largest of the three lines
+          LOG(1, "INFO: Linear-dependent case where point " << point << " is on line " << l << ".");
+          return (l.isContained(point));
+        }
+      } catch(ZeroVectorException) {
+        // two points actually coincide
+        try {
+          Line l = makeLineThrough(
+              lines[i]->endpoints[0]->node->getPosition(),
+              GetThirdEndpoint(lines[i])->node->getPosition());
+          LOG(1, "INFO: Degenerated case where point " << point << " is on line " << l << ".");
+          return (l.isContained(point));
+        } catch(ZeroVectorException) {
+          // all three points coincide
+          if (point.DistanceSquared(lines[i]->endpoints[0]->node->getPosition()) < MYEPSILON) {
+            LOG(1, "INFO: Full-Degenerated case where point " << point << " is on three endpoints "
+                << lines[i]->endpoints[0]->node->getPosition() << ".");
+            return true;
+          }
+          else return false;
+        }
+      }
+    }
+  }
+
+  // check whether it lies on the correct side as given by third endpoint for
+  // each BoundaryLine.
+  // NOTE: we assume here that endpoints are linear independent, as the case
+  // has been caught before already extensively
+  for (size_t i = 0; i < NDIM; ++i) {
+    Line l = makeLineThrough(
+        lines[i]->endpoints[0]->node->getPosition(),
+        lines[i]->endpoints[1]->node->getPosition());
+    Vector onLine( l.getClosestPoint(point) );
+    LOG(1, "INFO: Closest point on boundary line is " << onLine << ".");
+    Vector inTriangleDirection( GetThirdEndpoint(lines[i])->node->getPosition() - onLine );
+    Vector inPointDirection(point - onLine);
+    if ((inTriangleDirection.NormSquared() > MYEPSILON) && (inPointDirection.NormSquared() > MYEPSILON))
+      if (inTriangleDirection.ScalarProduct(inPointDirection) < -MYEPSILON)
+        return false;
+  }
+
+  return true;
+}
+
 
 /** Returns the endpoint which is not contained in the given \a *line.
Index: src/Tesselation/BoundaryTriangleSet.hpp
===================================================================
--- src/Tesselation/BoundaryTriangleSet.hpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Tesselation/BoundaryTriangleSet.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -42,4 +42,5 @@
     bool IsPresentTupel(const BoundaryPointSet * const Points[3]) const;
     bool IsPresentTupel(const BoundaryTriangleSet * const T) const;
+    bool IsInsideTriangle(const Vector &point) const;
 
     Plane getPlane() const;
Index: src/Tesselation/boundary.cpp
===================================================================
--- src/Tesselation/boundary.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Tesselation/boundary.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -1029,5 +1029,5 @@
   for (int i=0;i<NDIM;i++) {
     phi[i] = (random()/(rng_max-rng_min))*(2.*M_PI);
-    std::cout << "Random angle is " << phi[i] << std::endl;
+    LOG(4, "DEBUG: Random angle is " << phi[i] << ".");
   }
 
Index: src/Tesselation/triangleintersectionlist.cpp
===================================================================
--- src/Tesselation/triangleintersectionlist.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Tesselation/triangleintersectionlist.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -197,10 +197,33 @@
   if (!DistanceList.empty()) {
     // get closest triangle(s)
-    std::pair< DistanceTriangleMap::iterator, DistanceTriangleMap::iterator >  DistanceRange =
+    std::pair< DistanceTriangleMap::const_iterator, DistanceTriangleMap::const_iterator >  DistanceRange =
         DistanceList.equal_range(DistanceList.begin()->first);
+    {
+      size_t count = 0;
+      for (DistanceTriangleMap::const_iterator iter = DistanceRange.first;
+          iter != DistanceRange.second; ++iter)
+        ++count;
+      LOG(1, "INFO: There are " << count << " possible triangles at the smallest distance.");
+    }
     // if there is more than one, check all of their normal vectors
-    // return the one with positive SKP if present
-
-    runner = IntersectionList.find(DistanceList.begin()->second);
+    // return the one with positive SKP if present because if the point
+    // would be truely inside, all of the closest triangles would have to show
+    // their inner side
+    LOG(1, "INFO: Looking for first SKP greater than zero ...");
+    for (DistanceTriangleMap::const_iterator iter = DistanceRange.first;
+        iter != DistanceRange.second; ++iter) {
+      // find the entry by the triangle key in IntersectionList to get the Intersection point
+      runner = IntersectionList.find(iter->second);
+      Vector TestVector = (Point) - (*(*runner).second);
+      // construct SKP
+      const double sign = (*iter).second->NormalVector.ScalarProduct(TestVector);
+      LOG(1, "INFO: Checking SKP of closest triangle " << *(iter->second) << " = " << sign << ".");
+      // if positive return
+      if (sign > 0)
+        break;
+    }
+    // if there's just one or all are negative, runner is not set yet
+    if (runner == IntersectionList.end())
+      runner = IntersectionList.find(DistanceList.begin()->second);
   }
   return runner;
Index: src/Tesselation/unittests/Makefile.am
===================================================================
--- src/Tesselation/unittests/Makefile.am	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Tesselation/unittests/Makefile.am	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -14,7 +14,6 @@
 TESSELATIONTESTS = \
   TesselationUnitTest \
-  Tesselation_BoundaryTriangleUnitTest
-  
-XFAIL_TESTS += Tesselation_InOutsideUnitTest
+  Tesselation_BoundaryTriangleUnitTest \
+  Tesselation_InOutsideUnitTest
 
 TESTS += $(TESSELATIONTESTS)
Index: src/Tesselation/unittests/Tesselation_BoundaryTriangleUnitTest.cpp
===================================================================
--- src/Tesselation/unittests/Tesselation_BoundaryTriangleUnitTest.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Tesselation/unittests/Tesselation_BoundaryTriangleUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -30,4 +30,7 @@
 #include "Helpers/defs.hpp"
 #include "Atom/TesselPoint.hpp"
+#include "LinearAlgebra/Plane.hpp"
+#include "LinearAlgebra/RealSpaceMatrix.hpp"
+#include "LinearAlgebra/VectorSet.hpp"
 #include "Tesselation/BoundaryPointSet.hpp"
 #include "Tesselation/BoundaryLineSet.hpp"
@@ -49,24 +52,16 @@
 
 
-void TesselationBoundaryTriangleTest::setUp()
-{
-  setVerbosity(5);
+void TesselationBoundaryTriangleTest::createTriangle(const std::vector<Vector> &Vectors)
+{
+  CPPUNIT_ASSERT_EQUAL( (size_t)3, Vectors.size() );
 
   // create nodes
-  tesselpoints[0] = new TesselPoint;
-  tesselpoints[0]->setPosition(Vector(0., 0., 0.));
-  tesselpoints[0]->setName("1");
-  tesselpoints[0]->setNr(1);
-  points[0] = new BoundaryPointSet(tesselpoints[0]);
-  tesselpoints[1] = new TesselPoint;
-  tesselpoints[1]->setPosition(Vector(0., 1., 0.));
-  tesselpoints[1]->setName("2");
-  tesselpoints[1]->setNr(2);
-  points[1] = new BoundaryPointSet(tesselpoints[1]);
-  tesselpoints[2] = new TesselPoint;
-  tesselpoints[2]->setPosition(Vector(1., 0., 0.));
-  tesselpoints[2]->setName("3");
-  tesselpoints[2]->setNr(3);
-  points[2] = new BoundaryPointSet(tesselpoints[2] );
+  for (size_t count = 0; count < NDIM; ++count) {
+    tesselpoints[count] = new TesselPoint;
+    tesselpoints[count]->setPosition( Vectors[count] );
+    tesselpoints[count]->setName(toString(count));
+    tesselpoints[count]->setNr(count);
+    points[count] = new BoundaryPointSet(tesselpoints[count]);
+  }
 
   // create line
@@ -77,7 +72,21 @@
   // create triangle
   triangle = new BoundaryTriangleSet(lines, 0);
-  triangle->GetNormalVector(Vector(0.,0.,1.));
-};
-
+  Plane p(Vectors[0], Vectors[1], Vectors[2]);
+  triangle->GetNormalVector(p.getNormal());
+}
+
+void TesselationBoundaryTriangleTest::setUp()
+{
+  setVerbosity(5);
+
+  // create nodes
+  std::vector<Vector> Vectors;
+  Vectors.push_back( Vector(0., 0., 0.) );
+  Vectors.push_back( Vector(0., 1., 0.) );
+  Vectors.push_back( Vector(1., 0., 0.) );
+
+  // create triangle
+  createTriangle(Vectors);
+}
 
 void TesselationBoundaryTriangleTest::tearDown()
@@ -90,5 +99,213 @@
   logger::purgeInstance();
   errorLogger::purgeInstance();
-};
+}
+
+/** UnitTest for Tesselation::IsInsideTriangle()
+ */
+void TesselationBoundaryTriangleTest::IsInsideTriangleTest()
+{
+  // inside points
+  {
+    // check each endnode
+    for (size_t i=0; i< NDIM; ++i) {
+      const Vector testPoint(triangle->endpoints[i]->node->getPosition());
+      LOG(1, "INFO: Testing whether " << testPoint << " is an inner point.");
+      CPPUNIT_ASSERT( triangle->IsInsideTriangle( testPoint ) );
+    }
+  }
+
+  {
+    // check points along each BoundaryLine
+    for (size_t i=0; i< NDIM; ++i) {
+      Vector offset = triangle->endpoints[i%3]->node->getPosition();
+      Vector direction = triangle->endpoints[(i+1)%3]->node->getPosition() - offset;
+      for (double s = 0.1; s < 1.; s+= 0.1) {
+        Vector testPoint = offset + s*direction;
+        LOG(1, "INFO: Testing whether " << testPoint << " is an inner point.");
+        CPPUNIT_ASSERT( triangle->IsInsideTriangle( testPoint ) );
+      }
+    }
+  }
+
+  {
+    // check central point
+    Vector center;
+    triangle->GetCenter(center);
+    LOG(1, "INFO: Testing whether " << center << " is an inner point.");
+    CPPUNIT_ASSERT( triangle->IsInsideTriangle( center ) );
+  }
+
+  // outside points
+  {
+    // check points outside (i.e. those not in xy-plane through origin)
+    double n[3];
+    const double boundary = 4.;
+    const double step = 1.;
+    // go through the cube and check each point
+    for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
+      for (n[1] = -boundary; n[1] <= boundary; n[1]+=step)
+        for (n[2] = -boundary; n[2] <= boundary; n[2]+=step) {
+          const Vector testPoint(n[0], n[1], n[2]);
+          if (n[2] != 0) {
+            LOG(1, "INFO: Testing whether " << testPoint << " is not an inner point.");
+            CPPUNIT_ASSERT( !triangle->IsInsideTriangle( testPoint ) );
+          }
+        }
+  }
+
+  {
+    // check points within the plane but outside of triangle
+    double n[3];
+    const double boundary = 4.;
+    const double step = 1.;
+    n[2] = 0;
+    for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
+      for (n[1] = -boundary; n[1] <= boundary; n[1]+=step) {
+        const Vector testPoint(n[0], n[1], n[2]);
+        if ((n[0] >=0) && (n[1] >=0) && (n[0]<=1) && (n[1]<=1)) {
+          if (n[0]+n[1] <= 1) {
+            LOG(1, "INFO: Testing whether " << testPoint << " is an inner point.");
+            CPPUNIT_ASSERT( triangle->IsInsideTriangle( testPoint) );
+          } else {
+            LOG(1, "INFO: Testing whether " << testPoint << " is not an inner point.");
+            CPPUNIT_ASSERT( !triangle->IsInsideTriangle( testPoint) );
+          }
+        } else {
+          LOG(1, "INFO: Testing whether " << testPoint << " is not an inner point.");
+          CPPUNIT_ASSERT( !triangle->IsInsideTriangle( testPoint) );
+        }
+      }
+  }
+}
+
+/** UnitTest for Tesselation::IsInsideTriangle()
+ *
+ * We test for some specific points that occured in larger examples of the code.
+ *
+ */
+void TesselationBoundaryTriangleTest::IsInsideTriangle_specificTest()
+{
+  {
+    delete triangle;
+    // test is from --create-micelle 200 --radius 30. --position "0,0,0" of sles.data
+    // failure is: Intersection (23.1644,24.1867,65.1272) is not inside triangle [659|Na2451,O3652,Na3762].
+    const Vector testPoint(1.57318,1.57612,10.9874);
+    const Vector testIntersection(23.1644,24.1867,65.1272);
+    std::vector<Vector> vectors;
+    vectors.push_back( Vector(23.0563,30.4673,73.7555) );
+    vectors.push_back( Vector(25.473,25.1512,68.5467) );
+    vectors.push_back( Vector(23.1644,24.1867,65.1272) );
+    createTriangle(vectors);
+    CPPUNIT_ASSERT( triangle->IsInsideTriangle( testIntersection ) );
+  }
+  {
+    delete triangle;
+    // test is from --create-micelle 200 --radius 30. --position "0,0,0" of sles.data
+    // failure is: Intersection (20.6787,70.655,71.5657) is not inside triangle [622|Na1197,Na2166,O3366].
+    // fix is lower LINALG_MYEPSILON (not std::numeric_limits<doubble>*100 but *1e-4)
+    const Vector testPoint(1.57318,14.185,61.2155);
+    const Vector testIntersection(20.67867516517798,70.65496977054023,71.56572984946152);
+    std::vector<Vector> vectors;
+    vectors.push_back( Vector(22.9592,68.7791,77.5907) );
+    vectors.push_back( Vector(18.4729,72.0386,68.08839999999999) );
+    vectors.push_back( Vector(20.3834,71.0154,70.1443) );
+    createTriangle(vectors);
+    CPPUNIT_ASSERT( triangle->IsInsideTriangle( testIntersection ) );
+  }
+  {
+    delete triangle;
+    // test is from --create-micelle 200 --radius 30. --position "0,0,0" of sles.data
+    // failure is:Intersection (27.56537519896,13.40256646925,6.672946688134) is not inside triangle [702|Na5016,O6388,Na6498].
+    // note that the Intersection cannot possibly lie be within the triangle!
+    // we test now against correct intersection
+    const Vector testIntersection(14.6872,36.204,39.8043);
+    std::vector<Vector> vectors;
+    vectors.push_back( Vector(10.7513,43.4247,48.4127) );
+    vectors.push_back( Vector(13.7119,37.0827,47.4203) );
+    vectors.push_back( Vector(14.6872,36.204,39.8043) );
+    createTriangle(vectors);
+    CPPUNIT_ASSERT( triangle->IsInsideTriangle( testIntersection ) );
+  }
+}
+
+/** UnitTest for Tesselation::GetClosestPointInsideTriangle()
+ *
+ * We check whether this function always returns a intersection inside the
+ * triangle.
+ *
+ */
+void TesselationBoundaryTriangleTest::GetClosestPointInsideTriangleTest()
+{
+  Vector TestIntersection;
+
+  {
+    // march through a cube mesh on triangle in xy plane
+    double n[3];
+    const double boundary = 4.;
+    const double step = 1.;
+    // go through the cube and check each point
+    for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
+      for (n[1] = -boundary; n[1] <= boundary; n[1]+=step)
+        for (n[2] = -boundary; n[2] <= boundary; n[2]+=step) {
+          const Vector testPoint(n[0], n[1], n[2]);
+          triangle->GetClosestPointInsideTriangle(testPoint, TestIntersection);
+          CPPUNIT_ASSERT( triangle->IsInsideTriangle( TestIntersection ));
+        }
+  }
+
+  delete triangle;
+  // create better triangle;
+  VECTORSET(std::vector) Vectors;
+  Vectors.push_back( Vector(0., 0., 0.) );
+  Vectors.push_back( Vector(0., 1., 0.) );
+  Vectors.push_back( Vector(1., 0., 0.) );
+  RealSpaceMatrix M;
+  M.setRotation(M_PI/3., M_PI/4., 2.*M_PI/3.);
+  Vectors.transform(M);
+  createTriangle(Vectors);
+
+  {
+    // march through a cube mesh on rotated triangle
+    double n[3];
+    const double boundary = 4.;
+    const double step = 1.;
+    // go through the cube and check each point
+    for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
+      for (n[1] = -boundary; n[1] <= boundary; n[1]+=step)
+        for (n[2] = -boundary; n[2] <= boundary; n[2]+=step) {
+          const Vector testPoint(n[0], n[1], n[2]);
+          triangle->GetClosestPointInsideTriangle(testPoint, TestIntersection);
+          CPPUNIT_ASSERT( triangle->IsInsideTriangle( TestIntersection ));
+        }
+  }
+}
+
+/** UnitTest for Tesselation::GetClosestPointInsideTriangle()
+ *
+ * We test for some specific points that occured in larger examples of the code.
+ *
+ */
+void TesselationBoundaryTriangleTest::GetClosestPointInsideTriangle_specificTest()
+{
+  {
+    delete triangle;
+    // test is from --create-micelle 200 --radius 30. --position "0,0,0" of sles.data
+    // failure is:Intersection (27.56537519896,13.40256646925,6.672946688134) is not inside triangle [702|Na5016,O6388,Na6498].
+    // note that the Intersection cannot possibly lie be within the triangle
+    // however, it is on its plane (off only by 2.7e-12)
+    // testPoint2 is corrected version
+    const Vector testPoint(27.56537519896,13.40256646925,6.672946688134);
+    const Vector testPoint2(14.6872,36.204,39.8043);
+    Vector testIntersection;
+    std::vector<Vector> vectors;
+    vectors.push_back( Vector(10.7513,43.4247,48.4127) );
+    vectors.push_back( Vector(13.7119,37.0827,47.4203) );
+    vectors.push_back( Vector(14.6872,36.204,39.8043) );
+    createTriangle(vectors);
+    triangle->GetClosestPointInsideTriangle(testPoint, testIntersection);
+    CPPUNIT_ASSERT ( testPoint != testIntersection );
+    CPPUNIT_ASSERT ( testPoint2 == testIntersection );
+  }
+}
 
 /** UnitTest for Tesselation::IsInnerPoint()
Index: src/Tesselation/unittests/Tesselation_BoundaryTriangleUnitTest.hpp
===================================================================
--- src/Tesselation/unittests/Tesselation_BoundaryTriangleUnitTest.hpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/Tesselation/unittests/Tesselation_BoundaryTriangleUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -19,4 +19,7 @@
 #include <cppunit/extensions/HelperMacros.h>
 
+#include <vector>
+
+#include "LinearAlgebra/Vector.hpp"
 #include "LinkedCell/linkedcell.hpp"
 #include "Tesselation/tesselation.hpp"
@@ -29,4 +32,8 @@
 {
     CPPUNIT_TEST_SUITE( TesselationBoundaryTriangleTest) ;
+    CPPUNIT_TEST ( IsInsideTriangleTest );
+    CPPUNIT_TEST ( IsInsideTriangle_specificTest );
+    CPPUNIT_TEST ( GetClosestPointInsideTriangleTest );
+    CPPUNIT_TEST ( GetClosestPointInsideTriangle_specificTest );
     CPPUNIT_TEST ( GetClosestPointOnPlaneTest );
     CPPUNIT_TEST ( GetClosestPointOffPlaneTest );
@@ -36,8 +43,14 @@
       void setUp();
       void tearDown();
+      void IsInsideTriangleTest();
+      void IsInsideTriangle_specificTest();
+      void GetClosestPointInsideTriangleTest();
+      void GetClosestPointInsideTriangle_specificTest();
       void GetClosestPointOnPlaneTest();
       void GetClosestPointOffPlaneTest();
 
 private:
+      void createTriangle(const std::vector<Vector> &Vectors);
+
       static const double SPHERERADIUS;
 
Index: src/UIElements/CommandLineUI/CommandLineParser.cpp
===================================================================
--- src/UIElements/CommandLineUI/CommandLineParser.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/UIElements/CommandLineUI/CommandLineParser.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -51,4 +51,5 @@
   atom("Atom options"),
   command("Command options"),
+  fill("fill options"),
   fragmentation("Fragmentation options"),
   graph("Graph options"),
@@ -65,4 +66,5 @@
   CmdParserLookup["command"] = &command;
   CmdParserLookup["edit"] = &edit;
+  CmdParserLookup["fill"] = &fill;
   CmdParserLookup["fragmentation"] = &fragmentation;
   CmdParserLookup["graph"] = &graph;
Index: src/UIElements/CommandLineUI/CommandLineParser.hpp
===================================================================
--- src/UIElements/CommandLineUI/CommandLineParser.hpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/UIElements/CommandLineUI/CommandLineParser.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -58,4 +58,5 @@
   po::options_description command;
   po::options_description edit;
+  po::options_description fill;
   po::options_description fragmentation;
   po::options_description graph;
Index: src/UIElements/Makefile.am
===================================================================
--- src/UIElements/Makefile.am	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/UIElements/Makefile.am	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -263,4 +263,5 @@
 	libMolecuilderAnalysis.la \
 	libMolecuilderGraph.la \
+	libMolecuilderFilling.la \
 	libMolecuilder.la \
 	libMolecuilderFragmentation.la \
Index: src/UIElements/Menu/MenuDescription.cpp
===================================================================
--- src/UIElements/Menu/MenuDescription.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/UIElements/Menu/MenuDescription.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -49,4 +49,5 @@
   MenuPositionMap->insert(std::make_pair("command",TopPosition("",3)));
   MenuPositionMap->insert(std::make_pair("edit",TopPosition("",2)));
+  MenuPositionMap->insert(std::make_pair("fill",TopPosition("tools",5)));
   MenuPositionMap->insert(std::make_pair("fragmentation",TopPosition("tools",3)));
   MenuPositionMap->insert(std::make_pair("graph",TopPosition("tools",4)));
@@ -63,4 +64,5 @@
   MenuDescriptionsMap->insert(std::make_pair("command","Configuration"));
   MenuDescriptionsMap->insert(std::make_pair("edit","Edit"));
+  MenuDescriptionsMap->insert(std::make_pair("fill","Fill"));
   MenuDescriptionsMap->insert(std::make_pair("fragmentation","Fragmentation"));
   MenuDescriptionsMap->insert(std::make_pair("graph","Graph"));
@@ -77,4 +79,5 @@
   MenuNameMap->insert(std::make_pair("command","Configuration"));
   MenuNameMap->insert(std::make_pair("edit","Edit"));
+  MenuNameMap->insert(std::make_pair("fill","Fill"));
   MenuNameMap->insert(std::make_pair("fragmentation","Fragmentation"));
   MenuNameMap->insert(std::make_pair("graph","Graph"));
Index: src/documentation/constructs/atoms.dox
===================================================================
--- src/documentation/constructs/atoms.dox	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/documentation/constructs/atoms.dox	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -56,5 +56,28 @@
  * compatible implementation.
  *
+ * \section atoms-copy Copying atoms
  *
- * \date 2011-10-31
+ * Copying atoms is a frequent action. That's why there are specific functors
+ * to get it done in more and more complex ways. The functors all inherit
+ * the \ref CopyAtomsInterface and the more complex ones build upon the
+ * functionality of the simpler ones:
+ * -# CopyAtomsInterface: Internally sets to the number of desired atoms.
+ * -# CopyAtoms_Simple: Fills the internal set with true copies.
+ * -# CopyAtoms_withBonds: Additionally also adds bonds in between the copies
+ *    as they exist in between the original atoms.
+ * -# CopyAtoms_SaturateDanglingBonds: additionally checks for cut bond that
+ *    would now become dangling bonds and inserts additional hydrogens for
+ *    each cut bond such that the copied array of atoms is saturated.
+ *
+ * The CopyAtomsInterface is simple to use:
+ * \code
+ *   std::vector<atom *> atoms_to_copy;
+ *   CopyAtoms_Simple copyMethod;
+ *   copyMethod(atoms_to_copy);
+ *   std::vector<atom *> copiedAtoms = getCopiedAtoms();
+ * \endcode
+ *
+ *
+ * \date 2012-03-30
+ *
  */
Index: src/documentation/constructs/constructs.dox
===================================================================
--- src/documentation/constructs/constructs.dox	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/documentation/constructs/constructs.dox	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -2,5 +2,5 @@
  * Project: MoleCuilder
  * Description: creates and alters molecular systems
- * Copyright (C)  2010 University of Bonn. All rights reserved.
+ * Copyright (C)  2011-2012 University of Bonn. All rights reserved.
  * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
  */
@@ -22,4 +22,5 @@
  *  \li \ref atom
  *  \li \ref bondgraph
+ *  \li \ref filling
  *  \li \ref descriptors
  *  \li \ref fragmentation
@@ -41,5 +42,5 @@
  *
  *
- * \date 2012-01-05
+ * \date 2012-01-16
  *
  */
Index: src/documentation/constructs/filling.dox
===================================================================
--- src/documentation/constructs/filling.dox	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/documentation/constructs/filling.dox	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,78 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2010 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/**
+ * \file filling.dox
+ *
+ * Created on: Jan 16, 2012
+ *    Author: heber
+ */
+
+/** \page filling Filling a domain
+ *
+ * The idea behind filling a domain is to cluster it with a set of nodes,
+ * i.e. a position in space in such a way that e.g. around node is sufficient
+ * space to fill in the desired molecule. The logic of generating the nodes
+ * is responsible to create them in such a way as to allow for dense (or
+ * whatever specific) filling is desired. However, we must not make it too
+ * complicated. The generation logic for these nodes should concentrate on
+ * filling the specific domain (sphere, ellipsoid, cuboid, pyramid, ...)
+ * in the best possible way.
+ * Whether each node can be filled is then to be decided by a predicate.
+ *
+ * The filling routine uses then both to traverse the given nodes and
+ * evaluate the predicate at each.
+ *
+ * Hence, the filling of a domain is abstracted into the following parts:
+ *
+ *  -# \ref Mesh - node containers
+ *  -# \ref FillPredicate - predicates
+ *  -# \ref Filler - a filling routine which itself requires
+ *    -# \ref Cluster - a set of atoms alone(!) inside a specific Shape
+ *    -# \ref CopyAtomsInterface - copy Method for atoms used by Cluster::clone
+ *    -# \ref Inserter - an insertion routine for the cloned cluster
+ *
+ * \section filling-node-generation Node generation
+ *
+ * The node generation is basically just a point or mesh generator that fills
+ * a specified region (best would be based on the class Shape) with a mesh in
+ * such a way as to fulfill certain criteria:
+ *
+ *    -# equidistant
+ *    -# containing certain primitive volumes (e.g. for fitting polymers)
+ *    -# ...
+ *
+ * \section filling-predicate Predicates
+ *
+ * The Predicate pattern has already been used with Descriptors and Shapes.
+ * These are simply function objects that return a boolean value. I.e. they
+ * decide whether the current node in the mesh is vacant and can be filled or
+ * not. As with the predicate() function in the class Descriptor, these should
+ * be composable via logic operators such as || (or), && (and), ! (not), ...
+ *
+ * Note that each predicate receives on construction all the required
+ * information, e.g. LinkedCell_View or Tesselation references or objects, ...
+ *
+ * \section filling-filling-routine Filling routine
+ *
+ * The filling routine is then simply a function that goes through the given
+ * number of nodes (completely unaware of the geometry) and evaluates for each
+ * point the given predicates (which might be a composition of other predicates).
+ *
+ * It rejects all nodes that evaluate to false, the list of valid points is
+ * then traversed again and at each node a Cluster is created.
+ *
+ * Note that we rely on \ref Cluster's, objects containing a set of atomicId_t
+ * and that are inside a contained \ref Shape, to fill at each node. We use
+ * Cluster::clone() to create a copy that is subsequently placed at the desired
+ * node via an \ref Inserter functor. This allows to either simply shift the
+ * Cluster or even to perform some random translations and rotations on it, see
+ * the specific implementations of the class \ref Inserter.
+ *
+ *
+ * \date 2012-01-16
+ */
Index: src/molecule.cpp
===================================================================
--- src/molecule.cpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/molecule.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -44,4 +44,5 @@
 #include "LinkedCell/linkedcell.hpp"
 #include "IdPool_impl.hpp"
+#include "Shapes/BaseShapes.hpp"
 #include "Tesselation/tesselation.hpp"
 #include "World.hpp"
@@ -165,34 +166,4 @@
 /************************** Access to the List of Atoms ****************/
 
-
-molecule::iterator molecule::begin(){
-  return iterator(atomIds.begin(), FromIdToAtom());
-}
-
-molecule::const_iterator molecule::begin() const{
-  return const_iterator(atomIds.begin(), FromIdToAtom());
-}
-
-molecule::iterator molecule::end(){
-  return iterator(atomIds.end(), FromIdToAtom());
-}
-
-molecule::const_iterator molecule::end() const{
-  return const_iterator(atomIds.end(), FromIdToAtom());
-}
-
-bool molecule::empty() const
-{
-  return (atomIds.empty());
-}
-
-size_t molecule::size() const
-{
-  size_t counter = 0;
-  for (const_iterator iter = begin(); iter != end (); ++iter)
-    counter++;
-  return counter;
-}
-
 molecule::const_iterator molecule::erase( const_iterator loc )
 {
@@ -222,18 +193,13 @@
 }
 
-molecule::const_iterator molecule::find ( atom * key ) const
-{
-  return const_iterator(atomIds.find(key->getId()), FromIdToAtom());
-}
-
 pair<molecule::iterator,bool> molecule::insert ( atom * const key )
 {
   OBSERVE;
-  pair<atomIdSet::iterator,bool> res = atomIds.insert(key->getId());
+  std::pair<iterator,bool> res = atomIds.insert(key->getId());
   if (res.second) { // push atom if went well
     key->setNr(atomIdPool.getNextId());
     setAtomName(key);
     formula+=key->getType();
-    return pair<iterator,bool>(iterator(res.first, FromIdToAtom()),res.second);
+    return res;
   } else {
     return pair<iterator,bool>(end(),res.second);
@@ -256,10 +222,4 @@
 {
   World::AtomComposite vector_of_atoms;
-//  std::copy(MyIter(atomIds.begin(), FromIdToAtom()),
-//      MyIter(atomIds.end(), FromIdToAtom()),
-//      vector_of_atoms.begin());
-//  for (MyIter iter = MyIter(atomIds.begin(), FromIdToAtom());
-//      iter != MyIter(atomIds.end(), FromIdToAtom());
-//      ++iter)
   for (molecule::iterator iter = begin(); iter != end(); ++iter)
     vector_of_atoms.push_back(*iter);
@@ -589,7 +549,8 @@
 
 /** Creates a copy of this molecule.
+ * \param offset translation Vector for the new molecule relative to old one
  * \return copy of molecule
  */
-molecule *molecule::CopyMolecule() const
+molecule *molecule::CopyMolecule(const Vector &offset) const
 {
   molecule *copy = World::getInstance().createMolecule();
@@ -599,4 +560,5 @@
   for (iterator iter = begin(); iter != end(); ++iter) {
     atom * const copy_atom = copy->AddCopyAtom(*iter);
+    copy_atom->setPosition(copy_atom->getPosition() + offset);
     FatherFinder.insert( std::make_pair( *iter, copy_atom ) );
   }
@@ -851,5 +813,5 @@
       "molecule::isInMolecule() - atom is not designated to be in molecule '"
       +toString(this->getName())+"'.");
-  molecule::atomIdSet::const_iterator iter = atomIds.find(_atom->getId());
+  molecule::const_iterator iter = atomIds.find(_atom->getId());
   return (iter != atomIds.end());
 }
@@ -1063,4 +1025,33 @@
 }
 
+Shape molecule::getBoundingShape() const
+{
+  // get center and radius
+  Vector center;
+  double radius = 0.;
+  {
+    center.Zero();
+    for(const_iterator iter = begin(); iter != end(); ++iter)
+      center += (*iter)->getPosition();
+    center *= 1./(double)size();
+    for(const_iterator iter = begin(); iter != end(); ++iter) {
+      const Vector &position = (*iter)->getPosition();
+      const double temp_distance = position.DistanceSquared(center);
+      if (temp_distance > radius)
+        radius = temp_distance;
+    }
+  }
+  // convert radius to true value and add some small boundary
+  radius = sqrt(radius) + 1e+6*std::numeric_limits<double>::epsilon();
+  LOG(1, "INFO: The " << size() << " atoms of the molecule are contained in a sphere at "
+      << center << " with radius " << radius << ".");
+
+  Shape BoundingShape(Sphere(center, radius));
+  LOG(1, "INFO: Created sphere at " << BoundingShape.getCenter() << " and radius "
+      << BoundingShape.getRadius() << ".");
+  return BoundingShape;
+}
+
 // construct idpool
 CONSTRUCT_IDPOOL(atomId_t, continuousId)
+
Index: src/molecule.hpp
===================================================================
--- src/molecule.hpp	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/molecule.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -21,12 +21,10 @@
 #include <vector>
 
-#include <boost/iterator/transform_iterator.hpp>
-
 #include <string>
 
+#include "AtomIdSet.hpp"
 #include "Atom/AtomSet.hpp"
 #include "CodePatterns/Cacheable.hpp"
 #include "CodePatterns/Observer/Observable.hpp"
-#include "CodePatterns/Observer/ObservedIterator.hpp"
 #include "Descriptors/AtomIdDescriptor.hpp"
 #include "Fragmentation/HydrogenSaturation_enum.hpp"
@@ -35,8 +33,6 @@
 #include "IdPool_policy.hpp"
 #include "IdPool.hpp"
+#include "Shapes/Shape.hpp"
 #include "types.hpp"
-
-// TODO: Was is the include of MoleculeDescriptor_impl.hpp doing in molecule.hpp
-#include "Descriptors/MoleculeDescriptor_impl.hpp"
 
 /****************************************** forward declarations *****************************/
@@ -54,18 +50,7 @@
 class MoleculeLeafClass;
 class MoleculeListClass;
-class periodentafel;
+class MoleculeUnittest;
 class RealSpaceMatrix;
 class Vector;
-class Shape;
-
-/******************************** Some definitions for easier reading **********************************/
-
-struct FromIdToAtom :
-  public std::unary_function<atom *, atomId_t>
-{
-    atom * operator()(atomId_t id) const {
-     return World::getInstance().getAtom(AtomById(id));
-    }
-};
 
 /************************************* Class definitions ****************************************/
@@ -76,11 +61,15 @@
 class molecule : public Observable
 {
+  //!> grant unit test access
+  friend class MoleculeUnittest;
+  //!> function may access cstor
   friend molecule *NewMolecule();
+  //!> function may access dstor
   friend void DeleteMolecule(molecule *);
 
 public:
-  typedef std::set<atomId_t> atomIdSet;
-  typedef boost::transform_iterator<FromIdToAtom, atomIdSet::iterator, atom *, atomId_t> iterator;
-  typedef boost::transform_iterator<FromIdToAtom, atomIdSet::const_iterator, const atom *, atomId_t const &> const_iterator;
+  typedef AtomIdSet::atomIdSet atomIdSet;
+  typedef AtomIdSet::iterator iterator;
+  typedef AtomIdSet::const_iterator const_iterator;
 
   int MDSteps; //!< The number of MD steps in Trajectories
@@ -97,5 +86,5 @@
   Cacheable<int> BondCount; //!< number of atoms, brought up-to-date by doCountBonds()
   moleculeId_t id;
-  atomIdSet atomIds; //<!set of atomic ids to check uniqueness of atoms
+  AtomIdSet atomIds; //<!set of atomic ids to check uniqueness of atoms
   IdPool<atomId_t, uniqueId> atomIdPool;  //!< pool of internal ids such that way may guarantee uniqueness
 
@@ -125,12 +114,43 @@
   World::AtomComposite getAtomSet() const;
 
-  iterator begin();
-  const_iterator begin() const;
-  iterator end();
-  const_iterator end() const;
-  bool empty() const;
-  size_t size() const;
-  const_iterator find(atom * key) const;
-  pair<iterator, bool> insert(atom * const key);
+  // simply pass on all functions to AtomIdSet
+  iterator begin() {
+    return atomIds.begin();
+  }
+  const_iterator begin() const
+  {
+    return atomIds.begin();
+  }
+  iterator end()
+  {
+    return atomIds.end();
+  }
+  const_iterator end() const
+  {
+    return atomIds.end();
+  }
+  bool empty() const
+  {
+    return atomIds.empty();
+  }
+  size_t size() const
+  {
+    return atomIds.size();
+  }
+  const_iterator find(atom * key) const
+  {
+    return atomIds.find(key);
+  }
+
+  /** Returns the set of atomic ids contained in this molecule.
+   *
+   * @return set of atomic ids
+   */
+  const atomIdSet & getAtomIds() const {
+    return atomIds.getAtomIds();
+  }
+
+  std::pair<iterator, bool> insert(atom * const key);
+
   bool containsAtom(atom* key);
 
@@ -145,4 +165,5 @@
    */
   const_iterator erase(const_iterator loc);
+
   /** Erase an atom from the list.
    * \note This should only be called by atom::removeFromMolecule(),
@@ -177,4 +198,9 @@
 
 public:
+
+  /** Function to create a bounding spherical shape for the currently associated atoms.
+   *
+   */
+  Shape getBoundingShape() const;
 
   /// remove atoms from molecule.
@@ -229,5 +255,5 @@
   bond * CopyBond(atom *left, atom *right, bond *CopyBond);
 
-  molecule *CopyMolecule() const;
+  molecule *CopyMolecule(const Vector &offset = zeroVec) const;
   molecule* CopyMoleculeFromSubRegion(const Shape&) const;
 
Index: src/unittests/AtomIdSetUnitTest.cpp
===================================================================
--- src/unittests/AtomIdSetUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/unittests/AtomIdSetUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+
+/*
+ * AtomIdSetUnitTest.cpp
+ *
+ *  Created on: Feb 21, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include <algorithm>
+
+#include "Atom/atom.hpp"
+#include "AtomIdSet.hpp"
+#include "CodePatterns/Assert.hpp"
+#include "World.hpp"
+
+#include "AtomIdSetUnitTest.hpp"
+
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+/********************************************** Test classes **************************************/
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( AtomIdSetUnittest );
+
+size_t AtomIdSetUnittest::MaxAtoms = 6;
+
+void AtomIdSetUnittest::setUp(){
+  // failing asserts should be thrown
+  ASSERT_DO(Assert::Throw);
+
+  atomVector.resize((size_t)MaxAtoms);
+  std::generate_n(atomVector.begin(), MaxAtoms,
+      boost::bind(&World::createAtom, boost::ref(World::getInstance())));
+}
+
+void AtomIdSetUnittest::tearDown()
+{
+  World::purgeInstance();
+}
+
+void AtomIdSetUnittest::inserteraseTest()
+{
+  // insert all
+  for (size_t i=0; i< MaxAtoms; ++i) {
+    atoms.insert(atomVector[i]);
+  }
+  CPPUNIT_ASSERT_EQUAL( (size_t)MaxAtoms, atoms.size() );
+
+  // erase them again
+  for (size_t i=0; i< MaxAtoms; ++i) {
+    atoms.erase(atomVector[i]);
+  }
+  CPPUNIT_ASSERT_EQUAL( (size_t)0, atoms.size() );
+
+  {
+    // use atomVector in cstor
+    AtomIdSet otherAtoms(atomVector);
+    CPPUNIT_ASSERT_EQUAL( (size_t)MaxAtoms, otherAtoms.size() );
+  }
+}
+
+void AtomIdSetUnittest::positionTest()
+{
+  // non-const iterators
+  CPPUNIT_ASSERT( atoms.begin() == atoms.end() );
+
+  // const iterators
+  {
+    AtomIdSet::const_iterator beg_iter = atoms.begin();
+    AtomIdSet::const_iterator end_iter = atoms.end();
+    CPPUNIT_ASSERT( beg_iter == end_iter );
+  }
+
+  // insert an element
+  atoms.insert(atomVector[0]);
+  CPPUNIT_ASSERT( atoms.begin() != atoms.end() );
+
+  {
+    AtomIdSet::const_iterator beg_iter = atoms.begin();
+    AtomIdSet::const_iterator end_iter = atoms.end();
+    CPPUNIT_ASSERT( beg_iter != end_iter );
+    ++beg_iter;
+    CPPUNIT_ASSERT( beg_iter == end_iter );
+  }
+}
+
+void AtomIdSetUnittest::findTest()
+{
+  // search for atom
+  atoms.insert(atomVector[0]);
+  CPPUNIT_ASSERT( atoms.find(atomVector[0]) == atoms.begin() );
+  CPPUNIT_ASSERT( atoms.find(atomVector[0]) != atoms.end() );
+  atoms.erase(atomVector[0]);
+
+  // search for key
+  atoms.insert(atomVector[0]->getId());
+  CPPUNIT_ASSERT( atoms.find(atomVector[0]->getId()) == atoms.begin() );
+  CPPUNIT_ASSERT( atoms.find(atomVector[0]->getId()) != atoms.end() );
+  atoms.erase(atomVector[0]->getId());
+}
+
+
+void AtomIdSetUnittest::emptyTest()
+{
+  // initially empty
+  CPPUNIT_ASSERT( atoms.empty() );
+
+  // filled with one then no more
+  atoms.insert(atomVector[0]);
+  CPPUNIT_ASSERT( !atoms.empty() );
+
+  // erase and again empty
+  atoms.erase(atomVector[0]);
+  CPPUNIT_ASSERT( atoms.empty() );
+}
+
+void AtomIdSetUnittest::sizeTest()
+{
+  // initially empty
+  CPPUNIT_ASSERT_EQUAL( (size_t)0, atoms.size() );
+
+  // filled with one, then no more
+  atoms.insert(atomVector[0]);
+  CPPUNIT_ASSERT_EQUAL( (size_t)1, atoms.size() );
+
+  // erase and again empty
+  atoms.erase(atomVector[0]);
+  CPPUNIT_ASSERT_EQUAL( (size_t)0, atoms.size() );
+}
+
Index: src/unittests/AtomIdSetUnitTest.hpp
===================================================================
--- src/unittests/AtomIdSetUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/unittests/AtomIdSetUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,52 @@
+/*
+ * AtomIdSetUnitTest.hpp
+ *
+ *  Created on: Feb 21, 2012
+ *      Author: heber
+ */
+
+#ifndef ATOMIDSETUNITTEST_HPP_
+#define ATOMIDSETUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <vector>
+
+class atom;
+
+#include "AtomIdSet.hpp"
+
+class AtomIdSetUnittest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( AtomIdSetUnittest );
+  CPPUNIT_TEST ( inserteraseTest );
+  CPPUNIT_TEST ( positionTest );
+  CPPUNIT_TEST ( findTest );
+  CPPUNIT_TEST ( emptyTest );
+  CPPUNIT_TEST ( sizeTest );
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+  void setUp();
+  void tearDown();
+
+  void inserteraseTest();
+  void positionTest();
+  void findTest();
+  void emptyTest();
+  void sizeTest();
+
+private:
+  std::vector<atom *> atomVector;
+  AtomIdSet atoms;
+
+  static size_t MaxAtoms;
+};
+
+#endif /* ATOMIDSETUNITTEST_HPP_ */
Index: src/unittests/Makefile.am
===================================================================
--- src/unittests/Makefile.am	(revision 22425a9c1deaa6c8fe8844c40fe08d87a46164b9)
+++ src/unittests/Makefile.am	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -12,4 +12,5 @@
 include ../../src/Descriptors/unittests/Makefile.am
 include ../../src/Element/unittests/Makefile.am
+include ../../src/Filling/unittests/Makefile.am
 include ../../src/Fragmentation/unittests/Makefile.am
 include ../../src/Graph/unittests/Makefile.am
@@ -28,8 +29,10 @@
 
 GENERALTESTS = \
+  AtomIdSetUnitTest \
   BoxUnitTest \
   Box_BoundaryConditionsTest \
   FormulaUnittest \
   ListOfBondsUnitTest \
+  MoleculeUnitTest \
   WorldTimeUnitTest
 
@@ -59,4 +62,5 @@
 
 ALLLIBS = \
+	../libMolecuilderFilling.la \
 	../libMolecuilderUI.la \
 	../libMolecuilder.la \
@@ -70,4 +74,5 @@
 	${DESCRIPTORTESTSSOURCES} \
 	${ELEMENTTESTSSOURCES} \
+	${FILLINGTESTSSOURCES} \
 	${FRAGMENTATIONTESTSSOURCES} \
 	${GRAPHTESTSSOURCES} \
@@ -81,8 +86,10 @@
 	${UIELEMENTSMENUTESTSSOURCES} \
 	stubs/ObserverStub.cpp \
+	AtomIdSetUnitTest.cpp \
   BoxUnitTest.cpp \
 	Box_BoundaryConditionsUnitTest.cpp \
   FormulaUnitTest.cpp \
   ListOfBondsUnitTest.cpp \
+  MoleculeUnitTest.cpp \
   WorldTimeUnitTest.cpp
 
@@ -92,4 +99,5 @@
 	${DESCRIPTORTESTSHEADERS} \
 	${ELEMENTTESTSHEADERS} \
+	${FILLINGTESTSHEADERS} \
 	${FRAGMENTATIONTESTSHEADERS} \
 	${GRAPHTESTSHEADERS} \
@@ -103,8 +111,10 @@
 	${UIELEMENTSMENUTESTSHEADERS} \
 	stubs/ObserverStub.hpp \
+	AtomIdSetUnitTest.hpp \
   BoxUnitTest.hpp \
 	Box_BoundaryConditionsUnitTest.hpp \
   FormulaUnitTest.hpp \
   ListOfBondsUnitTest.hpp \
+  MoleculeUnitTest.hpp \
   WorldTimeUnitTest.hpp
   
@@ -114,5 +124,7 @@
 	BoxUnitTest.hpp \
 	stubs/ObserverStub.cpp \
-	stubs/ObserverStub.hpp	
+	stubs/ObserverStub.hpp \
+	../Shapes/unittests/stubs/ApproximateShapeAreaStub.cpp \
+	../Shapes/unittests/stubs/ApproximateShapeVolumeStub.cpp
 BoxUnitTest_LDADD = \
 	../libMolecuilder.la \
@@ -120,4 +132,9 @@
 	../libMolecuilderHelpers.la \
 	$(top_builddir)/LinearAlgebra/src/LinearAlgebra/libLinearAlgebra.la
+
+AtomIdSetUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+	AtomIdSetUnitTest.cpp \
+	AtomIdSetUnitTest.hpp
+AtomIdSetUnitTest_LDADD =  $(ALLLIBS)
 
 Box_BoundaryConditionsTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
@@ -140,4 +157,12 @@
 ListOfBondsUnitTest_LDADD = $(ALLLIBS)
 
+MoleculeUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+	MoleculeUnitTest.cpp \
+	MoleculeUnitTest.hpp
+MoleculeUnitTest_LDADD = \
+	../libMolecuilderUI.la \
+	../libMolecuilder.la \
+	$(top_builddir)/LinearAlgebra/src/LinearAlgebra/libLinearAlgebra.la
+
 WorldTimeUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
 	WorldTimeUnitTest.cpp \
Index: src/unittests/MoleculeUnitTest.cpp
===================================================================
--- src/unittests/MoleculeUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/unittests/MoleculeUnitTest.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+/*
+ * MoleculeUnitTest.cpp
+ *
+ *  Created on: Mar 19, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include <algorithm>
+
+#include "Atom/atom.hpp"
+#include "CodePatterns/Assert.hpp"
+#include "Element/element.hpp"
+#include "Element/periodentafel.hpp"
+#include "molecule.hpp"
+
+#include "MoleculeUnitTest.hpp"
+
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+/********************************************** Test classes **************************************/
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( MoleculeUnittest );
+
+size_t MoleculeUnittest::MaxAtoms = 6;
+
+void MoleculeUnittest::setUp(){
+  // failing asserts should be thrown
+  ASSERT_DO(Assert::Throw);
+
+  atomVector.resize((size_t)MaxAtoms);
+  std::generate_n(atomVector.begin(), MaxAtoms,
+      boost::bind(&World::createAtom, boost::ref(World::getInstance())));
+  std::for_each(atomVector.begin(), atomVector.end(),
+      boost::bind(static_cast<void (AtomInfo::*)(int)>(&AtomInfo::setType), _1, (atomicNumber_t)1));
+
+  mol = new molecule;
+  std::for_each(atomVector.begin(), atomVector.end(),
+      boost::bind(&molecule::AddAtom, boost::ref(mol), _1));
+}
+
+void MoleculeUnittest::tearDown()
+{
+  delete mol;
+  World::purgeInstance();
+}
+
+/** Unit test for molecule::getBoundingShape() with a linear chain
+ *
+ */
+void MoleculeUnittest::getBoundingShapeTest_linearchain()
+{
+  // prepare a chain of atoms
+  double offset = 0.;
+  BOOST_FOREACH(atom *_atom, atomVector) {
+    _atom->setPosition( Vector(offset, 0., 0.) );
+    offset += 1.;
+  }
+
+  {
+    // get bounding shape
+    Shape s = mol->getBoundingShape();
+
+    // check that each atom is truely inside the shape
+    BOOST_FOREACH(atom *_atom, atomVector) {
+      CPPUNIT_ASSERT( s.isInside(_atom->getPosition()) );
+    }
+  }
+}
+
+/** Unit test for molecule::getBoundingShape() with a v-shaped molecule.
+ *
+ */
+void MoleculeUnittest::getBoundingShapeTest_vshaped()
+{
+  double xoffset = -2.5;
+  double yoffset = -2.5;
+  double yadder = -1;
+  BOOST_FOREACH(atom *_atom, atomVector) {
+    _atom->setPosition( Vector(xoffset, yoffset, 0.) );
+    xoffset += 1.;
+    yoffset -= yadder;
+    if (yoffset <= 0) {
+      yadder = 1.;
+    }
+  }
+
+  {
+    // get bounding shape
+    Shape s = mol->getBoundingShape();
+
+    // check that each atom is truely inside the shape
+    BOOST_FOREACH(atom *_atom, atomVector) {
+      CPPUNIT_ASSERT( s.isInside(_atom->getPosition()) );
+    }
+  }
+}
Index: src/unittests/MoleculeUnitTest.hpp
===================================================================
--- src/unittests/MoleculeUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/unittests/MoleculeUnitTest.hpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,45 @@
+/*
+ * MoleculeUnitTest.hpp
+ *
+ *  Created on: Mar 19, 2012
+ *      Author: heber
+ */
+
+#ifndef MOLECULEUNITTEST_HPP_
+#define MOLECULEUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <vector>
+
+class atom;
+class molecule;
+
+class MoleculeUnittest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( MoleculeUnittest );
+  CPPUNIT_TEST ( getBoundingShapeTest_linearchain );
+  CPPUNIT_TEST ( getBoundingShapeTest_vshaped );
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+  void setUp();
+  void tearDown();
+
+  void getBoundingShapeTest_linearchain();
+  void getBoundingShapeTest_vshaped();
+
+private:
+  std::vector<atom *> atomVector;
+  molecule *mol;
+
+  static size_t MaxAtoms;
+};
+
+#endif /* MOLECULEUNITTEST_HPP_ */
Index: src/unittests/stubs/AtomStub.cpp
===================================================================
--- src/unittests/stubs/AtomStub.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/unittests/stubs/AtomStub.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+/*
+ * AtomStub.cpp
+ *
+ *  Created on: Dec 22, 2011
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "Atom/atom.hpp"
+
+int atom::getNr() const {
+  return 0;
+}
Index: src/unittests/stubs/WorldStub.cpp
===================================================================
--- src/unittests/stubs/WorldStub.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
+++ src/unittests/stubs/WorldStub.cpp	(revision 510f8114d39633be815ec5bf2eb8bf42f5b30f6a)
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+/*
+ * WorldStub.cpp
+ *
+ *  Created on: Dec 22, 2011
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "World.hpp"
+
+#include "CodePatterns/Observer/Channels.hpp"
+#include "CodePatterns/Observer/Notification.hpp"
+#include "CodePatterns/Observer/ObservedContainer_impl.hpp"
+#include "CodePatterns/Singleton_impl.hpp"
+#include "Descriptors/AtomDescriptor.hpp"
+#include "Descriptors/AtomIdDescriptor_impl.hpp"
+
+#include "IdPool_impl.hpp"
+
+atom* World::_lastchangedatom = NULL;
+
+AtomDescriptor::AtomDescriptor(impl_ptr ptr)
+{}
+
+AtomDescriptor::~AtomDescriptor()
+{}
+
+atom * AtomById(unsigned int i)
+{
+  return NULL;
+}
+
+World::World() :
+    Observable("World"),
+    atoms(this),
+    selectedAtoms(this),
+    atomIdPool(0, 20, 100),
+    molecules(this),
+    selectedMolecules(this),
+    moleculeIdPool(0, 20,100)
+{
+  // observable stuff
+  Channels *OurChannel = new Channels;
+  NotificationChannels.insert( std::make_pair(this, OurChannel) );
+  // add instance for each notification type
+  OurChannel->addChannel(World::AtomInserted);
+  OurChannel->addChannel(World::AtomRemoved);
+}
+
+World::~World()
+{
+  // observable stuff
+  std::map<Observable *, Channels*>::iterator iter = NotificationChannels.find(this);
+  delete iter->second;
+  NotificationChannels.erase(iter);
+}
+
+atom* World::getAtom(AtomDescriptor descr)
+{
+  return NULL;
+}
+
+CONSTRUCT_SINGLETON(World);
