Index: src/Actions/FragmentationAction/FragmentationAutomationAction.cpp
===================================================================
--- src/Actions/FragmentationAction/FragmentationAutomationAction.cpp	(revision a0f8d32c46a65add52f2d4294ddba66aa2b50eac)
+++ src/Actions/FragmentationAction/FragmentationAutomationAction.cpp	(revision 358ddb37ffa1a42ccb292d081c67a06b75b91005)
@@ -60,4 +60,6 @@
 #include "Fragmentation/Summation/AllLevelOrthogonalSummator.hpp"
 #include "Fragmentation/Summation/AllLevelSummator.hpp"
+#include "Fragmentation/Summation/OrthogonalFullSummator.hpp"
+#include "Fragmentation/Summation/OrthogonalSummation.hpp"
 #include "Fragmentation/Summation/writeTable.hpp"
 #include "Graph/DepthFirstSearchAnalysis.hpp"
@@ -70,4 +72,8 @@
 #ifdef HAVE_VMG
 #include "Jobs/VMGJob.hpp"
+#include "Jobs/VMGData.hpp"
+#include "Jobs/VMGDataFused.hpp"
+#include "Jobs/VMGDataMap.hpp"
+#include "Jobs/VMGData_printKeyNames.hpp"
 #endif
 #include "molecule.hpp"
@@ -336,4 +342,22 @@
 }
 
+template <>
+void convertDataTo<VMGData, VMGDataMap_t>(
+    const std::vector<VMGData> &longrangeData,
+    std::vector<VMGDataMap_t> &VMGData_fused)
+{
+  // energy_t
+  VMGData_fused.clear();
+  VMGData_fused.reserve(longrangeData.size());
+  for(std::vector<VMGData>::const_iterator dataiter = longrangeData.begin();
+      dataiter != longrangeData.end(); ++dataiter) {
+    const VMGData &extractedData = *dataiter;
+    LOG(2, "DEBUG: Current extracted Data is " << extractedData << ".");
+    VMGDataMap_t instance;
+    boost::fusion::at_key<VMGDataFused::sampled_potential>(instance) = extractedData.sampled_potential;
+    boost::fusion::at_key<VMGDataFused::energy_long>(instance) = extractedData.e_long;
+    VMGData_fused.push_back(instance);
+  }
+}
 
 void convertMPQCDatatoForceMap(
@@ -432,4 +456,30 @@
   // instantiate summator
   std::vector<TypeMap> Result_fused(subsetmap->getMaximumSubsetLevel());
+  AllLevelSummator<TypeMap> Summer(
+              subsetmap,
+              MPQCData_fused,
+              jobids,
+              container->getContainer(),
+              MatrixNrLookup,
+              Result_fused);
+  // sum up for each type key in TypeVector
+  boost::mpl::for_each<TypeVector>(boost::ref(Summer));
+  return Result_fused;
+}
+
+template <typename TypeMap, typename TypeVector>
+std::vector<TypeMap> OrthogonalSumUpPerLevel(
+    const std::vector<MPQCData> &fragmentData,
+    const std::vector<JobId_t> &jobids,
+    std::map< JobId_t, size_t > &MatrixNrLookup,
+    const IndexSetContainer::ptr &container,
+    SubsetMap::ptr &subsetmap
+    )
+{
+  // place data into boost::fusion::map instance
+  std::vector<TypeMap> MPQCData_fused;
+  convertDataTo<MPQCData, TypeMap>(fragmentData, MPQCData_fused);
+  // instantiate summator
+  std::vector<TypeMap> Result_fused(subsetmap->getMaximumSubsetLevel());
   AllLevelOrthogonalSummator<TypeMap> Summer(
               subsetmap,
@@ -489,8 +539,8 @@
   /// convert all MPQCData to MPQCDataMap_t
   std::vector<MPQCDataGridMap_t> Result_Grid_fused(
-    SumUpPerLevel<MPQCDataGridMap_t, MPQCDataGridVector_t>(
+    OrthogonalSumUpPerLevel<MPQCDataGridMap_t, MPQCDataGridVector_t>(
         fragmentData, jobids, MatrixNrLookup, container, subsetmap));
   std::vector<MPQCDataFragmentMap_t> Result_Fragment_fused(
-    SumUpPerLevel<MPQCDataFragmentMap_t, MPQCDataFragmentVector_t>(
+    OrthogonalSumUpPerLevel<MPQCDataFragmentMap_t, MPQCDataFragmentVector_t>(
         fragmentData, jobids, MatrixNrLookup, container, subsetmap));
   // obtain full grid
@@ -567,9 +617,10 @@
         "FragmentationAutomationAction::performCall() - ForceKeySet's KeySets and fragmentData differ in size.");
 
+    typedef boost::mpl::remove<MPQCDataEnergyVector_t, MPQCDataFused::energy_eigenvalues>::type MPQCDataEnergyVector_noeigenvalues_t;
     std::vector<MPQCDataEnergyMap_t> Result_Energy_fused(
-        SumUpPerLevel<MPQCDataEnergyMap_t, MPQCDataEnergyVector_t>(
+        OrthogonalSumUpPerLevel<MPQCDataEnergyMap_t, MPQCDataEnergyVector_t>(
             fragmentData, jobids, MatrixNrLookup, container, subsetmap));
     std::vector<MPQCDataGridMap_t> Result_Grid_fused(
-      SumUpPerLevel<MPQCDataGridMap_t, MPQCDataGridVector_t>(
+      OrthogonalSumUpPerLevel<MPQCDataGridMap_t, MPQCDataGridVector_t>(
           fragmentData, jobids, MatrixNrLookup, container, subsetmap));
     std::vector<MPQCDataTimeMap_t> Result_Time_fused(
@@ -595,5 +646,4 @@
     // print tables (without eigenvalues, they go extra)
     const size_t MaxLevel = subsetmap->getMaximumSubsetLevel();
-    typedef boost::mpl::remove<MPQCDataEnergyVector_t, MPQCDataFused::energy_eigenvalues>::type MPQCDataEnergyVector_noeigenvalues_t;
     const std::string energyresult =
         writeTable<MPQCDataEnergyMap_t, MPQCDataEnergyVector_noeigenvalues_t >()(
@@ -648,4 +698,140 @@
   }
   LOG(1, "INFO: Resulting forces are " << std::endl << output.str());
+
+  return true;
+}
+
+/** Print MPQCData from received results.
+ *
+ * @param fragmentresults results with short-range job ids to associate with fragment number
+ * @param longrangeresults results with long-range job ids to associate with fragment number
+ * @param fragmentData MPQCData resulting from the jobs
+ * @param longrangeData VMGData resulting from long-range jobs
+ * @param KeySetFilename filename with keysets to associate forces correctly
+ * @param NoAtoms total number of atoms
+ * @param full_sample summed up charge from fragments on return
+ */
+bool printReceivedFullResults(
+    const std::vector<FragmentResult::ptr> &fragmentresults,
+    const std::vector<FragmentResult::ptr> &longrangeresults,
+    const std::vector<MPQCData> &fragmentData,
+    const std::vector<VMGData> &longrangeData,
+    const std::string &KeySetFilename,
+    size_t NoAtoms,
+    SamplingGrid &full_sample)
+{
+  // create lookup from job nr to fragment number
+  std::map< JobId_t, size_t > MatrixNrLookup;
+  size_t FragmentCounter = 0;
+  createMatrixNrLookup(fragmentresults, MatrixNrLookup, FragmentCounter);
+  std::map< JobId_t, size_t > extraMatrixNrLookup;
+  size_t extraFragmentCounter = 0;
+  createMatrixNrLookup(longrangeresults, extraMatrixNrLookup, extraFragmentCounter);
+
+  // initialise keysets
+  KeySetsContainer KeySet;
+  KeySetsContainer ForceKeySet;
+  {
+    // else needs keysets without hydrogens
+    std::stringstream filename;
+    filename << FRAGMENTPREFIX << KEYSETFILE;
+    if (!KeySet.ParseKeySets(KeySetFilename, filename.str(), FragmentCounter)) return false;
+  }
+
+  {
+    // forces need keysets including hydrogens
+    std::stringstream filename;
+    filename << FRAGMENTPREFIX << FORCESFILE;
+    if (!ForceKeySet.ParseKeySets(KeySetFilename, filename.str(), FragmentCounter)) return false;
+  }
+
+  /// prepare for OrthogonalSummation
+
+  // convert KeySetContainer to IndexSetContainer
+  IndexSetContainer::ptr container(new IndexSetContainer(KeySet));
+  // create the map of all keysets
+  SubsetMap::ptr subsetmap(new SubsetMap(*container));
+
+  // create a vector of all job ids from short-range
+  std::vector<JobId_t> jobids(fragmentresults.size(), JobId::IllegalJob);
+  std::transform(fragmentresults.begin(), fragmentresults.end(), jobids.begin(),
+      boost::bind(&FragmentResult::getId,
+          boost::bind(&FragmentResult::ptr::operator->, _1)));
+  // create a vector of all job ids from long-range
+  std::vector<JobId_t> extrajobids(longrangeresults.size(), JobId::IllegalJob);
+  std::transform(longrangeresults.begin(), longrangeresults.end(), extrajobids.begin(),
+      boost::bind(&FragmentResult::getId,
+          boost::bind(&FragmentResult::ptr::operator->, _1)));
+
+  /// convert all MPQCData to MPQCDataMap_t
+  {
+    typedef boost::mpl::remove<MPQCDataEnergyVector_t, MPQCDataFused::energy_eigenvalues>::type MPQCDataEnergyVector_noeigenvalues_t;
+    std::vector<MPQCDataEnergyMap_t> Result_Energy_fused(
+        OrthogonalSumUpPerLevel<MPQCDataEnergyMap_t, MPQCDataEnergyVector_t>(
+            fragmentData, jobids, MatrixNrLookup, container, subsetmap));
+    std::vector<MPQCDataGridMap_t> Result_Grid_fused(
+      OrthogonalSumUpPerLevel<MPQCDataGridMap_t, MPQCDataGridVector_t>(
+          fragmentData, jobids, MatrixNrLookup, container, subsetmap));
+    std::vector<MPQCDataTimeMap_t> Result_Time_fused(
+      SumUpPerLevel<MPQCDataTimeMap_t, MPQCDataTimeVector_t>(
+          fragmentData, jobids, MatrixNrLookup, container, subsetmap));
+
+    // force has extra converter
+    std::vector<MPQCDataForceMap_t> MPQCData_Force_fused;
+    convertMPQCDatatoForceMap(fragmentData, ForceKeySet, MPQCData_Force_fused);
+    std::vector<MPQCDataForceMap_t> Result_Force_fused(subsetmap->getMaximumSubsetLevel());
+    AllLevelOrthogonalSummator<MPQCDataForceMap_t> forceSummer(
+                subsetmap,
+                MPQCData_Force_fused,
+                jobids,
+                container->getContainer(),
+                MatrixNrLookup,
+                Result_Force_fused);
+    boost::mpl::for_each<MPQCDataForceVector_t>(boost::ref(forceSummer));
+
+    // obtain full grid
+    std::vector<VMGDataMap_t> VMGData_Potential_fused;
+    convertDataTo<VMGData, VMGDataMap_t>(longrangeData, VMGData_Potential_fused);
+    OrthogonalFullSummator<VMGDataMap_t, VMGDataFused::sampled_potential> potentialSummer(
+                subsetmap,
+                VMGData_Potential_fused,
+                extrajobids,
+                container->getContainer(),
+                extraMatrixNrLookup);
+    potentialSummer(subsetmap->getMaximumSubsetLevel());
+    full_sample = potentialSummer.getFullContribution();
+    LOG(0, "Remaining long-range energy from potential integral is " << full_sample.integral() << ".");
+
+    OrthogonalFullSummator<VMGDataMap_t, VMGDataFused::energy_long> elongSummer(
+                subsetmap,
+                VMGData_Potential_fused,
+                extrajobids,
+                container->getContainer(),
+                extraMatrixNrLookup);
+    elongSummer(subsetmap->getMaximumSubsetLevel());
+    const double e_long = elongSummer.getFullContribution();
+    LOG(0, "Remaining long-range energy is " << e_long << ".");
+
+    // print tables (without eigenvalues, they go extra)
+    const size_t MaxLevel = subsetmap->getMaximumSubsetLevel();
+    const std::string energyresult =
+        writeTable<MPQCDataEnergyMap_t, MPQCDataEnergyVector_noeigenvalues_t >()(
+            Result_Energy_fused, MaxLevel);
+    LOG(0, "Energy table is \n" << energyresult);
+    const std::string eigenvalueresult;
+
+    LOG(0, "Eigenvalue table is \n" << eigenvalueresult);
+    const std::string forceresult =
+        writeTable<MPQCDataForceMap_t, MPQCDataForceVector_t>()(
+            Result_Force_fused, MaxLevel);
+    LOG(0, "Force table is \n" << forceresult);
+    // we don't want to print grid to a table
+    // print times (without flops for now)
+    typedef boost::mpl::remove<MPQCDataTimeVector_t, MPQCDataFused::times_flops>::type MPQCDataTimeVector_noflops_t;
+    const std::string timesresult =
+        writeTable<MPQCDataTimeMap_t, MPQCDataTimeVector_noflops_t >()(
+            Result_Time_fused, MaxLevel);
+    LOG(0, "Times table is \n" << timesresult);
+  }
 
   return true;
@@ -819,4 +1005,21 @@
       "FragmentationFragmentationAutomationAction::performCall() - number of MPQCresultd and VMGresults don't match.");
 
+  std::vector<VMGData> longrangeData;
+  ConvertFragmentResultTo<VMGData>(VMGresults, longrangeData);
+
+  // Final phase: print result
+  {
+    LOG(1, "INFO: Parsing fragment files from " << params.path.get() << ".");
+    printReceivedFullResults(
+        MPQCresults,
+        VMGresults,
+        fragmentData,
+        longrangeData,
+        params.path.get(),
+        getNoAtomsFromAdjacencyFile(params.path.get()),
+        full_sample);
+  }
+  }
+#else
   // Final phase: print result
   {
@@ -829,5 +1032,4 @@
         full_sample);
   }
-  }
 #endif
   size_t Exitflag = controller.getExitflag();
Index: src/Fragmentation/Summation/Makefile.am
===================================================================
--- src/Fragmentation/Summation/Makefile.am	(revision a0f8d32c46a65add52f2d4294ddba66aa2b50eac)
+++ src/Fragmentation/Summation/Makefile.am	(revision 358ddb37ffa1a42ccb292d081c67a06b75b91005)
@@ -13,4 +13,5 @@
 	Fragmentation/Summation/IndexSet.hpp \
 	Fragmentation/Summation/IndexSetContainer.hpp \
+	Fragmentation/Summation/OrthogonalFullSummator.hpp \
 	Fragmentation/Summation/OrthogonalSummation.hpp \
 	Fragmentation/Summation/OrthogonalSummation_impl.hpp \
Index: src/Fragmentation/Summation/OrthogonalFullSummator.hpp
===================================================================
--- src/Fragmentation/Summation/OrthogonalFullSummator.hpp	(revision 358ddb37ffa1a42ccb292d081c67a06b75b91005)
+++ src/Fragmentation/Summation/OrthogonalFullSummator.hpp	(revision 358ddb37ffa1a42ccb292d081c67a06b75b91005)
@@ -0,0 +1,140 @@
+/*
+ * OrthogonalFullSummator.hpp
+ *
+ *  Created on: 08.09.2012
+ *      Author: heber
+ */
+
+#ifndef ORTHOGONALFULLSUMMATOR_HPP_
+#define ORTHOGONALFULLSUMMATOR_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <boost/fusion/sequence.hpp>
+
+#include "Fragmentation/Summation/OrthogonalSummation.hpp"
+#include "Fragmentation/Summation/SetValue.hpp"
+#include "Jobs/MPQCDataMap.hpp"
+
+/** OrthogonalFullSummator is a general class for making us of OrthogonalSummation.
+ *
+ *
+ * This class is very similar to OrthogonalSummation only that we specifically include
+ * the full set (with a value!) as well. Also there is a function to obtain the
+ * contribution. This is intended to check a full calculation against the truncated
+ * sum.
+ */
+template <typename MapType, typename MapKey>
+struct OrthogonalFullSummator {
+  /** We retrieve the type of the MPQCData member variable from the
+   * boost::fusion::map and stored it in this typedef. Note that for
+   * internal types (e.g. MapValue::const_iterator we need to place
+   * \b typename before).
+   */
+  typedef typename boost::fusion::result_of::value_at_key<MapType, MapKey>::type MapValue;
+
+  /** Constructor for class OrthogonalFullSummator.
+   *
+   * \param _subsetmap map with hierarchy of IndexSet's
+   * \param _data MPQCData converted to MPQCDataMap_t type
+   * \param _jobids job ids to sum data in correct order
+   * \param _container container of IndexSet's such that each set has correct order
+   *        to job id and hence to _data.
+   * \param _MatrixNrLookup lookup from job id to ordering in above vectors
+   */
+  OrthogonalFullSummator(
+      SubsetMap::ptr &_subsetmap,
+      const std::vector<MapType> &_data,
+      const std::vector<JobId_t> &_jobids,
+      const IndexSetContainer::Container_t &_container,
+      std::map< JobId_t, size_t > &_MatrixNrLookup) : /* cannot make this const due to operator[] */
+    indices(getSubsets(_container)),
+    values(createValues(_data, _jobids, _container, _MatrixNrLookup)),
+    OS(indices, values, _subsetmap)
+  {
+    ASSERT( _data.size() == _container.size(),
+        "OrthogonalFullSummator() - data and indices don't have same size.");
+    ASSERT( _data.size() == _jobids.size(),
+        "OrthogonalFullSummator() - data and ids don't have same size.");
+    ASSERT( _jobids.size() == _MatrixNrLookup.size(),
+        "OrthogonalFullSummator() - ids and MatrixNrLookup don't have same size.");
+  }
+
+  /** Summation operator.
+   *
+   * Initialises instantiated OrthogonalSummation of the respective type via
+   * \a OrthogonalFullSummator::data, uses OrthogonalSummation::operator() to sum and returns
+   * the result.
+   *
+   * \param level up to which level to sum up
+   * \return result of OrthogonalSummation for given type from MPQCDataMap_t.
+   */
+  MapValue operator()(const size_t level)
+  {
+    // evaluate
+    const MapValue result = OS(level);
+    return result;
+  }
+
+  /** Getter for the remaining contribution of the full set.
+   *
+   * @return contribution of allindices
+   */
+  MapValue getFullContribution() const {
+    typename SetValueMap<MapValue>::const_iterator iter = --OS.getSetValues().end();
+    return iter->second->getContribution();
+  }
+
+private:
+  /** Tiny helper to create the indices from a given IndexSetContainer.
+   *
+   * @param container container with IndexSet
+   * @return all subsets contained in \a container
+   */
+  typename OrthogonalSummation<MapValue>::InputSets_t getSubsets(
+      const IndexSetContainer::Container_t &container)
+  {
+    typename OrthogonalSummation<MapValue>::InputSets_t indices(
+        container.begin(),
+        container.end());
+    return indices;
+  }
+
+  /** Tiny helper to create the values for the summation in the correct order.
+   *
+   * @param data
+   * @param jobids
+   * @param container
+   * @param MatrixNrLookup
+   * @return
+   */
+  typename OrthogonalSummation<MapValue>::InputValues_t createValues(
+      const std::vector<MapType> &data,
+      const std::vector<JobId_t> &jobids,
+      const IndexSetContainer::Container_t &container,
+      std::map< JobId_t, size_t > &MatrixNrLookup)
+  {
+    typename OrthogonalSummation<MapValue>::InputValues_t values(container.size());
+    typename std::vector<MapType>::const_iterator dataiter = data.begin();
+    std::vector<size_t>::const_iterator iditer = jobids.begin();
+    for (; dataiter != data.end(); ++dataiter, ++iditer) {
+      const MapType &Data = *dataiter;
+      const MapValue &value = boost::fusion::at_key<MapKey>(Data);
+      values[ MatrixNrLookup[*iditer] ] = value;
+    }
+    return values;
+  }
+private:
+  //!> created indices for OS such that we may hand over refs
+  typename OrthogonalSummation<MapValue>::InputSets_t indices;
+  //!> created values for OS such that we may hand over refs
+  typename OrthogonalSummation<MapValue>::InputValues_t values;
+  //!> Summation instance to use in operator()(level)
+  OrthogonalSummation<MapValue> OS;
+};
+
+
+#endif /* ORTHOGONALFULLSUMMATOR_HPP_ */
Index: src/Jobs/Makefile.am
===================================================================
--- src/Jobs/Makefile.am	(revision a0f8d32c46a65add52f2d4294ddba66aa2b50eac)
+++ src/Jobs/Makefile.am	(revision 358ddb37ffa1a42ccb292d081c67a06b75b91005)
@@ -24,4 +24,7 @@
 	Jobs/InterfaceVMGJob.hpp \
 	Jobs/VMGData.hpp \
+  Jobs/VMGDataFused.hpp \
+  Jobs/VMGDataMap.hpp \
+  Jobs/VMGData_printKeyNames.hpp \
 	Jobs/VMGJob.hpp
 endif
Index: src/Jobs/VMGDataFused.hpp
===================================================================
--- src/Jobs/VMGDataFused.hpp	(revision 358ddb37ffa1a42ccb292d081c67a06b75b91005)
+++ src/Jobs/VMGDataFused.hpp	(revision 358ddb37ffa1a42ccb292d081c67a06b75b91005)
@@ -0,0 +1,33 @@
+/*
+ * VMGDataFused.hpp
+ *
+ *  Created on: Aug 8, 2012
+ *      Author: heber
+ */
+
+#ifndef VMGDATAFUSED_HPP_
+#define VMGDATAFUSED_HPP_
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/** This namespace contains a key for each data member in MPQCData.
+ *
+ * We need these keys as enumeration of the data members to allow
+ * generic algorithms to work on it.
+ *
+ * \note forward declarations are not enough as we need the true (but empty)
+ * instance when going throughb the list with boost::mpl::for_each.
+ */
+namespace VMGDataFused {
+  // keys for sampled_potential
+  struct sampled_potential {};
+  struct energy_long {};
+}
+
+
+
+#endif /* VMGDATAFUSED_HPP_ */
Index: src/Jobs/VMGDataMap.hpp
===================================================================
--- src/Jobs/VMGDataMap.hpp	(revision 358ddb37ffa1a42ccb292d081c67a06b75b91005)
+++ src/Jobs/VMGDataMap.hpp	(revision 358ddb37ffa1a42ccb292d081c67a06b75b91005)
@@ -0,0 +1,42 @@
+/*
+ * VMGDataMap.hpp
+ *
+ *  Created on: Aug 8, 2012
+ *      Author: heber
+ */
+
+#ifndef VMGDATAMAP_HPP_
+#define VMGDATAMAP_HPP_
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <boost/fusion/container/map.hpp>
+#include <boost/mpl/list.hpp>
+
+#include "Jobs/VMGDataFused.hpp"
+
+class SamplingGrid;
+
+/** This boost::fusion map defines key-value or rather key-type pairs with
+ * which we associate all sampled_grid data members in VMGData and their type.
+ *
+ * This lets us resolves any ambiguitites of types in VMGData, e.g.
+ * to know vector<double> is forces or energy_eigenvalues.
+ *
+ */
+typedef boost::fusion::map<
+    boost::fusion::pair<VMGDataFused::sampled_potential, SamplingGrid >,
+    boost::fusion::pair<VMGDataFused::energy_long, double >
+> VMGDataMap_t;
+
+typedef boost::mpl::list<
+    VMGDataFused::sampled_potential,
+    VMGDataFused::energy_long
+> VMGDataVector_t;
+
+
+#endif /* VMGDATAMAP_HPP_ */
Index: src/Jobs/VMGData_printKeyNames.hpp
===================================================================
--- src/Jobs/VMGData_printKeyNames.hpp	(revision 358ddb37ffa1a42ccb292d081c67a06b75b91005)
+++ src/Jobs/VMGData_printKeyNames.hpp	(revision 358ddb37ffa1a42ccb292d081c67a06b75b91005)
@@ -0,0 +1,68 @@
+/*
+ * VMGData_printKeyNames.hpp
+ *
+ *  Created on: 08.08.2012
+ *      Author: heber
+ */
+
+#ifndef VMGDATA_PRINTKEYNAMES_HPP_
+#define VMGDATA_PRINTKEYNAMES_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+//#include <iosfwd>
+#include <string>
+
+#include <boost/preprocessor/iteration/local.hpp>
+#include <boost/preprocessor/seq/elem.hpp>
+#include <boost/preprocessor/seq/seq.hpp>
+#include <boost/preprocessor/seq/size.hpp>
+#include <boost/preprocessor/stringize.hpp>
+
+/** this is the boost::preprocessor::sequence of the keys in the boost::fusion::map
+ *
+ * Basically, every key appears here in brackets. If so, then the preprocessor magic
+ * below will create a template specialization of the printName() function in the
+ * namespace printKeyNames.
+ */
+#define tokensequence \
+	(sampled_potential) \
+  (energy_long)
+
+/// we take note of the number of keys in tokensequence as (local) loop bounds below
+#ifndef tokensequence
+#define MAXTOKENS 0
+#else
+#define MAXTOKENS BOOST_PP_SEQ_SIZE(tokensequence)
+#endif
+
+//!> this is the macro function which prints the specialized template function
+#define printName_specializer(z, n, NAMESPACE, TOKENSEQ, NAMESEQ ) \
+  template<> std::string printName< NAMESPACE :: BOOST_PP_SEQ_ELEM( n, TOKENSEQ ) >() { \
+    return std::string( BOOST_PP_STRINGIZE( BOOST_PP_SEQ_ELEM( n, NAMESEQ ) ) ); \
+  }
+
+/** Specific namespace for all the specialized template functions that print
+ * a useful name for each of the boost::fusion::map key.
+ */
+namespace printKeyNames {
+  /* iterate (line-wise) over the sequence and spill out a specialized printName
+   * for each member in the boost::fusion::map.
+   */
+#if defined tokensequence && defined MAXTOKENS && defined printName_specializer
+#define BOOST_PP_LOCAL_MACRO(n) printName_specializer(~, n, VMGDataFused, tokensequence, tokensequence)
+#define BOOST_PP_LOCAL_LIMITS  (0, MAXTOKENS-1)
+#include BOOST_PP_LOCAL_ITERATE()
+#endif
+
+}; /* namespace printKeyNames */
+
+#undef tokensequence
+#undef printName_specializer
+
+#undef MAXTOKENS
+
+#endif /* VMGDATA_PRINTKEYNAMES_HPP_ */
