docs: protected void _close(boolean removeConnectionListeners)
                      throws SIConnectionLostException, SIResourceException, SIErrorException
      {
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              SibTr.entry(tc, "_close", Boolean.valueOf(removeConnectionListeners));
          // Synchronize on the closed object so that we can't change it while
          // someone else is trying to check it. This will also block all operations
          // until we have finished cleaning up.
          synchronized (this)
          {
              if (_closed)
              {
                  if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                      SibTr.exit(tc, "_close", "Returning as already closed");
                  return;
              }
  
              _closed = true;
  
              // as the connection is now closed we need to log the user out.
  
              String busName = _messageProcessor.getBus().getName();
  
              _messageProcessor.getAuthorisationUtils().logout(busName, _subject);
  
              // Work down the list of active transactions owned by this connection
              // and roll them back.
              synchronized (_ownedTransactions)
              {
                  Iterator<LocalTransaction> itr = _ownedTransactions.iterator();
                  while (itr.hasNext())
                  {
                      LocalTransaction tran = itr.next();
                      itr.remove();
                      try
                      {
                          tran.rollback(); // Rollback the transaction
                      } catch (SIException e)
                      {
                          // No FFDC code needed
  
                          // It is possible that the MS has had to rollback this transaction
                          // already so we shouldn't worry if we see this exception
                      }
                  }
              }
  
              //Sequentially iterate over all of the sessions, closing them.
              //The internal _close() method is called in preference to close() on the API.
              //The standard close method will try to remove it's self from these lists
              //before actually closing. This would invalidate our iterators.
              //We will remove them from the lists ourselves using the specialized remove method
              //on the iterator.
  
              //synchronize on the list of producers etc. We might not actually need to
              //do this since no one else should be able to do anything while we have
              //the closed lock.
              synchronized (_producers)
              {
                  Iterator<ProducerSession> itr = _producers.iterator();
                  while (itr.hasNext())
                  {
                      ProducerSessionImpl ps = (ProducerSessionImpl) itr.next();
                      itr.remove();
                      ps._close();
                  }
              }
  
              // Close all the bifurcated consumers on this connection 
              // before closing all the consumers.
              synchronized (_bifurcatedConsumers)
              {
                  Iterator<BifurcatedConsumerSessionImpl> itr = _bifurcatedConsumers.iterator();
                  while (itr.hasNext())
                  {
                      BifurcatedConsumerSessionImpl bcs = itr.next();
                      itr.remove();
                      bcs._close();
                  }
              }
  
              synchronized (_consumers)
              {
                  Iterator<ConsumerSessionImpl> itr = _consumers.iterator();
                  while (itr.hasNext())
                  {
                      ConsumerSessionImpl cs = itr.next();
                      itr.remove();
                      _messageProcessor.removeConsumer(cs);
                      cs._close();
                  }
              }
              synchronized (_browsers)
              {
                  Iterator<BrowserSession> itr = _browsers.iterator();
                  while (itr.hasNext())
                  {
                      BrowserSessionImpl bs = (BrowserSessionImpl) itr.next();
                      itr.remove();
                      bs._close();
                  }
              }
              synchronized (_temporaryDestinations)
              {
                  Iterator<String> itr = _temporaryDestinations.iterator();
                  while (itr.hasNext())
                  {
                      String destinationName = itr.next();
                      try
                      {
                          _destinationManager.deleteTemporaryDestination(SIMPUtils.createJsDestinationAddress(destinationName,
                                                                                                              _messageProcessor.getMessagingEngineUuid()));
                      } catch (SIException e)
                      {
                          // No FFDC code needed
  
                          SibTr.exception(tc, e);
  
                          // This destination will be deleted at restart.
                      }
                      itr.remove();
                  }
              }
  
              if (removeConnectionListeners)
              {
                  synchronized (_connectionListeners)
                  {
                      Iterator<SICoreConnectionListener> itr = _connectionListeners.iterator();
                      while (itr.hasNext())
                      {
                          // Iterate through each of the connection listeners and remove them
                          itr.next();
                          itr.remove();
                      }
                  }
              }
  
              // Close processing for consumer set monitors
              try
              {
                  _messageProcessor.
                                  getMessageProcessorMatching().removeConsumerSetMonitors(this);
              } catch (SINotPossibleInCurrentConfigurationException e)
              {
                  // FFDC
                  FFDCFilter.processException(e,
                                              "com.ibm.ws.sib.processor.impl.ConnectionImpl._close",
                                              "1:745:1.347.1.25",
                                              this);
  
                  if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                      SibTr.exit(tc, "_close", e);
                  // Thrown if callback couldn't be found
                  throw new SIErrorException(nls.getFormattedMessage(
                                                                     "INTERNAL_MESSAGING_ERROR_CWSIP0001",
                                                                     new Object[] { "ConnectionImpl",
                                                                                   "1:754:1.347.1.25" },
                                                                     null), e);
              }
  
              // Remove any destination listeners associated with this connection
              _destinationManager.removeDestinationListener(this);
  
              // Now the close is complete, remove this connection.
              _messageProcessor.removeConnection(this);
          }
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              SibTr.exit(tc, "_close");
      }