@Override
  public void onRead(SelectionKey key) throws Exception {
    channel = (SocketChannel) key.channel();
    if (cursor == null) {
      if (key.attachment() instanceof Object[]) {
        Object[] ar = (Object[]) key.attachment();
        for (Object o : ar) {
          if (o instanceof ByteBuffer) {
            cursor = (ByteBuffer) o;
            continue;
          }
          if (o instanceof Rfc822HeaderState) {
            req = ((Rfc822HeaderState) o).$req();
            continue;
          }
        }
      }
      key.attach(this);
    }
    cursor =
        null == cursor
            ? ByteBuffer.allocateDirect(getReceiveBufferSize())
            : cursor.hasRemaining()
                ? cursor
                : ByteBuffer.allocateDirect(cursor.capacity() << 1)
                    .put((ByteBuffer) cursor.rewind());
    int read = channel.read(cursor);
    if (read == -1) key.cancel();
    Buffer flip = cursor.duplicate().flip();
    req = (HttpRequest) ActionBuilder.get().state().$req().apply((ByteBuffer) flip);
    if (!BlobAntiPatternObject.suffixMatchChunks(HEADER_TERMINATOR, req.headerBuf())) {
      return;
    }
    cursor = ((ByteBuffer) flip).slice();
    /*  int remaining = Integer.parseInt(req.headerString(HttpHeaders.Content$2dLength));
    final Impl prev = this;
    if (cursor.remaining() != remaining) key.attach(new Impl() {
      @Override
      public void onRead(SelectionKey key) throws Exception {
        int read1 = channel.read(cursor);
        if (read1 == -1)
          key.cancel();
        if (!cursor.hasRemaining()) {
          key.interestOps(SelectionKey.OP_WRITE).attach(prev);
          return;
        }
      }

    });*/
    key.interestOps(SelectionKey.OP_WRITE);
  }
  public void onWrite(SelectionKey key) throws Exception {

    String accepts = req.headerString(Accept$2dEncoding);
    String ceString = null;
    String finalFname = scrub(rootPath + "/./" + req.path());
    file = new File(finalFname);
    if (null != accepts) {
      //              String accepts = UTF8.decode((ByteBuffer)
      // addHeaderInterest.clear().limit(ints[1]).position(ints[0])).toString().trim();
      for (CompressionTypes compType : CompressionTypes.values()) {
        if (accepts.contains(compType.name())) {
          File f = new File(finalFname + "." + compType.suffix);
          if (f.isFile() && f.canRead()) {

            if (BlobAntiPatternObject.DEBUG_SENDJSON)
              System.err.println("sending compressed archive: " + f.getAbsolutePath());
            ceString = (compType.name());
            file = f;
            break;
          }
        }
      }
    }
    boolean send200 = false;
    try {
      send200 = file.canRead() && file.isFile();
    } finally {

    }

    if (send200) {
      final RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
      final long total = randomAccessFile.length();
      final FileChannel fileChannel = randomAccessFile.getChannel();

      String substring = finalFname.substring(finalFname.lastIndexOf('.') + 1);
      MimeType mimeType = MimeType.valueOf(substring);
      long length = randomAccessFile.length();

      final HttpResponse responseHeader = new Rfc822HeaderState().$res();

      responseHeader
          .status(HttpStatus.$200)
          .headerString(Content$2dType, (null == mimeType ? MimeType.bin : mimeType).contentType)
          .headerString(Content$2dLength, String.valueOf(length));
      if (null != ceString) responseHeader.headerString(Content$2dEncoding, ceString);
      ByteBuffer response = (ByteBuffer) responseHeader.as(ByteBuffer.class);
      int write = channel.write(response);
      final int sendBufferSize = BlobAntiPatternObject.getSendBufferSize();
      final long[] progress = {fileChannel.transferTo(0, sendBufferSize, channel)};
      key.interestOps(OP_WRITE | OP_CONNECT);
      key.selector().wakeup();
      key.attach(
          new Impl() {

            public void onWrite(SelectionKey key) throws Exception {
              long remaining = total - progress[0];
              progress[0] +=
                  fileChannel.transferTo(progress[0], min(sendBufferSize, remaining), channel);
              remaining = total - progress[0];
              if (0 == remaining) {
                fileChannel.close();
                randomAccessFile.close();
                key.selector().wakeup();
                key.interestOps(OP_READ);
                key.attach(null);
              }
            }
          });
    } else {
      key.selector().wakeup();
      key.interestOps(OP_WRITE)
          .attach(
              new Impl() {

                public void onWrite(SelectionKey key) throws Exception {

                  String response = "HTTP/1.1 404 Not Found\n" + "Content-Length: 0\n\n";
                  System.err.println("!!! " + file.getAbsolutePath());
                  int write = channel.write(UTF8.encode(response));
                  key.selector().wakeup();
                  key.interestOps(OP_READ).attach(null);
                }
              });
    }
  }