Index: src/Actions/FillAction/FillRegularGridAction.cpp
===================================================================
--- src/Actions/FillAction/FillRegularGridAction.cpp	(revision a090e3bbbb29271069f6efbe5ae41f0b9d0dcd57)
+++ src/Actions/FillAction/FillRegularGridAction.cpp	(revision 55736be799388502de9a57ac542d215e5ce0565a)
@@ -44,21 +44,9 @@
 #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 "Filling/Preparators/BoxFillerPreparator.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"
 
@@ -94,99 +82,75 @@
   filler->CenterEdge();
 
-  // check for selected atoms and create surfaces from them
-  std::vector<atom *> atoms(World::getInstance().getSelectedAtoms());
-  FillPredicate * surface_predicate = NULL;
-  LinkedCell_deprecated * LC = NULL;
-  Tesselation * TesselStruct = NULL;
+  // prepare the filler preparator
+  BoxFillerPreparator filler_preparator(filler);
   if (params.SphereRadius.get() != 0.) {
-    if ( atoms.size() == 0) {
+    if (World::getInstance().beginAtomSelection() == World::getInstance().endAtomSelection()) {
       STATUS("You have given a sphere radius "+toString(params.SphereRadius.get())
           +" != 0, but have not select any atoms.");
       return Action::failure;
     }
-    // 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.get());
-    TesselStruct = new Tesselation;
-    (*TesselStruct)(cloud, params.SphereRadius.get());
-
-    // and create predicate
-    surface_predicate = new FillPredicate( IsInsideSurface_FillPredicate( *TesselStruct, *LC ) );
-  }
-
-  // create predicate, mesh, and filler
+    std::vector<atom*> atoms(World::getInstance().getSelectedAtoms());
+    filler_preparator.addSurfacePredicate(
+        params.SphereRadius.get(),
+        atoms);
+  }
+  filler_preparator.addVoidPredicate(params.mindistance.get());
+  filler_preparator.addRandomInserter(
+      params.RandAtomDisplacement.get(),
+      params.RandMoleculeDisplacement.get(),
+      params.DoRotate.get());
+  filler_preparator.addCubeMesh(
+      params.counts.get(),
+      params.offset.get(),
+      World::getInstance().getDomain().getM());
+  if (!filler_preparator()) {
+    STATUS("Filler was not fully constructed.");
+    return Action::failure;
+  }
+
+  // use filler
+  bool successflag = false;
   FillRegularGridState *UndoState = NULL;
-  bool successflag = false;
   {
-    FillPredicate *voidnode_predicate = new FillPredicate(
-        IsVoidNode_FillPredicate(
-            Sphere(zeroVec, params.mindistance.get())
-            )
-        );
-    FillPredicate Andpredicate = (*voidnode_predicate);
-    if (surface_predicate != NULL)
-      Andpredicate = (Andpredicate) && !(*surface_predicate);
-    Mesh *mesh = new CubeMesh(params.counts.get(), params.offset.get(), World::getInstance().getDomain().getM());
-    Inserter *inserter = new Inserter(
-        Inserter::impl_ptr(
-            new RandomInserter(
-                params.RandAtomDisplacement.get(),
-                params.RandMoleculeDisplacement.get(),
-                params.DoRotate.get())
-            )
-        );
-
     // fill
-    {
-      Filler *fillerFunction = new Filler(*mesh, Andpredicate, *inserter);
-      // TODO: When molecule::getBoundingSphere() does not use a sphere anymore,
-      // we need to check whether we rotate the molecule randomly. For this to
-      // work we need a sphere!
-      const Shape s = filler->getBoundingSphere(params.RandAtomDisplacement.get());
-      ClusterInterface::Cluster_impl cluster( new Cluster(filler->getAtomIds(), s) );
-      CopyAtoms_withBonds copyMethod;
-      Filler::ClusterVector_t ClonedClusters;
-      successflag = (*fillerFunction)(copyMethod, cluster, ClonedClusters);
-      delete fillerFunction;
-
-      // append each cluster's atoms to clonedatoms (however not selected ones)
-      std::vector<const atom *> clonedatoms;
-      std::vector<AtomicInfo> clonedatominfos;
-      for (Filler::ClusterVector_t::const_iterator iter = ClonedClusters.begin();
-          iter != ClonedClusters.end(); ++iter) {
-        const AtomIdSet &atoms = (*iter)->getAtomIds();
-        clonedatoms.reserve(clonedatoms.size()+atoms.size());
-        for (AtomIdSet::const_iterator atomiter = atoms.begin(); atomiter != atoms.end(); ++atomiter)
-          if (!filler->containsAtom(*atomiter)) {
-            clonedatoms.push_back( *atomiter );
-            clonedatominfos.push_back( AtomicInfo(*(*atomiter)) );
-          }
-      }
-      std::vector< BondInfo > clonedbonds;
-      StoreBondInformationFromAtoms(clonedatoms, clonedbonds);
-      LOG(2, "DEBUG: There are " << clonedatominfos.size() << " newly created atoms.");
-
-      if (!successflag) {
-        STATUS("Insertion failed, removing inserted clusters, translating original one back");
-        RemoveAtomsFromAtomicInfo(clonedatominfos);
-        clonedatoms.clear();
-        SetAtomsFromAtomicInfo(movedatoms);
-      } else {
-        std::vector<Vector> MovedToVector(filler->size(), zeroVec);
-        std::transform(filler->begin(), filler->end(), MovedToVector.begin(),
-            boost::bind(&AtomInfo::getPosition, _1) );
-        UndoState = new FillRegularGridState(clonedatominfos,clonedbonds,movedatoms,MovedToVector,params);
-      }
+    Filler *fillerFunction = filler_preparator.obtainFiller();
+    // TODO: When molecule::getBoundingSphere() does not use a sphere anymore,
+    // we need to check whether we rotate the molecule randomly. For this to
+    // work we need a sphere!
+    const Shape s = filler->getBoundingSphere(params.RandAtomDisplacement.get());
+    ClusterInterface::Cluster_impl cluster( new Cluster(filler->getAtomIds(), s) );
+    CopyAtoms_withBonds copyMethod;
+    Filler::ClusterVector_t ClonedClusters;
+    successflag = (*fillerFunction)(copyMethod, cluster, ClonedClusters);
+    delete fillerFunction;
+
+    // append each cluster's atoms to clonedatoms (however not selected ones)
+    std::vector<const atom *> clonedatoms;
+    std::vector<AtomicInfo> clonedatominfos;
+    for (Filler::ClusterVector_t::const_iterator iter = ClonedClusters.begin();
+        iter != ClonedClusters.end(); ++iter) {
+      const AtomIdSet &atoms = (*iter)->getAtomIds();
+      clonedatoms.reserve(clonedatoms.size()+atoms.size());
+      for (AtomIdSet::const_iterator atomiter = atoms.begin(); atomiter != atoms.end(); ++atomiter)
+        if (!filler->containsAtom(*atomiter)) {
+          clonedatoms.push_back( *atomiter );
+          clonedatominfos.push_back( AtomicInfo(*(*atomiter)) );
+        }
     }
-
-    // remove
-    delete mesh;
-    delete inserter;
-    delete voidnode_predicate;
-    delete surface_predicate;
-    delete LC;
-    delete TesselStruct;
+    std::vector< BondInfo > clonedbonds;
+    StoreBondInformationFromAtoms(clonedatoms, clonedbonds);
+    LOG(2, "DEBUG: There are " << clonedatominfos.size() << " newly created atoms.");
+
+    if (!successflag) {
+      STATUS("Insertion failed, removing inserted clusters, translating original one back");
+      RemoveAtomsFromAtomicInfo(clonedatominfos);
+      clonedatoms.clear();
+      SetAtomsFromAtomicInfo(movedatoms);
+    } else {
+      std::vector<Vector> MovedToVector(filler->size(), zeroVec);
+      std::transform(filler->begin(), filler->end(), MovedToVector.begin(),
+          boost::bind(&AtomInfo::getPosition, _1) );
+      UndoState = new FillRegularGridState(clonedatominfos,clonedbonds,movedatoms,MovedToVector,params);
+    }
   }
 
