Index: src/FunctionApproximation/Extractors.cpp
===================================================================
--- src/FunctionApproximation/Extractors.cpp	(revision dbf8c8d003f93ca8d66a9d16660d7845c35ce59c)
+++ src/FunctionApproximation/Extractors.cpp	(revision caa00e9205bd9a094ecd605ffbf2f9685af58b83)
@@ -36,7 +36,9 @@
 #include "CodePatterns/MemDebug.hpp"
 
+#include <sstream>
 #include <utility>
 #include <vector>
 #include <boost/assign.hpp>
+#include <boost/foreach.hpp>
 
 #include "CodePatterns/Assert.hpp"
@@ -210,5 +212,5 @@
         chargeiter = ++tempiter;
       } else {
-        ELOG(1, "Could not find desired number of elements " << count << " in fragment.");
+        //ELOG(1, "Could not find desired number of elements " << count << " in fragment.");
         return Extractors::elementtargets_t();
       }
@@ -217,4 +219,43 @@
   return elementtargets;
 }
+
+Extractors::elementtargets_t
+Extractors::_detail::convertChargesToTargetMap(
+    const Fragment::charges_t& charges,
+    Fragment::charges_t elements
+    )
+{
+  // place each charge into a map
+  elementtargets_t completeelementtargets;
+  for (chargeiter_t chargeiter = charges.begin();
+      chargeiter != charges.end();
+      ++chargeiter) {
+    std::pair< elementtargets_t::iterator, bool> inserter =
+        completeelementtargets.insert( std::make_pair( *chargeiter, chargeiters_t(1, chargeiter)) );
+    // if already present, append to it
+    if (!inserter.second) {
+      inserter.first->second.push_back(chargeiter);
+    }
+  }
+  // pick out desired charges only
+  std::sort(elements.begin(), elements.end());
+  Fragment::charges_t::iterator eraseiter =
+      std::unique(elements.begin(), elements.end());
+  elements.erase(eraseiter, elements.end());
+  elementtargets_t elementtargets;
+  for(Fragment::charges_t::const_iterator iter = elements.begin();
+      iter != elements.end();
+      ++iter) {
+    elementtargets_t::const_iterator finditer = completeelementtargets.find(*iter);
+    ASSERT( finditer != completeelementtargets.end(),
+        "Extractors::_detail::convertChargesToTargetMap() - no element "+toString(*iter)+" present?");
+    std::pair< elementtargets_t::iterator, bool> inserter =
+        elementtargets.insert( std::make_pair( finditer->first, finditer->second) );
+    ASSERT( inserter.second,
+        "Extractors::_detail::convertChargesToTargetMap() - key twice?");
+  }
+  return elementtargets;
+}
+
 
 Extractors::chargeiters_t 
@@ -227,26 +268,159 @@
   chargeiters_t targets;
   elementcounts_t counts; // how many chargeiters of this element have been used
-  targets.reserve(elements.size());
-  for (Fragment::charges_t::const_iterator elementiter = elements.begin();
-      elementiter != elements.end(); ++elementiter) {
-    const element_t &element = *elementiter;
-    count_t &count = counts[element]; // if not present, std::map creates instances with default of 0
+  if (!elements.empty()) {  // skip if no elements given
+    targets.reserve(elements.size());
+    for (Fragment::charges_t::const_iterator elementiter = elements.begin();
+        elementiter != elements.end(); ++elementiter) {
+      const element_t &element = *elementiter;
+      count_t &count = counts[element]; // if not present, std::map creates instances with default of 0
 #ifndef NDEBUG
-    {
-      elementcounts_t::const_iterator testiter = elementcounts.find(element);
-      ASSERT( (testiter != elementcounts.end()) && (count < testiter->second),
-          "Extractors::_detail::realignElementTargets() - we want to use more chargeiters for element "
-          +toString(element)+" than we counted initially.");
-    }
+      {
+        elementcounts_t::const_iterator testiter = elementcounts.find(element);
+        ASSERT( (testiter != elementcounts.end()) && (count < testiter->second),
+            "Extractors::_detail::realignElementTargets() - we want to use more chargeiters for element "
+            +toString(element)+" than we counted initially.");
+      }
 #endif
-    elementtargets_t::const_iterator targetiter = elementtargets.find(element);
-    ASSERT (targetiter != elementtargets.end(),
-        "Extractors::_detail::realignElementTargets() - not enough chargeiters for element "
-        +toString(element)+".");
-    const chargeiters_t &chargeiters = targetiter->second;
-    const chargeiter_t &chargeiter = chargeiters[count++];
-    targets.push_back(chargeiter);
+      elementtargets_t::const_iterator targetiter = elementtargets.find(element);
+      if (targetiter != elementtargets.end()) {
+        const chargeiters_t &chargeiters = targetiter->second;
+        const chargeiter_t &chargeiter = chargeiters[count++];
+        targets.push_back(chargeiter);
+      }
+    }
   }
   return targets;
+}
+
+FunctionModel::arguments_t
+Extractors::gatherAllDistancesFromFragment(
+    const Fragment::positions_t& positions,
+    const Fragment::charges_t& charges,
+    const Fragment::charges_t elements,
+    const size_t globalid
+    )
+{
+  /// The main problem here is that we have to know how many same
+  /// elements (but different atoms!) we are required to find. Hence,
+  /// we first have to count same elements, then get different targets
+  /// for each and then associated them in correct order back again.
+
+  // 1. we have to place each charge into a map as unique chargeiter, i.e. map
+  elementtargets_t elementtargets =
+      Extractors::_detail::convertChargesToTargetMap(
+          charges,
+          elements);
+
+  // 2. now we have to combine elementcounts out of elementtargets per desired element
+  //    in a combinatorial fashion
+  targets_per_combination_t combinations =
+      Extractors::_detail::CombineChargesAndTargets(
+          elements,
+          elementtargets);
+
+  // 3. finally, convert chargeiters into argument list
+  FunctionModel::arguments_t args =
+      Extractors::_detail::convertTargetsToArguments(
+          positions,
+          charges,
+          combinations,
+          globalid);
+
+  return args;
+}
+
+Extractors::targets_per_combination_t
+Extractors::_detail::CombineChargesAndTargets(
+    const Fragment::charges_t& elements,
+    const elementtargets_t& elementtargets
+    )
+{
+  // recursively create all correct combinations of targets
+  targets_per_combination_t combinations;
+  chargeiters_t currenttargets;
+  boost::function<void (const chargeiters_t &currenttargets)> addFunction =
+      boost::bind(&targets_per_combination_t::push_back,
+          boost::ref(combinations),
+          _1);
+  pickLastElementAsTarget(elements, elementtargets, currenttargets, addFunction);
+
+  return combinations;
+}
+
+FunctionModel::arguments_t
+Extractors::_detail::convertTargetsToArguments(
+    const Fragment::positions_t& positions,
+    const Fragment::charges_t& charges,
+    const targets_per_combination_t combinations,
+    const size_t globalid
+    )
+{
+  FunctionModel::arguments_t args;
+  // create arguments from each combination
+  for (targets_per_combination_t::const_iterator iter = combinations.begin();
+      iter != combinations.end();
+      ++iter) {
+    Fragment::positions_t partpositions;
+    Fragment::charges_t partcharges;
+    partpositions.reserve(iter->size());
+    partcharges.reserve(iter->size());
+    for(chargeiters_t::const_iterator targetiter = iter->begin();
+        targetiter != iter->end();
+        ++targetiter) {
+      Fragment::positions_t::const_iterator positer = positions.begin();
+      std::advance(positer, std::distance(charges.begin(), *targetiter));
+      partpositions.push_back(*positer);
+      partcharges.push_back(**targetiter);
+    }
+    FunctionModel::arguments_t partargs =
+        gatherAllSymmetricDistanceArguments(partpositions, partcharges, globalid);
+    args.insert(args.end(), partargs.begin(), partargs.end());
+  }
+
+  return args;
+}
+
+void
+Extractors::_detail::pickLastElementAsTarget(
+    Fragment::charges_t elements,
+    elementtargets_t elementtargets,
+    chargeiters_t &currenttargets,
+    boost::function<void (const chargeiters_t &currenttargets)> &addFunction
+    )
+{
+  // get last element from charges
+  const Fragment::charge_t charge = elements.back();
+  elements.pop_back();
+  elementtargets_t::iterator iter = elementtargets.find(charge);
+  if (iter == elementtargets.end())
+    return;
+  bool NotEmpty = !iter->second.empty();
+  while (NotEmpty) {
+    // get last target from the vector of chargeiters
+    chargeiter_t target = iter->second.back();
+    iter->second.pop_back();
+    // remove this key if empty
+    if (iter->second.empty()) {
+      elementtargets.erase(iter);
+      NotEmpty = false;
+    }
+    currenttargets.push_back(target);
+    if (elements.empty()) {
+      // call add function
+      {
+        std::stringstream targetstream;
+        BOOST_FOREACH( chargeiter_t target, currenttargets ) {
+          targetstream << " " << *target;
+        }
+        LOG(3, "DEBUG: Adding set" << targetstream.str() << ".");
+      }
+      addFunction(currenttargets);
+    } else {
+      // if not, call us recursively
+      pickLastElementAsTarget(elements, elementtargets, currenttargets, addFunction);
+    }
+    // pop last in currenset again
+    currenttargets.pop_back();
+  }
 }
 
Index: src/FunctionApproximation/Extractors.hpp
===================================================================
--- src/FunctionApproximation/Extractors.hpp	(revision dbf8c8d003f93ca8d66a9d16660d7845c35ce59c)
+++ src/FunctionApproximation/Extractors.hpp	(revision caa00e9205bd9a094ecd605ffbf2f9685af58b83)
@@ -14,4 +14,6 @@
 #endif
 
+#include <boost/function.hpp>
+
 #include "Fragmentation/SetValues/Fragment.hpp"
 #include "FunctionApproximation/FunctionModel.hpp"
@@ -30,4 +32,5 @@
   typedef std::map< element_t, count_t> elementcounts_t;
   typedef std::map< element_t, chargeiters_t > elementtargets_t;
+  typedef std::vector< chargeiters_t > targets_per_combination_t;
 
   /** Namespace for some internal helper functions.
@@ -117,4 +120,59 @@
         const Fragment::charges_t& charges,
         const Fragment::charges_t elements
+        );
+
+    /** Brings all charges together in a map.
+     *
+     * @param charges charges as possible keys and their iterators as values in the map
+     * @param elements list of charges to pick as keys
+     * @return map of key and a vector of charge iterators
+     */
+    elementtargets_t convertChargesToTargetMap(
+        const Fragment::charges_t& charges,
+        Fragment::charges_t elements
+        );
+
+    /** Brings combinatorially together desired list of \a charges and \a targets.
+     *
+     * @param charges list of desired charges
+     * @param elementtargets map of available targets per element
+     * @return vector of chargeiters with all unique combinations
+     */
+    targets_per_combination_t
+    CombineChargesAndTargets(
+        const Fragment::charges_t& charges,
+        const elementtargets_t& elementtargets
+        );
+
+    /** Recursive function to pick the next target.
+     *
+     * This is used by \sa CombineChargesAndTargets()
+     *
+     * @param charges set of charges, reduced by one per recursion
+     * @param elementtargets targets, map of targets to pick from
+     * @param currenttargets current set of targets, "global" through recursion
+     * @param addFunction bound function to add a set when complete
+     */
+    void pickLastElementAsTarget(
+        Fragment::charges_t elements,
+        elementtargets_t elementtargets,
+        chargeiters_t& currenttargets,
+        boost::function<void (const chargeiters_t &currenttargets)> &addFunction
+        );
+
+    /** Converts a list of chargeiters to a list of respective arguments.
+     *
+     * @param positions positions from fragment
+     * @param charges charges associated to each element in \a positions
+     * @param combinations vector of chargeiters
+     * \param globalid refers to the index within the global set of configurations
+     * @return list of arguments
+     */
+    FunctionModel::arguments_t
+    convertTargetsToArguments(
+        const Fragment::positions_t& positions,
+        const Fragment::charges_t& charges,
+        const targets_per_combination_t combinations,
+        const size_t globalid
         );
   }
@@ -199,4 +257,5 @@
    * \param charges all nuclei charges
    * \param elements tuple of desired elements
+   * \param globalid refers to the index within the global set of configurations
    * \return vector of arguments_t containing those matched with elements
    */
@@ -208,4 +267,25 @@
       );
 
+  /** Gather all combinations of charges as distance arguments from the fragment.
+   *
+   * E.g. we have a water fragment, i.e. (8,1,1) and we we want elements (8,1),
+   * then two arguments are returned, first to second and first to third.
+   *
+   * With \sa gatherDistancesFromFragment() only the first distance would be
+   * returned.
+   *
+   * @param positions positions in fragment
+   * @param charges charges in fragment
+   * @param elements list of desired elements
+   * @param globalid some global id to discern training data tuples
+   * @return list of arguments with distances
+   */
+  FunctionModel::arguments_t gatherAllDistancesFromFragment(
+      const Fragment::positions_t& positions,
+      const Fragment::charges_t& charges,
+      const Fragment::charges_t elements,
+      const size_t globalid
+      );
+
   /** Reorder arguments by increasing distance.
    *
