private ContextPathHandler getCorrespondingHandler(
      SocketChannel socketChannel, MessageStat messageStat) {

    ContextPathHandler contextPathHandler =
        contextPathMap.get(messageStat.getHeader().get(RequestHeaderEntry.CONTEXT_PATH));

    return contextPathHandler != null
        ? contextPathHandler
        : contextPathMap.get(messageStat.getContextPathWithoutQuery());
  }
  /**
   * Handles request corresponding to the specified context paths.
   *
   * @param socketChannel Used to communicate between client and server.
   * @param messageStat Holds necessary request data to act on the context paths.
   */
  private void handle(SocketChannel socketChannel, MessageStat messageStat) {

    log.debug("stat: " + messageStat.getHeader().get(RequestHeaderEntry.CONTEXT_PATH));
    ContextPathHandler contextPathHandler = getCorrespondingHandler(socketChannel, messageStat);

    if (contextPathHandler != null) {
      contextPathHandler.handle(socketChannel, messageStat);
    } else {
      // TODO favicon.ico handler is needed
      if (messageStat.getContextPathWithoutQuery().equals("/favicon.ico")) {
        log.warn("currently favicon is not supported. will be done soon.");
      } else {
        contextPathMap.get("NotFound").handle(socketChannel, messageStat);
      }
    }
  }
  private void startPoll(SelectionKey key) {

    System.out.println("about to poll on server");
    MessageStat messageStat = null;
    ServerSocketChannel so = null;
    SocketChannel sc = null;

    while (true) {
      try {
        if (key.selector().select() <= 0) {
          continue;
        }

        Iterator<SelectionKey> itr = key.selector().selectedKeys().iterator();

        while (itr.hasNext()) {

          SelectionKey ready = itr.next();
          itr.remove();

          if (ready.isValid() && ready.isReadable()) {
            sc = (SocketChannel) ready.channel();
            messageStat = requestReader.read(sc);

            if (messageStat.isEndOfMessage()) {
              handle(sc, messageStat);
              sc.close();
              // TODO need to delete message stat entry ??
              // TODO with this way, Connection: keeyp-alive is meaningless ?
            }
          } else if (ready.isValid() && ready.isAcceptable()) {

            so = (ServerSocketChannel) key.channel();

            sc = so.accept();
            sc.configureBlocking(false);
            sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_CONNECT);
          }
        }
      } catch (IOException e) {
        e.printStackTrace();
      } catch (Exception ex) {
        ex.printStackTrace();
      }
    }
  }