@Override
  public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception {
    // Call finishDecode() first when a connection is closed.
    ProtocolDecoder decoder = getDecoder(session);
    ProtocolDecoderOutput decoderOut = getDecoderOut(session, nextFilter);

    try {
      decoder.finishDecode(session, decoderOut);
    } catch (Throwable t) {
      ProtocolDecoderException pde;
      if (t instanceof ProtocolDecoderException) {
        pde = (ProtocolDecoderException) t;
      } else {
        pde = new ProtocolDecoderException(t);
      }
      throw pde;
    } finally {
      // Dispose everything
      disposeCodec(session);
      decoderOut.flush(nextFilter, session);
    }

    // Call the next filter
    nextFilter.sessionClosed(session);
  }
 public void finishDecode(IoSession session, ProtocolDecoderOutput out) throws Exception {
   synchronized (decoder) {
     decoder.finishDecode(session, out);
   }
 }