public MqttIotHubAdapter(
            string deviceId,
            string iotHubHostName,
            IAuthorizationProvider passwordProvider,
            MqttTransportSettings mqttTransportSettings,
            IWillMessage willMessage,
            IMqttIotHubEventHandler mqttIotHubEventHandler,
            ProductInfo productInfo)
        {
            Contract.Requires(deviceId != null);
            Contract.Requires(iotHubHostName != null);
            Contract.Requires(passwordProvider != null);
            Contract.Requires(mqttTransportSettings != null);
            Contract.Requires(!mqttTransportSettings.HasWill || willMessage != null);
            Contract.Requires(productInfo != null);

            this.deviceId               = deviceId;
            this.iotHubHostName         = iotHubHostName;
            this.passwordProvider       = passwordProvider;
            this.mqttTransportSettings  = mqttTransportSettings;
            this.willMessage            = willMessage;
            this.mqttIotHubEventHandler = mqttIotHubEventHandler;
            this.pingRequestInterval    = this.mqttTransportSettings.KeepAliveInSeconds > 0 ? TimeSpan.FromSeconds(this.mqttTransportSettings.KeepAliveInSeconds / 4d) : TimeSpan.MaxValue;
            this.productInfo            = productInfo;

            this.deviceBoundOneWayProcessor = new SimpleWorkQueue <PublishPacket>(this.AcceptMessageAsync);
            this.deviceBoundTwoWayProcessor = new OrderedTwoPhaseWorkQueue <int, PublishPacket>(this.AcceptMessageAsync, p => p.PacketId, this.SendAckAsync);

            this.serviceBoundOneWayProcessor = new SimpleWorkQueue <PublishWorkItem>(this.SendMessageToServerAsync);
            this.serviceBoundTwoWayProcessor = new OrderedTwoPhaseWorkQueue <int, PublishWorkItem>(this.SendMessageToServerAsync, p => p.Value.PacketId, this.ProcessAckAsync);
        }
        public MqttIotHubAdapter(
            string deviceId,
            string iotHubHostName,
            string password,
            MqttTransportSettings mqttTransportSettings,
            IWillMessage willMessage,
            Action onConnected,
            Action <Message> onMessageReceived,
            Action <Exception> onError)
        {
            Contract.Requires(deviceId != null);
            Contract.Requires(iotHubHostName != null);
            Contract.Requires(password != null);
            Contract.Requires(mqttTransportSettings != null);
            Contract.Requires(!mqttTransportSettings.HasWill || willMessage != null);

            this.deviceId              = deviceId;
            this.iotHubHostName        = iotHubHostName;
            this.password              = password;
            this.mqttTransportSettings = mqttTransportSettings;
            this.willMessage           = willMessage;
            this.onConnected           = onConnected;
            this.onError             = onError;
            this.onMessageReceived   = onMessageReceived;
            this.pingRequestInterval = this.mqttTransportSettings.KeepAliveInSeconds > 0 ? TimeSpan.FromSeconds(this.mqttTransportSettings.KeepAliveInSeconds / 2d) : TimeSpan.MaxValue;

            this.deviceBoundOneWayProcessor = new SimpleWorkQueue <PublishPacket>(this.AcceptMessageAsync);
            this.deviceBoundTwoWayProcessor = new OrderedTwoPhaseWorkQueue <int, PublishPacket>(this.AcceptMessageAsync, p => p.PacketId, this.SendAckAsync);

            this.serviceBoundOneWayProcessor = new SimpleWorkQueue <PublishWorkItem>(this.SendMessageToServerAsync);
            this.serviceBoundTwoWayProcessor = new OrderedTwoPhaseWorkQueue <int, PublishWorkItem>(this.SendMessageToServerAsync, p => p.Value.PacketId, this.ProcessAckAsync);
        }