public void OnConnectionClosed(MqttClientConnection clientConnection)
        {
            // if client is connected
            MqttClientConnection connectedClient;

            if (clientConnection.IsConnected && MqttBroker.TryRemoveClientConnection(clientConnection.ClientId, out connectedClient))
            {
                // client has a will message
                if (clientConnection.WillFlag)
                {
                    // create the will PUBLISH message
                    MqttMsgPublish publish = new MqttMsgPublish(clientConnection.WillTopic, Encoding.UTF8.GetBytes(clientConnection.WillMessage), false, clientConnection.WillQosLevel, false);

                    // publish message through publisher manager
                    this.publishManager.Publish(publish);
                }

                // if not clean session
                if (!clientConnection.CleanSession)
                {
                    List <MqttSubscription> subscriptions = clientConnection.Subscriptions.Values.ToList();

                    if (subscriptions.Count > 0)
                    {
                        MqttSessionManager.SaveSession(clientConnection.ClientId, clientConnection.Session, subscriptions);

                        // TODO : persist client session if broker close
                    }
                }

                foreach (var topic in clientConnection.Subscriptions.Keys)
                {
                    // delete client from runtime subscription
                    MqttSubscriberManager.Unsubscribe(topic, clientConnection);
                }

                // close the client
                CloseClientConnection(clientConnection);
                clientConnectionManager.ReturnConnection(clientConnection);
                Interlocked.Decrement(ref numberOfConnectedClients);
            }
        }