Index: src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_bond.cpp
===================================================================
--- src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_bond.cpp	(revision 3b9aa1d67a8d8ea7123888eda5cdd0f9d1ac1060)
+++ src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_bond.cpp	(revision 96f14ae4f021b1976486ad5658a68c30645c7467)
@@ -47,7 +47,5 @@
 #include "CodePatterns/Assert.hpp"
 #include "CodePatterns/Log.hpp"
-#include "CodePatterns/Observer/Notification.hpp"
-#include "CodePatterns/Observer/ObserverLog.hpp"
-#include "Descriptors/AtomIdDescriptor.hpp"
+
 #include "Atom/atom.hpp"
 #include "Bond/bond.hpp"
@@ -56,275 +54,69 @@
 #include "LinearAlgebra/Line.hpp"
 #include "LinearAlgebra/Vector.hpp"
-#include "UIElements/Qt4/InstanceBoard/ObservedValue_wCallback.hpp"
 #include "World.hpp"
-
-
-// static entities
-const Observable::channels_t
-GLMoleculeObject_bond::IndexChannels(1, AtomObservable::IndexChanged);
-const Observable::channels_t
-GLMoleculeObject_bond::BondPositionChannels(1, AtomObservable::PositionChanged);
-const Observable::channels_t
-GLMoleculeObject_bond::BondDegreeChannels(1, BondObservable::DegreeChanged);
-const Observable::channels_t
-GLMoleculeObject_bond::BondElementChannels(1, AtomObservable::ElementChanged);
-
-static GLMoleculeObject_bond::bondIds_t getBondIdsForIds(
-    const boost::function<const atomId_t()> &_left,
-    const boost::function<const atomId_t()> &_right)
-{
-  return std::make_pair(_left(), _right());
-}
 
 GLMoleculeObject_bond::GLMoleculeObject_bond(
     QGLSceneNode *mesh[],
     QObject *parent,
-    const bondIds_t bondIds,
+    QtObservedBond::ptr &_ObservedBond,
     const enum SideOfBond side) :
   GLMoleculeObject(mesh, parent),
-  Observer(std::string("GLMoleculeObject_bond")
-      +toString(bondIds.first)
-      +std::string("-")
-      +toString(bondIds.second)),
-  leftowner(getAtomConst(bondIds.first)),
-  rightowner(getAtomConst(bondIds.second)),
-  bondowner(getAtomConst(bondIds.first)->getBond(getAtomConst(bondIds.second)).get()),
   BondSide(side),
-  ObservedValues(MAX_ObservedTypes),
-  subjectKilledCount(0),
-  leftobservable_enabled(false),
-  rightobservable_enabled(false),
-  board_subjectKilled(
-      boost::bind(
-          static_cast<void (GLMoleculeObject_bond::*) ()>(
-              &GLMoleculeObject_bond::countsubjectKilled),
-          this))
+  ObservedBond(_ObservedBond)
 {
-  boost::function<void(const atomId_t &)> leftsubjectKilled =
-      boost::bind(
-          static_cast<void (GLMoleculeObject_bond::*) (const atomId_t &)>(
-              &GLMoleculeObject_bond::countsubjectKilled),
-          this, _1);
-  boost::function<void(const atomId_t &)> rightsubjectKilled =
-      boost::bind(
-          static_cast<void (GLMoleculeObject_bond::*) (const atomId_t &)>(
-              &GLMoleculeObject_bond::countsubjectKilled)
-              , this, _1);
-  boost::function<void(const bondIds_t &)> bondsubjectKilled =
-      boost::bind(
-          static_cast<void (GLMoleculeObject_bond::*) (const bondIds_t &)>(
-              &GLMoleculeObject_bond::countsubjectKilled)
-              , this, _1);
-  initObservedValues(
-      ObservedValues,
-      bondIds.first,
-      bondIds.second,
-      leftowner,
-      rightowner,
-      bondowner,
-      leftsubjectKilled,
-      rightsubjectKilled,
-      bondsubjectKilled);
-
-  init();
-}
-
-GLMoleculeObject_bond::GLMoleculeObject_bond(
-    QGLSceneNode *mesh[],
-    QObject *parent,
-    const bondIds_t bondIds,
-    const enum SideOfBond side,
-    std::vector<boost::any> &_ObservedValues,
-    const boost::function<void (const bondIds_t)> &_subjectKilled) :
-  GLMoleculeObject(mesh, parent),
-  Observer(std::string("GLMoleculeObject_bond")
-      +toString(bondIds.first)
-      +std::string("-")
-      +toString(bondIds.second)),
-  leftowner(getAtomConst(bondIds.first)),
-  rightowner(getAtomConst(bondIds.second)),
-  bondowner(getAtomConst(bondIds.first)->getBond(getAtomConst(bondIds.second)).get()),
-  BondSide(side),
-  ObservedValues(_ObservedValues),
-  subjectKilledCount(0),
-  leftobservable_enabled(false),
-  rightobservable_enabled(false),
-  board_subjectKilled(_subjectKilled)
-{
-  init();
-}
-
-void GLMoleculeObject_bond::init()
-{
-  // sign on as observer (obtain non-const instance before)
-  bondowner->signOn(this, BondObservable::BondRemoved);
-  bondowner->signOn(this, BondObservable::DegreeChanged);
-  bond_enabled = true;
-  leftowner->signOn(this, AtomObservable::PositionChanged);
-  leftowner->signOn(this, AtomObservable::ElementChanged);
-  leftobservable_enabled = true;
-  rightowner->signOn(this, AtomObservable::PositionChanged);
-  rightowner->signOn(this, AtomObservable::ElementChanged);
-  rightobservable_enabled = true;
-
   resetElement();
   resetPosition();
   resetWidth();
 
-  connect(this, SIGNAL(elementChanged()), this, SLOT(resetElement()), Qt::QueuedConnection);
-  connect(this, SIGNAL(positionChanged()), this, SLOT(resetPosition()), Qt::QueuedConnection);
-  connect(this, SIGNAL(degreeChanged()), this, SLOT(resetWidth()), Qt::QueuedConnection);
+  // connect to observed bond's signals
+  connect(_ObservedBond.get(), SIGNAL(degreeChanged()), this, SLOT(resetWidth()));
+  if (side == left)
+    connect(_ObservedBond.get(), SIGNAL(leftAtomElementChanged()), this, SLOT(resetElement()));
+  else
+    connect(_ObservedBond.get(), SIGNAL(rightAtomElementChanged()), this, SLOT(resetElement()));
+  connect(_ObservedBond.get(), SIGNAL(leftAtomPositionChanged()), this, SLOT(resetPosition()));
+  connect(_ObservedBond.get(), SIGNAL(rightAtomPositionChanged()), this, SLOT(resetPosition()));
+}
+
+static const atomicNumber_t& getElement(
+    const QtObservedBond::ptr &_ObservedBond,
+    const enum GLMoleculeObject_bond::SideOfBond _side)
+{
+  if (_side == GLMoleculeObject_bond::left)
+    return _ObservedBond->getLeftAtomElement();
+  else
+    return _ObservedBond->getRightAtomElement();
+}
+
+static const Vector& getPosition(
+    const QtObservedBond::ptr &_ObservedBond,
+    const enum GLMoleculeObject_bond::SideOfBond _side)
+{
+  if (_side == GLMoleculeObject_bond::left)
+    return _ObservedBond->getLeftAtomPosition();
+  else
+    return _ObservedBond->getRightAtomPosition();
+}
+
+static const Vector& getOtherPosition(
+    const QtObservedBond::ptr &_ObservedBond,
+    const enum GLMoleculeObject_bond::SideOfBond _side)
+{
+  if (_side == GLMoleculeObject_bond::left)
+    return _ObservedBond->getRightAtomPosition();
+  else
+    return _ObservedBond->getLeftAtomPosition();
 }
 
 GLMoleculeObject_bond::~GLMoleculeObject_bond()
 {
-  LOG(3, "DEBUG: Destroying  GLMoleculeObject_bond to bond [" <<
-      getleftIndex() << "," << getrightIndex() << "] and side " << BondSide << ".");
+  LOG(4, "DEBUG: Destroying  GLMoleculeObject_bond to bond [" <<
+      ObservedBond->getBondIndex() << "] and side " << BondSide << ".");
   // signOff() if not already done
-  removeChannels();
-  destroyObservedValues(ObservedValues);
-}
-
-void GLMoleculeObject_bond::removeChannels()
-{
-  // at this point both atoms should still be alive, hence we may safely sign off
-  // from the AtomObservable itself
-  if (bond_enabled) {
-    if (bondowner != NULL) {
-      bondowner->signOff(this, BondObservable::BondRemoved);
-      bondowner->signOff(this, BondObservable::DegreeChanged);
-    }
-    bond_enabled = false;
-  }
-  if (leftobservable_enabled) {
-    if (leftowner != NULL) {
-      leftowner->signOff(this, AtomObservable::PositionChanged);
-      leftowner->signOff(this, AtomObservable::ElementChanged);
-    }
-    leftobservable_enabled = false;
-  }
-  if (rightobservable_enabled) {
-    if (rightowner != NULL) {
-      rightowner->signOff(this, AtomObservable::PositionChanged);
-      rightowner->signOff(this, AtomObservable::ElementChanged);
-    }
-    rightobservable_enabled = false;
-  }
-}
-
-void GLMoleculeObject_bond::update(Observable *publisher)
-{
-  ASSERT(0, "GLMoleculeObject_bond::update() - we are not signed on for any global updates.");
-}
-
-void GLMoleculeObject_bond::subjectKilled(Observable *publisher)
-{
-  // we signOff from all other sources
-  removeChannels();
-  // check whether we should be removed
-  board_subjectKilled(std::make_pair(getleftIndex(), getrightIndex()));
-}
-
-void GLMoleculeObject_bond::recieveNotification(Observable *publisher, Notification_ptr notification)
-{
-#ifdef LOG_OBSERVER
-  if (publisher == static_cast<const Observable *>(bondowner)) {
-    observerLog().addMessage() << "++ Update of Observer "
-        << observerLog().getName(static_cast<Observer*>(this))
-        << " received notification from bond for channel "
-        << notification->getChannelNo() << ".";
-  } else if (publisher == static_cast<const Observable * const>(leftowner)) {
-    observerLog().addMessage() << "++ Update of Observer "
-        << observerLog().getName(static_cast<Observer*>(this))
-        << " received notification from leftatom " << getleftIndex() << " for channel "
-        << notification->getChannelNo() << ".";
-  } else if (publisher == static_cast<const Observable * const>(rightowner)) {
-    observerLog().addMessage() << "++ Update of Observer "
-        << observerLog().getName(static_cast<Observer*>(this))
-        << " received notification from rightatom " << getrightIndex() << " for channel "
-        << notification->getChannelNo() << ".";
-  }
-#endif
-  if (publisher == static_cast<const Observable *>(bondowner)){
-    switch (notification->getChannelNo()) {
-    case BondObservable::BondRemoved:
-//      removeMe();
-      break;
-    case BondObservable::DegreeChanged:
-      emit degreeChanged();
-      break;
-    default:
-      ASSERT(0, "GLMoleculeObject_bond::recieveNotification() - unknown signal.");
-      break;
-    }
-  } else {
-    // from an atom
-    switch (notification->getChannelNo()) {
-    case AtomObservable::PositionChanged:
-      LOG(2, "INFO: Received notification of PositionChanged.");
-      emit positionChanged();
-      break;
-    case AtomObservable::ElementChanged:
-      LOG(2, "INFO: Received notification of ElementChanged.");
-      emit elementChanged();
-      break;
-    default:
-      break;
-    }
-  }
-}
-
-atomId_t GLMoleculeObject_bond::updateIndex()
-{
-  return const_cast<const World &>(World::getInstance()).lastChangedAtomId();
-}
-
-Vector GLMoleculeObject_bond::updateLeftPosition(
-    const boost::function<const atomId_t ()> &_getLeftAtomIndex)
-{
-  const atom * const _atom = getAtomConst(_getLeftAtomIndex());
-  return _atom->getPosition();
-}
-
-Vector GLMoleculeObject_bond::updateRightPosition(
-    const boost::function<const atomId_t ()> &_getRightAtomIndex)
-{
-  const atom * const _atom = getAtomConst(_getRightAtomIndex());
-  return _atom->getPosition();
-}
-
-atomicNumber_t GLMoleculeObject_bond::updateLeftElement(
-    const boost::function<const atomId_t ()> &_getLeftAtomIndex)
-{
-  const atom * const _atom = getAtomConst(_getLeftAtomIndex());
-  return _atom->getElementNo();
-}
-
-atomicNumber_t GLMoleculeObject_bond::updateRightElement(
-    const boost::function<const atomId_t ()> &_getRightAtomIndex)
-{
-  const atom * const _atom = getAtomConst(_getRightAtomIndex());
-  return _atom->getElementNo();
-}
-
-int GLMoleculeObject_bond::updateDegree(
-    const boost::function<const atomId_t ()> &_getLeftAtomIndex,
-    const boost::function<const atomId_t ()> &_getRightAtomIndex)
-{
-  const atom * const _leftatom = const_cast<const World &>(World::getInstance()).
-      getAtom(AtomById(_getLeftAtomIndex()));
-  const atom * const _rightatom = const_cast<const World &>(World::getInstance()).
-      getAtom(AtomById(_getRightAtomIndex()));
-  if ((_leftatom != NULL) && (_rightatom != NULL)) {
-    bond::ptr _bond = _leftatom->getBond(_rightatom);
-    return _bond->getDegree();
-  } else {
-    return 1;
-  }
 }
 
 void GLMoleculeObject_bond::resetElement()
 {
-  size_t elementno = getrightElement();
+  const atomicNumber_t& elementno = getElement(ObservedBond, BondSide);
   QGLMaterial *elementmaterial = getMaterial(elementno);
   setMaterial(elementmaterial);
@@ -333,6 +125,6 @@
 void GLMoleculeObject_bond::resetWidth()
 {
-  const double factor = 1.0f+.5f*(getDegree()-1);
-  LOG(2, "DEBUG: GLMoleculeObject_bond::resetWidth() - setting bond's width to " << factor << ".");
+  const double factor = 1.0f+.5f*(ObservedBond->getBondDegree()-1);
+  LOG(4, "DEBUG: GLMoleculeObject_bond::resetWidth() - setting bond's width to " << factor << ".");
   setScaleX(factor);
   setScaleY(factor);
@@ -343,6 +135,6 @@
 void GLMoleculeObject_bond::resetPosition()
 {
-  Vector Position = getleftPosition();
-  Vector OtherPosition = getrightPosition();
+  const Vector& Position = getPosition(ObservedBond, BondSide);
+  const Vector& OtherPosition = getOtherPosition(ObservedBond, BondSide);
   const double distance =
       Position.distance(OtherPosition)/2.;
@@ -355,5 +147,5 @@
   Vector OtherAxis;
   double alpha;
-  a = Position - OtherPosition;
+  a = OtherPosition - Position;
   // construct rotation axis
   b = a;
@@ -370,9 +162,9 @@
   // check
   Vector a_rotated = axis.rotateVector(a, alpha);
-  LOG(3, "INFO: Created cylinder from "// << Position << " to " << OtherPosition
+  LOG(4, "DEBUG: Created cylinder from "// << Position << " to " << OtherPosition
       << a << " to " << a_rotated << " around " << b << " by " << alpha/M_PI*180. << ", respectively.");
 
   // set position (cylinder offset is in its barymetric center)
-  Vector OneFourth(Position - 0.75 * a);
+  Vector OneFourth(OtherPosition - 0.75 * a);
   setPosition(QVector3D(OneFourth[0], OneFourth[1], OneFourth[2]));
   setRotationVector(QVector3D(b[0], b[1], b[2]));
@@ -381,181 +173,2 @@
   emit changed();
 }
-
-atom * const GLMoleculeObject_bond::getAtom(const atomId_t _id)
-{
-  atom * const _atom = World::getInstance().getAtom(AtomById(_id));
-  return _atom;
-}
-
-const atom * const GLMoleculeObject_bond::getAtomConst(const atomId_t _id)
-{
-  const atom * const _atom = const_cast<const World &>(World::getInstance()).
-      getAtom(AtomById(_id));
-  return _atom;
-}
-
-void GLMoleculeObject_bond::countsubjectKilled()
-{
-  ++subjectKilledCount;
-
-  if (subjectKilledCount > ObservedValues.size())
-    emit BondRemoved(getleftIndex(), getrightIndex());
-}
-
-void GLMoleculeObject_bond::initObservedValues(
-    std::vector<boost::any> &_ObservedValues,
-    const atomId_t _leftatomId,
-    const atomId_t _rightatomId,
-    const Observable * const _leftowner,
-    const Observable * const _rightowner,
-    const Observable * const _bondowner,
-    const boost::function<void(const atomId_t &)> &_leftsubjectKilled,
-    const boost::function<void(const atomId_t &)> &_rightsubjectKilled,
-    const boost::function<void(const bondIds_t &)> &_bondsubjectKilled)
-{
-  /* This is an old note from when the code was still part of cstor's initializer body.
-   * TODO: Probably does not apply anymore but has not yet been tested.
-   *
-   * We must not use boost::cref(this) as "this" has not been properly constructed and seemingly
-   * boost::cref tries to do some magic to grasp the inheritance hierarchy which fails because
-   * the class has not been fully constructed yet. "This" itself seems to be working fine.
-   */
-
-  ASSERT( _ObservedValues.size() == MAX_ObservedTypes,
-      "GLMoleculeObject_bond::initObservedValues() - given ObservedValues has not correct size.");
-
-  // fill ObservedValues: index first
-  // Note that we only need one as the function just checks on the last changed id
-  // and ids cannot be changed simultaneously
-  const boost::function<atomId_t ()> AtomIndexUpdater(
-      boost::bind(&GLMoleculeObject_bond::updateIndex));
-
-  ObservedValue_wCallback<atomId_t> * const LeftIndexObservable =
-      new ObservedValue_wCallback<atomId_t>(
-        _leftowner,
-        AtomIndexUpdater,
-        "Bonds_LeftAtomIndex_"+toString(_leftatomId),
-        _leftatomId,
-        IndexChannels,
-        _leftsubjectKilled);
-  _ObservedValues[leftIndex] = LeftIndexObservable;
-  ObservedValue_wCallback<atomId_t> * const RightIndexObservable =
-      new ObservedValue_wCallback<atomId_t>(
-        _rightowner,
-        AtomIndexUpdater,
-        "Bonds_RightAtomIndex_"+toString(_rightatomId),
-        _rightatomId,
-        IndexChannels,
-        _rightsubjectKilled);
-  _ObservedValues[rightIndex] = RightIndexObservable;
-
-  const boost::function<const atomId_t ()> LeftIndexGetter =
-      boost::bind(&ObservedValue_wCallback<atomId_t>::get,
-          LeftIndexObservable);
-  const boost::function<const atomId_t ()> RightIndexGetter =
-      boost::bind(&ObservedValue_wCallback<atomId_t>::get,
-          RightIndexObservable);
-
-  // fill ObservedValues: then all the other that need index
-  const boost::function<Vector ()> LeftPositionUpdater(
-      boost::bind(&GLMoleculeObject_bond::updateLeftPosition, LeftIndexGetter));
-  const boost::function<Vector ()> RightPositionUpdater(
-      boost::bind(&GLMoleculeObject_bond::updateRightPosition, RightIndexGetter));
-  const boost::function<atomicNumber_t ()> LeftElementUpdater(
-      boost::bind(&GLMoleculeObject_bond::updateLeftElement, LeftIndexGetter));
-  const boost::function<atomicNumber_t ()> RightElementUpdater(
-      boost::bind(&GLMoleculeObject_bond::updateRightElement, RightIndexGetter));
-  const boost::function<int ()> DegreeUpdater(
-      boost::bind(&GLMoleculeObject_bond::updateDegree, LeftIndexGetter, RightIndexGetter));
-  const boost::function<bondIds_t ()> BondIdGetter(
-      boost::bind(&getBondIdsForIds, LeftIndexGetter, RightIndexGetter));
-
-  _ObservedValues[leftPosition] = new ObservedValue_wCallback<Vector, atomId_t>(
-      _leftowner,
-      LeftPositionUpdater,
-      "BondleftPosition_"+toString(_leftatomId),
-      LeftPositionUpdater(),
-      BondPositionChannels,
-      _leftsubjectKilled,
-      LeftIndexGetter);
-  _ObservedValues[rightPosition] = new ObservedValue_wCallback<Vector, atomId_t>(
-      _rightowner,
-      RightPositionUpdater,
-      "BondrightPosition_"+toString(_rightatomId),
-      RightPositionUpdater(),
-      BondPositionChannels,
-      _rightsubjectKilled,
-      RightIndexGetter);
-  _ObservedValues[leftElement] = new ObservedValue_wCallback<atomicNumber_t, atomId_t>(
-      _leftowner,
-      LeftElementUpdater,
-      "BondleftElement"+toString(_leftatomId),
-      LeftElementUpdater(),
-      BondElementChannels,
-      _leftsubjectKilled,
-      LeftIndexGetter);
-  _ObservedValues[rightElement] = new ObservedValue_wCallback<atomicNumber_t, atomId_t>(
-      _rightowner,
-      RightElementUpdater,
-      "BondrightElement"+toString(_rightatomId),
-      RightElementUpdater(),
-      BondElementChannels,
-      _rightsubjectKilled,
-      RightIndexGetter);
-  _ObservedValues[Degree] = new ObservedValue_wCallback<int, bondIds_t>(
-      _bondowner,
-      DegreeUpdater,
-      "BondDegree"+toString(_leftatomId)+"_"+toString(_rightatomId),
-      DegreeUpdater(),
-      BondDegreeChannels,
-      _bondsubjectKilled,
-      BondIdGetter);
-}
-
-void GLMoleculeObject_bond::destroyObservedValues(
-    std::vector<boost::any> &_ObservedValues)
-{
-  delete boost::any_cast<ObservedValue_wCallback<atomId_t> *>(_ObservedValues[leftIndex]);
-  delete boost::any_cast<ObservedValue_wCallback<atomId_t> *>(_ObservedValues[rightIndex]);
-  delete boost::any_cast<ObservedValue_wCallback<Vector,atomId_t> *>(_ObservedValues[leftPosition]);
-  delete boost::any_cast<ObservedValue_wCallback<Vector,atomId_t> *>(_ObservedValues[rightPosition]);
-  delete boost::any_cast<ObservedValue_wCallback<atomicNumber_t,atomId_t> *>(_ObservedValues[leftElement]);
-  delete boost::any_cast<ObservedValue_wCallback<atomicNumber_t,atomId_t> *>(_ObservedValues[rightElement]);
-  delete boost::any_cast<ObservedValue_wCallback<int, bondIds_t> *>(_ObservedValues[Degree]);
-  _ObservedValues.clear();
-}
-
-const atomId_t& GLMoleculeObject_bond::getleftIndex() const
-{
-  return boost::any_cast<ObservedValue_wCallback<atomId_t> *>(ObservedValues[leftIndex])->get();
-}
-
-const atomId_t& GLMoleculeObject_bond::getrightIndex() const
-{
-  return boost::any_cast<ObservedValue_wCallback<atomId_t> *>(ObservedValues[rightIndex])->get();
-}
-
-const Vector& GLMoleculeObject_bond::getleftPosition() const
-{
-  return boost::any_cast<ObservedValue_wCallback<Vector,atomId_t> *>(ObservedValues[leftPosition])->get();
-}
-
-const Vector& GLMoleculeObject_bond::getrightPosition() const
-{
-  return boost::any_cast<ObservedValue_wCallback<Vector, atomId_t> *>(ObservedValues[rightPosition])->get();
-}
-
-const atomicNumber_t& GLMoleculeObject_bond::getleftElement() const
-{
-  return boost::any_cast<ObservedValue_wCallback<atomicNumber_t, atomId_t> *>(ObservedValues[leftElement])->get();
-}
-
-const atomicNumber_t& GLMoleculeObject_bond::getrightElement() const
-{
-  return boost::any_cast<ObservedValue_wCallback<atomicNumber_t, atomId_t> *>(ObservedValues[rightElement])->get();
-}
-
-const int& GLMoleculeObject_bond::getDegree() const
-{
-  return boost::any_cast<ObservedValue_wCallback<int, bondIds_t> *>(ObservedValues[Degree])->get();
-}
