public void StartListening(MethodInfo method, Type channel, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            HttpListener httpChannel = new HttpListener();

            ChannelConfigurationInfo channelConfig = _configuration.Configure(httpChannel, channel, method, _baseURL);

            //Keep the ChannelMethod open for new requests
            while (true)
            {
                try
                {
                    httpChannel.Start();
                }
                catch (HttpListenerException hle)
                {
                    Console.WriteLine($"System.Net.HttpListenerException encountered on {channelConfig.MethodUrl} with reason :{hle.Message}");
                    return;
                }

                Console.WriteLine($"Listening on {channelConfig.MethodUrl}");
                HttpListenerContext      context       = httpChannel.GetContext();
                HttpListenerRequest      request       = context.Request;
                HttpListenerResponse     response      = context.Response;
                IChannelHeuristicContext heuristicsCtx = _services.Get <IChannelHeuristicContext>();

                bool executedIfCached = ExecuteIfCached(channel, method, request, response, heuristicsCtx);
                if (executedIfCached)
                {
                    heuristicsCtx.Clear();
                    goto EndRequest;
                }

                LogChannel.Write(LogSeverity.Info, $"Request coming to {channelConfig.Endpoint.Name}");
                LogChannel.Write(LogSeverity.Info, $"HttpMethod:{request.HttpMethod}");

                bool authFailed = AuthenticationFailedIfRequired(context, request, response, channelConfig, out bool authenticated);
                if (authFailed)
                {
                    goto EndRequest;
                }

                //Check if the Http Method is correct
                if (channelConfig.HttpMethod.ToString() != request.HttpMethod && channelConfig.HttpMethod != ChannelHttpMethod.Unknown)
                {
                    _msgService.WrongHttpMethod(response, channelConfig.HttpMethod);
                    LogChannel.Write(LogSeverity.Error, "Wrong HttpMethod... Closing request");
                    goto EndRequest;
                }


                ChannelMethodInfo methodDescription         = _channelMethodDescriptor.GetMethodDescription(method);
                List <object>     channelRequestBody        = null;
                ChannelMethodDeserializerFactory dsrFactory = null;

                if (request.HttpMethod == "GET")
                {
                    bool invoked = TryInvokeGetRequest(channel, method, request, response, dsrFactory, methodDescription, channelConfig, channelRequestBody, authenticated);
                    goto EndRequest;
                }

                //Enter only if Request Body is supplied with POST Method
                if (request.HasEntityBody == true && request.HttpMethod == "POST")
                {
                    StreamWriter writer = new StreamWriter(response.OutputStream);
                    try
                    {
                        dsrFactory         = new ChannelMethodDeserializerFactory(request.InputStream);
                        channelRequestBody = dsrFactory.DeserializeFromBody(methodDescription, request.ContentType);
                        InitChannelMethodContext(channelConfig.Endpoint, request, response, authenticated, channelConfig.HttpMethod, channelRequestBody);
                        _requestActivator.PostActivate(channel, method, channelRequestBody, response);
                    }
                    catch (ChannelMethodContentTypeException cEx)
                    {
                        response.StatusCode = 400;
                        _msgService.ExceptionHandler(writer, cEx, response);
                        LogChannel.Write(LogSeverity.Error, cEx.Message);
                    }
                    catch (ChannelMethodParameterException pEx)
                    {
                        response.StatusCode = 400;
                        _msgService.ExceptionHandler(writer, pEx, response);
                        LogChannel.Write(LogSeverity.Error, pEx.Message);
                    }
                    catch (TargetParameterCountException tEx)
                    {
                        response.StatusCode = 400;
                        _msgService.ExceptionHandler(writer, tEx, response);
                        LogChannel.Write(LogSeverity.Error, tEx.Message);
                    }
                    catch (Exception ex)
                    {
                        response.StatusCode = 500;
                        _msgService.ExceptionHandler(writer, ex, response);
                        LogChannel.Write(LogSeverity.Fatal, ex.Message);
                    }
                    finally
                    {
                        _contextProvider.DestroyChannelMethodContext(channelConfig.Endpoint);
                        writer.Flush();
                        writer.Close();
                    }
                }

EndRequest:
                LogChannel.Write(LogSeverity.Debug, "Request finished...");
                LogChannel.Write(LogSeverity.Debug, "Closing the response");
                response.Close();
            }
        }
        public void Start()
        {
            State     = EntityState.Starting;
            StateName = Enum.GetName(typeof(EntityState), EntityState.Starting);

            _httpListener = new HttpListener();
            ChannelConfigurationInfo channelConfig = _configuration.Configure(_httpListener, _channel, _method, _baseURL);

            Url = channelConfig.MethodUrl;
            //Keep the ChannelMethod open for new requests
            while (true)
            {
                try
                {
                    _httpListener.Start();
                    State     = EntityState.Running;
                    StateName = Enum.GetName(typeof(EntityState), EntityState.Running);
                }
                catch (HttpListenerException hle)
                {
                    Console.WriteLine($"System.Net.HttpListenerException encountered on {channelConfig.MethodUrl} with reason :{hle.Message}");
                    return;
                }

                if (!_isManaged)
                {
                    Console.WriteLine($"Listening on {Url}");
                }

                HttpListenerContext      context       = _httpListener.GetContext();
                HttpListenerRequest      request       = context.Request;
                HttpListenerResponse     response      = context.Response;
                IChannelHeuristicContext heuristicsCtx = _services.Get <IChannelHeuristicContext>();

                LogChannel.Write(LogSeverity.Info, $"Request coming to {channelConfig.Endpoint.Name}");
                LogChannel.Write(LogSeverity.Info, $"HttpMethod:{request.HttpMethod}");

                ChannelAuthenticationInspector authInspector = new ChannelAuthenticationInspector(_authenticationService, _msgService, _settings, _session, _basicAuthenticationMethod, _tokenAuthenticationMethod);

                //Even if method is cached check authenticaion first
                bool authFailed = authInspector.AuthenticationFailedIfRequired(context, request, response, channelConfig, out bool authenticated);
                if (authFailed)
                {
                    goto EndRequest;
                }

                List <object> channelRequestBody = null;

                ChannelMethodCacheInspector cacheInspector       = new ChannelMethodCacheInspector(_msgService, _heuristics);
                CacheExecutionResult        cacheExecutionResult = cacheInspector.ExecuteIfCached(_channel, _method, request, response, heuristicsCtx);

                if (cacheExecutionResult.Executed)
                {
                    heuristicsCtx.Clear();
                    goto EndRequest;
                }

                if (channelConfig.HttpMethod.ToString() != request.HttpMethod && channelConfig.HttpMethod != ChannelHttpMethod.Unknown)
                {
                    _msgService.WrongHttpMethod(response, channelConfig.HttpMethod);
                    LogChannel.Write(LogSeverity.Error, "Wrong HttpMethod... Closing request");
                    goto EndRequest;
                }

                ChannelMethodInfo   methodDescription   = _channelMethodDescriptor.GetMethodDescription(_method);
                ChannelMethodCaller channelMethodCaller = new ChannelMethodCaller(_msgService, _contextProvider, _requestActivator);

                if (request.HttpMethod == "GET")
                {
                    channelMethodCaller.TryInvokeGetRequest(_channel, _method, request, response, methodDescription, channelConfig, channelRequestBody, authenticated, cacheExecutionResult);
                    goto EndRequest;
                }

                //Enter only if Request Body is supplied with POST Method
                if (request.HasEntityBody == true && request.HttpMethod == "POST")
                {
                    channelMethodCaller.TryInvokePostRequest(_channel, _method, request, response, channelRequestBody, methodDescription, channelConfig, authenticated, cacheExecutionResult);
                }

EndRequest:
                LogChannel.Write(LogSeverity.Debug, "Request finished...");
                LogChannel.Write(LogSeverity.Debug, "Closing the response");
                response.Close();
            }
        }