docs: @Override
      public void close() throws Exception {         
  
          if(webConnection_closeComplete){
              if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                  Tr.debug(tc, "WebConnection close previously completed ...return ");
              }
              return;
          }
          else{
              // this is for the case to avoid infinite loop if handler destroy end up calling webconnection close.  
              if(upgradeHandler_DestroyStarted){
                  return;
              }
              synchronized(this) {
                  //check it again 
                  if(webConnection_closeComplete || webConnection_closeOngoing){
                      if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                          Tr.debug(tc, "WebConnection close previously completed .....return ");
                      }
                      return;
                  }
                  webConnection_closeOngoing = true;
  
  
                  //      Call UpgradeHandler destroy() API.      
                  //upgradeHandler_DestroyComplete  is needed if close is called again from complete , we do not call destroy again
                  if (!upgradeHandler_DestroyComplete && _upgradeHandler != null) { 
                      /// call application handler class destroy
  
                      try{ 
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                              Tr.debug(tc, "call Handler destroy "+ this._upgradeHandler);                      
                          } 
                          upgradeHandler_DestroyStarted= true;
                          _upgradeHandler.destroy();
                      }
                      finally{
                          upgradeHandler_DestroyComplete = true;
                          upgradeHandler_DestroyStarted= false;
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                              Tr.debug(tc, "Handler destroy successful"+ this._upgradeHandler);                      
                          }
                      }
                  }          
  
                  if(_in != null && (_in.getInputBufferHelper().get_tcpChannelCallback() != null)){
                      if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                          Tr.debug(tc, " input callback");
                      }
                      inputCallback = true;
                  }
  
                  //close the streams , make sure even if one fails we close rest. 
                  try{
                      if(_in!= null)
                          _in.close();
                  }catch(IOException ioe){
                      if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                          Tr.debug(tc, " closing of inputStream failed ..");
                      }
                      closeUpgradeException = ioe;
                  }
  
                  // now close output
                  // close connection
                  closeOutputandConnection();
              }
          }
      }