Index: src/Actions/FragmentationAction/FragmentationAutomationAction.cpp
===================================================================
--- src/Actions/FragmentationAction/FragmentationAutomationAction.cpp	(revision 995e2f630769a5f3b1bfaa3010c8e6eb0e1f0a9e)
+++ src/Actions/FragmentationAction/FragmentationAutomationAction.cpp	(revision c9f9bbb2d96080528233d702e81243480b34033d)
@@ -40,4 +40,5 @@
 
 #include <boost/mpl/remove.hpp>
+#include <boost/lambda/lambda.hpp>
 
 #include "CodePatterns/Assert.hpp"
@@ -173,9 +174,8 @@
 void ConvertFragmentResultTo(
     const std::vector<FragmentResult::ptr> &results,
-    std::vector<T> &fragmentData)
+    std::map<JobId_t, T> &fragmentData)
 {
   // extract results
   fragmentData.clear();
-  fragmentData.reserve(results.size());
 
   LOG(2, "DEBUG: Parsing now through " << results.size() << " results.");
@@ -189,5 +189,5 @@
     ia >> extractedData;
     LOG(1, "INFO: extracted data is " << extractedData << ".");
-    fragmentData.push_back(extractedData);
+    fragmentData.insert( std::make_pair( (*iter)->getId(), extractedData) );
   }
 
@@ -225,5 +225,4 @@
 /** Place results from FragmentResult into EnergyMatrix and ForceMatrix.
  *
- * @param jobids jobids with ids to associate with fragment number
  * @param fragmentData MPQCData resulting from the jobs
  * @param MatrixNrLookup Lookup up-map from job id to fragment number
@@ -235,6 +234,5 @@
  */
 bool putResultsintoMatrices(
-    const std::vector<JobId_t> &jobids,
-    const std::vector<MPQCData> &fragmentData,
+    const std::map<JobId_t, MPQCData> &fragmentData,
     std::map< JobId_t, size_t > &MatrixNrLookup,
     const size_t FragmentCounter,
@@ -243,10 +241,8 @@
     ForceMatrix &Force)
 {
-  ASSERT( jobids.size() == fragmentData.size(),
-      "putResultsintoMatrices() - jobids and fragmentData differ in size.");
-  std::vector<MPQCData>::const_iterator dataiter = fragmentData.begin();
-  std::vector<JobId_t>::const_iterator iditer = jobids.begin();
-  for (; dataiter != fragmentData.end(); ++dataiter, ++iditer) {
-    const MPQCData &extractedData = *dataiter;
+  for (std::map<JobId_t, MPQCData>::const_iterator dataiter = fragmentData.begin();
+      dataiter != fragmentData.end(); ++dataiter) {
+    const MPQCData &extractedData = dataiter->second;
+    const JobId_t &jobid = dataiter->first;
     // place results into EnergyMatrix ...
     {
@@ -255,7 +251,7 @@
       matrix[0].resize(1, extractedData.energies.total);
       if (!Energy.AddMatrix(
-          std::string("MPQCJob ")+toString(*iditer),
+          std::string("MPQCJob ")+toString(jobid),
           matrix,
-          MatrixNrLookup[*iditer])) {
+          MatrixNrLookup[jobid])) {
         ELOG(1, "Adding energy matrix failed.");
         return false;
@@ -276,7 +272,7 @@
       }
       if (!Force.AddMatrix(
-          std::string("MPQCJob ")+toString(*iditer),
+          std::string("MPQCJob ")+toString(jobid),
           matrix,
-          MatrixNrLookup[*iditer])) {
+          MatrixNrLookup[jobid])) {
         ELOG(1, "Adding force matrix failed.");
         return false;
@@ -301,6 +297,5 @@
 /** Print MPQCData from received results.
  *
- * @param jobids jobids with ids to associate with fragment number
- * @param fragmentData MPQCData resulting from the jobs
+ * @param fragmentData MPQCData resulting from the jobs, each associated to a job
  * @param KeySetFilename filename with keysets to associate forces correctly
  * @param NoAtoms total number of atoms
@@ -309,10 +304,16 @@
  */
 bool sumUpChargeDensity(
-    const std::vector<JobId_t> &jobids,
-    const std::vector<MPQCData> &fragmentData,
+    const std::map<JobId_t,MPQCData> &fragmentData,
     const std::string &KeySetFilename,
     SamplingGrid &full_sample,
     Fragment &full_fragment)
 {
+  // create a vector of all job ids
+  std::vector<JobId_t> jobids;
+  std::transform(fragmentData.begin(),fragmentData.end(),
+      std::back_inserter(jobids),
+      boost::bind( &std::map<JobId_t,MPQCData>::value_type::first, boost::lambda::_1 )
+  );
+
   // create lookup from job nr to fragment number
   std::map< JobId_t, size_t > MatrixNrLookup;
@@ -339,8 +340,8 @@
   std::vector<MPQCDataGridMap_t> Result_Grid_fused(
     OrthogonalSumUpPerLevel<MPQCDataGridMap_t, MPQCDataGridVector_t>(
-        fragmentData, jobids, MatrixNrLookup, container, subsetmap));
+        fragmentData, MatrixNrLookup, container, subsetmap));
   std::vector<MPQCDataFragmentMap_t> Result_Fragment_fused(
     OrthogonalSumUpPerLevel<MPQCDataFragmentMap_t, MPQCDataFragmentVector_t>(
-        fragmentData, jobids, MatrixNrLookup, container, subsetmap));
+        fragmentData, MatrixNrLookup, container, subsetmap));
   // obtain full grid
   full_sample = boost::fusion::at_key<MPQCDataFused::sampled_grid>(Result_Grid_fused.back());
@@ -352,6 +353,5 @@
 /** Print MPQCData from received results.
  *
- * @param results results with ids to associate with fragment number
- * @param fragmentData MPQCData resulting from the jobs
+ * @param fragmentData MPQCData resulting from the jobs, associated to job id
  * @param KeySetFilename filename with keysets to associate forces correctly
  * @param NoAtoms total number of atoms
@@ -359,10 +359,16 @@
  */
 bool printReceivedMPQCResults(
-    const std::vector<JobId_t> &jobids,
-    const std::vector<MPQCData> &fragmentData,
+    const std::map<JobId_t, MPQCData> &fragmentData,
     const std::string &KeySetFilename,
     size_t NoAtoms,
     SamplingGrid &full_sample)
 {
+  // create a vector of all job ids
+  std::vector<JobId_t> jobids;
+  std::transform(fragmentData.begin(),fragmentData.end(),
+      std::back_inserter(jobids),
+      boost::bind( &std::map<JobId_t,MPQCData>::value_type::first, boost::lambda::_1 )
+  );
+
   // create lookup from job nr to fragment number
   std::map< JobId_t, size_t > MatrixNrLookup;
@@ -373,5 +379,5 @@
   EnergyMatrix Energy;
   ForceMatrix Force;
-  if (!putResultsintoMatrices(jobids, fragmentData, MatrixNrLookup, FragmentCounter, NoAtoms, Energy, Force))
+  if (!putResultsintoMatrices(fragmentData, MatrixNrLookup, FragmentCounter, NoAtoms, Energy, Force))
     return false;
 
@@ -412,14 +418,14 @@
     std::vector<MPQCDataEnergyMap_t> Result_Energy_fused(
         OrthogonalSumUpPerLevel<MPQCDataEnergyMap_t, MPQCDataEnergyVector_t>(
-            fragmentData, jobids, MatrixNrLookup, container, subsetmap));
+            fragmentData, MatrixNrLookup, container, subsetmap));
     std::vector<MPQCDataGridMap_t> Result_Grid_fused(
       OrthogonalSumUpPerLevel<MPQCDataGridMap_t, MPQCDataGridVector_t>(
-          fragmentData, jobids, MatrixNrLookup, container, subsetmap));
+          fragmentData, MatrixNrLookup, container, subsetmap));
     std::vector<MPQCDataTimeMap_t> Result_Time_fused(
       SumUpPerLevel<MPQCDataTimeMap_t, MPQCDataTimeVector_t>(
-          fragmentData, jobids, MatrixNrLookup, container, subsetmap));
+          fragmentData, MatrixNrLookup, container, subsetmap));
 
     // force has extra converter
-    std::vector<MPQCDataForceMap_t> MPQCData_Force_fused;
+    std::map<JobId_t, MPQCDataForceMap_t> MPQCData_Force_fused;
     convertMPQCDatatoForceMap(fragmentData, ForceKeySet, MPQCData_Force_fused);
     std::vector<MPQCDataForceMap_t> Result_Force_fused(subsetmap->getMaximumSubsetLevel());
@@ -427,5 +433,4 @@
                 subsetmap,
                 MPQCData_Force_fused,
-                jobids,
                 container->getContainer(),
                 MatrixNrLookup,
@@ -496,6 +501,4 @@
 /** 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
@@ -506,8 +509,6 @@
  */
 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::map<JobId_t,MPQCData> &fragmentData,
+    const std::map<JobId_t,VMGData> &longrangeData,
     const VMGData &fullsolutionData,
     const std::string &KeySetFilename,
@@ -515,9 +516,10 @@
     SamplingGrid &full_sample)
 {
-  // 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
+  std::vector<JobId_t> jobids;
+  std::transform(fragmentData.begin(),fragmentData.end(),
+      std::back_inserter(jobids),
+      boost::bind( &std::map<JobId_t,MPQCData>::value_type::first, boost::lambda::_1 )
+  );
 
   // create lookup from job nr to fragment number
@@ -555,17 +557,17 @@
     std::vector<MPQCDataEnergyMap_t> Result_Energy_fused(
         OrthogonalSumUpPerLevel<MPQCDataEnergyMap_t, MPQCDataEnergyVector_t>(
-            fragmentData, jobids, MatrixNrLookup, container, subsetmap));
+            fragmentData, MatrixNrLookup, container, subsetmap));
     std::vector<MPQCDataGridMap_t> Result_Grid_fused(
       OrthogonalSumUpPerLevel<MPQCDataGridMap_t, MPQCDataGridVector_t>(
-          fragmentData, jobids, MatrixNrLookup, container, subsetmap));
+          fragmentData, MatrixNrLookup, container, subsetmap));
     std::vector<MPQCDataTimeMap_t> Result_Time_fused(
       SumUpPerLevel<MPQCDataTimeMap_t, MPQCDataTimeVector_t>(
-          fragmentData, jobids, MatrixNrLookup, container, subsetmap));
+          fragmentData, MatrixNrLookup, container, subsetmap));
     std::vector<MPQCDataFragmentMap_t> Result_Fragment_fused(
       OrthogonalSumUpPerLevel<MPQCDataFragmentMap_t, MPQCDataFragmentVector_t>(
-          fragmentData, jobids, MatrixNrLookup, container, subsetmap));
+          fragmentData, MatrixNrLookup, container, subsetmap));
 
     // force has extra converter
-    std::vector<MPQCDataForceMap_t> MPQCData_Force_fused;
+    std::map<JobId_t, MPQCDataForceMap_t> MPQCData_Force_fused;
     convertMPQCDatatoForceMap(fragmentData, ForceKeySet, MPQCData_Force_fused);
     std::vector<MPQCDataForceMap_t> Result_Force_fused(subsetmap->getMaximumSubsetLevel());
@@ -573,5 +575,4 @@
                 subsetmap,
                 MPQCData_Force_fused,
-                jobids,
                 container->getContainer(),
                 MatrixNrLookup,
@@ -580,10 +581,9 @@
 
     // obtain full grid
-    std::vector<VMGDataMap_t> VMGData_Potential_fused;
+    std::map<JobId_t, VMGDataMap_t> VMGData_Potential_fused;
     convertDataTo<VMGData, VMGDataMap_t>(longrangeData, VMGData_Potential_fused);
     OrthogonalFullSummator<VMGDataMap_t, VMGDataFused::sampled_potential> potentialSummer(
                 subsetmap,
                 VMGData_Potential_fused,
-                jobids,
                 container->getContainer(),
                 MatrixNrLookup);
@@ -592,5 +592,4 @@
                 subsetmap,
                 VMGData_Potential_fused,
-                jobids,
                 container->getContainer(),
                 MatrixNrLookup);
@@ -605,5 +604,4 @@
                 subsetmap,
                 VMGData_Potential_fused,
-                jobids,
                 container->getContainer(),
                 MatrixNrLookup);
@@ -685,5 +683,5 @@
     FragmentController &controller,
     const FragmentationFragmentationAutomationAction::FragmentationFragmentationAutomationParameters &params,
-    const std::vector<MPQCData> &fragmentData,
+    const std::map<JobId_t, MPQCData> &fragmentData,
     const SamplingGrid &full_sampled_grid,
     const Fragment &full_fragment)
@@ -692,11 +690,11 @@
   // add one job for each fragment as the short-range correction which we need
   // to subtract from the obtained full potential to get the long-range part only
-  for (std::vector<MPQCData>::const_iterator iter = fragmentData.begin();
+  for (std::map<JobId_t, MPQCData>::const_iterator iter = fragmentData.begin();
       iter != fragmentData.end(); ++iter) {
     const JobId_t next_id = controller.getAvailableId();
-    LOG(1, "INFO: Creating VMGJob with " << iter->sampled_grid.sampled_grid.size()
-        << " gridpoints and " << iter->charges.size() << " particle charges.");
+    LOG(1, "INFO: Creating VMGJob with " << iter->second.sampled_grid.sampled_grid.size()
+        << " gridpoints and " << iter->second.charges.size() << " particle charges.");
     FragmentJob::ptr testJob(
-        new VMGJob(next_id, iter->sampled_grid, iter->positions, iter->charges) );
+        new VMGJob(next_id, iter->second.sampled_grid, iter->second.positions, iter->second.charges) );
     jobs.push_back(testJob);
   }
@@ -776,5 +774,5 @@
   RunService(io_service, "Requesting short-range results");
   std::vector<FragmentResult::ptr> MPQCresults = controller.getReceivedResults();
-  std::vector<MPQCData> fragmentData;
+  std::map<JobId_t, MPQCData> fragmentData;
   ConvertFragmentResultTo<MPQCData>(MPQCresults, fragmentData);
 
@@ -795,5 +793,4 @@
   Fragment full_fragment;
   sumUpChargeDensity(
-      jobids,
       fragmentData,
       params.path.get(),
@@ -818,9 +815,9 @@
       "FragmentationFragmentationAutomationAction::performCall() - number of MPQCresultd and VMGresults don't match.");
 
-  std::vector<VMGData> longrangeData;
+  std::map<JobId_t, VMGData> longrangeData;
   ConvertFragmentResultTo<VMGData>(VMGresults, longrangeData);
-  // remove full solution from vector, has to be treated extra
-  VMGData fullsolutionData = longrangeData.back();
-  longrangeData.pop_back();
+  // remove full solution from map (must be highest id), has to be treated extra
+  VMGData fullsolutionData = (--longrangeData.end())->second;
+  longrangeData.erase(--longrangeData.end());
 
   // Final phase: print result
@@ -828,6 +825,4 @@
     LOG(1, "INFO: Parsing fragment files from " << params.path.get() << ".");
     printReceivedFullResults(
-        MPQCresults,
-        VMGresults,
         fragmentData,
         longrangeData,
@@ -843,5 +838,4 @@
     LOG(1, "INFO: Parsing fragment files from " << params.path.get() << ".");
     printReceivedMPQCResults(
-        jobids,
         fragmentData,
         params.path.get(),
