/** {@inheritDoc} */
  @Override
  public void removeEventListener(HadoopIgfsStreamDelegate desc) {
    long streamId = desc.target();

    HadoopIgfsStreamEventListener lsnr0 = lsnrs.remove(streamId);

    if (lsnr0 != null && log.isDebugEnabled())
      log.debug("Removed stream event listener [streamId=" + streamId + ']');
  }
  /** {@inheritDoc} */
  @Override
  public void addEventListener(HadoopIgfsStreamDelegate desc, HadoopIgfsStreamEventListener lsnr) {
    long streamId = desc.target();

    HadoopIgfsStreamEventListener lsnr0 = lsnrs.put(streamId, lsnr);

    assert lsnr0 == null || lsnr0 == lsnr;

    if (log.isDebugEnabled()) log.debug("Added stream event listener [streamId=" + streamId + ']');
  }
  /** {@inheritDoc} */
  @Override
  public void closeStream(HadoopIgfsStreamDelegate desc) throws IOException {
    final IgfsStreamControlRequest msg = new IgfsStreamControlRequest();

    msg.command(CLOSE);
    msg.streamId((long) desc.target());

    try {
      io.send(msg).chain(BOOL_RES).get();
    } catch (IgniteCheckedException e) {
      throw HadoopIgfsUtils.cast(e);
    }
  }
  /** {@inheritDoc} */
  @Override
  public void writeData(HadoopIgfsStreamDelegate desc, byte[] data, int off, int len)
      throws IOException {
    final IgfsStreamControlRequest msg = new IgfsStreamControlRequest();

    msg.command(WRITE_BLOCK);
    msg.streamId((long) desc.target());
    msg.data(data);
    msg.position(off);
    msg.length(len);

    try {
      io.sendPlain(msg);
    } catch (IgniteCheckedException e) {
      throw HadoopIgfsUtils.cast(e);
    }
  }
  /** {@inheritDoc} */
  @Override
  public IgniteInternalFuture<byte[]> readData(
      HadoopIgfsStreamDelegate desc,
      long pos,
      int len,
      final @Nullable byte[] outBuf,
      final int outOff,
      final int outLen) {
    assert len > 0;

    final IgfsStreamControlRequest msg = new IgfsStreamControlRequest();

    msg.command(READ_BLOCK);
    msg.streamId((long) desc.target());
    msg.position(pos);
    msg.length(len);

    try {
      return io.send(msg, outBuf, outOff, outLen);
    } catch (IgniteCheckedException e) {
      return new GridFinishedFuture<>(e);
    }
  }