code: public void interceptStream(int index, T stream) throws GuacamoleException {
  
          InterceptedStream<T> interceptedStream;
          String indexString = Integer.toString(index);
  
          // Atomically verify tunnel is open and add the given stream
          synchronized (tunnel) {
  
              // Do nothing if tunnel is not open
              if (!tunnel.isOpen())
                  return;
  
              // Wrap stream
              interceptedStream = new InterceptedStream<T>(indexString, stream);
  
              // Replace any existing stream
              streams.put(interceptedStream);
  
          }
  
          // Produce/consume all stream data
          handleInterceptedStream(interceptedStream);
  
          // Wait for stream to close
          streams.waitFor(interceptedStream);
  
          // Throw any asynchronously-provided exception
          if (interceptedStream.hasStreamError())
              throw interceptedStream.getStreamError();
  
      }
docs: Intercept the stream having the given index, producing or consuming its
  data as appropriate. The given stream object will automatically be closed
  when the stream ends. If there is no stream having the given index, then
  the stream object will be closed immediately. This function will block
  until all data has been handled and the stream is ended.
  
  @param index
  The index of the stream to intercept.
  
  @param stream
  The stream object which will produce or consume all data for the
  stream having the given index.
  
  @throws GuacamoleException
  If an error occurs while intercepting the stream, or if the stream
  itself reports an error.