Index: src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_molecule.cpp
===================================================================
--- src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_molecule.cpp	(revision e254484494f1093b5f83e79385d6f87cc3ea6588)
+++ src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_molecule.cpp	(revision 2831b30765e296e23df0592428b94ccda962210e)
@@ -63,4 +63,6 @@
 #include "Atom/TesselPoint.hpp"
 #include "World.hpp"
+
+#include "ObservedValue_wCallback.hpp"
 
 using namespace boost::assign;
@@ -122,16 +124,6 @@
       boost::bind(&GLMoleculeObject_molecule::updateAtoms, this)
       ),
-  MolIndex(
-      molref,
-      MolIndexUpdater,
-      "MoleculeIndex_"+toString(_molid),
-      _molid,
-      IndexChannels),
-  MolName(
-      molref,
-      MolNameUpdater,
-      "MoleculeName_"+toString(_molid),
-      updateName(),
-      NameChannels),
+  ObservedValues(MAX_ObservedTypes),
+  subjectKilledCount(0),
   TesselationHull(
       molref,
@@ -139,18 +131,8 @@
       "MoleculeTesselationHull_"+toString(_molid),
       HullChannels),
-  BoundingBox(
-      molref,
-      BoundingBoxUpdater,
-      "MoleculeBoundingBox_"+toString(_molid),
-      initBoundingBox(),
-      BoundingBoxChannels),
-  PresentAtoms(
-      molref,
-      PresentAtomsUpdater,
-      "MoleculeAtoms_"+toString(_molid),
-      updateAtoms(),
-      AtomsChannels),
   hoverAtomId(-1)
 {
+  initObservedValues(_molid);
+
   setObjectId(_molid);
   setMaterial(getMaterial(1));
@@ -199,16 +181,6 @@
       boost::bind(&GLMoleculeObject_molecule::updateAtoms, this)
       ),
-  MolIndex(
-      molref,
-      MolIndexUpdater,
-      "MoleculeIndex_"+toString(_molid),
-      _molid,
-      IndexChannels),
-  MolName(
-      molref,
-      MolNameUpdater,
-      "MoleculeName_"+toString(_molid),
-      updateName(),
-      NameChannels),
+  ObservedValues(MAX_ObservedTypes),
+  subjectKilledCount(0),
   TesselationHull(
       molref,
@@ -216,18 +188,8 @@
       "MoleculeTesselationHull_"+toString(_molid),
       HullChannels),
-  BoundingBox(
-      molref,
-      BoundingBoxUpdater,
-      "MoleculeBoundingBox_"+toString(_molid),
-      initBoundingBox(),
-      BoundingBoxChannels),
-  PresentAtoms(
-      molref,
-      PresentAtomsUpdater,
-      "MoleculeAtoms_"+toString(_molid),
-      atoms_t(),
-      AtomsChannels),
   hoverAtomId(-1)
 {
+  initObservedValues(_molid);
+
   setObjectId(_molid);
   setMaterial(getMaterial(1));
@@ -254,4 +216,5 @@
 {
   deactivateObserver();
+  destroyObservedValues();
 }
 
@@ -270,5 +233,5 @@
 {
   // sign on as observer (obtain non-const instance before)
-  const molecule * const _molecule = getMolecule(MolIndex.get());
+  const molecule * const _molecule = getMolecule(getMolIndex());
   if (_molecule != NULL) {
     owner = static_cast<const Observable *>(_molecule);
@@ -278,5 +241,5 @@
     owner->signOn(this, molecule::IndexChanged);
   } else {
-    ELOG(1, "GLMoleculeObject_molecule() - added null object for not present mol id " << MolIndex.get());
+    ELOG(1, "GLMoleculeObject_molecule() - added null object for not present mol id " << getMolIndex());
   }
 
@@ -332,7 +295,7 @@
   QGeometryData geo;
 
-  const molecule * const molref = getMolecule(MolIndex.get());
+  const molecule * const molref = getMolecule(getMolIndex());
   if (molref == NULL) {
-    ELOG(1, "Could not createMoleculeMesh, molecule with id " << MolIndex.get() << " already gone.");
+    ELOG(1, "Could not createMoleculeMesh, molecule with id " << getMolIndex() << " already gone.");
     return geo;
   }
@@ -353,8 +316,8 @@
 
   // we need at least three points for tesselation
-  if (PresentAtoms.get().size() >= 3) {
+  if (getPresentAtoms().size() >= 3) {
     // Tesselate the points.
     Tesselation T;
-    PointCloudAdaptor<molecule> cloud(const_cast<molecule *>(molref), MolName.get());
+    PointCloudAdaptor<molecule> cloud(const_cast<molecule *>(molref), getMolName());
     T(cloud, minradius);
 
@@ -413,10 +376,10 @@
 molecule::BoundingBoxInfo GLMoleculeObject_molecule::updateBoundingBox() const
 {
-  return BoundingBox.get();
+  return getBoundingBox();
 }
 
 GLMoleculeObject_molecule::atoms_t GLMoleculeObject_molecule::updateAtoms()
 {
-  const molecule * const mol = getMolecule(MolIndex.get());
+  const molecule * const mol = getMolecule(getMolIndex());
   if (mol != NULL) {
     const atomId_t id = mol->lastChangedAtomId();
@@ -436,5 +399,5 @@
 std::string GLMoleculeObject_molecule::updateName() const
 {
-  const molecule * const mol = getMolecule(MolIndex.get());
+  const molecule * const mol = getMolecule(getMolIndex());
   return mol->getName();
 }
@@ -448,5 +411,5 @@
 void GLMoleculeObject_molecule::resetBoundingBox()
 {
-  molecule::BoundingBoxInfo info = BoundingBox.get();
+  molecule::BoundingBoxInfo info = getBoundingBox();
   setPosition(QVector3D(info.position[0], info.position[1], info.position[2]));
   setScale(info.radius + 0.3); // getBoundingSphere() only sees atoms as points, so make the box a bit bigger
@@ -455,5 +418,5 @@
 void GLMoleculeObject_molecule::resetAtoms()
 {
-  const atoms_t atoms = PresentAtoms.get();
+  const atoms_t atoms = getPresentAtoms();
   std::vector<atomId_t> InsertedAtoms;
   std::vector<atomId_t> RemovedAtoms;
@@ -479,5 +442,5 @@
 void GLMoleculeObject_molecule::resetIndex()
 {
-  const atomId_t newId = MolIndex.get();
+  const atomId_t newId = getMolIndex();
   const size_t oldId = objectId();
   ASSERT( newId != oldId,
@@ -544,9 +507,11 @@
   // remove owner: no more signOff needed
   owner = NULL;
+
+  countsubjectKilled();
 }
 
 void GLMoleculeObject_molecule::recieveNotification(Observable *publisher, Notification_ptr notification)
 {
-  const molecule * const _molecule = getMolecule(MolIndex.get());
+  const molecule * const _molecule = getMolecule(getMolIndex());
   // when molecule is NULL we will soon get destroyed anyway
   if (_molecule == NULL)
@@ -556,5 +521,5 @@
 #ifdef LOG_OBSERVER
     observerLog().addMessage() << "++ Update of Observer "<< observerLog().getName(static_cast<Observer *>(this))
-          << " received notification from molecule " << MolIndex.get() << " for channel "
+          << " received notification from molecule " << getMolIndex() << " for channel "
           << notification->getChannelNo() << ".";
 #endif
@@ -577,5 +542,4 @@
         observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been removed.";
   #endif
-        emit AtomRemoved(_id);
         emit TesselationHullChanged();
         emit BoundingBoxChanged();
@@ -719,4 +683,5 @@
   connect (atomObject, SIGNAL(BondsRemoved(const atomId_t, const atomId_t)), this, SLOT(bondRemoved(const atomId_t, const atomId_t)));
   connect (atomObject, SIGNAL(indexChanged(GLMoleculeObject_atom*, const atomId_t, const atomId_t)), this, SLOT(changeAtomId(GLMoleculeObject_atom*, const atomId_t, const atomId_t)));
+  connect (atomObject, SIGNAL(InstanceRemoved(const atomId_t)), this, SIGNAL(AtomRemoved(const atomId_t)));
 
   if (m_objectId  == -1)
@@ -773,5 +738,5 @@
     if (moleculeObject == this){
       // Propagate signal.
-      emit hoverChanged(MolIndex.get(), 0);
+      emit hoverChanged(getMolIndex(), 0);
     }
   }
@@ -871,6 +836,6 @@
 void GLMoleculeObject_molecule::wasClicked()
 {
-  LOG(4, "INFO: GLMoleculeObject_molecule: atom " << MolIndex.get() << " has been clicked");
-  emit moleculeClicked(MolIndex.get());
+  LOG(4, "INFO: GLMoleculeObject_molecule: atom " << getMolIndex() << " has been clicked");
+  emit moleculeClicked(getMolIndex());
 }
 
@@ -906,2 +871,74 @@
   return mol;
 }
+
+void GLMoleculeObject_molecule::countsubjectKilled()
+{
+  ++subjectKilledCount;
+
+  if (subjectKilledCount > ObservedValues.size())
+    emit InstanceRemoved(getMolIndex());
+}
+
+void GLMoleculeObject_molecule::initObservedValues(const moleculeId_t _molid)
+{
+  // fill ObservedValues
+  boost::function<void()> subjectKilled =
+      boost::bind(&GLMoleculeObject_molecule::countsubjectKilled, this);
+  ObservedValues[MolIndex] = new ObservedValue_wCallback<moleculeId_t>(
+      molref,
+      MolIndexUpdater,
+      "MoleculeIndex_"+toString(_molid),
+      _molid,
+      IndexChannels,
+      subjectKilled);
+  ObservedValues[MolName] = new ObservedValue_wCallback<std::string>(
+      molref,
+      MolNameUpdater,
+      "MoleculeName_"+toString(_molid),
+      updateName(),
+      NameChannels,
+      subjectKilled);
+  ObservedValues[BoundingBox] = new ObservedValue_wCallback<molecule::BoundingBoxInfo>(
+      molref,
+      BoundingBoxUpdater,
+      "MoleculeBoundingBox_"+toString(_molid),
+      initBoundingBox(),
+      BoundingBoxChannels,
+      subjectKilled);
+  ObservedValues[PresentAtoms] = new ObservedValue_wCallback<atoms_t>(
+      molref,
+      PresentAtomsUpdater,
+      "MoleculeAtoms_"+toString(_molid),
+      updateAtoms(),
+      AtomsChannels,
+      subjectKilled);
+}
+
+void GLMoleculeObject_molecule::destroyObservedValues()
+{
+  delete boost::any_cast<ObservedValue_wCallback<moleculeId_t> *>(ObservedValues[MolIndex]);
+  delete boost::any_cast<ObservedValue_wCallback<std::string> *>(ObservedValues[MolName]);
+  delete boost::any_cast<ObservedValue_wCallback<molecule::BoundingBoxInfo> *>(ObservedValues[BoundingBox]);
+  delete boost::any_cast<ObservedValue_wCallback<atoms_t> *>(ObservedValues[PresentAtoms]);
+  ObservedValues.clear();
+}
+
+moleculeId_t GLMoleculeObject_molecule::getMolIndex() const
+{
+  return boost::any_cast<ObservedValue_wCallback<moleculeId_t> *>(ObservedValues[MolIndex])->get();
+}
+
+std::string GLMoleculeObject_molecule::getMolName() const
+{
+  return boost::any_cast<ObservedValue_wCallback<std::string> *>(ObservedValues[MolName])->get();
+}
+
+molecule::BoundingBoxInfo GLMoleculeObject_molecule::getBoundingBox() const
+{
+  return boost::any_cast<ObservedValue_wCallback<molecule::BoundingBoxInfo> *>(ObservedValues[BoundingBox])->get();
+}
+
+GLMoleculeObject_molecule::atoms_t GLMoleculeObject_molecule::getPresentAtoms() const
+{
+  return boost::any_cast<ObservedValue_wCallback<atoms_t> *>(ObservedValues[PresentAtoms])->get();
+}
