static void ProcessMessage(AzureReceiveState state) {

            logger.Log(LogLevel.Info, "ProcessMessage Start received new message={0} Thread={1} MessageId={2}",
                state.Data.EndPointData.SubscriptionName, Thread.CurrentThread.ManagedThreadId, state.Message.MessageId);

            using (var usingMesssage = state.Message) {
                try {

                    IDictionary<string, object> values = new Dictionary<string, object>();

                    if (state.Message.Properties != null) {
                        foreach (var item in state.Message.Properties) {
                            if (item.Key != AzureSenderReceiverBase.TYPE_HEADER_NAME) {
                                values.Add(item);
                            }
                        }
                    }

                    using (var serial = state.CreateSerializer()) {
                        var stream = state.Message.GetBody<Stream>();
                        stream.Position = 0;
                        object msg = serial.Deserialize(stream, state.Data.EndPointData.MessageType);

                        //TODO create a cache for object creation.
                        var gt = typeof(ReceivedMessage<>).MakeGenericType(state.Data.EndPointData.MessageType);

                        object receivedMessage = Activator.CreateInstance(gt, new object[] { state.Message, msg });

                        logger.Log(LogLevel.Info, "ProcessMessage invoke callback message start message={0} Thread={1} MessageId={2}", state.Data.EndPointData.SubscriptionName, Thread.CurrentThread.ManagedThreadId, state.Message.MessageId);

                        if (state.Data.EndPointData.IsReusable && state.Data.EndPointData.StaticInstance != null) {
                            state.MethodInfo.Invoke(state.Data.EndPointData.StaticInstance, new object[] { receivedMessage, values });
                        }
                        else {
                            var obj = Activator.CreateInstance(state.Data.EndPointData.DeclaredType);
                            state.MethodInfo.Invoke(obj, new object[] { receivedMessage, values });
                        }

                        logger.Log(LogLevel.Info, "ProcessMessage invoke callback message end message={0} Thread={1} MessageId={2}", state.Data.EndPointData.SubscriptionName, Thread.CurrentThread.ManagedThreadId, state.Message.MessageId);
                    }
                    state.Message.Complete();
                }
                catch (Exception ex) {
                    logger.Log(LogLevel.Error, "ProcessMessage invoke callback message failed message={0} Thread={1} MessageId={2} Exception={3}", state.Data.EndPointData.SubscriptionName, Thread.CurrentThread.ManagedThreadId, state.Message.MessageId, ex.ToString());
                    //TODO remove hard code dead letter value
                    if (state.Message.DeliveryCount == 5) {
                        Helpers.Execute(() => state.Message.DeadLetter(ex.ToString(), "Died"));
                    }
                }

                logger.Log(LogLevel.Info, "ProcessMessage End received new message={0} Thread={1} MessageId={2}",
                    state.Data.EndPointData.SubscriptionName, Thread.CurrentThread.ManagedThreadId, state.Message.MessageId);

                usingMesssage.Dispose();
            }
        }
            void ProcessMessageCallBack(AzureReceiveState state) {
                Guard.ArgumentNotNull(state, "state");
                logger.Debug("ProcessMessage Start received new message={0} Thread={1} MessageId={2}",
                    state.Data.EndPointData.SubscriptionName, Thread.CurrentThread.ManagedThreadId, state.Message.MessageId);

                string objectTypeName = string.Empty;

                try {

                    IDictionary<string, object> values = new Dictionary<string, object>();

                    if (state.Message.Properties != null) {
                        foreach (var item in state.Message.Properties) {
                            if (item.Key != AzureSenderReceiverBase.TYPE_HEADER_NAME) {
                                values.Add(item);
                            }
                        }
                    }

                    using (var serial = state.CreateSerializer()) {
                        var stream = state.Message.GetBody<Stream>();
                        stream.Position = 0;
                        object msg = serial.Deserialize(stream, state.Data.EndPointData.MessageType);

                        //TODO create a cache for object creation.
                        var gt = typeof(ReceivedMessage<>).MakeGenericType(state.Data.EndPointData.MessageType);

                        object receivedMessage = Activator.CreateInstance(gt, new object[] { state.Message, msg, values });

                        objectTypeName = receivedMessage.GetType().FullName;

                        logger.Debug("ProcessMessage invoke callback message start Type={0} message={1} Thread={2} MessageId={3}", objectTypeName, state.Data.EndPointData.SubscriptionName, Thread.CurrentThread.ManagedThreadId, state.Message.MessageId);

                        var handler = BusConfiguration.Container.Resolve(state.Data.EndPointData.DeclaredType);

                        logger.Debug("ProcessMessage reflection callback message start MethodInfo Type={0} Declared={1} handler={2} MethodInfo={3} Thread={4} MessageId={5}", objectTypeName, state.Data.EndPointData.DeclaredType, handler.GetType().FullName, state.MethodInfo.Name, Thread.CurrentThread.ManagedThreadId, state.Message.MessageId);

                        state.MethodInfo.Invoke(handler, new object[] { receivedMessage });
                        logger.Debug("ProcessMessage invoke callback message end Type={0} message={1} Thread={2} MessageId={3}", objectTypeName, state.Data.EndPointData.SubscriptionName, Thread.CurrentThread.ManagedThreadId, state.Message.MessageId);
                    }
                }
                catch (Exception ex) {
                    logger.Error("ProcessMessage invoke callback message failed Type={0} message={1} Thread={2} MessageId={3} Exception={4}", objectTypeName, state.Data.EndPointData.SubscriptionName, Thread.CurrentThread.ManagedThreadId, state.Message.MessageId, ex.ToString());

                    if (state.Message.DeliveryCount >= state.Data.EndPointData.AttributeData.MaxRetries) {
                        if (state.Data.EndPointData.AttributeData.DeadLetterAfterMaxRetries) {
                            SafeDeadLetter(state.Message, ex.Message);
                        }
                        else {
                            SafeComplete(state.Message);
                        }
                    }
                    throw;
                }

                logger.Debug("ProcessMessage End received new message={0} Thread={1} MessageId={2}",
                    state.Data.EndPointData.SubscriptionName, Thread.CurrentThread.ManagedThreadId, state.Message.MessageId);
            }
        static void ProcessMessagesForSubscription(object state) {

            var data = state as AzureBusReceiverState;

            if (data == null) {
                throw new ArgumentNullException("state");
            }

            logger.Log(LogLevel.Info, "ProcessMessagesForSubscription Message Start {0} Declared {1} MessageTytpe {2}, IsReusable {3}", data.EndPointData.SubscriptionName,
                data.EndPointData.DeclaredType.ToString(), data.EndPointData.MessageType.ToString(), data.EndPointData.IsReusable);

            //TODO create a cache for object creation.
            var gt = typeof(IReceivedMessage<>).MakeGenericType(data.EndPointData.MessageType);

            //set up the methodinfo
            var methodInfo = data.EndPointData.DeclaredType.GetMethod("Handle",
                new Type[] { gt, typeof(IDictionary<string, object>) });

            var serializer = BusConfiguration.Container.Resolve<IServiceBusSerializer>();

            BrokeredMessage message;
            while (!data.Cancel) {
                while ((message = data.Client.Receive(TimeSpan.FromSeconds(55))) != null) {
                    logger.Log(LogLevel.Info, "ProcessMessagesForSubscription Start received new message: {0}", data.EndPointData.SubscriptionName);
                    var receiveState = new AzureReceiveState(data, methodInfo, serializer, message);
                    ProcessMessage(receiveState);
                    logger.Log(LogLevel.Info, "ProcessMessagesForSubscription End received new message: {0}", data.EndPointData.SubscriptionName);
                }
                logger.Log(LogLevel.Info, "ProcessMessagesForSubscription No Messages Received in past 55 seconds: {0}", data.EndPointData.SubscriptionName);
            }

            data.Cancelled = true;

            logger.Log(LogLevel.Info, "ProcessMessagesForSubscription Message Complete={0} Declared={1} MessageTytpe={2} IsReusable={3}", data.EndPointData.SubscriptionName,
                data.EndPointData.DeclaredType.ToString(), data.EndPointData.MessageType.ToString(), data.EndPointData.IsReusable);
        }
            public void ProcessMessagesForSubscription() {

                try {

                    Guard.ArgumentNotNull(data, "data");

                    logger.Info("ProcessMessagesForSubscription Message Start {0} Declared {1} MessageTytpe {2}, IsReusable {3}", data.EndPointData.SubscriptionName,
                            data.EndPointData.DeclaredType.ToString(), data.EndPointData.MessageType.ToString(), data.EndPointData.IsReusable);

                    //TODO create a cache for object creation.
                    var gt = typeof(IReceivedMessage<>).MakeGenericType(data.EndPointData.MessageType);

                    //set up the methodinfo
                    var methodInfo = data.EndPointData.DeclaredType.GetMethod("Handle", new Type[] { gt });

                    var serializer = BusConfiguration.Container.Resolve<IServiceBusSerializer>();

                    var waitTimeout = TimeSpan.FromSeconds(30);

                    // Declare an action acting as a callback whenever a message arrives on a queue.
                    AsyncCallback completeReceive = null;

                    // Declare an action acting as a callback whenever a non-transient exception occurs while receiving or processing messages.
                    Action<Exception> recoverReceive = null;

                    // Declare an action implementing the main processing logic for received messages.
                    Action<AzureReceiveState> processMessage = ((receiveState) => {
                        // Put your custom processing logic here. DO NOT swallow any exceptions.
                        ProcessMessageCallBack(receiveState);
                    });

                    var client = data.Client;

                    bool messageReceived = false;

                    bool lastAttemptWasError = false;

                    // Declare an action responsible for the core operations in the message receive loop.
                    Action receiveMessage = (() => {
                        // Use a retry policy to execute the Receive action in an asynchronous and reliable fashion.
                        retryPolicy.ExecuteAction
                        (
                            (cb) => {
                                if (lastAttemptWasError) {
                                    if (Data.EndPointData.AttributeData.PauseTimeIfErrorWasThrown > 0) {
                                        Thread.Sleep(Data.EndPointData.AttributeData.PauseTimeIfErrorWasThrown);
                                    }
                                    else {
                                        Thread.Sleep(1000);
                                    }
                                }
                                // Start receiving a new message asynchronously.
                                client.BeginReceive(waitTimeout, cb, null);
                            },
                            (ar) => {
                                messageReceived = false;
                                // Make sure we are not told to stop receiving while we were waiting for a new message.
                                if (!data.CancelToken.IsCancellationRequested) {
                                    BrokeredMessage msg = null;
                                    try {
                                        // Complete the asynchronous operation. This may throw an exception that will be handled internally by retry policy.
                                        msg = client.EndReceive(ar);

                                        // Check if we actually received any messages.
                                        if (msg != null) {
                                            // Make sure we are not told to stop receiving while we were waiting for a new message.
                                            if (!data.CancelToken.IsCancellationRequested) {
                                                // Process the received message.
                                                messageReceived = true;
                                                logger.Debug("ProcessMessagesForSubscription Start received new message: {0}", data.EndPointData.SubscriptionName);
                                                var receiveState = new AzureReceiveState(data, methodInfo, serializer, msg);
                                                processMessage(receiveState);
                                                logger.Debug("ProcessMessagesForSubscription End received new message: {0}", data.EndPointData.SubscriptionName);

                                                // With PeekLock mode, we should mark the processed message as completed.
                                                if (client.Mode == ReceiveMode.PeekLock) {
                                                    // Mark brokered message as completed at which point it's removed from the queue.
                                                    SafeComplete(msg);
                                                }
                                            }
                                        }
                                    }
                                    catch (Exception) {
                                        //do nothing
                                        throw;
                                    }
                                    finally {
                                        // With PeekLock mode, we should mark the failed message as abandoned.
                                        if (msg != null) {
                                            if (client.Mode == ReceiveMode.PeekLock) {
                                                // Abandons a brokered message. This will cause Service Bus to unlock the message and make it available 
                                                // to be received again, either by the same consumer or by another completing consumer.
                                                SafeAbandon(msg);
                                            }
                                            msg.Dispose();
                                        }
                                    }
                                }
                                // Invoke a custom callback method to indicate that we have completed an iteration in the message receive loop.
                                completeReceive(ar);
                            },
                            () => {
                                //do nothing, we completed.
                            },
                            (ex) => {
                                // Invoke a custom action to indicate that we have encountered an exception and
                                // need further decision as to whether to continue receiving messages.
                                recoverReceive(ex);
                            });
                    });

                    // Initialize a custom action acting as a callback whenever a message arrives on a queue.
                    completeReceive = ((ar) => {
                        lastAttemptWasError = false;
                        if (!data.CancelToken.IsCancellationRequested) {
                            // Continue receiving and processing new messages until we are told to stop.
                            receiveMessage();
                        }
                        else {
                            data.SetMessageLoopCompleted();
                        }

                        if (messageReceived) {
                            logger.Debug("ProcessMessagesForSubscription Message Complete={0} Declared={1} MessageTytpe={2} IsReusable={3}", data.EndPointData.SubscriptionName,
                                data.EndPointData.DeclaredType.ToString(), data.EndPointData.MessageType.ToString(), data.EndPointData.IsReusable);
                        }
                    });

                    // Initialize a custom action acting as a callback whenever a non-transient exception occurs while receiving or processing messages.
                    recoverReceive = ((ex) => {
                        // Just log an exception. Do not allow an unhandled exception to terminate the message receive loop abnormally.
                        lastAttemptWasError = true;
                        logger.Error(string.Format("ProcessMessagesForSubscription Message Error={0} Declared={1} MessageTytpe={2} IsReusable={3} Error={4}",
                            data.EndPointData.SubscriptionName,
                            data.EndPointData.DeclaredType.ToString(),
                            data.EndPointData.MessageType.ToString(),
                            data.EndPointData.IsReusable,
                            ex.ToString()));

                        if (!data.CancelToken.IsCancellationRequested) {
                            // Continue receiving and processing new messages until we are told to stop regardless of any exceptions.
                            receiveMessage();
                        }
                        else {
                            data.SetMessageLoopCompleted();
                        }

                        if (messageReceived) {
                            logger.Debug("ProcessMessagesForSubscription Message Complete={0} Declared={1} MessageTytpe={2} IsReusable={3}", data.EndPointData.SubscriptionName,
                                data.EndPointData.DeclaredType.ToString(), data.EndPointData.MessageType.ToString(), data.EndPointData.IsReusable);
                        }
                    });

                    // Start receiving messages asynchronously.
                    receiveMessage();
                }
                catch (Exception ex) {
                    failCounter++;
                    logger.Error("ProcessMessagesForSubscription: Error during receive during loop. See details and fix: {0}", ex);
                    if (failCounter < 100) {
                        //try again
                        ProcessMessagesForSubscription();
                    }
                }

            }