Index: src/Actions/FragmentationAction/FragmentationAction.cpp
===================================================================
--- src/Actions/FragmentationAction/FragmentationAction.cpp	(revision db6f7d5bfbb4b11d713dc5ba5ec62d4a67309ab8)
+++ src/Actions/FragmentationAction/FragmentationAction.cpp	(revision 79ac0395a78b6767dfc9c1d71f87c49f607546b7)
@@ -37,12 +37,19 @@
 #include "Atom/atom.hpp"
 #include "CodePatterns/Log.hpp"
+#include "Fragmentation/Exporters/ExportGraph_ToFiles.hpp"
 #include "Fragmentation/Fragmentation.hpp"
+#include "Fragmentation/Graph.hpp"
 #include "Fragmentation/HydrogenSaturation_enum.hpp"
+#include "Graph/AdjacencyList.hpp"
 #include "Graph/DepthFirstSearchAnalysis.hpp"
+#include "Helpers/defs.hpp"
 #include "molecule.hpp"
 #include "World.hpp"
 
+#include <boost/filesystem.hpp>
 #include <iostream>
+#include <map>
 #include <string>
+#include <vector>
 
 #include "Actions/FragmentationAction/FragmentationAction.hpp"
@@ -56,7 +63,8 @@
 Action::state_ptr FragmentationFragmentationAction::performCall() {
   clock_t start,end;
-  molecule *mol = NULL;
-  int ExitFlag = 0;
+  int ExitFlag = -1;
+  World &world = World::getInstance();
 
+  // inform about used parameters
   LOG(0, "STATUS: Fragmenting molecular system with current connection matrix maximum bond distance "
       << params.distance.get() << " up to "
@@ -65,19 +73,98 @@
       << params.types.get() << "." << std::endl);
 
+  // check for selected atoms
+  if (world.beginAtomSelection() == world.endAtomSelection()) {
+    ELOG(1, "There are not atoms selected for fragmentation.");
+    return Action::failure;
+  }
+
+  // go through all atoms, note down their molecules and group them
+  typedef std::multimap<molecule *, atom *> clusters_t;
+  typedef std::vector<atomId_t> atomids_t;
+  atomids_t atomids;
+  clusters_t clusters;
+  for (World::AtomSelectionConstIterator iter = world.beginAtomSelection();
+      iter != world.endAtomSelection(); ++iter) {
+    clusters.insert( std::make_pair(iter->second->getMolecule(), iter->second) );
+    atomids.push_back(iter->second->getId());
+  }
+  LOG(1, "INFO: There are " << clusters.size()  << " molecules to consider.");
+
+  // get whether to saturate or not
+  const enum HydrogenSaturation saturation =  params.DoSaturation.get() ? DoSaturate : DontSaturate;
+
+  // parse in Adjacency file
+  boost::shared_ptr<AdjacencyList> FileChecker;
+  boost::filesystem::path filename(params.prefix.get() + std::string(ADJACENCYFILE));
+  if (boost::filesystem::exists(filename) && boost::filesystem::is_regular_file(filename)) {
+    std::ifstream File;
+    File.open(filename.string().c_str(), ios::out);
+    FileChecker.reset(new AdjacencyList(File));
+    File.close();
+  } else {
+    LOG(1, "INFO: Could not open default adjacency file " << filename.string() << ".");
+    FileChecker.reset(new AdjacencyList);
+  }
+
   DepthFirstSearchAnalysis DFS;
-  for (World::MoleculeSelectionConstIterator iter = World::getInstance().beginMoleculeSelection(); iter != World::getInstance().endMoleculeSelection(); ++iter) {
-    mol = iter->second;
-    ASSERT(mol != NULL, "No molecule has been picked for fragmentation.");
-    LOG(2, "INFO: Fragmenting molecule with bond distance " << params.distance.get() << " angstroem, order of " << params.order.get() << ".");
-    start = clock();
-    if (mol->hasBondStructure()) {
-      Fragmentation Fragmenter(mol, params.DoSaturation.get() ? DoSaturate : DontSaturate);
-      Fragmenter.setOutputTypes(params.types.get());
-      ExitFlag = Fragmenter.FragmentMolecule(params.order.get(), params.prefix.get(), DFS);
+  start = clock();
+  // go through all keys (i.e. all molecules)
+  clusters_t::const_iterator advanceiter;
+  Graph TotalGraph;
+  int keysetcounter = 0;
+  for (clusters_t::const_iterator iter = clusters.begin();
+      iter != clusters.end();
+      iter = advanceiter) {
+    // get iterator to past last atom in this molecule
+    molecule * mol = iter->first;
+    advanceiter = clusters.upper_bound(mol);
+
+    // copy molecule's atoms' ids as parameters to Fragmentation's AtomMask
+    std::vector<atomId_t> mols_atomids;
+    std::transform(iter, advanceiter, std::back_inserter(mols_atomids),
+        boost::bind( &atom::getNr,
+            boost::bind( &clusters_t::value_type::second, _1 ))
+    );
+    LOG(2, "INFO: Fragmenting in molecule " << mol->getName() << " in " << clusters.count(mol) 
+        << " atoms, out of " << mol->getAtomCount() << ".");
+    const enum HydrogenSaturation saturation =  params.DoSaturation.get() ? DoSaturate : DontSaturate;
+    Fragmentation Fragmenter(mol, *FileChecker, saturation);
+
+    // perform fragmentation
+    LOG(0, std::endl << " ========== Fragmentation of molecule " << mol->getName() << " ========================= ");
+    {
+      const int tempFlag = Fragmenter.FragmentMolecule(mols_atomids, params.order.get(), params.prefix.get(), DFS);
+      if ((ExitFlag == 2) && (tempFlag != 2))
+        ExitFlag = tempFlag; // if there is one molecule that needs further fragmentation, it overrides others
+      if (ExitFlag == -1)
+        ExitFlag = tempFlag; // if we are the first, we set the standard
     }
-    World::getInstance().setExitFlag(ExitFlag);
-    end = clock();
-    LOG(0, "STATUS: Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s.");
+    TotalGraph.InsertGraph(Fragmenter.getGraph(), keysetcounter);
+
   }
+  LOG(0, "STATUS: There are " << keysetcounter << " fragments.");
+
+  // store molecule's fragment to file
+  {
+    ExportGraph_ToFiles exporter(TotalGraph, saturation);
+    exporter.setPrefix(params.prefix.get());
+    exporter.setOutputTypes(params.types.get());
+    exporter();
+  }
+
+  // store Adjacency to file
+  {
+    std::string filename = params.prefix.get() + ADJACENCYFILE;
+    std::ofstream AdjacencyFile;
+    AdjacencyFile.open(filename.c_str(), ios::out);
+    AdjacencyList adjacency(atomids);
+    adjacency.StoreToFile(AdjacencyFile);
+    AdjacencyFile.close();
+  }
+
+  World::getInstance().setExitFlag(ExitFlag);
+  end = clock();
+  LOG(0, "STATUS: Clocks for this operation: " << (end-start) << ", time: " << ((double)(end-start)/CLOCKS_PER_SEC) << "s.");
+
   return Action::success;
 }
