docs: @Override
      public void complete(VirtualConnection vc) {
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())    
              Tr.debug(tc, "complete callback called , WriteListener enabled: " + this._wl); 
  
  
          synchronized(_hout) {
              if (null == vc) {
                  return;
              }
              if (_hout.getExceptionDuringOnWP()){
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())    
                      Tr.debug(tc, "earlier exception happened, onError was called , WriteListener enabled: " + this._wl); 
                  _hout.setExceptionDuringOnWP(false);
                  return;
              }
              //clean up any request state we had on this thread.
              WebContainerRequestState reqState = WebContainerRequestState.getInstance(true);                 
              reqState.init();
  
              try {                    
                  _hout.writeRemainingToBuffers();
              } catch (Exception ex) {
                  //Print exception
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()){  
                      Tr.debug(tc, "Exception during writeRemainingToBuffers : " + ex);
                  }
                  this.error(vc, ex);
                  return;
              }
  
              // everything must be written now , 
              if (_hout.get_internalReady()) {
                  // this case will only be true if write which went aysnc was from println, now we have to write crlf
                  if(_hout.write_crlf_pending){
                      if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())    
                          Tr.debug(tc, "ready to write CRLF bytes  , WriteListener enabled: " + this._wl); 
                      try {                    
                          //_hout.set_internalReady(true); // since CRLF needs to be written we are still not external ready
                          reqState.setAttribute("com.ibm.ws.webcontainer.WriteAllowedonThisThread", true);        
                          reqState.setAttribute("com.ibm.ws.webcontainer.CRLFWriteinPorgress", true);                            
                          _out.writeCRLFIfNeeded();
                      } catch (IOException e) {
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()){  
                              Tr.debug(tc, "Exception during write CRLF bytes: " + e);
                          }
                          _hout.write_crlf_pending = false;
                          this.error(vc, e);                       
                          return;
                      }                   
                  }
              }
              if (_hout.get_internalReady()) {
                  synchronized(_hout._writeReadyLockObj){   
  
                      //Setting isReady to true since a complete call means data is written out                      
                      WebContainerRequestState.getInstance(true).setAttribute("com.ibm.ws.webcontainer.WriteAllowedonThisThread", true);
                      _hout.setWriteReady(true);
                  }
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()){  
                      Tr.debug(tc, "WriteListener enabled: " + this._wl + " , status_not_ready_checked -->" + _hout.status_not_ready_checked);
                  }
                  if( _hout.status_not_ready_checked) {                                       
                      try{
                          _hout.status_not_ready_checked = false;
                          
                          SRTServletRequestThreadData.getInstance().init(_requestDataAsyncWriteCallbackThread);
                          
                          //Push the original thread's context onto the current thread, also save off the current thread's context
                          tcm.pushContextData();
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()){  
                              Tr.debug(tc, "WriteListener enabled: " + this._wl + " , call onWritePossible.");
                          }
                          //Call into the user's WriteListener to indicate more data cane be written
                          _wl.onWritePossible();
  
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()){  
                              Tr.debug(tc, "WriteListener enabled: " + this._wl + " , returned from onWritePossible.");
                          }
                      } catch (Exception ex) {
                          //Print exception
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()){  
                              Tr.debug(tc, "Exception during onWritePossible : " + ex);
                          }
                          this.error(vc, ex);    
                      }
                      finally{
                          //Revert back to the thread's current context
                          tcm.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 has gone async");
                      }
                  }
              }
          }
  
  
      }