@Override
  protected void indicating(CDODataInput in, OMMonitor monitor) throws IOException {
    try {
      monitor.begin();
      Async async = monitor.forkAsync();

      try {
        int viewID = in.readInt();
        CDOBranchPoint branchPoint = in.readCDOBranchPoint();

        int size = in.readInt();
        List<CDOID> invalidObjects = new ArrayList<CDOID>(size);
        for (int i = 0; i < size; i++) {
          CDOID id = in.readCDOID();
          invalidObjects.add(id);
        }

        InternalView view = getSession().getView(viewID);
        view.changeTarget(branchPoint, invalidObjects, allChangedObjects, allDetachedObjects);
      } finally {
        async.stop();
      }

    } finally {
      monitor.done();
    }
  }
  protected void writeRevision(InternalCDORevision revision, OMMonitor monitor) {
    Async async = null;
    monitor.begin(10);

    try {
      try {
        async = monitor.forkAsync();
        if (revision.isResourceNode()) {
          checkDuplicateResources(revision);
        }
      } finally {
        if (async != null) {
          async.stop();
        }
      }

      // TODO removal of previous version implies query, this should be optimized

      long start = System.currentTimeMillis();
      CDOID id = revision.getID();
      DB4OStore.removeRevision(getObjectContainer(), id);
      DB4ORevision primitiveRevision = DB4ORevision.getDB4ORevision(revision);
      writeObject(primitiveRevision, monitor);
      long end = System.currentTimeMillis();
      OM.LOG.debug("Writing revision " + id + " took: " + (end - start) + " milliseconds");
    } finally {
      monitor.done();
    }
  }
  protected void writeObject(Object object, OMMonitor monitor) {
    monitor.begin();
    Async async = monitor.forkAsync();

    try {
      getObjectContainer().store(object);
    } catch (Throwable t) {
      OM.LOG.error(t);
    } finally {
      async.stop();
      monitor.done();
    }
  }
  @Override
  protected void detachObjects(
      CDOID[] detachedObjects, CDOBranch branch, long timeStamp, OMMonitor monitor) {
    monitor.begin(detachedObjects.length);

    try {
      for (CDOID id : detachedObjects) {
        DB4OStore.removeRevision(getObjectContainer(), id);
        monitor.worked();
      }
    } finally {
      monitor.done();
    }
  }
  @Override
  protected void writeRevisions(
      InternalCDORevision[] revisions, CDOBranch branch, OMMonitor monitor) {
    monitor.begin(revisions.length);

    try {
      long start = System.currentTimeMillis();
      for (InternalCDORevision revision : revisions) {
        writeRevision(revision, monitor.fork());
      }
      long end = System.currentTimeMillis();
      OM.LOG.debug(
          "Storage of " + revisions.length + " revisions took: " + (end - start) + " milliseconds");
    } finally {
      monitor.done();
    }
  }
  @Override
  protected void doCommit(OMMonitor monitor) {
    monitor.begin();
    Async async = monitor.forkAsync();

    try {
      long start = System.currentTimeMillis();
      getObjectContainer().commit();
      long end = System.currentTimeMillis();
      OM.LOG.debug("Commit took -> " + (end - start) + " milliseconds");
    } catch (Exception e) {
      OM.LOG.error(e);
    } finally {
      async.stop();
      monitor.done();
    }
  }
  public void writePackageUnits(InternalCDOPackageUnit[] packageUnits, OMMonitor monitor) {
    monitor.begin(packageUnits.length);

    try {
      DB4OStore store = getStore();
      ObjectContainer objectContainer = getObjectContainer();

      for (InternalCDOPackageUnit packageUnit : packageUnits) {
        DB4OPackageUnit primitivePackageUnit =
            DB4OPackageUnit.getPrimitivePackageUnit(store, packageUnit);
        objectContainer.store(primitivePackageUnit);
        monitor.worked(1);
      }
    } catch (Exception ex) {
      OM.LOG.error(ex);
    } finally {
      monitor.done();
    }
  }
  public void createMapping(
      Connection connection, InternalCDOPackageUnit[] packageUnits, OMMonitor monitor) {
    Async async = null;
    monitor.begin();

    try {
      async = monitor.forkAsync();

      try {
        mapPackageUnits(packageUnits, connection, false);
      } finally {
        if (async != null) {
          async.stop();
        }
      }
    } finally {
      monitor.done();
    }
  }
  public Set<CDOID> readChangeSet(
      IDBStoreAccessor accessor, OMMonitor monitor, CDOChangeSetSegment[] segments) {
    Set<CDOID> result = new HashSet<CDOID>();
    Collection<IClassMapping> classMappings = getClassMappings().values();

    monitor.begin(classMappings.size());

    try {
      for (IClassMapping mapping : classMappings) {
        Async async = monitor.forkAsync();

        try {
          Set<CDOID> ids = mapping.readChangeSet(accessor, segments);
          result.addAll(ids);
        } finally {
          async.stop();
        }
      }

      return result;
    } finally {
      monitor.done();
    }
  }