Index: src/UIElements/Views/Qt4/MoleculeList/QtMoleculeItem.cpp
===================================================================
--- src/UIElements/Views/Qt4/MoleculeList/QtMoleculeItem.cpp	(revision 6d1e0a20c242ab6c7b0ace4bf93ff53336b9cc26)
+++ src/UIElements/Views/Qt4/MoleculeList/QtMoleculeItem.cpp	(revision 53c1ffef25e1f1a2be3255d54d76e7406c289ab9)
@@ -48,5 +48,5 @@
 
 QtMoleculeItem::QtMoleculeItem(
-     const molecule *_mol,
+     const molecule * const _mol,
      const channellist_t &_channellist,
      const enum MoveTypes _movetype,
@@ -104,5 +104,5 @@
       signOffFromMolecule();
       // prevent any remaining updates from accessing the molecule
-      mol = NULL;
+      //mol = NULL;
       dirty = false;
     } else {
@@ -124,5 +124,4 @@
 {
   IsSignedOn = false;
-//  // we have to signal removal
-//  emit removeMolecule(this);
+  dirty = false;
 }
Index: src/UIElements/Views/Qt4/MoleculeList/QtMoleculeItem.hpp
===================================================================
--- src/UIElements/Views/Qt4/MoleculeList/QtMoleculeItem.hpp	(revision 6d1e0a20c242ab6c7b0ace4bf93ff53336b9cc26)
+++ src/UIElements/Views/Qt4/MoleculeList/QtMoleculeItem.hpp	(revision 53c1ffef25e1f1a2be3255d54d76e7406c289ab9)
@@ -52,5 +52,5 @@
 
   QtMoleculeItem(
-      const molecule *_mol,
+      const molecule * const _mol,
       const channellist_t &_channellist,
       const enum MoveTypes _movetype,
@@ -62,4 +62,11 @@
    */
   void updateState();
+
+  /** Const getter to this item's molecule.
+   *
+   * \return const ref to \a mol
+   */
+  const molecule * const getMolecule() const
+  { return mol; }
 
 private:
@@ -78,5 +85,5 @@
 
   //!> molecule we are signed on to
-  const molecule *mol;
+  const molecule * const mol;
 
 private:
Index: src/UIElements/Views/Qt4/MoleculeList/QtMoleculeItemFactory.cpp
===================================================================
--- src/UIElements/Views/Qt4/MoleculeList/QtMoleculeItemFactory.cpp	(revision 6d1e0a20c242ab6c7b0ace4bf93ff53336b9cc26)
+++ src/UIElements/Views/Qt4/MoleculeList/QtMoleculeItemFactory.cpp	(revision 53c1ffef25e1f1a2be3255d54d76e7406c289ab9)
@@ -85,5 +85,5 @@
 QList<QStandardItem *>
 QtMoleculeItemFactory::createMoleculeItems(
-    const molecule *_mol,
+    const molecule * const _mol,
     const QtMoleculeItem::emitDirtyState_t &_emitDirtyState)
 {
@@ -102,5 +102,5 @@
   QList<QStandardItem *> groupItems;
   // fill item list
-  QStandardItem *mainitem = new QStandardItem(QString(""));
+  QStandardItem *mainitem = new QStandardItem(QString(_formula.c_str()));
   mainitem->setFlags(mainitem->flags() ^ Qt::ItemIsSelectable);
   groupItems << mainitem;
Index: src/UIElements/Views/Qt4/MoleculeList/QtMoleculeItemFactory.hpp
===================================================================
--- src/UIElements/Views/Qt4/MoleculeList/QtMoleculeItemFactory.hpp	(revision 6d1e0a20c242ab6c7b0ace4bf93ff53336b9cc26)
+++ src/UIElements/Views/Qt4/MoleculeList/QtMoleculeItemFactory.hpp	(revision 53c1ffef25e1f1a2be3255d54d76e7406c289ab9)
@@ -51,5 +51,5 @@
    */
   QList<QStandardItem *> createMoleculeItems(
-      const molecule *_mol,
+      const molecule * const _mol,
       const QtMoleculeItem::emitDirtyState_t &_emitDirtyState);
 
Index: src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.cpp
===================================================================
--- src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.cpp	(revision 6d1e0a20c242ab6c7b0ace4bf93ff53336b9cc26)
+++ src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.cpp	(revision 53c1ffef25e1f1a2be3255d54d76e7406c289ab9)
@@ -35,10 +35,15 @@
 #include "QtMoleculeList.hpp"
 
-#include <QMetaMethod>
-
+#include <QModelIndex>
+
+#include "UIElements/Views/Qt4/MoleculeList/QtMoleculeItem.hpp"
+#include "UIElements/Views/Qt4/MoleculeList/QtMoleculeItemFactory.hpp"
+
+#include <boost/bind.hpp>
 #include <iostream>
 
 #include "CodePatterns/MemDebug.hpp"
 
+#include "CodePatterns/Log.hpp"
 #include "CodePatterns/Observer/Notification.hpp"
 
@@ -52,25 +57,20 @@
 using namespace std;
 
-// maybe this should go with the definition of molecules
-
-// some attributes need to be easier to find for molecules
-// these attributes are skipped so far
-const int QtMoleculeList::COLUMNCOUNT = COLUMNTYPES_MAX;
-const char *QtMoleculeList::COLUMNNAMES[QtMoleculeList::COLUMNCOUNT]={"Name","Visibility", "Atoms","Formula","Occurrence"/*,"Size"*/};
+const unsigned int QtMoleculeList::update_times_per_second = 20;
 
 QtMoleculeList::QtMoleculeList() :
-  Observer("QtMoleculeList")
-{
-  setColumnCount(COLUMNCOUNT);
-//  setSelectionMode(QAbstractItemView::MultiSelection);
+  Observer("QtMoleculeList"),
+  selecting(false),
+  changing(false),
+  ChangingChildrensVisibility(false),
+  list_accessing(false),
+  update_timer(NULL),
+  callback_DirtyItems(boost::bind(&QtMoleculeList::informDirtyState, this, _1, _2))
+{
+  setColumnCount(QtMoleculeItemFactory::COLUMNCOUNT);
 
   World::getInstance().signOn(this, World::MoleculeInserted);
   World::getInstance().signOn(this, World::MoleculeRemoved);
 
-  dirty = true;
-  clearing = false;
-  selecting = false;
-  changing = false;
-  ChangingChildrensVisibility = false;
   refill();
 
@@ -91,6 +91,6 @@
   if (role == Qt::DisplayRole) {
     if (orientation == Qt::Horizontal) {
-      if (section < COLUMNTYPES_MAX)
-        return QString(COLUMNNAMES[section]);
+      if (section < QtMoleculeItemFactory::COLUMNTYPES_MAX)
+        return QString(QtMoleculeItemFactory::COLUMNNAMES[section]);
     }
   }
@@ -103,5 +103,5 @@
 }
 
-QStandardItem * QtMoleculeList::MoleculeToItem(const molecule * const _mol)
+QtMoleculeItem * QtMoleculeList::MoleculeToItem(const molecule * const _mol) const
 {
   MoleculeItemBiMap_t::left_const_iterator iter =
@@ -112,4 +112,22 @@
 }
 
+const molecule * const QtMoleculeList::ItemToMolecule(const QtMoleculeItem * const _item) const
+{
+  const MoleculeItemBiMap_t::right_const_iterator iter =
+      MoleculeItemBiMap.right.find(const_cast<QtMoleculeItem * const>(_item));
+  ASSERT( iter != MoleculeItemBiMap.right.end(),
+      "QtMoleculeList::IndexToMolecule() - index to unknown molecule given.");
+  return iter->second;
+}
+
+const molecule * const QtMoleculeList::IndexToMolecule(const QModelIndex &_index) const
+{
+  QtMoleculeItem * const item = dynamic_cast<QtMoleculeItem *>(itemFromIndex(_index));
+  if (item == NULL)
+    return NULL;
+  else
+    return ItemToMolecule(item);
+}
+
 void QtMoleculeList::recieveNotification(Observable *publisher, Notification_ptr notification)
 {
@@ -119,5 +137,8 @@
       {
         const molecule * const mol = World::getInstance().lastChanged<molecule>();
-        addItem( mol );
+        while(list_accessing);
+        list_accessing = true;
+        newItems.push_back( mol );
+        list_accessing = false;
         break;
       }
@@ -125,5 +146,19 @@
       {
         const molecule * const mol = World::getInstance().lastChanged<molecule>();
-        removeItem(  mol );
+
+        while(list_accessing);
+        list_accessing = true;
+        toBeRemovedItems.push_back( mol ); // remove in any case, as we also got insert
+        list_accessing = false;
+
+        const QtMoleculeItem *mol_item = MoleculeToItem(mol);
+        if (mol_item != NULL) {
+          QStandardItem *parent_item = mol_item->parent();
+          if (parent_item != NULL)
+            addToBeSetOccurrence( parent_item );
+          else
+            ELOG(2, "QtMoleculeList::recieveNotification() - item to molecule "
+                +toString(mol)+" has no parent.");
+        }
         break;
       }
@@ -134,9 +169,4 @@
     }
   }
-
-  if (selecting)
-    return;
-
-  dirty = true;
 }
 
@@ -145,49 +175,41 @@
     const std::string &_molecule_formula)
 {
-  QList<QStandardItem *> groupItems;
-  // fill item list
-  mainitem = new QStandardItem(QString("default"));
-  mainitem->setFlags(mainitem->flags() ^ Qt::ItemIsSelectable);
+  QList<QStandardItem *> groupItems =
+      QtMoleculeItemFactory::getInstance().createGroupItems(_molecule_formula);
+  mainitem = groupItems.front();
   formula.insert( std::make_pair(_molecule_formula, mainitem) );
-  groupItems << mainitem;
-  QStandardItem *visitem = new QStandardItem;
-  visitem->setCheckState(Qt::Unchecked);
-  visitem->setFlags(mainitem->flags() | Qt::ItemIsUserCheckable);
-  groupItems << visitem;
-  groupItems << new QStandardItem(QString::number(0));
-  groupItems << new QStandardItem(QString(""));
-  groupItems << new QStandardItem(QString::number(0));
   invisibleRootItem()->appendRow(groupItems);
-//  _groupItem->setData(0, Qt::UserRole, QVariant(-1));
+}
+
+void QtMoleculeList::addToBeSetOccurrence(
+    QStandardItem *_groupitem)
+{
+  while (list_accessing);
+  list_accessing = true;
+  toBeSetOccurrenceItems.insert( _groupitem );
+  list_accessing = false;
 }
 
 void QtMoleculeList::addMoleculeItem(
     QStandardItem *_groupitem,
-    const molecule *_mol,
+    const molecule * const _mol,
     const std::string &_molecule_formula)
 {
-  QList<QStandardItem *> molItems;
-  QStandardItem *mainitem = new QStandardItem(QString(_mol->getName().c_str()));
-  mainitem->setFlags(mainitem->flags() | Qt::ItemIsSelectable);
-//  mainitem->setSelected(World::getInstance().isSelected(_mol));
-  MoleculeItemBiMap.left.insert( std::make_pair(_mol, mainitem) );
-  molItems << mainitem;
-  QStandardItem *visitem = new QStandardItem();
-  visitem->setCheckState(Qt::Unchecked);
-  visitem->setFlags(mainitem->flags() | Qt::ItemIsUserCheckable);
-  molItems << visitem;
-  molItems << new QStandardItem(QString::number(_mol->getAtomCount()));
-  molItems << new QStandardItem(QString(_molecule_formula.c_str()));
-  molItems << new QStandardItem(QString::number(0));
-//  const int index = _mol->getId();
-//  molItem->setData(0, Qt::UserRole, QVariant(index));
+  QList<QStandardItem *> molItems =
+      QtMoleculeItemFactory::getInstance().createMoleculeItems(_mol, callback_DirtyItems);
+  QtMoleculeItem *mol_item = dynamic_cast<QtMoleculeItem *>(molItems.front());
+  ASSERT( mol_item != NULL,
+      "QtMoleculeList::addMoleculeItem() - item from factory was not a QtMoleculeItem?");
+  MoleculeItemBiMap.left.insert( std::make_pair(_mol, mol_item) );
+  LOG(1, "Inserting molecule " << _mol->getId() << ": " << _mol);
   _groupitem->appendRow(molItems);
-}
-
-void QtMoleculeList::addItem(const molecule *_mol)
-{
-  if (changing)
-    return;
-  changing = true;
+
+  // here update for the occurence will happen "one tick" later, but we don't
+  // have the groupitem any time earlier
+  addToBeSetOccurrence(_groupitem);
+}
+
+void QtMoleculeList::addMolecule(const molecule * const _mol)
+{
   // find group if already in list
   QStandardItem *groupItem = NULL;
@@ -215,36 +237,39 @@
   }
   ASSERT( groupItem != NULL,
-      "QtMoleculeList::addItem() - item with id "+toString(_mol->getId())
+      "QtMoleculeList::addMolecule() - item with id "+toString(_mol->getId())
       +" has not parent?");
 
   // add molecule
   addMoleculeItem(groupItem, _mol, molecule_formula);
-
-  // increase group occurrence
-  const int index = groupItem->index().row();
-  QStandardItem *occ_item = invisibleRootItem()->child(index, OCCURRENCE);
-  int count = occ_item->text().toInt() + 1;
-  occ_item->setText(QString::number(count));
-
-  changing = false;
-}
-
-void QtMoleculeList::removeItem(const molecule *_mol)
-{
-  if (changing)
-    return;
+}
+
+void QtMoleculeList::removeItem(QtMoleculeItem * const _item)
+{
+  const QModelIndex mol_index = indexFromItem(_item);
+  QStandardItem *groupitem = _item->parent();
+  const QModelIndex group_index = groupitem->index();
+  removeRows(mol_index.row(), 1, group_index);
+  MoleculeItemBiMap_t::right_iterator removeiter =
+      MoleculeItemBiMap.right.find(_item);
+  ASSERT( removeiter != MoleculeItemBiMap.right.end(),
+      "QtMoleculeList::removeItem() - could not find item in BiMap.");
+  LOG(1, "Erasing molecule " << (removeiter->second));
+  MoleculeItemBiMap.right.erase(removeiter);
+
+  // don't need to, groupitem is already present in toBeSetOccurrenceItems
+//  addToBeSetOccurrence(_groupitem);
+}
+
+void QtMoleculeList::refill()
+{
+  // check timer's presence
+  if (update_timer == NULL) {
+    update_timer = new QTimer(this);
+    connect( update_timer, SIGNAL(timeout()), this, SLOT(checkState()));
+  } else
+    update_timer->stop();
+
   changing = true;
 
-  dirty = true;
-  // TODO: We have to get some Model into the Table in order to "find" items right
-  // away
-//  QTreeWidgetItem *molItem = itemFromIndex(mol->getId());
-//  delete molItem1;
-
-  changing = false;
-}
-
-void QtMoleculeList::refill() {
-  clearing = true;
   const std::vector<molecule*> &molecules = World::getInstance().getAllMolecules();
 
@@ -252,27 +277,47 @@
   formula.clear();
   FormulaVisibilityCountMap.clear();
+  LOG(1, "Clearing list.");
   MoleculeItemBiMap.clear();
+  dirtyItems.clear();
+  toBeMovedItems.clear();
+  newItems.clear();
+  toBeRemovedItems.clear();
+  toBeSetOccurrenceItems.clear();
 
   for (std::vector<molecule*>::const_iterator iter = molecules.begin();
       iter != molecules.end();
-      iter++) {
-
-    addItem(*iter);
-  }
-  dirty = false;
-  clearing = false;
-}
-
-/*
-void QtMoleculeList::paintEvent(QPaintEvent * event)
-{
+      iter++)
+    addMolecule(*iter);
+
+  changing = false;
+
+  // activate timer
+  update_timer->start(1000/update_times_per_second);
+}
+
+bool QtMoleculeList::areAnyItemsDirty()
+{
+  // get whether any items are dirty
+  while (list_accessing);
+  list_accessing = true;
+  bool dirty = false;
+  dirty |= !dirtyItems.empty();
+  dirty |= !newItems.empty();
+  dirty |= !toBeRemovedItems.empty();
+  dirty |= !toBeSetOccurrenceItems.empty();
+  list_accessing = false;
+  return dirty;
+}
+
+void QtMoleculeList::checkState()
+{
+  const bool dirty = areAnyItemsDirty();
+  // update if required
   if (dirty)
-    refill();
-  QTreeWidget::paintEvent(event);
-}
-*/
-
-void QtMoleculeList::subjectKilled(Observable *publisher) {
-}
+    updateItemStates();
+}
+
+void QtMoleculeList::subjectKilled(Observable *publisher)
+{}
 
 /*
@@ -280,7 +325,7 @@
 {
   if ((!changing) && (!clearing) && (!ChangingChildrensVisibility))
-    if (column == VISIBILITY) {
+    if (column == QtMoleculeItemFactory::VISIBILITY) {
       const moleculeId_t molid = item->data(0, Qt::UserRole).toInt();
-      const bool visible = item->checkState(VISIBILITY);
+      const bool visible = item->checkState(QtMoleculeItemFactory::VISIBILITY);
       if (molid != (unsigned int)-1) { // molecule item
         World::MoleculeConstIterator moliter =
@@ -308,10 +353,10 @@
           if (FormulaVisibilityCountMap[molecule_formula] ==
               (unsigned int)(groupItem->text(OCCURRENCE).toInt()))
-            groupItem->setCheckState(VISIBILITY, Qt::Checked);
+            groupItem->setCheckState(QtMoleculeItemFactory::VISIBILITY, Qt::Checked);
         } else {
           --(FormulaVisibilityCountMap[molecule_formula]);
           // none selected anymore?
           if (FormulaVisibilityCountMap[molecule_formula] == 0)
-            groupItem->setCheckState(VISIBILITY, Qt::Unchecked);
+            groupItem->setCheckState(QtMoleculeItemFactory::VISIBILITY, Qt::Unchecked);
         }
         ChangingChildrensVisibility = false;
@@ -329,5 +374,5 @@
               "QtMoleculeList::visibilityChanged() - to child with index"
               +toString(i)+" there is no molecule?");
-          molItem->setCheckState(VISIBILITY, visible ? Qt::Checked : Qt::Unchecked);
+          molItem->setCheckState(QtMoleculeItemFactory::VISIBILITY, visible ? Qt::Checked : Qt::Unchecked);
 
           // emit signal
@@ -338,5 +383,5 @@
             item->text(FORMULA).toStdString();
         FormulaVisibilityCountMap[molecule_formula] =
-            visible ? item->text(OCCURRENCE).toInt() : 0;
+            visible ? item->text(QtMoleculeItemFactory::OCCURRENCE).toInt() : 0;
 
         ChangingChildrensVisibility = false;
@@ -349,57 +394,206 @@
   /*int idx = verticalHeaderItem(row)->data(Qt::UserRole).toInt();
   molecule *mol = molecules->ReturnIndex(idx);
-  string cellValue = item(row,NAME)->text().toStdString();
+  string cellValue = item(row,QtMoleculeItemFactory::NAME)->text().toStdString();
   if(mol->getName() != cellValue && cellValue !="") {
     mol->setName(cellValue);
   }
   else if(cellValue==""){
-    item(row,NAME)->setText(QString(mol->getName().c_str()));
+    item(row,QtMoleculeItemFactory::NAME)->setText(QString(mol->getName().c_str()));
   }*/
 }
 
-/*
-void QtMoleculeList::rowsSelected(const QItemSelection & selected, const QItemSelection & deselected){
-
-  if (clearing)
+
+int QtMoleculeList::setOccurrence(QStandardItem * const _groupitem)
+{
+  QModelIndex modelindex = _groupitem->index();
+  ASSERT( modelindex.isValid(),
+      "QtMoleculeList::setOccurrence() - groupitem not associated to model anymore.");
+  const int index = modelindex.row();
+  QStandardItem *parent_item =
+      _groupitem->parent() == NULL ? invisibleRootItem() : _groupitem->parent();
+  ASSERT( parent_item != NULL,
+      "QtMoleculeList::setOccurrence() - group item at "+toString(index)
+      +" does not have a parent?");
+  QStandardItem *occ_item = parent_item->child(index, QtMoleculeItemFactory::OCCURRENCE);
+  ASSERT( occ_item != NULL,
+      "QtMoleculeList::setOccurrence() - group item at "+toString(index)
+      +" does not have an occurrence?");
+  const int count = _groupitem->rowCount();
+  if (count == 0) {
+    // we have to remove the group item completely
+    const std::string molecule_formula = _groupitem->text().toStdString();
+    formula.erase(molecule_formula);
+    FormulaVisibilityCountMap.erase(molecule_formula);
+    return index;
+  } else {
+    occ_item->setText(QString::number(count));
+    return -1;
+  }
+}
+
+void QtMoleculeList::readdItem(QtMoleculeItem *_molitem)
+{
+  // use takeRows of molecule ..
+  QStandardItem *groupitem = _molitem->parent();
+  ASSERT( groupitem != NULL,
+      "QtMoleculeList::readdItem() - mol item at "+toString(_molitem->index().row())
+      +" does not have a groupitem?");
+  QList<QStandardItem *> mol_row = _molitem->parent()->takeRow(_molitem->index().row());
+  // call setOccurrence on the old group later
+  addToBeSetOccurrence(groupitem);
+  // ..  and re-add where new formula fits
+  const std::string molecule_formula = _molitem->getMolecule()->getFormula().toString();
+  FormulaTreeItemMap_t::iterator iter = formula.find(molecule_formula);
+  if (iter == formula.end()) {
+    // add new group item and formula entry
+     addGroupItem(groupitem, molecule_formula);
+  } else {
+    groupitem = iter->second;
+  }
+  ASSERT( groupitem != NULL,
+      "QtMoleculeList::readdItem() - failed to create a sensible new groupitem");
+  // finally add again
+  groupitem->appendRow(mol_row);
+  // call setOccurrence on the new group later
+  addToBeSetOccurrence(groupitem);
+}
+
+void QtMoleculeList::informDirtyState(
+    QtMoleculeItem *_item,
+    const QtMoleculeItem::MoveTypes _type)
+{
+  while (list_accessing);
+  list_accessing = true;
+
+  dirtyItems.insert(_item);
+  if (_type == QtMoleculeItem::NeedsMove) {
+    // we have to convert whatever item raised the dirty signal to the first
+    // item in the row as otherwise multiple items in the row are selected
+    // as to be moved, i.e. the same row is moved multiple times
+    QStandardItem *group_item = _item->parent();
+    QtMoleculeItem *mol_item =
+        dynamic_cast<QtMoleculeItem *>(group_item->child(_item->row(), 0));
+    toBeMovedItems.insert(mol_item);
+//    // add group item, too
+//    toBeSetOccurrenceItems.insert(group_item);
+  }
+
+  list_accessing = false;
+}
+
+void QtMoleculeList::updateItemStates()
+{
+  // wait till initial refill has been executed
+  if (changing)
     return;
-  if (selecting)
-    return;
-  selecting = true;
-
-  // Select all molecules which belong to newly selected rows.
-  QModelIndex index;
+
+  changing = true;
+
+  /// copy lists such that new signals for dirty/.. may come in right away
+  // TODO: if we had move semantics ...
+  while (list_accessing);
+  list_accessing = true;
+  list_of_items_t dirtyItems_copy = dirtyItems;
+  dirtyItems.clear();
+  list_of_items_t toBeMovedItems_copy = toBeMovedItems;
+  toBeMovedItems.clear();
+  std::vector<const molecule *> newItems_copy = newItems;
+  newItems.clear();
+  std::vector<const molecule *> toBeRemovedItems_copy = toBeRemovedItems;
+  toBeRemovedItems.clear();
+  std::set<QStandardItem*> toBeSetOccurrenceItems_copy = toBeSetOccurrenceItems;
+  toBeSetOccurrenceItems.clear();
+  list_accessing = false;
+
+  /// first check consistency among the sets:
+  /// -# if we remove an item, we don't have to update it before anymore
+  /// -# if we remove an item, we don't have to move it before anymore
+  /// -# if we remove an item, we don't have to change its visibility
+  /// -# don't add molecule that are also removed
+
+  //  // remove molecules added and removed immediately in both lists
+  std::vector<const molecule *> addedremoved;
+  std::sort(newItems_copy.begin(), newItems_copy.end());
+  std::sort(toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end());
+  std::set_intersection(
+      newItems_copy.begin(), newItems_copy.end(),
+      toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end(),
+      std::back_inserter(addedremoved));
   {
-    QModelIndexList items = selected.indexes();
-    molids_t ids;
-    ids.reserve(items.size());
-    foreach (index, items)
-      if (index.column() == 0){
-        int mol_id = model()->data(index, Qt::UserRole).toInt();
-        if (mol_id < 0)
-          continue;
-        ids.push_back(mol_id);
-        //std::cout << "select molecule" << std::endl;
-      }
-    MoleCuilder::SelectionMoleculeById(ids);
-  }
-
-  // Unselect all molecules which belong to newly unselected rows.
+    std::vector<const molecule *>::iterator removeiter = std::set_difference(
+        newItems_copy.begin(), newItems_copy.end(),
+        addedremoved.begin(), addedremoved.end(),
+        newItems_copy.begin());
+    newItems_copy.erase(removeiter, newItems_copy.end());
+  }
   {
-    QModelIndexList items = deselected.indexes();
-    molids_t ids;
-    ids.reserve(items.size());
-    foreach (index, items)
-      if (index.column() == 0){
-        int mol_id = model()->data(index, Qt::UserRole).toInt();
-        if (mol_id < 0)
-          continue;
-        //std::cout << "unselect molecule" << std::endl;
-        ids.push_back(mol_id);
-      }
-    MoleCuilder::SelectionNotMoleculeById(ids);
-  }
-
-  selecting = false;
-}
-
-*/
+    std::vector<const molecule *>::iterator removeiter = std::set_difference(
+        toBeRemovedItems_copy.begin(), toBeRemovedItems_copy.end(),
+        addedremoved.begin(), addedremoved.end(),
+        toBeRemovedItems_copy.begin());
+    toBeRemovedItems_copy.erase(removeiter, toBeRemovedItems_copy.end());
+  }
+  addedremoved.clear();
+
+  for (std::vector<const molecule *>::iterator removeiter = toBeRemovedItems_copy.begin();
+      removeiter != toBeRemovedItems_copy.end(); ++removeiter) {
+    QtMoleculeItem *item = MoleculeToItem(*removeiter);
+    dirtyItems_copy.erase(item);
+    toBeMovedItems_copy.erase(item);
+  }
+
+  /// 1. do the update for each dirty item
+  for (list_of_items_t::const_iterator dirtyiter = dirtyItems_copy.begin();
+      dirtyiter != dirtyItems_copy.end(); ++dirtyiter) {
+    LOG(1, "Updating item " << *dirtyiter);
+    (*dirtyiter)->updateState();
+  }
+
+  /// 2. move all items that need to be moved
+  for (list_of_items_t::const_iterator moveiter = toBeMovedItems_copy.begin();
+      moveiter != toBeMovedItems_copy.end(); ++moveiter) {
+    LOG(1, "Moving item " << *moveiter);
+    readdItem(*moveiter);
+  }
+
+  /// 3. remove all items whose molecules have been removed
+  for (std::vector<const molecule *>::const_iterator removeiter = toBeRemovedItems_copy.begin();
+      removeiter != toBeRemovedItems_copy.end(); ++removeiter) {
+    LOG(1, "Removing molecule " << *removeiter); // cannot access directly, molecule is gone
+    QtMoleculeItem *item = MoleculeToItem(*removeiter);
+    if (item != NULL)
+      removeItem(item);
+  }
+
+  /// 4. instantiate all new items
+  for (std::vector<const molecule *>::const_iterator moliter = newItems_copy.begin();
+      moliter != newItems_copy.end(); ++moliter) {
+    LOG(1, "Adding molecule " << (*moliter)->getName());
+    // check that World knows the molecule still
+    const molecule * const mol =
+        World::getInstance().getMolecule(MoleculeById((*moliter)->getId()));
+    if ((mol != NULL) && (mol == *moliter)) {
+      addMolecule(mol);
+    }
+  }
+
+  /// 5a. update the group item's occurrence
+  std::set<int> RowsToRemove;
+  for (std::set<QStandardItem*>::const_iterator groupiter = toBeSetOccurrenceItems_copy.begin();
+      groupiter != toBeSetOccurrenceItems_copy.end(); ++groupiter) {
+    LOG(1, "Updating group item " << *groupiter);
+    const int index = setOccurrence(*groupiter);
+    if (index != -1)
+      RowsToRemove.insert(index);
+  }
+
+  /// 5b. remove all rows with 0 occurrence starting from last
+  for (std::set<int>::reverse_iterator riter = RowsToRemove.rbegin();
+      riter != RowsToRemove.rend(); ++riter) {
+    LOG(1, "Removing group item at row " << *riter);
+    removeRows(*riter, 1, invisibleRootItem()->index());
+  }
+
+  // and done
+  changing = false;
+}
Index: src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.hpp
===================================================================
--- src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.hpp	(revision 6d1e0a20c242ab6c7b0ace4bf93ff53336b9cc26)
+++ src/UIElements/Views/Qt4/MoleculeList/QtMoleculeList.hpp	(revision 53c1ffef25e1f1a2be3255d54d76e7406c289ab9)
@@ -14,12 +14,17 @@
 #endif
 
+#include <QtGui/QItemSelection>
 #include <QtGui/QStandardItem>
 #include <QtGui/QStandardItemModel>
+#include <QTimer>
 
 #include <boost/bimap.hpp>
 #include <map>
+#include <set>
 #include <string>
 
 #include "CodePatterns/Observer/Observer.hpp"
+
+#include "UIElements/Views/Qt4/MoleculeList/QtMoleculeItem.hpp"
 
 #include "types.hpp"
@@ -27,4 +32,5 @@
 class molecule;
 class MoleculeListClass;
+class QtMoleculeItem;
 class QtMoleculeListView;
 
@@ -41,10 +47,6 @@
   virtual void recieveNotification(Observable *publisher, Notification_ptr notification);
   virtual void subjectKilled(Observable *publisher);
-//  virtual void paintEvent(QPaintEvent * event);
+
   void refill();
-
-  static const int COLUMNCOUNT;
-  enum {NAME,VISIBILITY,ATOMCOUNT,FORMULA,OCCURRENCE,COLUMNTYPES_MAX} COLUMNTYPES;
-  static const char *COLUMNNAMES[];
 
   QVariant headerData(int section, Qt::Orientation orientation, int role) const;
@@ -53,7 +55,10 @@
   void moleculeChanged();
 //  void visibilityChanged(QStandardItem*, int);
+  void checkState();
+
+  friend class QtMoleculeItem;
 
 //  void rowsSelected(const QItemSelection & selected, const QItemSelection & deselected);
-
+  void readdItem(QtMoleculeItem *_molitem);
 
 signals:
@@ -63,17 +68,33 @@
 
 private:
-  bool dirty;
-  bool clearing;
+
   bool selecting;
   bool changing;
   bool ChangingChildrensVisibility;
+  bool list_accessing;
+
+  //!> informs the view in regular intervals about updates
+  QTimer *update_timer;
+
+  //!> how often per second update is signalled to view
+  static const unsigned int update_times_per_second;
 
   friend class QtMoleculeListView;
-  QStandardItem * MoleculeToItem(const molecule * const _mol);
 
-  void addItem(const molecule * const _mol);
+  QtMoleculeItem * MoleculeToItem(const molecule * const _mol) const;
+  const molecule * const IndexToMolecule(const QModelIndex &_index) const;
+  const molecule * const ItemToMolecule(const QtMoleculeItem * const _item) const;
+
+  void addMolecule(const molecule * const _mol);
   void addGroupItem(QStandardItem *&mainitem, const std::string &_molecule_formula);
-  void addMoleculeItem(QStandardItem *_groupitem, const molecule *_mol, const std::string &molecule_formula);
-  void removeItem(const molecule * const _mol);
+  void addMoleculeItem(QStandardItem *_groupitem, const molecule * const _mol, const std::string &molecule_formula);
+  void removeItem(QtMoleculeItem * const _item);
+  int setOccurrence(QStandardItem * const _groupitem);
+  bool areAnyItemsDirty();
+  void addToBeSetOccurrence(QStandardItem *_groupitem);
+
+  void informDirtyState(QtMoleculeItem *_item, const QtMoleculeItem::MoveTypes _type);
+
+  void updateItemStates();
 
   typedef std::map<std::string, unsigned int> FormulaVisibilityCountMap_t;
@@ -84,6 +105,21 @@
   FormulaTreeItemMap_t formula;
 
-  typedef boost::bimap<const molecule *, QStandardItem*> MoleculeItemBiMap_t;
+  typedef boost::bimap<const molecule *, QtMoleculeItem*> MoleculeItemBiMap_t;
   MoleculeItemBiMap_t MoleculeItemBiMap;
+
+  //!> callback function to hand over to items that inform about requiring update
+  const QtMoleculeItem::emitDirtyState_t callback_DirtyItems;
+
+  typedef std::set<QtMoleculeItem*> list_of_items_t;
+  //!> list of items that need an update
+  list_of_items_t dirtyItems;
+  //!> list of items to molecule's whose formulas has changed and need to be moved
+  list_of_items_t toBeMovedItems;
+  //!> list of items to new molecules which need to be added
+  std::vector<const molecule *> newItems;
+  //!> list of items to molecules that have been removed
+  std::vector<const molecule *> toBeRemovedItems;
+  //!> list of group items that need update due to moved molecule items
+  std::set<QStandardItem*> toBeSetOccurrenceItems;
 };
 
