docs: protected void addAsFirst(NonDelayedClassInfo classInfo) {
          String methodName = "addAsFirst";
          boolean doLog = tc.isDebugEnabled();
          String useHashText = (doLog ? getHashText() : null);
          String useClassHashText = (doLog ? classInfo.getHashText() : null);
  
          if (doLog) {
              logLinks(methodName, classInfo);
          }
  
          if (firstClassInfo == null) {
              if (doLog) {
                  Tr.debug(tc, MessageFormat.format("[ {0} ] Adding [ {1} ] to empty",
                                                    new Object[] { useHashText, useClassHashText }));
              }
  
              firstClassInfo = classInfo;
  
              lastClassInfo = classInfo;
  
              // last == first
              // lastClassInfoName == firstClassInfoName
  
              // first.next remains null
              // first.prev remains null
  
          } else if (firstClassInfo == lastClassInfo) {
              if (doLog) {
                  Tr.debug(tc, MessageFormat.format("[ {0} ] Adding [ {1} ] to singleton [ {2} ]",
                                                    new Object[] { useHashText, useClassHashText, firstClassInfo.getHashText() }));
              }
  
              firstClassInfo = classInfo;
  
              firstClassInfo.setNextClassInfo(lastClassInfo);
              lastClassInfo.setPriorClassInfo(classInfo);
  
              // last != first
              // lastClassInfoName != firstClassInfoName
  
              // first.prev == null
              // first.next == last
  
              // last.prev == first
              // last.next == null
  
          } else {
              if (doLog) {
                  Tr.debug(tc, MessageFormat.format("[ {0} ] Adding [ {1} ] to multitude [ {2} ]",
                                                    new Object[] { useHashText,
                                                                  useClassHashText,
                                                                  firstClassInfo.getHashText() }));
              }
  
              classInfo.setNextClassInfo(firstClassInfo);
  
              firstClassInfo.setPriorClassInfo(classInfo);
  
              firstClassInfo = classInfo;
  
              if (classInfos.size() > ClassInfoCache.classInfoCacheLimit) {
                  NonDelayedClassInfo oldLastClassInfo = lastClassInfo;
                  String lastClassName = lastClassInfo.getName();
                  classInfos.remove(lastClassName);
  
                  discardRef(lastClassName); // No current use for the old last class name; discard it.
  
                  lastClassInfo = oldLastClassInfo.getPriorClassInfo();
  
                  lastClassInfo.setNextClassInfo(null);
  
                  // oldLastClassInfo.setNextClassInfo(null);
                  oldLastClassInfo.setPriorClassInfo(null);
  
                  if (doLog) {
                      Tr.debug(tc, MessageFormat.format("[ {0} ] new last [ {1} ] displaces [ {2} ]",
                                                        new Object[] { useHashText,
                                                                      lastClassInfo.getHashText(),
                                                                      oldLastClassInfo.getHashText() }));
                  }
  
                  DelayedClassInfo delayedClassInfo = oldLastClassInfo.getDelayedClassInfo();
                  if (delayedClassInfo != null) {
                      if (doLog) {
                          Tr.debug(tc, MessageFormat.format("[ {0} ] Clearing link on displaced [ {1} ]",
                                                            new Object[] { useHashText, oldLastClassInfo.getHashText() }));
                      }
  
                      delayedClassInfo.setClassInfo(null);
                      oldLastClassInfo.setDelayedClassInfo(null);
                  }
              }
          }
      }