/// <summary>
        /// If the component is connected to LOC server, it sends a new GetNeighbourNodesByDistanceLocalRequest request
        /// to get fresh information about the profile server's neighborhood.
        /// </summary>
        public async Task RefreshLocAsync()
        {
            log.Trace("()");

            if (locServerInitialized)
            {
                try
                {
                    LocProtocolMessage request = client.MessageBuilder.CreateGetNeighbourNodesByDistanceLocalRequest();
                    if (await client.SendMessageAsync(request))
                    {
                        log.Trace("GetNeighbourNodesByDistanceLocalRequest sent to LOC server to get fresh neighborhood data.");
                    }
                    else
                    {
                        log.Warn("Unable to send message to LOC server.");
                    }
                }
                catch (Exception e)
                {
                    log.Warn("Exception occurred: {0}", e.ToString());
                }
            }
            else
            {
                log.Debug("LOC server not initialized yet, can not refresh.");
            }

            log.Trace("(-)");
        }
        /// <summary>
        /// Processing of a message received from a client.
        /// </summary>
        /// <param name="Client">TCP client who received the message.</param>
        /// <param name="IncomingMessage">Full ProtoBuf message to be processed.</param>
        /// <returns>true if the conversation with the client should continue, false if a protocol violation error occurred and the client should be disconnected.</returns>
        public async Task <bool> ProcessMessageAsync(ClientBase Client, IProtocolMessage IncomingMessage)
        {
            LocClient          client          = (LocClient)Client;
            LocProtocolMessage incomingMessage = (LocProtocolMessage)IncomingMessage;

            log.Debug("()");

            bool res = false;

            try
            {
                log.Trace("Received message type is {0}, message ID is {1}.", incomingMessage.MessageTypeCase, incomingMessage.Id);

                switch (incomingMessage.MessageTypeCase)
                {
                case Message.MessageTypeOneofCase.Request:
                {
                    LocProtocolMessage responseMessage = client.MessageBuilder.CreateErrorProtocolViolationResponse(incomingMessage);
                    Request            request         = incomingMessage.Request;

                    SemVer version = new SemVer(request.Version);
                    log.Trace("Request type is {0}, version is {1}.", request.RequestTypeCase, version);
                    switch (request.RequestTypeCase)
                    {
                    case Request.RequestTypeOneofCase.LocalService:
                    {
                        log.Trace("Local service request type is {0}.", request.LocalService.LocalServiceRequestTypeCase);
                        switch (request.LocalService.LocalServiceRequestTypeCase)
                        {
                        case LocalServiceRequest.LocalServiceRequestTypeOneofCase.NeighbourhoodChanged:
                        {
                            responseMessage = await ProcessMessageNeighbourhoodChangedNotificationRequestAsync(client, incomingMessage);

                            break;
                        }

                        default:
                            log.Warn("Invalid local service request type '{0}'.", request.LocalService.LocalServiceRequestTypeCase);
                            break;
                        }

                        break;
                    }

                    default:
                        log.Warn("Invalid request type '{0}'.", request.RequestTypeCase);
                        break;
                    }


                    if (responseMessage != null)
                    {
                        // Send response to client.
                        res = await client.SendMessageAsync(responseMessage);

                        if (res)
                        {
                            // If the message was sent successfully to the target, we close the connection only in case of protocol violation error.
                            if (responseMessage.MessageTypeCase == Message.MessageTypeOneofCase.Response)
                            {
                                res = responseMessage.Response.Status != Status.ErrorProtocolViolation;
                            }
                        }
                    }
                    else
                    {
                        // If there is no response to send immediately to the client,
                        // we want to keep the connection open.
                        res = true;
                    }
                    break;
                }

                case Message.MessageTypeOneofCase.Response:
                {
                    Response response = incomingMessage.Response;
                    log.Trace("Response status is {0}, details are '{1}', response type is {2}.", response.Status, response.Details, response.ResponseTypeCase);

                    // The only response we should ever receive here is GetNeighbourNodesByDistanceResponse in response to our refresh request that we do from time to time.
                    bool isGetNeighbourNodesByDistanceResponse = (response.Status == Status.Ok) &&
                                                                 (response.ResponseTypeCase == Response.ResponseTypeOneofCase.LocalService) &&
                                                                 (response.LocalService.LocalServiceResponseTypeCase == LocalServiceResponse.LocalServiceResponseTypeOneofCase.GetNeighbourNodes);

                    if (!isGetNeighbourNodesByDistanceResponse)
                    {
                        log.Error("Unexpected response type {0} received, status code {1}.", response.ResponseTypeCase, response.Status);
                        break;
                    }

                    // Process the response.
                    res = await ProcessMessageGetNeighbourNodesByDistanceResponseAsync(incomingMessage, false);

                    break;
                }

                default:
                    log.Error("Unknown message type '{0}', connection to the client will be closed.", incomingMessage.MessageTypeCase);
                    await SendProtocolViolation(client);

                    // Connection will be closed in ReceiveMessageLoop.
                    break;
                }
            }
            catch (Exception e)
            {
                log.Error("Exception occurred, connection to the client will be closed: {0}", e.ToString());
                await SendProtocolViolation(client);

                // Connection will be closed in ReceiveMessageLoop.
            }

            log.Debug("(-):{0}", res);
            return(res);
        }