docs: public void readObject(java.io.DataInputStream dataInputStream,
                             ObjectManagerState objectManagerState)
                      throws ObjectManagerException
      {
          if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
              trace.entry(this, cclass,
                          "readObject",
                          "DataInputStream="
                                          + dataInputStream
                                          + ", ObjectManagerState="
                                          + objectManagerState);
  
          try {
              byte version = dataInputStream.readByte();
              if (Tracing.isAnyTracingEnabled() && trace.isDebugEnabled())
                  trace.debug(this, cclass
                              , "readObject"
                              , "version=" + version + "(byte)"
                                  );
              super.readObject(dataInputStream,
                               objectManagerState);
  
              activeSubListCount = dataInputStream.readInt();
              subListTokens = new Token[activeSubListCount];
  
              for (int i = 0; i < subListTokens.length; i++) {
                  subListTokens[i] = Token.restore(dataInputStream,
                                                   objectManagerState);
              } // for subLists.    
  
          } catch (java.io.IOException exception) {
              // No FFDC Code Needed.
              ObjectManager.ffdc.processException(this, cclass, "readObject", exception, "1:1280:1.26");
  
              if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                  trace.exit(this, cclass
                             , "readObject"
                             , "via PermanentIOException"
                                  );
              throw new PermanentIOException(this,
                                             exception);
          } // catch (java.io.IOException exception).
  
          // Force a full search when the first removeFirst operation occurs.
          headSequenceNumber = Long.MAX_VALUE;
          headSequenceNumberLock = new HeadSequenceNumberLock();
          tailSequenceNumber = 0;
          tailSequenceNumberLock = new TailSequenceNumberLock();
          subLists = new ConcurrentSubList[subListTokens.length];
  
          // Defect 322295
          // This check has been added to handle the case where a ConcurrentLinkedList 
          // has been deleted but only (some or all of) the sub list deletions were 
          // forced to the object store before a crash. 
          //
          //  i.e.  [subList del][subList del][OS Force][subList del][CLList del][crash]
          //
          // This results in the ConcurrentLinkedList having tokens that point to some sub 
          // lists that no longer have managed objects so the references being setup below 
          // could be null. At recovery time however these null references will be replaced
          // with DummyManagedObjects when each individual sub list delete is replayed by
          // the log. This results in a ClassCastException below.
          //
          // To avoid the exception we only add the real sub list managed objects to the 
          // array. This should be ok as once recovery has completed the entire linked list
          // should have been deleted so no exhaustive list of sub lists is required.
          //
          // TODO: Can we avoid this check by grouping transaction work into a single checkpoint?
          for (int i = 0; i < subListTokens.length; i++) {
  
              ManagedObject managedObject = subListTokens[i].getManagedObject();
  
              if (managedObject instanceof ConcurrentSubList)
              {
                  subLists[i] = (ConcurrentSubList) managedObject;
              }
          } // for subList.
  
          // During recovery some of the sublists may not have completed their recovery when the concurrentList is found.
          // Also some of the links in the subLists may have already been deleted by later Transactions and so be 
          // unavailable during recovery.
          // Also if we look at the sublists during recovery we create cyclic dependancies between the overall 
          // lists and the subLists. We defer setting the tailSequenceNumber until first use of the list. 
  
          if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
              trace.exit(this, cclass,
                         "readObject");
      }