/// <summary>
        /// Process the incoming request and forms a formatted outgoing response.
        /// </summary>
        /// <param name="incomingRequest">Incoming request</param>
        /// <returns>Message instance containing the outgoing response</returns>
        public Message ProcessRequest(Request incomingRequest)
        {
            _baseUri = _serviceHost.ServiceBaseUri;

            _responseSerializationFormat = incomingRequest.ResponseSerializationFormat;

            _incomingEntities = incomingRequest.EntityList;

            _idToTempIdMapping = incomingRequest.IdToTempIdMapping;

            // Check and invoke request interceptor
            this.PrepareAndProcessRequestInterceptor();

            IAsymmetricProviderService providerService =
                new SqlSyncProviderService(_configuration,
                                           Convert.ToString(incomingRequest.CommandParams[CommandParamType.ScopeName]),
                                           incomingRequest.ProviderParams,
                                           base._operationContext);

            // Set a callback for the ApplyClientChangeFailed delegate.
            ((SqlSyncProviderService)providerService).ApplyClientChangeFailed = ClientChangeFailedToApply;

            // Loop over client input and pull all inserts to a different collection.
            _incomingNewInsertEntities = _incomingEntities.Where(e => string.IsNullOrEmpty(e.ServiceMetadata.Id)).ToList();

            _applyChangesResponse = providerService.ApplyChanges(incomingRequest.SyncBlob, incomingRequest.EntityList);

            // Give the inserts permanent Ids
            AssignRealIdsForClientInserts(_incomingNewInsertEntities);

            // Process the rejected entities if any
            this.ProcessRejectedEntities((SqlSyncProviderService)providerService);

            // Check and fire response interceptor
            this.PrepareAndProcessResponseInterceptor(providerService);

            var oDataWriter = GetSyncWriterWithContents();

            return base.CreateResponseMessage(incomingRequest.ResponseSerializationFormat, oDataWriter);
        }
        /// <summary>
        /// This function loops the rejected entites and sends back a SyncError for each entity. For each entity it does the following
        /// 1. Retrieve the current version in server.
        /// 1.a If its null then it copies the primary key to a new object and marks it as tombstone.
        /// 2. Adds the SyncError to existing list of SyncErrors.
        /// </summary>
        /// <param name="sqlProvider"></param>
        private void ProcessRejectedEntities(SqlSyncProviderService sqlProvider)
        {
            if (this._rejectedEntities == null || this._rejectedEntities.Count == 0)
            {
                return;
            }

            try
            {
                List<IOfflineEntity> serverVersions = sqlProvider.GetCurrentServerVersionForEntities(this._rejectedEntities.Keys);
                if (serverVersions.Count != this._rejectedEntities.Count)
                {
                    // Ensure we get a server version for each entity we passed
                    throw new InvalidOperationException("Did not get server versions for all rejected entities.");
                }
                for (int i = 0; i < this._rejectedEntities.Keys.Count; i++)
                {
                    IOfflineEntity server = serverVersions[i];
                    IOfflineEntity client = this._rejectedEntities.Keys.ElementAt(i);

                    if (server == null)
                    {
                        // This means the server didnt contain a version for the entity. Need to send a tombstone back then
                        // create a new object and copy the values over
                        ConstructorInfo constructorInfo = client.GetType().GetConstructor(Type.EmptyTypes);
                        server = (IOfflineEntity)constructorInfo.Invoke(null);
                        // Copy the primary key values over
                        foreach (PropertyInfo info in ReflectionUtility.GetPrimaryKeysPropertyInfoMapping(client.GetType()))
                        {
                            info.SetValue(server, info.GetValue(client, null), null);
                        }
                        server.ServiceMetadata.IsTombstone = true;
                    }

                    SyncError error = new SyncError()
                    {
                        ErrorEntity = client,
                        LiveEntity = server,
                        Description = this._rejectedEntities[client]
                    };

                    _applyChangesResponse.Errors.Add(error);
                }
            }
            catch (Exception e)
            {
                throw new InvalidOperationException("Error in reading server row values. " + e.Message);
            }
        }
        /// <summary>
        /// Process the incoming request and forms a formatted outgoing response.
        /// </summary>
        /// <param name="incomingRequest">Incoming request</param>
        /// <returns>Message instance containing the outgoing response</returns>
        public Message ProcessRequest(Request incomingRequest)
        {
            _baseUri = _serviceHost.ServiceBaseUri;

            _responseSerializationFormat = incomingRequest.ResponseSerializationFormat;

            // Check and fire request interceptor.
            if (_configuration.HasRequestInterceptors(this._scopeName, SyncOperations.Download))
            {
                // Init the SyncOperationContext
                this.InitRequestOperationContext();

                // Fire the request Interceptors if any
                base.ProcessRequestInterceptors();
            }

            SqlSyncProviderService providerService =
                new SqlSyncProviderService(_configuration,
                                           Convert.ToString(incomingRequest.CommandParams[CommandParamType.ScopeName]),
                                           incomingRequest.ProviderParams, 
                                           base._operationContext);

            _getChangesResponse = providerService.GetChanges(incomingRequest.SyncBlob);

            // Check and fire response interceptor.
            this.PrepareAndProcessResponseInterceptors();

            var oDataWriter = GetSyncWriterWithContents();

            return base.CreateResponseMessage(incomingRequest.ResponseSerializationFormat, oDataWriter);
        }