docs: @Override
      public void complete(com.ibm.wsspi.channelfw.VirtualConnection vc, com.ibm.wsspi.tcpchannel.TCPWriteRequestContext wsc) {
          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())  
              Tr.debug(tc, "complete called : " + vc + "WriteListener enabled: " + this._wl);
  
          synchronized(_upgradeOut) {
  
              if (null == vc) {
                  return;
              }
  
              if (_upgradeOut.getBufferHelper().isOutputStream_closed()) {
  
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                      Tr.debug(tc, "complete , outputStream closed ignoring complete : " + vc);
  
                  return;
              }
  
              // clean up any request state we had on this thread.
              WebContainerRequestState reqState = WebContainerRequestState.getInstance(true);
              reqState.init();
              try{    
                  _upgradeOut.getBufferHelper().writeRemainingToBuffers();                 
  
              } catch (Exception e) {
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()){  
                      Tr.debug(tc, "exception during writeBuffers" + e.toString());
                  }
                  this.error(vc, e);
                  return;
              }
  
  
              // rest must be written now ,
              // this case will only be true if write which went aysnc was
              // from println, now we have to write crlf
              if ( _upgradeOut.getBufferHelper().isInternalReady() && _upgradeOut.getBufferHelper().write_crlf_pending) {
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                      Tr.debug(tc, "write CRLF bytes  , WriteListener enabled: " + this._wl);
                  try {
                      reqState.setAttribute("com.ibm.ws.webcontainer.upgrade.WriteAllowedonThisThread", true);
                      reqState.setAttribute("com.ibm.ws.webcontainer.upgrade.CRLFWriteinPorgress", true);
                      _upgradeOut.getBufferHelper().writeCRLFIfNeeded();
                  } catch (IOException e) {
                      if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) 
                          Tr.debug(tc, " Exception during write CRLF bytes: " + e);
  
                      _upgradeOut.getBufferHelper().write_crlf_pending = false;
                      this.error(vc, e);
                      return;
                  }
              }
  
              if( _upgradeOut.getBufferHelper().isInternalReady()){
                  WebContainerRequestState.getInstance(true).setAttribute("com.ibm.ws.webcontainer.upgrade.WriteAllowedonThisThread", true);
  
                  _upgradeOut.getBufferHelper().setReadyForApp(true);
  
                  // if close was in progress
                  if(_upgradeOut.getBufferHelper().isOutputStream_close_initiated_but_not_Flush_ready()){
                      if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()){
                          Tr.debug(tc, "complete , In process of closing outputStream, no more data is left to write, call close");
                      }
                      try {
                          if(_upCon.isOutputStream_CloseStartedFromWC()){
                              //at this point inputstream and handler are already closed
                              _upCon.closeOutputandConnection();
                          }
                          else{
                              _upgradeOut.close();
                          }
                      } catch (Exception e) {
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                              Tr.debug(tc, "complete , stack exception" + e.toString());
  
                          this.error(vc, e);
                      }
  
                  }// no close in progress now check if onWP needs to be called.
                  else{
                      if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()){  
                          Tr.debug(tc, "WriteListener enabled: " + this._wl + " ,status_not_ready_checked -->" + _upgradeOut.getBufferHelper().status_not_ready_checked);
                      }
                      if (_upgradeOut.getBufferHelper().status_not_ready_checked) {
                          try{
                              _upgradeOut.getBufferHelper().status_not_ready_checked = false;
  
                              // Push the original thread's context onto the current thread,
                              // also save off the current thread's context
                              _contextManager.pushContextData();
                              if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()){  
                                  Tr.debug(tc, "Calling user's WriteListener onWritePossible");
                              }
                              // Call into the user's WriteListener to indicate more data cane
                              // be written
                              _wl.onWritePossible();
                          } catch (Exception e) {
                              if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()){  
                                  Tr.debug(tc, "stack exception" + e.toString());
                              }
                              this.error(vc, e);
                          } finally {
                              // Revert back to the thread's current context
                              _contextManager.popContextData();
                          }
                      }
                      else{
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()){  
                              Tr.debug(tc, "WriteListener enabled: " 
                                              + this._wl + " .onWritePossible will be skipped as isReady has not been checked since write went async.");
                          }
                      }
                  }
              }
          }
      }