code: @Override
      public void close() {
          if (closing.compareAndSet(false, true)) {
              if (log.isDebugEnabled()) {
                  log.debug("close: {}", sessionId);
              }
              stopWaitForHandshake();
              stopRoundTripMeasurement();
              // update our state
              if (state != null) {
                  final byte s = getStateCode();
                  switch (s) {
                      case RTMP.STATE_DISCONNECTED:
                          if (log.isDebugEnabled()) {
                              log.debug("Already disconnected");
                          }
                          return;
                      default:
                          if (log.isDebugEnabled()) {
                              log.debug("State: {}", RTMP.states[s]);
                          }
                          setStateCode(RTMP.STATE_DISCONNECTING);
                  }
              }
              Red5.setConnectionLocal(this);
              IStreamService streamService = (IStreamService) ScopeUtils.getScopeService(scope, IStreamService.class, StreamService.class);
              if (streamService != null) {
                  //in the end of call streamService.deleteStream we do streams.remove
                  for (Iterator<IClientStream> it = streams.values().iterator(); it.hasNext();) {
                      IClientStream stream = it.next();
                      if (log.isDebugEnabled()) {
                          log.debug("Closing stream: {}", stream.getStreamId());
                      }
                      streamService.deleteStream(this, stream.getStreamId());
                  }
              } else {
                  if (log.isDebugEnabled()) {
                      log.debug("Stream service was not found for scope: {}", (scope != null ? scope.getName() : "null or non-existant"));
                  }
              }
              // close the base connection - disconnect scopes and unregister client
              super.close();
              // kill all the collections etc
              channels.clear();
              streams.clear();
              pendingCalls.clear();
              deferredResults.clear();
              pendingVideos.clear();
              streamBuffers.clear();
              if (log.isTraceEnabled()) {
                  // dump memory stats
                  log.trace("Memory at close - free: {}K total: {}K", Runtime.getRuntime().freeMemory() / 1024, Runtime.getRuntime().totalMemory() / 1024);
              }
          } else if (log.isDebugEnabled()) {
              log.debug("Already closing..");
          }
      }
docs: {@inheritDoc}