Index: src/UIElements/Qt4/InstanceBoard/QtObservedBond.cpp
===================================================================
--- src/UIElements/Qt4/InstanceBoard/QtObservedBond.cpp	(revision b4bd0ec170830621ec3bcc64a4a1a99403399bd9)
+++ src/UIElements/Qt4/InstanceBoard/QtObservedBond.cpp	(revision b4bd0ec170830621ec3bcc64a4a1a99403399bd9)
@@ -0,0 +1,748 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2016 Frederik Heber. All rights reserved.
+ *
+ *
+ *   This file is part of MoleCuilder.
+ *
+ *    MoleCuilder is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation, either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    MoleCuilder is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with MoleCuilder.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * QtObservedBond.cpp
+ *
+ *  Created on: Mar 03, 2016
+ *      Author: heber
+ */
+
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "QtObservedBond.hpp"
+
+#include <QtCore/QMetaType>
+
+#include "UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.hpp"
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include <boost/assign.hpp>
+
+#include "Atom/atom.hpp"
+#include "Bond/bond.hpp"
+#include "World.hpp"
+
+#include "UIElements/Qt4/InstanceBoard/ObservedValue_wCallback.hpp"
+
+using namespace boost::assign;
+
+static const Observable::channels_t getAllObservedAtomChannels()
+{
+  Observable::channels_t channels;
+  channels +=
+      AtomObservable::IndexChanged,
+      AtomObservable::ElementChanged,
+      AtomObservable::PositionChanged;
+  return channels;
+}
+
+static const molecule * getMolecule(const bond::ptr _bond)
+{
+  ASSERT( _bond->leftatom->getMolecule() == _bond->rightatom->getMolecule(),
+      "getMolecule() - leftatom and rightatom belong to different molecules.");
+  return _bond->leftatom->getMolecule();
+}
+
+static const molecule * const getMoleculeConst(const bond::ptr _bond)
+{
+  ASSERT( _bond->leftatom->getMolecule() == _bond->rightatom->getMolecule(),
+      "getMolecule() - leftatom and rightatom belong to different molecules.");
+  return _bond->leftatom->getMolecule();
+}
+
+template <class T>
+Observable * const getObservable(const T * _ptr)
+{
+  return static_cast<Observable * const>(
+      const_cast<T * const>(_ptr));
+}
+
+static QtObservedBond::ObservableCount_t initAllsignedOnChannels(const bond::ptr _bond)
+{
+  const QtObservedBond::ObservableCount_t returnlist =
+      boost::assign::list_of< QtObservedBond::ObservableCount_t::value_type >
+            ( getObservable(_bond.get()), 1)
+            ( getObservable(_bond->leftatom), getAllObservedAtomChannels().size())
+            ( getObservable(_bond->rightatom), getAllObservedAtomChannels().size())
+            ( getObservable(getMolecule(_bond)), 1);
+  return returnlist;
+}
+
+
+// static entities
+const Observable::channels_t
+QtObservedBond::BondDegreeChannels(1, BondObservable::DegreeChanged);
+
+
+QtObservedBond::QtObservedBond(
+    const bondId_t _id,
+    const bond::ptr _bond,
+    QtObservedInstanceBoard &_board,
+    QWidget * _parent) :
+  QWidget(_parent),
+  Observer("QtObservedBond"),
+  AllsignedOnChannels(initAllsignedOnChannels(_bond)),
+  bondowner(NULL),
+  leftatomowner(NULL),
+  rightatomowner(NULL),
+  moleculeowner(NULL),
+  oldbondId(_id),
+  oldleftatomId(_id.first),
+  oldrightatomId(_id.second),
+  oldmoleculeId(getMolecule(_bond)->getId()),
+  board(_board),
+  BoardIsGone(false),
+  ObservedValues(QtObservedBond::MAX_ObservedTypes)
+{
+  qRegisterMetaType<bondId_t>("bondId_t");
+
+  typedef boost::function<ObservableCount_t::mapped_type& (const ObservableCount_t::key_type&)> map_accessor_t;
+  const map_accessor_t accessor =
+      boost::bind<ObservableCount_t::mapped_type&>(
+          &ObservableCount_t::at,
+          boost::ref(subjectKilledCount), _1);
+
+  const boost::function<void (const ObservedValue_Index_t)> bondSubjectKilled(
+      boost::bind(&QtObservedBond::countValuesSubjectKilled,
+          boost::ref(*this),
+          boost::bind(&QtObservedBond::getIndex, boost::cref(*this)),
+          boost::bind(accessor,
+              getObservable(_bond.get()))));
+  const boost::function<void (const ObservedValue_Index_t)> leftatomSubjectKilled(
+      boost::bind(&QtObservedBond::countValuesSubjectKilled,
+          boost::ref(*this),
+          boost::bind(&QtObservedBond::getIndex, boost::cref(*this)),
+          boost::bind(accessor,
+              getObservable(_bond->leftatom))));
+  const boost::function<void (const ObservedValue_Index_t)> rightatomSubjectKilled(
+      boost::bind(&QtObservedBond::countValuesSubjectKilled,
+          boost::ref(*this),
+          boost::bind(&QtObservedBond::getIndex, boost::cref(*this)),
+          boost::bind(accessor,
+              getObservable(_bond->rightatom))));
+  const boost::function<void (const ObservedValue_Index_t)> moleculeSubjectKilled(
+      boost::bind(&QtObservedBond::countValuesSubjectKilled,
+          boost::ref(*this),
+          boost::bind(&QtObservedBond::getIndex, boost::cref(*this)),
+          boost::bind(accessor,
+              getObservable(getMolecule(_bond)))));
+  initObservedValues( ObservedValues, _id, _bond,
+      bondSubjectKilled, leftatomSubjectKilled, rightatomSubjectKilled, moleculeSubjectKilled);
+
+  // activating Observer is done by ObservedValueContainer when it's inserted
+}
+
+QtObservedBond::~QtObservedBond()
+{
+  boost::any_cast<ObservedValue_wCallback<int, ObservedValue_Index_t> *>(ObservedValues[BondDegree])->noteCallBackIsGone();
+  boost::any_cast<ObservedValue_wCallback<atomId_t, ObservedValue_Index_t> *>(ObservedValues[leftAtomIndex])->noteCallBackIsGone();
+  boost::any_cast<ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t> *>(ObservedValues[leftAtomElement])->noteCallBackIsGone();
+  boost::any_cast<ObservedValue_wCallback<Vector, ObservedValue_Index_t> *>(ObservedValues[leftAtomPosition])->noteCallBackIsGone();
+  boost::any_cast<ObservedValue_wCallback<atomId_t, ObservedValue_Index_t> *>(ObservedValues[rightAtomIndex])->noteCallBackIsGone();
+  boost::any_cast<ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t> *>(ObservedValues[rightAtomElement])->noteCallBackIsGone();
+  boost::any_cast<ObservedValue_wCallback<Vector, ObservedValue_Index_t> *>(ObservedValues[rightAtomPosition])->noteCallBackIsGone();
+  boost::any_cast<ObservedValue_wCallback<moleculeId_t, ObservedValue_Index_t> *>(ObservedValues[moleculeIndex])->noteCallBackIsGone();
+
+  deactivateObserver();
+
+  destroyObservedValues(ObservedValues);
+}
+
+#ifdef HAVE_INLINE
+inline
+#endif
+int QtObservedBond::updateDegree(const bond &_bond)
+{
+  return _bond.getDegree();
+}
+
+#ifdef HAVE_INLINE
+inline
+#endif
+atomId_t QtObservedBond::updateLeftAtomIndex(const atom &_atom)
+{
+  return _atom.getId();
+}
+
+#ifdef HAVE_INLINE
+inline
+#endif
+atomicNumber_t QtObservedBond::updateLeftAtomElement(const atom &_atom)
+{
+  return _atom.getElementNo();
+}
+
+#ifdef HAVE_INLINE
+inline
+#endif
+Vector QtObservedBond::updateLeftAtomPosition(const atom &_atom)
+{
+  return _atom.getPosition();
+}
+
+#ifdef HAVE_INLINE
+inline
+#endif
+atomId_t QtObservedBond::updateRightAtomIndex(const atom &_atom)
+{
+  return _atom.getId();
+}
+
+#ifdef HAVE_INLINE
+inline
+#endif
+atomicNumber_t QtObservedBond::updateRightAtomElement(const atom &_atom)
+{
+  return _atom.getElementNo();
+}
+
+#ifdef HAVE_INLINE
+inline
+#endif
+Vector QtObservedBond::updateRightAtomPosition(const atom &_atom)
+{
+  return _atom.getPosition();
+}
+
+#ifdef HAVE_INLINE
+inline
+#endif
+moleculeId_t QtObservedBond::updateMoleculeIndex(const molecule &_mol)
+{
+  return _mol.getId();
+}
+
+void QtObservedBond::update(Observable *publisher)
+{
+  ASSERT(0, "QtObservedBond::update() - we are not signed on for global updates.");
+}
+
+void QtObservedBond::subjectKilled(Observable *publisher)
+{
+  ++(signedOffChannels[publisher]);
+
+  checkForRemoval(getIndex());
+}
+
+void QtObservedBond::countValuesSubjectKilled(
+    ObservedValue_Index_t _id,
+    unsigned int &_counter)
+{
+  ASSERT( _id == getIndex(),
+      "QtObservedBond::countValuesSubjectKilled() - bond "+toString(getIndex())
+      +" received countValuesSubjectKilled for bond id "+toString(_id)+".");
+
+  ++_counter;
+
+  checkForRemoval(_id);
+}
+
+void QtObservedBond::checkForRemoval(ObservedValue_Index_t _id)
+{
+  if (leftatomowner != NULL) {
+    // left atom gone?
+    const ObservableCount_t::const_iterator subjectkilledleftiter =
+        subjectKilledCount.find(const_cast<Observable *>(leftatomowner));
+    ASSERT( (subjectkilledleftiter != subjectKilledCount.end()),
+        "QtObservedBond::checkForRemoval() - leftatomowner not present in subjectKilledCount.");
+    if (subjectkilledleftiter->second == 3) {
+      leftatomowner = NULL;
+    }
+  }
+
+  if (rightatomowner != NULL) {
+    // right atom gone?
+    const ObservableCount_t::const_iterator subjectkilledrightiter =
+        subjectKilledCount.find(const_cast<Observable *>(rightatomowner));
+    ASSERT( (subjectkilledrightiter != subjectKilledCount.end()),
+        "QtObservedBond::checkForRemoval() - rightatomowner not present in subjectKilledCount.");
+    if (subjectkilledrightiter->second == 3) {
+      rightatomowner = NULL;
+    }
+  }
+
+  if (moleculeowner != NULL) {
+    // molecule gone?
+    const ObservableCount_t::const_iterator subjectkilledmoliter =
+        subjectKilledCount.find(const_cast<Observable *>(moleculeowner));
+    ASSERT( (subjectkilledmoliter != subjectKilledCount.end()),
+        "QtObservedBond::checkForRemoval() - moleculeowner not present in subjectKilledCount.");
+    if (subjectkilledmoliter->second == 3) {
+      moleculeowner = NULL;
+    }
+  }
+
+  if (bondowner != NULL) {
+    // only bond needs to be destroyed to signal removal
+    const ObservableCount_t::const_iterator subjectkillediter =
+        subjectKilledCount.find(const_cast<Observable *>(bondowner));
+    const ObservableCount_t::const_iterator allsignediter =
+        AllsignedOnChannels.find(const_cast<Observable *>(bondowner));
+    const ObservableCount_t::const_iterator signedoffiter =
+        signedOffChannels.find(const_cast<Observable *>(bondowner));
+    ASSERT( (subjectkillediter != subjectKilledCount.end())
+        && (allsignediter != AllsignedOnChannels.end())
+        && (signedoffiter != signedOffChannels.end()),
+        "QtObservedBond::checkForRemoval() - something is wrong here.");
+    if ((signedoffiter->second == allsignediter->second)
+        && (subjectkillediter->second == allsignediter->second)) {
+      // remove owner: no more signOff needed
+      bondowner = NULL;
+
+      emit bondRemoved();
+
+      if (!BoardIsGone) {
+        board.markObservedBondAsDisconnected(_id);
+        board.markObservedBondForErase(_id);
+      }
+    }
+  }
+}
+
+void QtObservedBond::recieveNotification(Observable *publisher, Notification_ptr notification)
+{
+  // ObservedValues have been updated before, hence convert updates to Qt's signals
+  if (publisher == leftatomowner) {
+    switch (notification->getChannelNo()) {
+      case AtomObservable::IndexChanged:
+      {
+        const atomId_t newId = getLeftAtomIndex();
+        emit leftAtomIndexChanged(oldleftatomId, newId);
+        oldleftatomId = newId;
+        break;
+      }
+      case AtomObservable::ElementChanged:
+      {
+        emit leftAtomElementChanged();
+        break;
+      }
+      case AtomObservable::PositionChanged:
+      {
+        emit leftAtomPositionChanged();
+        break;
+      }
+      default:
+        ASSERT(0, "QtObservedBond::recieveNotification() - we are not signed on to channel "
+            +toString(notification->getChannelNo())+" of the left atom "
+            +toString(getLeftAtomIndex())+".");
+        break;
+    }
+  } else if (publisher == rightatomowner) {
+    switch (notification->getChannelNo()) {
+      case AtomObservable::IndexChanged:
+      {
+        const atomId_t newId = getRightAtomIndex();
+        emit rightAtomIndexChanged(oldrightatomId, newId);
+        oldrightatomId = newId;
+        break;
+      }
+      case AtomObservable::ElementChanged:
+      {
+        emit rightAtomElementChanged();
+        break;
+      }
+      case AtomObservable::PositionChanged:
+      {
+        emit rightAtomPositionChanged();
+        break;
+      }
+      default:
+        ASSERT(0, "QtObservedBond::recieveNotification() - we are not signed on to channel "
+            +toString(notification->getChannelNo())+" of the right atom "
+            +toString(getRightAtomIndex())+".");
+        break;
+    }
+  } else if (publisher == bondowner) {
+    switch (notification->getChannelNo()) {
+      case BondObservable::DegreeChanged:
+        emit degreeChanged();
+        break;
+      default:
+        ASSERT(0, "QtObservedBond::recieveNotification() - we are not signed on to channel "
+            +toString(notification->getChannelNo())+" of the bond "
+            +toString(getBondIndex())+".");
+        break;
+    }
+  } else if (publisher == moleculeowner) {
+    switch (notification->getChannelNo()) {
+      case molecule::IndexChanged:
+      {
+        const moleculeId_t newId = getMoleculeIndex();
+        emit moleculeIndexChanged(oldmoleculeId, newId);
+        oldmoleculeId = newId;
+        break;
+      }
+      default:
+        ASSERT(0, "QtObservedBond::recieveNotification() - we are not signed on to channel "
+            +toString(notification->getChannelNo())+" of the molecule #"
+            +toString(getMoleculeIndex())+".");
+        break;
+    }
+  } else
+    ASSERT(0,
+        "QtObservedBond::recieveNotification() - received signal from unknown source.");
+}
+
+static QtObservedBond::ObservableCount_t::mapped_type getObservableCountValue(
+    const QtObservedBond::ObservableCount_t &_map,
+    const Observable *_obs)
+{
+  Observable * const obs_const = const_cast<Observable * const>(_obs);
+  QtObservedBond::ObservableCount_t::const_iterator iter = _map.find(obs_const);
+  ASSERT( iter != _map.end(),
+      "getObservableCount_tValue");
+  return iter->second;
+}
+
+static void assignObservableCountValue(
+    QtObservedBond::ObservableCount_t &_map,
+    const Observable *_obs,
+    const QtObservedBond::ObservableCount_t::mapped_type &_value)
+{
+  Observable * const obs_const = const_cast<Observable * const>(_obs);
+  QtObservedBond::ObservableCount_t::iterator iter = _map.find(obs_const);
+  ASSERT( iter != _map.end(),
+      "getObservableCount_tValue");
+  iter->second = _value;
+}
+
+void QtObservedBond::activateObserver()
+{
+  signedOffChannels.clear();
+  subjectKilledCount.clear();
+
+  const atom * rightatom = getAtom(getRightAtomIndex());
+  {
+    const Observable::channels_t channels = getAllObservedAtomChannels();
+    if (rightatom != NULL) {
+      rightatomowner = static_cast<const Observable *>(rightatom);
+      for (Observable::channels_t::const_iterator iter = channels.begin();
+          iter != channels.end(); ++iter)
+        rightatomowner->signOn(this, *iter);
+      subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(rightatomowner), 0));
+      signedOffChannels.insert( std::make_pair(const_cast<Observable * const>(rightatomowner), 0));
+    } else {
+      subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(rightatomowner), channels.size()));
+      assignObservableCountValue(signedOffChannels, rightatomowner,
+          getObservableCountValue(AllsignedOnChannels, rightatomowner));
+    }
+  }
+
+  {
+    const atom * leftatom = getAtom(getLeftAtomIndex());
+    const Observable::channels_t channels = getAllObservedAtomChannels();
+    if (leftatom != NULL) {
+      leftatomowner = static_cast<const Observable *>(leftatom);
+      for (Observable::channels_t::const_iterator iter = channels.begin();
+          iter != channels.end(); ++iter)
+        leftatomowner->signOn(this, *iter);
+      subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(leftatomowner), 0));
+      signedOffChannels.insert( std::make_pair(const_cast<Observable * const>(leftatomowner), 0));
+
+      bond::ptr bondref = leftatom->getBond(rightatom);
+      if (bondref != NULL) {
+        // bond
+        {
+          bondowner = static_cast<const Observable *>(bondref.get());
+          bondowner->signOn(this, BondObservable::DegreeChanged);
+          subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(bondowner), 0));
+          signedOffChannels.insert( std::make_pair(const_cast<Observable * const>(bondowner), 0));
+        }
+
+        const molecule * mol = leftatom->getMolecule();
+        if (mol != NULL) {
+          // molecule
+          moleculeowner = static_cast<const Observable *>(mol);
+          moleculeowner->signOn(this, molecule::IndexChanged);
+          subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(moleculeowner), 0));
+          signedOffChannels.insert( std::make_pair(const_cast<Observable * const>(moleculeowner), 0));
+        } else {
+          subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(moleculeowner), 1));
+          assignObservableCountValue(signedOffChannels, moleculeowner,
+              getObservableCountValue(AllsignedOnChannels, moleculeowner));
+        }
+
+        // and mark as connected
+        if (!BoardIsGone)
+          board.markObservedBondAsConnected(getIndex());
+      } else {
+        subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(bondowner), 1));
+        assignObservableCountValue(signedOffChannels, bondowner,
+            getObservableCountValue(AllsignedOnChannels, bondowner));
+      }
+    } else {
+      subjectKilledCount.insert( std::make_pair(const_cast<Observable * const>(leftatomowner), channels.size()));
+      assignObservableCountValue(signedOffChannels, leftatomowner,
+          getObservableCountValue(AllsignedOnChannels, leftatomowner));
+    }
+  }
+}
+
+void QtObservedBond::deactivateObserver()
+{
+  // sign Off
+  if (leftatomowner != NULL) {
+    const ObservableCount_t::iterator subjectkilledleftiter =
+        subjectKilledCount.find(const_cast<Observable *>(leftatomowner));
+    ASSERT( (subjectkilledleftiter != subjectKilledCount.end()),
+        "QtObservedBond::deactivateObserver() - no entry in subjectKilledCount for left atom "
+        +toString(leftatomowner)+", has activateObserver() been called?");
+    ASSERT( (subjectkilledleftiter->second == 3) || (subjectkilledleftiter->second == 0),
+        "QtObservedBond::deactivateObserver() - cannot deal with partially signed off left atom.");
+    if (subjectkilledleftiter->second == 0) {
+      Observable::channels_t channels = getAllObservedAtomChannels();
+      for (Observable::channels_t::const_iterator iter = channels.begin();
+          iter != channels.end(); ++iter)
+        leftatomowner->signOff(this, *iter);
+      subjectkilledleftiter->second = 3;
+    }
+    leftatomowner = NULL;
+  }
+  if (rightatomowner != NULL) {
+    const ObservableCount_t::iterator subjectkilledrightiter =
+        subjectKilledCount.find(const_cast<Observable *>(rightatomowner));
+    ASSERT( (subjectkilledrightiter != subjectKilledCount.end()),
+        "QtObservedBond::deactivateObserver() - no entry in subjectKilledCount for right atom"
+        +toString(rightatomowner)+", has activateObserver() been called?");
+    ASSERT( (subjectkilledrightiter->second == 3) || (subjectkilledrightiter->second == 0),
+        "QtObservedBond::deactivateObserver() - cannot deal with partially signed off right atom .");
+    if (subjectkilledrightiter->second == 0) {
+      Observable::channels_t channels = getAllObservedAtomChannels();
+      for (Observable::channels_t::const_iterator iter = channels.begin();
+          iter != channels.end(); ++iter)
+        rightatomowner->signOff(this, *iter);
+      subjectkilledrightiter->second = 3;
+    }
+    rightatomowner = NULL;
+  }
+  if (moleculeowner != NULL) {
+    const ObservableCount_t::iterator subjectkilledmoliter =
+        subjectKilledCount.find(const_cast<Observable *>(moleculeowner));
+    ASSERT( (subjectkilledmoliter != subjectKilledCount.end()),
+        "QtObservedBond::deactivateObserver() - no entry in subjectKilledCount for molecule"
+        +toString(moleculeowner)+", has activateObserver() been called?");
+    if (subjectkilledmoliter->second == 0)
+      moleculeowner->signOff(this, molecule::IndexChanged);
+    subjectkilledmoliter->second = 1;
+    moleculeowner = NULL;
+  }
+  if (bondowner != NULL) {
+    const ObservableCount_t::iterator subjectkilledbonditer =
+        subjectKilledCount.find(const_cast<Observable *>(bondowner));
+    ASSERT( (subjectkilledbonditer != subjectKilledCount.end()),
+        "QtObservedBond::deactivateObserver() - no entry in subjectKilledCount for bond"
+        +toString(bondowner)+","
+        +" has activateObserver() been called?");
+    if (subjectkilledbonditer->second == 0)
+      bondowner->signOff(this, BondObservable::DegreeChanged);
+    subjectkilledbonditer->second = 1;
+    bondowner = NULL;
+    signedOffChannels.clear();
+    signedOffChannels.insert(AllsignedOnChannels.begin(), AllsignedOnChannels.end());
+
+    if (!BoardIsGone)
+      board.markObservedBondAsDisconnected(getIndex());
+  }
+}
+
+const atom * const QtObservedBond::getAtomConst(const atomId_t _id)
+{
+  const atom * const _atom = const_cast<const World &>(World::getInstance()).
+      getAtom(AtomById(_id));
+  return _atom;
+}
+
+atom * const QtObservedBond::getAtom(const atomId_t _id)
+{
+  atom * const _atom = World::getInstance().getAtom(AtomById(_id));
+  return _atom;
+}
+
+void QtObservedBond::initObservedValues(
+    ObservedValues_t &_ObservedValues,
+    const bondId_t _id,
+    const bond::ptr _bondref,
+    const boost::function<void(const ObservedValue_Index_t)> &_bondsubjectKilled,
+    const boost::function<void(const ObservedValue_Index_t)> &_leftatomsubjectKilled,
+    const boost::function<void(const ObservedValue_Index_t)> &_rightatomsubjectKilled,
+    const boost::function<void(const ObservedValue_Index_t)> &_moleculesubjectKilled)
+{
+  // fill ObservedValues: index first
+  const boost::function<ObservedValue_Index_t ()> BondIndexGetter =
+      boost::bind(&QtObservedBond::getIndex,
+          boost::cref(*this));
+
+  // fill ObservedValues: then all the other that need index
+  const boost::function<int ()> BondDegreeUpdater(
+      boost::bind(&QtObservedBond::updateDegree, boost::cref(*_bondref)));
+  const boost::function<atomId_t ()> leftAtomIndexUpdater(
+      boost::bind(&QtObservedBond::updateLeftAtomIndex, boost::cref(*_bondref->leftatom)));
+  const boost::function<atomicNumber_t ()> leftAtomElementUpdater(
+      boost::bind(&QtObservedBond::updateLeftAtomElement, boost::cref(*_bondref->leftatom)));
+  const boost::function<Vector ()> leftAtomPositionUpdater(
+      boost::bind(&QtObservedBond::updateLeftAtomPosition, boost::cref(*_bondref->leftatom)));
+  const boost::function<atomId_t ()> rightAtomIndexUpdater(
+      boost::bind(&QtObservedBond::updateRightAtomIndex, boost::cref(*_bondref->rightatom)));
+  const boost::function<atomicNumber_t ()> rightAtomElementUpdater(
+      boost::bind(&QtObservedBond::updateRightAtomElement, boost::cref(*_bondref->rightatom)));
+  const boost::function<Vector ()> rightAtomPositionUpdater(
+      boost::bind(&QtObservedBond::updateRightAtomPosition, boost::cref(*_bondref->rightatom)));
+  const boost::function<moleculeId_t ()> MoleculeIndexUpdater(
+      boost::bind(&QtObservedBond::updateMoleculeIndex, boost::cref(*_bondref->leftatom->getMolecule())));
+
+  _ObservedValues[BondDegree] = new ObservedValue_wCallback<int, ObservedValue_Index_t>(
+      _bondref.get(),
+      BondDegreeUpdater,
+      "BondDegree_bond"+toString(_id),
+      BondDegreeUpdater(),
+      BondDegreeChannels,
+      _bondsubjectKilled,
+      BondIndexGetter);
+  _ObservedValues[leftAtomIndex] = new ObservedValue_wCallback<atomId_t, ObservedValue_Index_t>(
+      _bondref->leftatom,
+      leftAtomIndexUpdater,
+      "LeftAtomIndex_bond"+toString(_id),
+      leftAtomIndexUpdater(),
+      Observable::channels_t(1, AtomObservable::IndexChanged),
+      _leftatomsubjectKilled,
+      BondIndexGetter);
+  _ObservedValues[leftAtomElement] = new ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t>(
+      _bondref->leftatom,
+      leftAtomElementUpdater,
+      "LeftAtomElement_bond"+toString(_id),
+      leftAtomElementUpdater(),
+      Observable::channels_t(1, AtomObservable::ElementChanged),
+      _leftatomsubjectKilled,
+      BondIndexGetter);
+  _ObservedValues[leftAtomPosition] = new ObservedValue_wCallback<Vector, ObservedValue_Index_t>(
+      _bondref->leftatom,
+      leftAtomPositionUpdater,
+      "LeftAtomPosition_bond"+toString(_id),
+      leftAtomPositionUpdater(),
+      Observable::channels_t(1, AtomObservable::PositionChanged),
+      _leftatomsubjectKilled,
+      BondIndexGetter);
+  _ObservedValues[rightAtomIndex] = new ObservedValue_wCallback<atomId_t, ObservedValue_Index_t>(
+      _bondref->rightatom,
+      rightAtomIndexUpdater,
+      "RightAtomIndex_bond"+toString(_id),
+      rightAtomIndexUpdater(),
+      Observable::channels_t(1, AtomObservable::IndexChanged),
+      _rightatomsubjectKilled,
+      BondIndexGetter);
+  _ObservedValues[rightAtomElement] = new ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t>(
+      _bondref->rightatom,
+      rightAtomElementUpdater,
+      "RightAtomElement_bond"+toString(_id),
+      rightAtomElementUpdater(),
+      Observable::channels_t(1, AtomObservable::ElementChanged),
+      _rightatomsubjectKilled,
+      BondIndexGetter);
+  _ObservedValues[rightAtomPosition] = new ObservedValue_wCallback<Vector, ObservedValue_Index_t>(
+      _bondref->rightatom,
+      rightAtomPositionUpdater,
+      "RightAtomPosition_bond"+toString(_id),
+      rightAtomPositionUpdater(),
+      Observable::channels_t(1, AtomObservable::PositionChanged),
+      _rightatomsubjectKilled,
+      BondIndexGetter);
+  _ObservedValues[moleculeIndex] = new ObservedValue_wCallback<moleculeId_t, ObservedValue_Index_t>(
+      _bondref->leftatom->getMolecule(),
+      MoleculeIndexUpdater,
+      "MoleculeIndex_bond"+toString(_id),
+      MoleculeIndexUpdater(),
+      Observable::channels_t(1, AtomObservable::PositionChanged),
+      _moleculesubjectKilled,
+      BondIndexGetter);
+}
+
+void QtObservedBond::destroyObservedValues(
+    std::vector<boost::any> &_ObservedValues)
+{
+  delete boost::any_cast<ObservedValue_wCallback<int, ObservedValue_Index_t> *>(_ObservedValues[BondDegree]);
+  delete boost::any_cast<ObservedValue_wCallback<atomId_t, ObservedValue_Index_t> *>(_ObservedValues[leftAtomIndex]);
+  delete boost::any_cast<ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t> *>(_ObservedValues[leftAtomElement]);
+  delete boost::any_cast<ObservedValue_wCallback<Vector, ObservedValue_Index_t> *>(_ObservedValues[leftAtomPosition]);
+  delete boost::any_cast<ObservedValue_wCallback<atomId_t, ObservedValue_Index_t> *>(_ObservedValues[rightAtomIndex]);
+  delete boost::any_cast<ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t> *>(_ObservedValues[rightAtomElement]);
+  delete boost::any_cast<ObservedValue_wCallback<Vector, ObservedValue_Index_t> *>(_ObservedValues[rightAtomPosition]);
+  delete boost::any_cast<ObservedValue_wCallback<moleculeId_t, ObservedValue_Index_t> *>(_ObservedValues[moleculeIndex]);
+  _ObservedValues.clear();
+}
+
+ObservedValue_Index_t QtObservedBond::getIndex() const
+{
+  ASSERT( bondowner != NULL,
+      "QtObservedBond::getIndex() - index is NULL");
+  return bondowner;
+}
+
+const QtObservedBond::bondId_t QtObservedBond::getBondIndex() const
+{
+  return QtObservedBond::bondId_t(getLeftAtomIndex(), getRightAtomIndex());
+}
+
+const int& QtObservedBond::getBondDegree() const
+{
+  return boost::any_cast<ObservedValue_wCallback<int, ObservedValue_Index_t> *>(ObservedValues[BondDegree])->get();
+}
+
+const atomId_t& QtObservedBond::getLeftAtomIndex() const
+{
+  return boost::any_cast<ObservedValue_wCallback<atomId_t, ObservedValue_Index_t> *>(ObservedValues[leftAtomIndex])->get();
+}
+
+const atomicNumber_t& QtObservedBond::getLeftAtomElement() const
+{
+  return boost::any_cast<ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t> *>(ObservedValues[leftAtomElement])->get();
+}
+
+const Vector& QtObservedBond::getLeftAtomPosition() const
+{
+  return boost::any_cast<ObservedValue_wCallback<Vector, ObservedValue_Index_t> *>(ObservedValues[leftAtomPosition])->get();
+}
+
+const atomId_t& QtObservedBond::getRightAtomIndex() const
+{
+  return boost::any_cast<ObservedValue_wCallback<atomId_t, ObservedValue_Index_t> *>(ObservedValues[rightAtomIndex])->get();
+}
+
+const atomicNumber_t& QtObservedBond::getRightAtomElement() const
+{
+  return boost::any_cast<ObservedValue_wCallback<atomicNumber_t, ObservedValue_Index_t> *>(ObservedValues[rightAtomElement])->get();
+}
+
+const Vector& QtObservedBond::getRightAtomPosition() const
+{
+  return boost::any_cast<ObservedValue_wCallback<Vector, ObservedValue_Index_t> *>(ObservedValues[rightAtomPosition])->get();
+}
+
+const moleculeId_t& QtObservedBond::getMoleculeIndex() const
+{
+  return boost::any_cast<ObservedValue_wCallback<moleculeId_t, ObservedValue_Index_t> *>(ObservedValues[moleculeIndex])->get();
+}
Index: src/UIElements/Qt4/InstanceBoard/QtObservedBond.hpp
===================================================================
--- src/UIElements/Qt4/InstanceBoard/QtObservedBond.hpp	(revision b4bd0ec170830621ec3bcc64a4a1a99403399bd9)
+++ src/UIElements/Qt4/InstanceBoard/QtObservedBond.hpp	(revision b4bd0ec170830621ec3bcc64a4a1a99403399bd9)
@@ -0,0 +1,332 @@
+/*
+ * QtObservedBond.hpp
+ *
+ *  Created on: Mar 03, 2016
+ *      Author: heber
+ */
+
+
+#ifndef QTOBSERVEDBOND_HPP_
+#define QTOBSERVEDBOND_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <QtGui/QWidget>
+
+#include <boost/function.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include "CodePatterns/Observer/Observable.hpp"
+#include "CodePatterns/Observer/Observer.hpp"
+
+#include "LinearAlgebra/Vector.hpp"
+
+#include "Bond/bond.hpp"
+#include "UIElements/Qt4/InstanceBoard/ObservedValue_types.hpp"
+#include "UIElements/Qt4/InstanceBoard/ObservedValuesContainer.hpp"
+#include "types.hpp"
+
+class atom;
+class molecule;
+class QtObservedInstanceBoard;
+class QtObservedMolecule;
+
+/** This instance is the ObservedValue representation of a World's bond.
+ *
+ * Due to the signal/slot mechanism and its delays, lifetime of objects in the
+ * World and their QtGui representation cannot directly be related (without
+ * slowing down Actions just for having the representation up to speed).
+ * Hence, the required information for displaying and representing these
+ * objects must be contained in an extra instance.
+ *
+ * This is the instance for information about a particular bond.
+ *
+ * Essentially, this is the interface between molecuilder's World (and a
+ * particular bond) and the QtGui part of the code.
+ */
+class QtObservedBond : public QWidget, public Observer
+{
+  Q_OBJECT
+
+public:
+  typedef std::pair<atomId_t, atomId_t> bondId_t;
+
+  //!> typedef for instance wrapped in shared ptr
+  typedef boost::shared_ptr<QtObservedBond> ptr;
+
+  //!> typedef for instance wrapped in weak shared ptr
+  typedef boost::weak_ptr<QtObservedBond> weak_ptr;
+
+private:
+  //!> ObservedValuesContainer needs to access private cstor and dstor
+  friend class ObservedValuesContainer<QtObservedBond, ObservedValue_Index_t>;
+  //!> QtObservedInstanceBoard needs to access private cstor and dstor
+  friend class QtObservedInstanceBoard;
+
+  /** Cstor of QtObservedBond.
+   *
+   * \param _id id of observed bond
+   * \param _bond ref to observed bond
+   * \param _board ref to InstanceBoard for callbacks on occasion of subjectKilled()
+   * \param _parent Qt parent to automatically destroy when parent is destroyed
+   */
+  QtObservedBond(
+      const bondId_t _id,
+      const bond::ptr _bond,
+      QtObservedInstanceBoard &_board,
+      QWidget * _parent=0);
+
+public:
+
+  /** Dstor of QtObservedBond.
+   *
+   */
+  ~QtObservedBond();
+
+  // Observer functions
+  void update(Observable *publisher);
+  void subjectKilled(Observable *publisher);
+  void recieveNotification(Observable *publisher, Notification_ptr notification);
+
+  /** Getter for a permanent and unique index of this instance.
+   *
+   * \note ALWAYS use this index if you need to store and identifier to this
+   * instance which you might need to retrieve at some later date.
+   *
+   * \warning DO NOT STORE the QtObserved...:ptr directly. This will possibly
+   * prevent their eventual destruction. Only store the ObservedValue_Index_t
+   * as means to obtain the ptr from the QtObservedInstanceBoard.
+   *
+   * \return returns a unique and permanent index that can be used to retrieve this
+   * instance from the QtObservedInstanceBoard as it must not be stored.
+   */
+  ObservedValue_Index_t getIndex() const;
+
+  /** Getter to bond's index pair contained in \a ObservedValues.
+   *
+   * \return bond's index pair
+   */
+  const bondId_t getBondIndex() const;
+
+  /** Getter to bond's degree contained in \a ObservedValues.
+   *
+   * \return bond's degree
+   */
+  const int& getBondDegree() const;
+
+  /** Getter to bond's left atom index contained in \a ObservedValues.
+   *
+   * \return bond's left atom index
+   */
+  const atomId_t& getLeftAtomIndex() const;
+
+  /** Getter to bond's left atom element contained in \a ObservedValues.
+   *
+   * \return bond's left atom element
+   */
+  const atomicNumber_t& getLeftAtomElement() const;
+
+  /** Getter to bond's right atom position contained in \a ObservedValues.
+   *
+   * \return bond's left atom position
+   */
+  const Vector& getLeftAtomPosition() const;
+
+  /** Getter to bond's right atom index contained in \a ObservedValues.
+   *
+   * \return bond's right atom index
+   */
+  const atomId_t& getRightAtomIndex() const;
+
+  /** Getter to bond's right atom element contained in \a ObservedValues.
+   *
+   * \return bond's right atom element
+   */
+  const atomicNumber_t& getRightAtomElement() const;
+
+  /** Getter to bond's right atom position contained in \a ObservedValues.
+   *
+   * \return bond's right atom position
+   */
+  const Vector& getRightAtomPosition() const;
+
+  /** Getter to bond's molecule index contained in \a ObservedValues.
+   *
+   * \return bond's molecule index
+   */
+  const moleculeId_t& getMoleculeIndex() const;
+
+  //!> typedef for internal observable counter maps
+  typedef std::map<Observable * const, unsigned int> ObservableCount_t;
+
+signals:
+
+  void indexChanged(bondId_t, bondId_t);
+  void degreeChanged();
+  void leftAtomIndexChanged(atomId_t, atomId_t);
+  void leftAtomElementChanged();
+  void leftAtomPositionChanged();
+  void rightAtomIndexChanged(atomId_t, atomId_t);
+  void rightAtomElementChanged();
+  void rightAtomPositionChanged();
+  void moleculeIndexChanged(moleculeId_t, moleculeId_t);
+  void bondRemoved();
+
+//private slots:
+
+private:
+  void activateObserver();
+  void deactivateObserver();
+
+  static const atom * const getAtomConst(const atomId_t _id);
+  static atom * const getAtom(const atomId_t _id);
+
+private:
+  static int updateDegree(const bond &_bond);
+  static atomId_t updateLeftAtomIndex(const atom &_atomref);
+  static atomicNumber_t updateLeftAtomElement(const atom &_atomref);
+  static Vector updateLeftAtomPosition(const atom &_atomref);
+  static atomId_t updateRightAtomIndex(const atom &_atomref);
+  static atomicNumber_t updateRightAtomElement(const atom &_atomref);
+  static Vector updateRightAtomPosition(const atom &_atomref);
+  static moleculeId_t updateMoleculeIndex(const molecule &_molref);
+
+  //!> enumeration of observed values to match with entries in ObservedValues
+  enum ObservedTypes {
+    //!> contains the current bond degree
+    BondDegree,
+    //!> contains the index of the left atom
+    leftAtomIndex,
+    //!> contains the position of the left atom
+    leftAtomPosition,
+    //!> contains the element of the left atom
+    leftAtomElement,
+    //!> contains the index of the right atom
+    rightAtomIndex,
+    //!> contains the position of the right atom
+    rightAtomPosition,
+    //!> contains the element of the right atom
+    rightAtomElement,
+    //!> contains the id of the molecule this bond is associated with
+    moleculeIndex,
+    //!> gives the size of the enumeration
+    MAX_ObservedTypes
+  };
+
+  /** Initializes all \a ObservedValues entries.
+   *
+   * \param _ObservedValues vector of ObservedValue to be filled
+   * \param _id bond id
+   * \param _bondref reference to bond
+   * \param _bondsubjectKilled ref to function to call on subjectKilled() from bond
+   * \param _leftatomsubjectKilled ref to function to call on subjectKilled() from leftatom
+   * \param _rightatomsubjectKilled ref to function to call on subjectKilled() from rightatom
+   * \param _moleculesubjectKilled ref to function to call on subjectKilled() from molecule
+   */
+  void initObservedValues(
+      ObservedValues_t &_ObservedValues,
+      const bondId_t _id,
+      const bond::ptr _bondref,
+      const boost::function<void(const ObservedValue_Index_t)> &_bondsubjectKilled,
+      const boost::function<void(const ObservedValue_Index_t)> &_leftatomsubjectKilled,
+      const boost::function<void(const ObservedValue_Index_t)> &_rightatomsubjectKilled,
+      const boost::function<void(const ObservedValue_Index_t)> &_moleculesubjectKilled);
+
+  /** Destroys all \a ObservedValues entries.
+   *
+   * \param _ObservedValues vector of ObservedValue to be destroyed
+   */
+  static void destroyObservedValues(
+      std::vector<boost::any> &_ObservedValues);
+
+  /** Function is called by InstanceBoard to inform about its destruction.
+   *
+   * \note callbacks must not be used after this
+   */
+  void noteBoardIsGone()
+  { BoardIsGone = true; }
+
+  /** Counts the number of subject killed received from the observed values.
+   *
+   * \param _id id to check against ours
+   * \param _counter counter to decrease
+   */
+  void countValuesSubjectKilled(ObservedValue_Index_t _id, unsigned int &_counter);
+
+  //!> counts how many ObservedValues have already been subjectKilled() for a given observable
+  mutable ObservableCount_t subjectKilledCount;
+
+  /** Helper function to check that all subjectKilled have been received for both
+   * this instance and all its internal observed values.
+   *
+   * \param _id id to check against ours
+   */
+  void checkForRemoval(ObservedValue_Index_t _id);
+
+private:
+
+  //!> list of channels when index needs to update
+  static const Observable::channels_t BondDegreeChannels;
+
+  //!> we get multiple subjectKilled(), count and call callback() only on last
+  const ObservableCount_t AllsignedOnChannels;
+  ObservableCount_t signedOffChannels;
+
+  //!> the Observable we are signed on, also indicates whether we are sign on (not NULL)
+  const Observable *bondowner;
+  const Observable *leftatomowner;
+  const Observable *rightatomowner;
+  const Observable *moleculeowner;
+
+private:
+
+  /** Internal setter for the weak shared_ptr instance that we sometimes
+   * need to convert the ref to this instance into an shared ptr instance that
+   * is safe to hand around.
+   *
+   * \param _selfref ref to shared ptr instance that is internally stored
+   */
+  void setSelfRef(const weak_ptr &_selfref)
+  { const_cast<weak_ptr &>(selfref) = _selfref; }
+
+  //!> reference to this instance wrapped in a shared ptr for handing around
+  const weak_ptr selfref;
+
+public:
+
+  /** Getter for this instance safely wrapped in a shared ptr instance for
+   * handing arount.
+   *
+   * \return shared ptr of this instance
+   */
+  ptr getRef() const
+  { return ptr(selfref); }
+
+private:
+  //!> contains still the old id after the index of the bond changed
+  bondId_t oldbondId;
+
+  //!> contains still the old id after the index of the left atom changed
+  atomId_t oldleftatomId;
+
+  //!> contains still the old id after the index of the right atom changed
+  atomId_t oldrightatomId;
+
+  //!> contains still the old id after the index of the molecule changed
+  moleculeId_t oldmoleculeId;
+
+  //!> reference to InstanceBoard for callbacks on subjectKilled()
+  QtObservedInstanceBoard & board;
+
+  //!> is board still alive or not, impacts callbacks
+  bool BoardIsGone;
+
+  //!> internal reference to ObservedValues held by QtObservedInstanceBoard
+  ObservedValues_t ObservedValues;
+};
+
+
+#endif /* QTOBSERVEDBOND_HPP_ */
Index: src/UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.cpp
===================================================================
--- src/UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.cpp	(revision bf6245259c76b4be2e6085db24148e21e1844c8f)
+++ src/UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.cpp	(revision b4bd0ec170830621ec3bcc64a4a1a99403399bd9)
@@ -62,4 +62,8 @@
       *this,
       boost::bind(&QtObservedInstanceBoard::atomcountsubjectKilled, this, _1)),
+  bondObservedValues(
+      "bond",
+      *this,
+      boost::bind(&QtObservedInstanceBoard::bondcountsubjectKilled, this, _1)),
   moleculeObservedValues(
       "molecule",
@@ -69,4 +73,5 @@
   qRegisterMetaType<ObservedValue_Index_t>("ObservedValue_Index_t");
   qRegisterMetaType<QtObservedAtom::ptr>("QtObservedAtom::ptr");
+  qRegisterMetaType<QtObservedBond::ptr>("QtObservedBond::ptr");
   qRegisterMetaType<QtObservedMolecule::ptr>("QtObservedMolecule::ptr");
 
@@ -83,9 +88,10 @@
     World::getInstance().signOff(this, World::MoleculeInserted);
   }
-  // sign off from all remaining molecules and atoms
+  // sign off from all remaining molecules, bonds, and atoms
   for (SignedOn_t::iterator iter = AtomSignedOn.begin(); !AtomSignedOn.empty();
       iter = AtomSignedOn.begin()) {
     (*iter)->signOff(this, atom::IndexChanged);
-    AtomSignedOn.erase(iter);
+    (*iter)->signOff(this, atom::BondsAdded);
+    AtomSignedOn.erase(*iter);
   }
 
@@ -108,5 +114,5 @@
   if ( iter != AtomSignedOn.end()) {
     LOG(3, "DEBUG: InstanceBoard got subjectKilled() from atom " << publisher);
-    AtomSignedOn.erase(iter);
+    AtomSignedOn.erase(iter); // only remove one
   } else {
     iter = MoleculeSignedOn.find(publisher);
@@ -176,4 +182,6 @@
           LOG(3, "DEBUG: InformationBoard signOn()s to atom " << _id);
           _atom->signOn(this, atom::IndexChanged);
+          _atom->signOn(this, atom::BondsAdded);
+          AtomSignedOn.insert( static_cast<Observable *>(const_cast<atom *>(_atom)) );
           AtomSignedOn.insert( static_cast<Observable *>(const_cast<atom *>(_atom)) );
           emit atomInserted(observedatom);
@@ -232,4 +240,30 @@
         break;
       }
+      case AtomObservable::BondsAdded:
+      {
+        const atom * _atom = dynamic_cast<atom *>(publisher);
+        const atomId_t _id = _atom->getId();
+#ifdef LOG_OBSERVER
+      observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been inserted.";
+#endif
+        LOG(3, "DEBUG: InformationBoard got bondInserted signal for atom " << _id);
+        if (_atom != NULL) {
+          // find the new bond by simply taking the last added to the list
+          const BondList &ListOfBonds = _atom->getListOfBonds();
+          const bond::ptr bondref = ListOfBonds.back();
+          const bondId_t bondid =
+              std::make_pair( bondref->leftatom->getId(), bondref->rightatom->getId());
+          LOG(3, "DEBUG: InformationBoard initializes QtObservedBond for " << bondid);
+          QtObservedBond::ptr observedbond(
+              new QtObservedBond(bondid, bondref, *this));
+          const ObservedValue_Index_t index = observedbond->getIndex();
+          bondObservedValues.insert(index, observedbond);
+          bondids_lookup.left.insert( std::make_pair(bondid, index) );
+          emit bondInserted(observedbond);
+        } else {
+          ELOG(1, "QtObservedInstanceBoard got BondsAdded for unknown atom id " << _id);
+        }
+        break;
+      }
       default:
         ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - we cannot get here.");
@@ -239,16 +273,4 @@
     ASSERT(0, "QtObservedInstanceBoard::recieveNotification() - notification from unknown source.");
   }
-}
-
-void QtObservedInstanceBoard::atomcountsubjectKilled(ObservedValue_Index_t _id)
-{
-  LOG(3, "DEBUG: InstanceBoard emits atomRemoved for " << _id);
-  emit atomRemoved(_id);
-}
-
-void QtObservedInstanceBoard::moleculecountsubjectKilled(ObservedValue_Index_t _id)
-{
-  LOG(3, "DEBUG: InstanceBoard emits moleculeRemoved for " << _id);
-  emit moleculeRemoved(_id);
 }
 
@@ -262,4 +284,14 @@
 }
 
+const QtObservedInstanceBoard::bondId_t
+QtObservedInstanceBoard::getBondIdToIndex(ObservedValue_Index_t _id) const
+{
+  typename IdtoIndex_t<bondId_t>::right_const_iterator iter = bondids_lookup.right.find(_id);
+  ASSERT( iter != bondids_lookup.right.end(),
+      "QtObservedInstanceBoard::getBondIdToIndex() - index "
+      +toString(_id)+" is unknown.");
+  return iter->second;
+}
+
 const moleculeId_t QtObservedInstanceBoard::getMoleculeIdToIndex(ObservedValue_Index_t _id) const
 {
@@ -271,4 +303,22 @@
 }
 
+void QtObservedInstanceBoard::atomcountsubjectKilled(ObservedValue_Index_t _id)
+{
+  LOG(3, "DEBUG: InstanceBoard emits atomRemoved for " << getAtomIdToIndex(_id));
+  emit atomRemoved(_id);
+}
+
+void QtObservedInstanceBoard::bondcountsubjectKilled(ObservedValue_Index_t _id)
+{
+  LOG(3, "DEBUG: InstanceBoard emits bondRemoved for " << getBondIdToIndex(_id));
+  emit bondRemoved(_id);
+}
+
+void QtObservedInstanceBoard::moleculecountsubjectKilled(ObservedValue_Index_t _id)
+{
+  LOG(3, "DEBUG: InstanceBoard emits moleculeRemoved for " << getMoleculeIdToIndex(_id));
+  emit moleculeRemoved(_id);
+}
+
 QtObservedAtom::ptr QtObservedInstanceBoard::getObservedAtom(const atomId_t _id)
 {
@@ -279,4 +329,14 @@
 {
   return atomObservedValues.get(_id);
+}
+
+QtObservedBond::ptr QtObservedInstanceBoard::getObservedBond(const bondId_t _id)
+{
+  return bondObservedValues.get(bondids_lookup.left.at(_id));
+}
+
+QtObservedBond::ptr QtObservedInstanceBoard::getObservedBond(ObservedValue_Index_t _id)
+{
+  return bondObservedValues.get(_id);
 }
 
@@ -307,4 +367,20 @@
 }
 
+void QtObservedInstanceBoard::markObservedBondAsConnected(ObservedValue_Index_t _id)
+{
+  bondObservedValues.markObservedValuesAsConnected(_id);
+}
+
+void QtObservedInstanceBoard::markObservedBondAsDisconnected(ObservedValue_Index_t _id)
+{
+  bondObservedValues.markObservedValuesAsDisconnected(_id);
+}
+
+void QtObservedInstanceBoard::markObservedBondForErase(ObservedValue_Index_t _id)
+{
+  bondObservedValues.eraseObservedValues(_id);
+  bondids_lookup.right.erase(_id);
+}
+
 void QtObservedInstanceBoard::markObservedMoleculeAsConnected(ObservedValue_Index_t _id)
 {
Index: src/UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.hpp
===================================================================
--- src/UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.hpp	(revision bf6245259c76b4be2e6085db24148e21e1844c8f)
+++ src/UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.hpp	(revision b4bd0ec170830621ec3bcc64a4a1a99403399bd9)
@@ -18,4 +18,5 @@
 
 #include "UIElements/Qt4/InstanceBoard/QtObservedAtom.hpp"
+#include "UIElements/Qt4/InstanceBoard/QtObservedBond.hpp"
 #include "UIElements/Qt4/InstanceBoard/QtObservedMolecule.hpp"
 
@@ -64,4 +65,7 @@
 
 public:
+  //!> copy bond id type from QtObservedBond
+  typedef QtObservedBond::bondId_t bondId_t;
+
   /** Cstor of QtObservedInstanceBoard.
    *
@@ -81,8 +85,11 @@
 
   const atomId_t getAtomIdToIndex(ObservedValue_Index_t _id) const;
+  const bondId_t getBondIdToIndex(ObservedValue_Index_t _id) const;
   const moleculeId_t getMoleculeIdToIndex(ObservedValue_Index_t _id) const;
 
   QtObservedAtom::ptr getObservedAtom(const atomId_t _id);
   QtObservedAtom::ptr getObservedAtom(ObservedValue_Index_t _id);
+  QtObservedBond::ptr getObservedBond(const bondId_t _id);
+  QtObservedBond::ptr getObservedBond(ObservedValue_Index_t _id);
   QtObservedMolecule::ptr getObservedMolecule(const moleculeId_t _id);
   QtObservedMolecule::ptr getObservedMolecule(ObservedValue_Index_t _id);
@@ -90,4 +97,7 @@
   void markObservedAtomAsDisconnected(ObservedValue_Index_t _id);
   void markObservedAtomForErase(ObservedValue_Index_t _id);
+  void markObservedBondAsConnected(ObservedValue_Index_t _id);
+  void markObservedBondAsDisconnected(ObservedValue_Index_t _id);
+  void markObservedBondForErase(ObservedValue_Index_t _id);
   void markObservedMoleculeAsConnected(ObservedValue_Index_t _id);
   void markObservedMoleculeAsDisconnected(ObservedValue_Index_t _id);
@@ -98,4 +108,7 @@
   void atomRemoved(ObservedValue_Index_t _atomid);
   void atomIndexChanged(const atomId_t _oldid, const atomId_t _newid);
+  void bondInserted(QtObservedBond::ptr _bond);
+  void bondRemoved(ObservedValue_Index_t _bondid);
+  void bondIndexChanged(const bondId_t _oldid, const bondId_t _newid);
   void moleculeInserted(QtObservedMolecule::ptr _mol);
   void moleculeRemoved(ObservedValue_Index_t _molid);
@@ -111,5 +124,5 @@
   bool WorldSignedOn;
 
-  typedef std::set<Observable *> SignedOn_t;
+  typedef std::multiset<Observable *> SignedOn_t;
   //!> map indicating to which atom we are currently signed on
   SignedOn_t AtomSignedOn;
@@ -121,4 +134,5 @@
   struct IdtoIndex_t : boost::bimap<id, ObservedValue_Index_t> {};
   IdtoIndex_t<atomId_t> atomids_lookup;
+  IdtoIndex_t<bondId_t> bondids_lookup;
   IdtoIndex_t<moleculeId_t> moleculeids_lookup;
 
@@ -132,4 +146,14 @@
    */
   void atomcountsubjectKilled(ObservedValue_Index_t _id);
+
+  /** Counts how many bond's ObservedValues got subjectKilled.
+   *
+   * This is used to give removal signal only when each and every
+   * ObservedValue (and the instance itself) has been subjectKilled by the
+   * monitored Observable. Only then can we safely remove the instance.
+   *
+   * \param _bondid id of the bond
+   */
+  void bondcountsubjectKilled(ObservedValue_Index_t _bondid);
 
   /** Counts how many molecule's ObservedValues got subjectKilled.
@@ -145,4 +169,6 @@
   //!> container with all ObservedValues for each atom, associated by id
   ObservedValuesContainer<QtObservedAtom, ObservedValue_Index_t> atomObservedValues;
+  //!> container with all ObservedValues for each bond, associated by id pairs
+  ObservedValuesContainer<QtObservedBond, ObservedValue_Index_t> bondObservedValues;
   //!> container with all ObservedValues for each molecule, associated by id
   ObservedValuesContainer<QtObservedMolecule, ObservedValue_Index_t> moleculeObservedValues;
