docs: synchronized void putValueGuts(String pName, Object pValue) {
          if (com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled() && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINE)) {
              LoggingUtil.SESSION_LOGGER_WAS.entering(methodClassName, methodNames[PUT_VALUE_GUTS], "pName = " + pName);
          }
  
          if (pName == null || pValue == null) {
              return;
          }
  
          // If in Servlet 2.2 mode and Distributable Web App and data in not serializable
          // then throw an exception
          boolean distributableWebApp = getIStore().isDistributable();
          boolean swappable = true;
          Object convObj = replaceObjectForSerialization(pValue);
          if (convObj == null) {
              swappable = false;
              convObj = pValue;
          }
  
          if (!swappable) { //105962 (tWAS 745384) update the trace message logic to be more specific
              if (distributableWebApp) {
                  if (com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled() && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINE)) {
                      LoggingUtil.SESSION_LOGGER_WAS.logp(Level.FINE, methodClassName, methodNames[PUT_VALUE_GUTS], "IllegalArgumentException");
                  }
  
                  throw new IllegalArgumentException("Attribute with name " + pName + " is not java.io.Serializable. All attributes stored in session must be Serializable when web module is marked as distributable");
              } else if (com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled() && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINE)) {
                  LoggingUtil.SESSION_LOGGER_WAS.logp(Level.FINE, methodClassName, methodNames[PUT_VALUE_GUTS], "Attribute with name " + pName + " is not Serializable. This may cause a problem on a failover.");
              }
          }
  
          if (appDataChanges == null) {
              if (com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled() && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINE)) {
                  LoggingUtil.SESSION_LOGGER_WAS.logp(Level.FINE, methodClassName, methodNames[PUT_VALUE_GUTS], "init appDataChanges");
              }
              appDataChanges = new Hashtable();
          }
  
          if (swappable) {
              // Still want to update lists since whole session may not get written at first EOS
              includeInAppDataChanges(pName, _smc.writeGetAndSetAttributes() ? pValue : convObj, PUT_VALUE_GUTS);
  
              boolean listenerFlagSetInMethod = false; //a check for instanceof was moved into the individual instancof blocks ... still only want to get getListenerFlag() once.
  
              if (pValue instanceof HttpSessionBindingListener) {
                  if (com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled() && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINE)) {
                      LoggingUtil.SESSION_LOGGER_WAS.logp(Level.FINE, methodClassName, methodNames[PUT_VALUE_GUTS], "Property is a binding listener: " + pName);
                  }
                  if (!isNew()) { // listenerFlag should be up-to-date for new session
                      //Read from the database only once
                      listenerFlag = getListenerFlag();
                      listenerFlagSetInMethod = true;
                  }
  
                  switch (listenerFlag) {
                      case HTTP_SESSION_NO_LISTENER:
                          listenerFlag = HTTP_SESSION_BINDING_LISTENER;
                          listenCntHit = true;
                          break;
                      case HTTP_SESSION_ACTIVATION_LISTENER:
                          listenerFlag = HTTP_SESSION_BINDING_AND_ACTIVATION_LISTENER;
                          listenCntHit = true;
                          break;
                      default:
                          break;
                  }
              }
  
              if (pValue instanceof HttpSessionActivationListener) {
  
                  if (com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled() && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINE)) {
                      LoggingUtil.SESSION_LOGGER_WAS.logp(Level.FINE, methodClassName, methodNames[PUT_VALUE_GUTS], "Property is an Activation listener: " + pName);
                  }
                  if (!isNew() && !listenerFlagSetInMethod) { // listenerFlag should be up-to-date for new session
                      //Read from the database only once
                      listenerFlag = getListenerFlag();
                  }
  
                  switch (listenerFlag) {
                      case HTTP_SESSION_NO_LISTENER:
  
                          listenerFlag = HTTP_SESSION_ACTIVATION_LISTENER;
                          listenCntHit = true;
                          break;
                      case HTTP_SESSION_BINDING_LISTENER:
                          listenerFlag = HTTP_SESSION_BINDING_AND_ACTIVATION_LISTENER;
                          listenCntHit = true;
                          break;
                      default:
                          break;
                  }
              }
  
              //if value is removed and then put back, remove it from removalList
              // long term, we may want to check all the threads
              // We need to remove it from the removals even if new since removals are updated when new
  
              if (appDataRemovals != null) {
  
                  if (appDataTablesPerThread) {
                      Thread t = Thread.currentThread();
                      Hashtable sht2 = (Hashtable) appDataRemovals.get(t);
                      if (sht2 != null) {
                          sht2.remove(pName);
  
                          if (sht2.isEmpty()) {
                              appDataRemovals.remove(t);
                          }
                      }
                  } else { // appDataTablesPerSession
                      appDataRemovals.remove(pName);
                  }
              }
          } //end if (swappable) block
  
          if (swappable) {
              if (mNonswappableData != null) { // don't call getNonswappable if null
                                               // don't want to allocate unless needed
                  getNonswappableData().remove(pName); // make sure it doesn't exist in nonswappable
              }
              getSwappableData().put(pName, convObj);
          } else {
              getSwappableData().remove(pName);// ensure it doesn't exist in swappable
                                               // this probably won't work for multi-row
              getNonswappableData().put(pName, convObj);
          }
      }