public SystemChangedRespMC SystemChangedStreaming(SystemChangedReqMC request)
        {
            const string StatusReceiving = "Receiving";
            const string StatusCompleted = "Completed";
            const string StatusFailed = "Failed   ";

            try
            {
                AddProgressBar(request.Id);

                using (FileStream createdFile = File.Create(Environment.CurrentDirectory + @"\" + Path.GetFileName(request.FullPath)))
                {
                    const int Length = 4096;
                    byte[] buffer = new byte[Length];
                    int bytesRead = request.FileStream.Read(buffer, 0, Length);
                    long totalBytesRead = bytesRead;

                    while (bytesRead > 0)
                    {
                        DrawFileProgressBar(GetProgressBarRow(request.Id), Path.GetFileName(request.FullPath), (int)totalBytesRead, (int)request.FileStreamLength, StatusReceiving);
                        createdFile.Write(buffer, 0, bytesRead);
                        bytesRead = request.FileStream.Read(buffer, 0, Length);
                        totalBytesRead = totalBytesRead + bytesRead;
                    }

                    request.FileStream.Close();
                }

                if (request.Checksum == CalculateMD5Sum(Environment.CurrentDirectory + @"\" + Path.GetFileName(request.FullPath)))
                {
                    DrawFileProgressBar(GetProgressBarRow(request.Id), Path.GetFileName(request.FullPath), (int)request.FileStreamLength, (int)request.FileStreamLength, StatusCompleted);
                }
                else
                {
                    DrawFileProgressBar(GetProgressBarRow(request.Id), Path.GetFileName(request.FullPath), (int)request.FileStreamLength, (int)request.FileStreamLength, StatusFailed);
                }

                RemoveProgressBar(request.Id);

                SystemChangedRespMC systemChangedRespMC = new SystemChangedRespMC();
                systemChangedRespMC.Message = "Request handled.";

                return systemChangedRespMC;
            }
            catch (Exception ex)
            {
                int row;
                if (TryGetProgressBarRow(request.Id, out row))
                {
                    DrawFileProgressBar(row, Path.GetFileName(request.FullPath), (int)request.FileStreamLength, (int)request.FileStreamLength, StatusFailed);
                    RemoveProgressBar(request.Id);
                }

                DefaultFault defaultFault = new DefaultFault();
                defaultFault.Message = ex.Message;
                defaultFault.Id = Guid.NewGuid();

                throw new FaultException<DefaultFault>(defaultFault);
            }
        }
        /// <summary>
        /// Call service specified in file watcher event args.
        /// </summary>
        /// <param name="e">File watcher event args for calling a service.</param>
        private void CallServiceSynchronized(FileWatcherEventArgs e)
        {
            // Turn on process running for synchronization of processes.
            SetProcessRunningOn();
            // Increase external process counter.
            SetExternalProcessRunningOn();

            // Run threaded event in main thread.
            _synchronizationContext.Send(new SendOrPostCallback(delegate
            {
                EventHandler<ServiceBeginCallEventArgs> handler = ServiceBeginCall;
                if (handler != null)
                {
                    handler(this,
                            new ServiceBeginCallEventArgs(e.ConfigurationKeyValuePair.Key,
                                                          GetProcessQueueCount(),
                                                          e.Id));
                }
            }), null);

            FileWatcherStreamingServiceProxy fileWatcherStreamingServiceProxy = null;
            FileWatcherServiceProxy fileWatcherServiceProxy = null;

            if (e.ConfigurationKeyValuePair.Value.StreamFile)
            {
                fileWatcherStreamingServiceProxy = CreateStreamingProxy(e.ConfigurationKeyValuePair.Key);
            }
            else
            {
                fileWatcherServiceProxy = CreateProxy(e.ConfigurationKeyValuePair.Key);
            }

            // If failed to create a proxy.
            if (fileWatcherStreamingServiceProxy == null &&
                fileWatcherServiceProxy == null)
            {
                // Decrease external process counter.
                SetExternalProcessRunningOff();

                // Run threaded event in main thread.
                _synchronizationContext.Send(new SendOrPostCallback(delegate
                {
                    EventHandler<ServiceProxyCreationErrorEventArgs> handler = ServiceProxyCreationError;
                    if (handler != null)
                    {
                        handler(this,
                                new ServiceProxyCreationErrorEventArgs(e.ConfigurationKeyValuePair.Key,
                                                                       e.Id,
                                                                       GetProcessQueueCount()));
                    }
                }), null);

                // Remove available process from the file watcher.
                RemoveAvailableProcess(e.ConfigurationKeyValuePair.Key);

                // Decrease file watcher process count.
                RemoveProcessFromProcessBatchSize(e.ConfigurationKeyValuePair.Key);

                SetProcessRunningOff();

                return;
            }

            try
            {
                IResponse response;
                string checksum = CalculateMD5Sum(e.FullPath);

                if (e.ConfigurationKeyValuePair.Value.StreamFile)
                {
                    using (Stream fileStream = File.OpenRead(e.FullPath))
                    {
                        response = new SystemChangedRespMC();

                        response.Message =
                            fileWatcherStreamingServiceProxy.SystemChangedStreaming(e.ChangeType,
                                                                                    checksum,
                                                                                    e.ConfigurationKeyValuePair.Key,
                                                                                    e.DateTime,
                                                                                    e.FileName,
                                                                                    fileStream.Length,
                                                                                    e.FullPath,
                                                                                    e.Id,
                                                                                    Environment.MachineName,
                                                                                    e.OldFullPath,
                                                                                    fileStream);
                    }

                    // Close proxy.
                    fileWatcherStreamingServiceProxy.Close();
                }
                else
                {
                    response = fileWatcherServiceProxy.SystemChanged(CreateRequest(e, checksum));

                    // Close proxy.
                    fileWatcherServiceProxy.Close();
                }

                // Decrease external process counter.
                SetExternalProcessRunningOff();

                if (response == null)
                {
                    // Run threaded event in main thread.
                    _synchronizationContext.Send(new SendOrPostCallback(delegate
                    {
                        EventHandler<ServiceCalledEventArgs> handler = ServiceCalled;
                        if (handler != null)
                        {
                            handler(this,
                                    new ServiceCalledEventArgs(e.ConfigurationKeyValuePair.Key,
                                                               String.Empty,
                                                               e.Id));
                        }
                    }), null);
                }
                else
                {
                    // Run threaded event in main thread.
                    _synchronizationContext.Send(new SendOrPostCallback(delegate
                    {
                        EventHandler<ServiceCalledEventArgs> handler = ServiceCalled;
                        if (handler != null)
                        {
                            handler(this,
                                    new ServiceCalledEventArgs(e.ConfigurationKeyValuePair.Key,
                                                               response.Message,
                                                               e.Id));
                        }
                    }), null);
                }
            }
            catch (Exception ex)
            {
                // Abort proxy.
                if (e.ConfigurationKeyValuePair.Value.StreamFile)
                {
                    fileWatcherStreamingServiceProxy.Abort();
                }
                else
                {
                    fileWatcherServiceProxy.Abort();
                }

                // Decrease external process counter.
                SetExternalProcessRunningOff();

                // Run threaded event in main thread.
                _synchronizationContext.Send(new SendOrPostCallback(delegate
                {
                    EventHandler<ServiceErrorEventArgs> handler = ServiceError;
                    if (handler != null)
                    {
                        handler(this,
                                new ServiceErrorEventArgs(e.ConfigurationKeyValuePair.Key,
                                                          ex,
                                                          e.Id,
                                                          GetProcessQueueCount()));
                    }
                }), null);
            }
            finally
            {
                // Remove available process from the file watcher.
                RemoveAvailableProcess(e.ConfigurationKeyValuePair.Key);

                // Decrease file watcher process count.
                RemoveProcessFromProcessBatchSize(e.ConfigurationKeyValuePair.Key);

                SetProcessRunningOff();
            }
        }