I/O and protocol logging improvements
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
index 831114b..17002ec 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
@@ -410,6 +410,13 @@
 
         commitFrame(settingsFrame);
         localSettingState = SettingsHandshake.TRANSMITTED;
+
+        if (streamListener != null) {
+            final int initInputWindow = connInputWindow.get();
+            streamListener.onInputFlowControl(this, 0, initInputWindow, initInputWindow);
+            final int initOutputWindow = connOutputWindow.get();
+            streamListener.onOutputFlowControl(this, 0, initOutputWindow, initOutputWindow);
+        }
     }
 
     public final void onInput(final ByteBuffer src) throws HttpException, IOException {
@@ -613,6 +620,13 @@
                 final H2Stream stream = new H2Stream(channel, streamHandler, false);
                 streamMap.put(streamId, stream);
 
+                if (streamListener != null) {
+                    final int initInputWindow = stream.getInputWindow().get();
+                    streamListener.onInputFlowControl(this, streamId, initInputWindow, initInputWindow);
+                    final int initOutputWindow = stream.getOutputWindow().get();
+                    streamListener.onOutputFlowControl(this, streamId, initOutputWindow, initOutputWindow);
+                }
+
                 if (stream.isOutputReady()) {
                     stream.produceOutput();
                 }
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingH2StreamListener.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingH2StreamListener.java
index 4b071a4..83802f8 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingH2StreamListener.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingH2StreamListener.java
@@ -128,14 +128,14 @@
     @Override
     public void onInputFlowControl(final HttpConnection connection, final int streamId, final int delta, final int actualSize) {
         if (flowCtrlLog.isDebugEnabled()) {
-            logFlowControl(LoggingSupport.getId(connection) + " <<", streamId, delta, actualSize);
+            logFlowControl(LoggingSupport.getId(connection) + "  in", streamId, delta, actualSize);
         }
     }
 
     @Override
     public void onOutputFlowControl(final HttpConnection connection, final int streamId, final int delta, final int actualSize) {
         if (flowCtrlLog.isDebugEnabled()) {
-            logFlowControl(LoggingSupport.getId(connection) + " >>", streamId, delta, actualSize);
+            logFlowControl(LoggingSupport.getId(connection) + " out", streamId, delta, actualSize);
         }
     }
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/IOSessionImpl.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/IOSessionImpl.java
index ac111af..437aa87 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/IOSessionImpl.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/IOSessionImpl.java
@@ -64,20 +64,14 @@
     private volatile long lastWriteTime;
     private volatile long lastEventTime;
 
-    /**
-     * Creates new instance of IOSessionImpl.
-     *
-     * @param key the selection key.
-     * @param socketChannel the socket channel
-     */
-    public IOSessionImpl(final SelectionKey key, final SocketChannel socketChannel) {
+    public IOSessionImpl(final String type, final SelectionKey key, final SocketChannel socketChannel) {
         super();
         this.key = Args.notNull(key, "Selection key");
         this.channel = Args.notNull(socketChannel, "Socket channel");
         this.commandQueue = new ConcurrentLinkedDeque<>();
         this.lock = new ReentrantLock();
         this.socketTimeout = Timeout.DISABLED;
-        this.id = String.format("i/o-%08X", COUNT.getAndIncrement());
+        this.id = String.format(type + "-%08X", COUNT.getAndIncrement());
         this.handlerRef = new AtomicReference<>();
         this.status = new AtomicInteger(ACTIVE);
         final long currentTimeMillis = System.currentTimeMillis();
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java
index 78bc3a7..43b3201 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java
@@ -206,7 +206,7 @@
             } catch (final ClosedChannelException ex) {
                 return;
             }
-            final IOSession ioSession = new IOSessionImpl(key, socketChannel);
+            final IOSession ioSession = new IOSessionImpl("a", key, socketChannel);
             final InternalDataChannel dataChannel = new InternalDataChannel(
                     ioSessionDecorator != null ? ioSessionDecorator.decorate(ioSession) : ioSession,
                     null,
@@ -363,7 +363,7 @@
                     final SocketChannel socketChannel,
                     final NamedEndpoint namedEndpoint,
                     final Object attachment) {
-                final IOSession ioSession = new IOSessionImpl(key, socketChannel);
+                final IOSession ioSession = new IOSessionImpl("c", key, socketChannel);
                 final InternalDataChannel dataChannel = new InternalDataChannel(
                         ioSessionDecorator != null ? ioSessionDecorator.decorate(ioSession) : ioSession,
                         namedEndpoint,