removeObsoleteViewData = (nodes, view) => {

  if (!ViewAbstraction.exists(view) || !nodes) {
    return;
  }

  view = new ViewAbstraction(view);

  const data = view.getNodeData();

  let obsoleteDataItems = 0;
  for (let id in data) {
    if (nodes[id] === undefined && data[id] != null) {
      // we only set this to undefined as deletion would
      // slow down V8, however, this necessarily requires
      // a safeguard agains recursion: data[id] != null

      data[id] = undefined;
      obsoleteDataItems++;
    }
  }

  if (obsoleteDataItems) {
    $tm.logger('debug', '[Cleanup]',
      'Removed obsolete node data:',
      view.getLabel(), obsoleteDataItems);
    view.saveNodeData(data);
  }

}
Garbage collector for obsolete node data.

@param {Object<string, Node>} nodes
@param {ViewAbstraction|string} view