private async void Listen()
        {
            _socket.Listen(backlog: 2);
            while (!_disposed)
            {
                Http2ServerSession session = null;
                Socket clientSocket = null;
                Stream stream = null;
                try
                {
                    clientSocket = await Task.Factory.FromAsync(_socket.BeginAccept, (Func<IAsyncResult, Socket>)_socket.EndAccept, null);
                    stream = new NetworkStream(clientSocket, ownsSocket: true);

                    X509Certificate clientCert = null;

                    if (_enableSsl)
                    {
                        SslStream sslStream = new SslStream(stream);
                        await sslStream.AuthenticateAsServerAsync(_serverCert, clientCertificateRequired: false, enabledSslProtocols: _sslProtocols, checkCertificateRevocation: false);
                        clientCert = sslStream.RemoteCertificate;
                        stream = sslStream;
                    }

                    // TODO: At this point we could read the first bit of the first byte received on this connection to determine if it is a HTTP/1.1 or 2.0 request.

                    IPEndPoint localEndPoint = (IPEndPoint)clientSocket.LocalEndPoint;
                    IPEndPoint remoteEndPoint = (IPEndPoint)clientSocket.RemoteEndPoint;

                    TransportInformation transportInfo = new TransportInformation()
                    {
                        ClientCertificate = clientCert,
                        LocalPort = localEndPoint.Port.ToString(CultureInfo.InvariantCulture),
                        RemotePort = remoteEndPoint.Port.ToString(CultureInfo.InvariantCulture),
                    };

                    // Side effect of using dual mode sockets, the IPv4 addresses look like 0::ffff:127.0.0.1.
                    if (localEndPoint.Address.IsIPv4MappedToIPv6)
                    {
                        transportInfo.LocalIpAddress = localEndPoint.Address.MapToIPv4().ToString();
                    }
                    else
                    {
                        transportInfo.LocalIpAddress = localEndPoint.Address.ToString();
                    }

                    if (remoteEndPoint.Address.IsIPv4MappedToIPv6)
                    {
                        transportInfo.RemoteIpAddress = remoteEndPoint.Address.MapToIPv4().ToString();
                    }
                    else
                    {
                        transportInfo.RemoteIpAddress = remoteEndPoint.Address.ToString();
                    }

                    session = new Http2ServerSession(_next, transportInfo);
                    // TODO: awaiting here will only let us accept the next connection/session after the current one finishes.
                    await session.Start(stream, CancellationToken.None);
                }
                catch (ProtocolViolationException)
                {
                    // Handshake failure, most likely do to receiving a HTTP/1.1 text request.
                }
                catch (SocketException)
                {
                    // Disconnect?
                }
                catch (ObjectDisposedException)
                {
                    Dispose();
                }
                catch (Exception)
                {
                    Dispose();
                    throw;
                }
                finally
                {
                    if (session != null)
                    {
                        session.Dispose();
                    }

                    if (stream != null)
                    {
                        stream.Dispose();
                    }

                    if (clientSocket != null)
                    {
                        clientSocket.Dispose();
                    }
                }
            }
        }