Fixing bugs in HTTP/2 pipeline exception handling

Motivation:

HTTP/2 codec does not properly test exception passed to
exceptionCaught() for instanceof Http2Exception (since the exception
will always be wrapped in a PipelineException), so it will never
properly handle Http2Exceptions in the pipeline.

Also if any streams are present, the connection close logic will execute
twice when a pipeline exception. This is because the exception logic
calls ctx.close() which then triggers the handleInActive() logic to
execute.  This clears all of the remaining streams and then attempts to
run the closeListener logic (which has already been run).

Modifications:

Changed exceptionCaught logic to properly extract Http2Exception from
the PipelineException.  Also added logic to the closeListener so that is
only run once.

Added a test for verifying that a pipeline exception closes the
connection.

Result:

Exception handling logic is tidied up.
@nmittler - I agree we should keep the inbound/outbound processing separated.  This seems to be consistent with other netty codecs having a separate encoder/decoder.  However what would the inbound adapter do that `Http2FrameListener` does not do?  Also how does this address your original concern of having the inbound side know about the outbound side?

I'm not sure I follow the extension to the HTTP/2 protocol statement.  My mental model is the protocol is not being extended at this level but instead just being used protocol.  Maybe the inbound adapter you suggested will clarify this distinction?

I plan to extend `Http2OutboundConnectionAdapter` to provide data a compression interface similar to the decompression interface.