Index: src/analysis_bonds.cpp
===================================================================
--- src/analysis_bonds.cpp	(revision 58ed4a7c2bc8ff58164d0438ee813b30de7a34da)
+++ src/analysis_bonds.cpp	(revision 388049e8a31cd0cd058d1ddd9577886a8a3c2fa8)
@@ -9,4 +9,6 @@
 #include "atom.hpp"
 #include "bond.hpp"
+#include "element.hpp"
+#include "info.hpp"
 #include "log.hpp"
 #include "molecule.hpp"
@@ -79,2 +81,140 @@
   }
 };
+
+
+/** Counts the number of hydrogen bridge bonds.
+ * With \a *InterfaceElement an extra element can be specified that identifies some boundary.
+ * Then, counting is for the h-bridges that connect to interface only.
+ * \param *molecules molecules to count bonds
+ * \param *InterfaceElement or NULL
+ */
+int CountHydrogenBridgeBonds(MoleculeListClass *molecules, element * InterfaceElement = NULL)
+{
+  Info FunctionInfo(__func__);
+  atom *Walker = NULL;
+  atom *Runner = NULL;
+  Vector OHBond;
+  Vector OOBond;
+  int count = 0;
+  bool InterfaceFlag = false;
+  for (MoleculeList::const_iterator MolWalker = molecules->ListOfMolecules.begin();MolWalker != molecules->ListOfMolecules.end(); MolWalker++) {
+    Walker = (*MolWalker)->start;
+    while (Walker->next != (*MolWalker)->end) {
+      Walker = Walker->next;
+      for (MoleculeList::const_iterator MolRunner = molecules->ListOfMolecules.begin();MolRunner != MolWalker; MolRunner++) {
+        Runner = (*MolRunner)->start;
+        while (Runner->next != (*MolRunner)->end) {
+          Runner = Runner->next;
+          if ((Runner != Walker) && (Walker->type->Z  == 8) && (Runner->type->Z  == 8)) {
+            // check distance
+            const double distance = Runner->x.DistanceSquared(&Walker->x);
+            if ((distance > MYEPSILON) && (distance < HBRIDGEDISTANCE*HBRIDGEDISTANCE)) { // distance >0 means  different atoms
+              InterfaceFlag = (InterfaceElement == NULL);
+              // on other atom(Runner) we check for bond to interface element
+              for (BondList::const_iterator BondRunner = Runner->ListOfBonds.begin(); ((!InterfaceFlag) && (BondRunner != Runner->ListOfBonds.end())); BondRunner++) {
+                atom * const OtherAtom = (*BondRunner)->GetOtherAtom(Runner);
+                InterfaceFlag = InterfaceFlag || (OtherAtom->type == InterfaceElement);
+              }
+              if (InterfaceFlag) {
+                // on this element (Walker) we check for bond to hydrogen, i.e. part of water molecule
+                for (BondList::const_iterator BondRunner = Walker->ListOfBonds.begin(); BondRunner != Walker->ListOfBonds.end(); BondRunner++) {
+                  atom * const OtherAtom = (*BondRunner)->GetOtherAtom(Walker);
+                  if (OtherAtom->type->Z == 1) {
+                    // check angle
+                    OHBond.CopyVector(&OtherAtom->x);
+                    OHBond.SubtractVector(&Walker->x);
+                    OOBond.CopyVector(&Runner->x);
+                    OOBond.SubtractVector(&Walker->x);
+                    const double angle = OHBond.Angle(&OOBond);
+                    if (angle < M_PI*(30./180.)) {
+                      DoLog(1) && (Log() << Verbose(1) << Walker->Name << ", " << OtherAtom->Name << " and " << Runner->Name << " have a hydrogen bridge bond with " << sqrt(distance) << " and at angle " << (180./M_PI)*angle << " degrees." << endl);
+                      count++;
+                      break;
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  return count;
+}
+
+/** Counts the number of bonds between two given elements.
+ * \param *molecules list of molecules with all atoms
+ * \param *first pointer to first element
+ * \param *second pointer to second element
+ * \return number of found bonds (\a *first-\a *second)
+ */
+int CountBondsOfTwo(MoleculeListClass * const molecules, const element * const first, const element * const second)
+{
+  atom *Walker = NULL;
+  int count = 0;
+
+  for (MoleculeList::const_iterator MolWalker = molecules->ListOfMolecules.begin();MolWalker != molecules->ListOfMolecules.end(); MolWalker++) {
+    Walker = (*MolWalker)->start;
+    while (Walker->next != (*MolWalker)->end) {
+      Walker = Walker->next;
+      if ((Walker->type == first) || (Walker->type == second)) {  // first element matches
+        for (BondList::const_iterator BondRunner = Walker->ListOfBonds.begin(); BondRunner != Walker->ListOfBonds.end(); BondRunner++) {
+          atom * const OtherAtom = (*BondRunner)->GetOtherAtom(Walker);
+          if (((OtherAtom->type == first) || (OtherAtom->type == second)) && (Walker->nr < OtherAtom->nr)) {
+            count++;
+            DoLog(1) && (Log() << Verbose(1) << first->name << "-" << second->name << " bond found between " << *Walker << " and " << *OtherAtom << "." << endl);
+          }
+        }
+      }
+    }
+  }
+  return count;
+};
+
+/** Counts the number of bonds between three given elements.
+ * Note that we do not look for arbitrary sequence of given bonds, but \a *second will be the central atom and we check
+ * whether it has bonds to both \a *first and \a *third.
+ * \param *molecules list of molecules with all atoms
+ * \param *first pointer to first element
+ * \param *second pointer to second element
+ * \param *third pointer to third element
+ * \return number of found bonds (\a *first-\a *second-\a *third, \a *third-\a *second-\a *first, respectively)
+ */
+int CountBondsOfThree(MoleculeListClass * const molecules, const element * const first, const element * const second, const element * const third)
+{
+  int count = 0;
+  bool MatchFlag[2];
+  bool result = false;
+  atom *Walker = NULL;
+  const element * ElementArray[2];
+  ElementArray[0] = first;
+  ElementArray[1] = third;
+
+  for (MoleculeList::const_iterator MolWalker = molecules->ListOfMolecules.begin();MolWalker != molecules->ListOfMolecules.end(); MolWalker++) {
+    Walker = (*MolWalker)->start;
+    while (Walker->next != (*MolWalker)->end) {
+      Walker = Walker->next;
+      if (Walker->type == second) {  // first element matches
+        for (int i=0;i<2;i++)
+          MatchFlag[i] = false;
+        for (BondList::const_iterator BondRunner = Walker->ListOfBonds.begin(); BondRunner != Walker->ListOfBonds.end(); BondRunner++) {
+          atom * const OtherAtom = (*BondRunner)->GetOtherAtom(Walker);
+          for (int i=0;i<2;i++)
+            if ((!MatchFlag[i]) && (OtherAtom->type == ElementArray[i])) {
+              MatchFlag[i] = true;
+              break;  // each bonding atom can match at most one element we are looking for
+            }
+        }
+        result = true;
+        for (int i=0;i<2;i++) // gather results
+          result = result && MatchFlag[i];
+        if (result) { // check results
+          count++;
+          DoLog(1) && (Log() << Verbose(1) << first->name << "-" << second->name << "-" << third->name << " bond found at " << *Walker << "." << endl);
+        }
+      }
+    }
+  }
+  return count;
+};
