Index: src/Graph/CyclicStructureAnalysis.cpp
===================================================================
--- src/Graph/CyclicStructureAnalysis.cpp	(revision 748fc7c0d1024191307cd0382559ca5a2f64eacb)
+++ src/Graph/CyclicStructureAnalysis.cpp	(revision a91710c7feb7eb12c5521615d53366bd9ac68106)
@@ -103,10 +103,20 @@
 }
 
-/** Performs a BFS from \a *Root, trying to find the same node and hence a cycle.
+/** Performs a BFS from \a *Root, trying to find the same node and hence all cycles.
+ *
+ * We exclude the back edge, hence the direct way is prohibited. But as it is a back edge,
+ * there must be at least one more way to \a *Root. This leads us to all cycles for this
+ * back edge.
+ *
  * \param OtherAtom pointing to Root on return indicating found cycle
  * \param *&BackEdge the edge from root that we don't want to move along
- */
-void CyclicStructureAnalysis::CyclicBFSFromRootToRoot(atom *&OtherAtom, bond::ptr &BackEdge)
-{
+ * \param MinRingSize set to minimum over all cycles encountered
+ */
+void CyclicStructureAnalysis::findAllCyclesforBackEdge(
+    atom *&OtherAtom,
+    bond::ptr &BackEdge,
+    int &MinRingSize)
+{
+  size_t MaximumHorizon = (size_t)-1; // will overflow to largest number
   atom *Walker = NULL;
   do { // look for Root
@@ -115,86 +125,76 @@
     BFSStack.pop_back();
     LOG(2, "INFO: Current Walker is " << *Walker << ", we look for SP to Root " << *Root << ".");
-    const BondList& ListOfBonds = Walker->getListOfBonds();
-    for (BondList::const_iterator Runner = ListOfBonds.begin();
-        Runner != ListOfBonds.end();
-        ++Runner) {
-      if ((*Runner) != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
-        OtherAtom = (*Runner)->GetOtherAtom(Walker);
-        if ((treatment == IncludeHydrogen) || (OtherAtom->getType()->getAtomicNumber() != 1)) {
-          LOG(2, "INFO: Current OtherAtom is: " << OtherAtom->getName() << " for bond " << *(*Runner) << ".");
-          if (ColorList[OtherAtom->getNr()] == GraphEdge::white) {
-            TouchedStack.push_front(OtherAtom);
-            ColorList[OtherAtom->getNr()] = GraphEdge::lightgray;
-            PredecessorList[OtherAtom->getNr()] = Walker; // Walker is the predecessor
-            ShortestPathList[OtherAtom->getNr()] = ShortestPathList[Walker->getNr()] + 1;
-            LOG(2, "INFO: Coloring OtherAtom " << OtherAtom->getName() << " lightgray, its predecessor is " << Walker->getName() << " and its Shortest Path is " << ShortestPathList[OtherAtom->getNr()] << " egde(s) long.");
-            //if (ShortestPathList[OtherAtom->getNr()] < MinimumRingSize[Walker->GetTrueFather()->getNr()]) { // Check for maximum distance
-            LOG(3, "ACCEPT: Putting OtherAtom " << OtherAtom->getName() << " into queue.");
-            BFSStack.push_front(OtherAtom);
-            //}
+
+    // check all edges/bonds from current Walker
+    if (MaximumHorizon >=  (size_t)ShortestPathList[Walker->getNr()]) {
+      const BondList& ListOfBonds = Walker->getListOfBonds();
+      for (BondList::const_iterator Runner = ListOfBonds.begin();
+          Runner != ListOfBonds.end();
+          ++Runner) {
+        if ((*Runner) != BackEdge) { // only walk along DFS spanning tree (otherwise we always find SP of one being backedge Binder)
+          OtherAtom = (*Runner)->GetOtherAtom(Walker);
+          if ((treatment == IncludeHydrogen) || (OtherAtom->getType()->getAtomicNumber() != 1)) {
+            LOG(2, "INFO: Current OtherAtom is: " << OtherAtom->getName() << " for bond " << *(*Runner) << ".");
+            if (ColorList[OtherAtom->getNr()] == GraphEdge::white) {
+              // we discovered a new node/atom
+              TouchedStack.push_front(OtherAtom);
+              ColorList[OtherAtom->getNr()] = GraphEdge::lightgray;
+              PredecessorList[OtherAtom->getNr()] = Walker; // Walker is the predecessor
+              ShortestPathList[OtherAtom->getNr()] = ShortestPathList[Walker->getNr()] + 1;
+              LOG(2, "INFO: Coloring OtherAtom " << OtherAtom->getName() << " lightgray, its predecessor is " << Walker->getName() << " and its Shortest Path is " << ShortestPathList[OtherAtom->getNr()] << " egde(s) long.");
+              //if (ShortestPathList[OtherAtom->getNr()] < MinimumRingSize[Walker->GetTrueFather()->getNr()]) { // Check for maximum distance
+              LOG(3, "ACCEPT: Putting OtherAtom " << OtherAtom->getName() << " into queue.");
+              BFSStack.push_front(OtherAtom);
+              //}
+            } else {
+              LOG(3, "REJECT: Not Adding, has already been visited.");
+            }
+            if (OtherAtom == Root)
+              break;
           } else {
-            LOG(3, "REJECT: Not Adding, has already been visited.");
+            LOG(2, "INFO: Skipping hydrogen atom " << *OtherAtom << ".");
+            ColorList[OtherAtom->getNr()] = GraphEdge::black;
           }
-          if (OtherAtom == Root)
-            break;
         } else {
-          LOG(2, "INFO: Skipping hydrogen atom " << *OtherAtom << ".");
-          ColorList[OtherAtom->getNr()] = GraphEdge::black;
+          LOG(2, "REJECT: Bond " << *(*Runner) << " not Visiting, is the back edge.");
         }
-      } else {
-        LOG(2, "REJECT: Bond " << *(*Runner) << " not Visiting, is the back edge.");
-      }
-    }
-    ColorList[Walker->getNr()] = GraphEdge::black;
-    LOG(1, "INFO: Coloring Walker " << Walker->getName() << " " << GraphEdge::getColorName(ColorList[Walker->getNr()]) << ".");
-    if (OtherAtom == Root) { // if we have found the root, check whether this cycle wasn't already found beforehand
-      // step through predecessor list
-      LOG(4, "DEBUG: Checking whether all predecessors are already marked cyclic ...");
-      while (OtherAtom != BackEdge->rightatom) {  // Note that leftatom is Root itself
-        if (!OtherAtom->GetTrueFather()->IsCyclic) { // if one bond in the loop is not marked as cyclic, we haven't found this cycle yet
-          LOG(4, "\tDEBUG: OtherAtom " << *OtherAtom << " is not cyclic, breaking.");
-          break;
-        } else
-          OtherAtom = PredecessorList[OtherAtom->getNr()];
-      }
-      LOG(4, "DEBUG: Checking done.");
-      // if each atom in found cycle is cyclic, loop's been found before already
-      if (OtherAtom == BackEdge->rightatom) { // loop got round completely
-        LOG(3, "INFO: All bonds are marked cyclic already, checking allcycles whether cycle is already present.");
-        const cycle_t currentcycle = extractCurrentCycle(BackEdge);
-        const cycles_t::const_iterator iter =
-            std::find(allcycles.begin(), allcycles.end(), currentcycle);
-        if (iter == allcycles.end()) { // not found
-          OtherAtom = Root;
-          LOG(2, "INFO: Cycle is not present.");
-          LOG(2, "INFO: We have reached Root " << *OtherAtom << " and may extract the cycle.");
-        } else {
-          LOG(2, "INFO: Cycle is already present.");
-          do {
-            ASSERT(!TouchedStack.empty(), "CyclicStructureAnalysis_CyclicBFSFromRootToRoot() - TouchedStack is empty!");
-            OtherAtom = TouchedStack.front();
-            TouchedStack.pop_front();
-            if (PredecessorList[OtherAtom->getNr()] == Walker) {
-              LOG(4, "INFO: Removing " << *OtherAtom << " from lists and stacks.");
-              PredecessorList[OtherAtom->getNr()] = NULL;
-              ShortestPathList[OtherAtom->getNr()] = -1;
-              ColorList[OtherAtom->getNr()] = GraphEdge::white;
-              // rats ... deque has no find()
-              std::deque<atom *>::iterator iter = find(
-                  BFSStack.begin(),
-                  BFSStack.end(),
-                  OtherAtom);
-              ASSERT(iter != BFSStack.end(),
-                  "CyclicStructureAnalysis_CyclicBFSFromRootToRoot() - can't find "+toString(*OtherAtom)+" on stack!");
-              BFSStack.erase(iter);
-            }
-          } while ((!TouchedStack.empty()) && (PredecessorList[OtherAtom->getNr()] == NULL));
-          TouchedStack.push_front(OtherAtom); // last was wrongly popped
-          OtherAtom = BackEdge->rightatom; // set to not Root
+      }
+      ColorList[Walker->getNr()] = GraphEdge::black;
+      LOG(1, "INFO: Coloring Walker " << Walker->getName() << " " << GraphEdge::getColorName(ColorList[Walker->getNr()]) << ".");
+    } else {
+      LOG(1, "INFO: Skipping bonds for " << Walker->getName() << " as it resides on the horizon.");
+    }
+
+    // have we closed the cycle, i.e. stumbled upon Root by another mean than
+    // the back edge?
+    if (OtherAtom == Root) {
+      // check whether this cycle wasn't already found beforehand by stepping
+      // through predecessor list
+      int RingSize = RetrieveCycleMembers(OtherAtom, BackEdge, MinRingSize);
+      MaximumHorizon = std::min( MaximumHorizon, (size_t)RingSize );
+      LOG(2, "INFO: Maximum horizon is set to " << MaximumHorizon);
+
+      // remove last step and prepare for a possible yet another path to Root
+      do {
+        ASSERT(!TouchedStack.empty(), "CyclicStructureAnalysis_CyclicBFSFromRootToRoot() - TouchedStack is empty!");
+        OtherAtom = TouchedStack.front();
+        TouchedStack.pop_front();
+        if (PredecessorList[OtherAtom->getNr()] == Walker) {
+          LOG(4, "INFO: Removing " << *OtherAtom << " from lists and stacks.");
+          PredecessorList[OtherAtom->getNr()] = NULL;
+          ShortestPathList[OtherAtom->getNr()] = -1;
+          ColorList[OtherAtom->getNr()] = GraphEdge::white;
+          // rats ... deque has no find()
+          std::deque<atom *>::iterator iter = find(
+              BFSStack.begin(),
+              BFSStack.end(),
+              OtherAtom);
+          ASSERT(iter != BFSStack.end(),
+              "CyclicStructureAnalysis_CyclicBFSFromRootToRoot() - can't find "+toString(*OtherAtom)+" on stack!");
+          BFSStack.erase(iter);
         }
-      } else {
-        OtherAtom = Root;
-        LOG(2, "INFO: We have reached Root " << *OtherAtom << " and may extract the cycle.");
-      }
+      } while ((!TouchedStack.empty()) && (PredecessorList[OtherAtom->getNr()] == NULL));
+      TouchedStack.push_front(OtherAtom); // last was wrongly popped
+      OtherAtom = BackEdge->rightatom; // set to not Root
     }
   } while ((!BFSStack.empty()) && (OtherAtom != Root) && (OtherAtom != NULL)); // || (ShortestPathList[OtherAtom->getNr()] < MinimumRingSize[Walker->GetTrueFather()->getNr()])));
@@ -233,49 +233,81 @@
  * \param &BFS accounting structure
  * \param &MinRingSize global minimum distance from one node without encountering oneself, set on return
- * \param &NumCyles number of cycles in graph
- */
-void CyclicStructureAnalysis::RetrieveCycleMembers(
+ * \return size of found cycle, -1 - nothing found, something went wrong
+ */
+int CyclicStructureAnalysis::RetrieveCycleMembers(
     atom *&OtherAtom,
     bond::ptr &BackEdge,
-    int &MinRingSize,
-    int &NumCycles)
-{
-  atom *Walker = NULL;
+    int &MinRingSize)
+{
   int RingSize = -1;
+  bool newcycle = false;
 
   if (OtherAtom == Root) {
     // now climb back the predecessor list and thus find the cycle members
-    NumCycles++;
     Root->GetTrueFather()->IsCyclic = true;
 
-    // exctract cycle
     {
-      allcycles.push_back(extractCurrentCycle(BackEdge));
-      CyclicStructureAnalysis::cycle_t &lastcycle = allcycles.back();
-      RingSize = lastcycle.size();
-      LOG(0, "INFO: " << "Found ring contains: " << lastcycle << "  with a length of " << RingSize);
-    }
-
-    // walk through all and set MinimumRingSize
-    Walker = Root;
-    if ((MinimumRingSize.count(Walker->GetTrueFather()->getNr()) == 0)
-        || (RingSize < MinimumRingSize[Walker->GetTrueFather()->getNr()])) {
-      MinimumRingSize[Walker->GetTrueFather()->getNr()] = RingSize;
-    } else {
-      LOG(3, "INFO: Not setting MinimumRingSize of "<< *(Walker->GetTrueFather())
-          << " to " << RingSize << " which is already set to "
-          << MinimumRingSize[Walker->GetTrueFather()->getNr()] << ".");
-    }
-    while (Walker != BackEdge->rightatom) { // note that Root is leftatom
-      Walker = PredecessorList[Walker->getNr()];
+      // check whether cycle is present already
+      atom *Walker = Root;
+      LOG(4, "DEBUG: Checking whether all predecessors are already marked cyclic ...");
+      while (Walker != BackEdge->rightatom) {  // Note that leftatom is Root itself
+        if (!Walker->GetTrueFather()->IsCyclic) { // if one bond in the loop is not marked as cyclic, we haven't found this cycle yet
+          LOG(4, "\tDEBUG: Walker " << *Walker << " is not cyclic, breaking.");
+          break;
+        } else
+          Walker = PredecessorList[Walker->getNr()];
+      }
+      LOG(4, "DEBUG: Checking done.");
+
+      // if each atom in found cycle is cyclic, loop's been found before already
+
+      // exctract cycle
+      {
+        const cycle_t currentcycle = extractCurrentCycle(BackEdge);
+        if (Walker != BackEdge->rightatom) { // loop got round completely
+          allcycles.push_back(currentcycle);
+          newcycle = true;
+        } else {
+          LOG(3, "INFO: All bonds are marked cyclic already, checking allcycles whether cycle is already present.");
+          const cycles_t::const_iterator iter =
+              std::find(allcycles.begin(), allcycles.end(), currentcycle);
+          if (iter == allcycles.end()) { // not found
+            allcycles.push_back(currentcycle);
+            newcycle = true;
+          }
+        }
+        RingSize = currentcycle.size();
+        if (newcycle) {
+          LOG(0, "INFO: " << "Found ring contains: " << currentcycle << "  with a length of " << RingSize);
+        } else {
+          LOG(1, "INFO: cycle " << currentcycle << " is already present.");
+        }
+      }
+    }
+
+    if (newcycle) {
+      // walk through all and set MinimumRingSize
+      atom *Walker = Root;
       if ((MinimumRingSize.count(Walker->GetTrueFather()->getNr()) == 0)
-          || (RingSize < MinimumRingSize[Walker->GetTrueFather()->getNr()]))
+          || (RingSize < MinimumRingSize[Walker->GetTrueFather()->getNr()])) {
         MinimumRingSize[Walker->GetTrueFather()->getNr()] = RingSize;
-    }
-    if ((RingSize < MinRingSize) || (MinRingSize == -1))
-      MinRingSize = RingSize;
+      } else {
+        LOG(3, "INFO: Not setting MinimumRingSize of "<< *(Walker->GetTrueFather())
+            << " to " << RingSize << " which is already set to "
+            << MinimumRingSize[Walker->GetTrueFather()->getNr()] << ".");
+      }
+      while (Walker != BackEdge->rightatom) { // note that Root is leftatom
+        Walker = PredecessorList[Walker->getNr()];
+        if ((MinimumRingSize.count(Walker->GetTrueFather()->getNr()) == 0)
+            || (RingSize < MinimumRingSize[Walker->GetTrueFather()->getNr()]))
+          MinimumRingSize[Walker->GetTrueFather()->getNr()] = RingSize;
+      }
+      if ((RingSize < MinRingSize) || (MinRingSize == -1))
+        MinRingSize = RingSize;
+    }
   } else {
     LOG(1, "INFO: No ring containing " << *Root << " with length equal to or smaller than " << MinimumRingSize[Root->GetTrueFather()->getNr()] << " found.");
   }
+  return RingSize;
 }
 
@@ -358,7 +390,6 @@
  * \param *&MinimumRingSize array with minimum distance without encountering oneself for each atom
  * \param MinRingSize global minium distance
- * \param NumCyles number of cycles in graph
- */
-void CyclicStructureAnalysis::AssignRingSizetoNonCycleMembers(const int MinRingSize, const int NumCycles)
+ */
+void CyclicStructureAnalysis::AssignRingSizetoNonCycleMembers(const int MinRingSize)
 {
   atom *Walker = NULL;
@@ -380,5 +411,5 @@
       LOG(1, "INFO: Minimum ring size of " << *Walker << " is " << MinimumRingSize[Walker->GetTrueFather()->getNr()] << ".");
     }
-    LOG(1, "INFO: Minimum ring size is " << MinRingSize << ", over " << NumCycles << " cycle(s) total.");
+    LOG(1, "INFO: Minimum ring size is " << MinRingSize << ", over " << allcycles.size() << " cycle(s) total.");
   } else
     LOG(1, "INFO: No rings were detected in the molecular structure.");
@@ -399,5 +430,4 @@
   atom *OtherAtom = NULL;
   bond::ptr BackEdge;
-  int NumCycles = 0;
   int MinRingSize = -1;
 
@@ -415,5 +445,4 @@
 
   LOG(1, "STATUS: Analysing cycles ... ");
-  NumCycles = 0;
   while (!BackEdgeStack->empty()) {
     BackEdge = BackEdgeStack->front();
@@ -428,12 +457,10 @@
     LOG(1, "---------------------------------------------------------------------------------------------------------");
     OtherAtom = NULL;
-    // go to next cycle via BFS
-    CyclicBFSFromRootToRoot(OtherAtom, BackEdge);
-    // get all member nodes of this cycle
-    RetrieveCycleMembers(OtherAtom, BackEdge, MinRingSize, NumCycles);
+    // find all cycles for current BackEdge
+    findAllCyclesforBackEdge(OtherAtom, BackEdge, MinRingSize);
 
     CleanAllTouched();
   }
-  AssignRingSizetoNonCycleMembers(MinRingSize, NumCycles);
+  AssignRingSizetoNonCycleMembers(MinRingSize);
 }
 
Index: src/Graph/CyclicStructureAnalysis.hpp
===================================================================
--- src/Graph/CyclicStructureAnalysis.hpp	(revision 748fc7c0d1024191307cd0382559ca5a2f64eacb)
+++ src/Graph/CyclicStructureAnalysis.hpp	(revision a91710c7feb7eb12c5521615d53366bd9ac68106)
@@ -58,9 +58,9 @@
   void InitializeToRoot(atom *&Walker);
   // performing tasks
-  void CyclicBFSFromRootToRoot(atom *&OtherAtom, bond::ptr &BackEdge);
-  void RetrieveCycleMembers(atom *&OtherAtom, bond::ptr &BackEdge, int &MinRingSize, int &NumCycles);
+  void findAllCyclesforBackEdge(atom *&OtherAtom, bond::ptr &BackEdge, int &MinRingSize);
+  int RetrieveCycleMembers(atom *&OtherAtom, bond::ptr &BackEdge, int &MinRingSize);
   cycle_t extractCurrentCycle(bond::ptr &BackEdge);
   void BFSToNextCycle(atom *Walker);
-  void AssignRingSizetoNonCycleMembers(const int MinRingSize, const int NumCycles);
+  void AssignRingSizetoNonCycleMembers(const int MinRingSize);
   // output
   void OutputAlreadyVisited(int *list);
