docs: public void remove(Token token,
                         boolean requiresCurrentCheckpoint)
                      throws ObjectManagerException {
          final String methodName = "remove";
          if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
              trace.entry(this,
                          cclass,
                          methodName,
                          new Object[] { token, new Boolean(requiresCurrentCheckpoint) });
  
          super.remove(token, requiresCurrentCheckpoint);
  
          // Cancel any writing.
          managedObjectsToWrite.remove(new Long(token.storedObjectIdentifier));
  
          // Schedule the deletion of the disk copy.
          if (storeStrategy == STRATEGY_SAVE_ONLY_ON_SHUTDOWN) {
              // We don't need to add Objects that are not in the directory as they wont need to be 
              // deleted. This is important for Stores only written at shutdown as they may 
              // accumulate a lot of delete operations.
              Directory.StoreArea storeArea = (Directory.StoreArea) directory.getEntry(new Long(token.storedObjectIdentifier));
              if (storeArea != null)
                  tokensToDelete.put(new Long(token.storedObjectIdentifier),
                                     token);
  
          } else if (requiresCurrentCheckpoint) {
              // The checkpoint logic in ObjectManagerState never calls flush until all of the
              // requiresCurrentCheckpoint transactions have been checkpointed. So no need to synchronize 
              // on checkpointManagedObjectsToWrite.
              if (checkpointTokensToDelete == null)
                  captureCheckpointManagedObjects();
  
              checkpointTokensToDelete.put(new Long(token.storedObjectIdentifier),
                                           token);
  
          } else {
              // If flush() gets ahead of our addition to this table it will be deleted
              // next time.
              // Repeat attempts to insert the token into the tokensToDelete until we find one that 
              // we can be sure was included in a flush().
              for (;;) {
                  java.util.Map myTokensToDelete = tokensToDelete;
                  myTokensToDelete.put(new Long(token.storedObjectIdentifier),
                                       token);
                  // Make sure the flush() did not steal tokensToDelete while we were adding to it.
                  if (myTokensToDelete == tokensToDelete)
                      break;
              } // for (;;).
          }
  
          // Cancel the ManagedObjects reference from the cache, if it is in memory. We might get the wrong
          // ManagedObject if the slot has been reused, that's OK because it's just the same as if it 
          // is being reused.
          if (token.managedObjectReference != null) {
              ManagedObject managedObject = (ManagedObject) token.managedObjectReference.get();
              if (managedObject != null) {
                  java.lang.ref.SoftReference[] localCachedManagedObjects = cachedManagedObjects;
                  if (managedObject.objectStoreCacheIndex < localCachedManagedObjects.length)
                      localCachedManagedObjects[managedObject.objectStoreCacheIndex] = null;
              }
          } // if (token.managedObjectReference != null).
  
          if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
              trace.exit(this,
                         cclass,
                         methodName);
      }