docs: protected Link addEntry(Token token,
                              Transaction transaction,
                              long sequenceNumber,
                              ConcurrentLinkedList parentList)
                      throws ObjectManagerException
      {
          final String methodName = "addEntry";
          if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
              trace.entry(this, cclass, methodName, new Object[] { token,
                                                                  transaction,
                                                                  new Long(sequenceNumber),
                                                                  parentList});
          Link newLink;
          synchronized (this) {
              // Prevent other transactions using the list until its creation is commited.
              if (!(state == stateReady)
                  && !((state == stateAdded) && lockedBy(transaction))) {
  
                  if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                      trace.exit(this, cclass, methodName, new Object[] { new Integer(state),
                                                                         stateNames[state] });
                  throw new InvalidStateException(this, state, stateNames[state]);
              }
  
              // All optimistic replace updates to links in the list must be made
              // together, so we construct a single log record for all of them.
              managedObjectsToAdd.clear();
              managedObjectsToReplace.clear();
              reservedSpaceInStore = storeSpaceForAdd();
              owningToken.objectStore.reserve((int) reservedSpaceInStore, false);
  
              // TODO Do not need to do the following now that we hold the
              // tailSequenceNumberLock while we do the add.
              // Move backward through the list until we find an element that has a
              // sequence number
              // less than the one we want to add.
              Token previousToken = tail;
              Link previousLink = null;
              searchBackward: while (previousToken != null) {
                  previousLink = (Link) previousToken.getManagedObject();
                  if (previousLink.sequenceNumber <= sequenceNumber)
                      break searchBackward;
                  previousToken = previousLink.previous;
              } // While (previousLink != null).
  
              Token nextToken = null;
              if (previousToken == null) // We are to go at the head of the list.
                  nextToken = head; // May be null after us if the list is empty.
              else
                  // Chain the remainder of the list after us.
                  nextToken = previousLink.next;
  
              // Create the new link and add it to its object store.
              newLink = new Link(this, // Create the Link for the new object.
                                 token, // Object referenced by the link.
                                 previousToken,
                                 nextToken,
                                 transaction, // Transaction controling the addition.
                                 sequenceNumber);
              managedObjectsToAdd.add(newLink);
  
              // Chain the new Link in the list. If the transaction backs
              // out we will rewrite the links to remove the new one.
              if (previousToken == null) { // First element in the list?
                  head = newLink.getToken();
                  availableHead = head;
              } else { // Not the head of the list.
                  previousLink.next = newLink.getToken();
                  managedObjectsToReplace.add(previousLink);
                  // See if we should move the availableHead up the list ( towards the head ).
                  if (availableHead == null) // All of the list ahead of us is to be
                                             // deleted.
                      availableHead = newLink.getToken();
                  else if (((Link) availableHead.getManagedObject()).sequenceNumber > sequenceNumber)
                      availableHead = newLink.getToken();
              } // if (previousLink == null).
  
              if (nextToken == null) { // Anything after the insertPoint?
                  tail = newLink.getToken(); // Last element in the list.
              } else { // Not the tail of the list.
                  Link nextLink = (Link) nextToken.getManagedObject();
                  nextLink.previous = newLink.getToken();
                  managedObjectsToReplace.add(nextLink);
              } // if (nextToken == null).
  
              // clone(Transaction transaction, ObjectStore objectStore) does not lock the cloned list.
              if ( parentList.tailSequenceNumberLock.isHeldByCurrentThread())
                parentList.tailSequenceNumberLock.unlock();
        
              incrementSize(); // Adjust list length assuming we will commit.
              managedObjectsToReplace.add(this); // The anchor for the list.
  
              // Harden the updates. If the update fails, because the log is full,
              // we have affected the structure of the list so we will have to 
              // reverse the changes. Reserve enough space to reverse the update if the
              // transaction backs out.
              try {
                  transaction.optimisticReplace(managedObjectsToAdd,
                                                managedObjectsToReplace,
                                                null, // No tokens to delete.
                                                null, // No tokens to notify.
                                                logSpaceForDelete());
                  // Give up reserved space, but keep back enough to remove the entry if we have to.
                  owningToken.objectStore.reserve((int) (storeSpaceForRemove() - reservedSpaceInStore), false);
  
              } catch (InvalidStateException exception) {
                  // No FFDC Code Needed, user error.
                  // Remove the link we just added.
                  undoAdd(newLink);
                  if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                      trace.exit(this, cclass, methodName, exception);
                  throw exception;
  
              } catch (LogFileFullException exception) {
                  // No FFDC Code Needed, InternalTransaction has already done this.
                  // Remove the link we just added.
                  undoAdd(newLink);
  
                  if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                      trace.exit(this, cclass, methodName, exception);
                  throw exception;
  
                  // We should not see ObjectStoreFullException because we have preReserved 
                  // the ObjectStore space.
  //      } catch (ObjectStoreFullException exception) {
  //        // No FFDC Code Needed, InternalTransaction has already done this.
  //        // Remove the link we just added.
  //        undoAdd(newLink);       
  //        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
  //          trace.exit(this, cclass, methodName, exception);
  //        throw exception;
              } // try.
  
          } // synchronized (this).
  
          if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
              trace.exit(this, cclass, methodName, new Object[] { newLink });
          return newLink;
      }