/// <summary>
        /// Updates the Request Queue by Cancelling any existing update,create operations for the PublishRequest provided and adds the new one.
        /// </summary>
        /// <param name="publishRequest">PublishRequest containing DataModelNamespace and ResouceTypeName</param>
        internal void UpdateRequestQueue(PublishRequest publishRequest)
        {
            Globals.TraceMessage(TraceEventType.Verbose, publishRequest.ToString(), Properties.Messages.StartedFunctionMessage);

            lock (lockObject)
            {
                IEnumerable <PublishRequest> updatePublishRequest = publishRequestQueue.Where(p =>
                                                                                              p.DataModelNamespace.Equals(publishRequest.DataModelNamespace, StringComparison.OrdinalIgnoreCase) &&
                                                                                              p.ResourceTypeName.Equals(publishRequest.ResourceTypeName, StringComparison.OrdinalIgnoreCase));

                if (updatePublishRequest != null && updatePublishRequest.Count() > 0)
                {
                    foreach (PublishRequest request in updatePublishRequest)
                    {
                        request.CancelRequest();
                    }
                }
            }

            // Add the new publish request by calling submit
            this.Submit(publishRequest);

            Globals.TraceMessage(TraceEventType.Verbose, publishRequest.ToString(), Properties.Messages.FinishedFunctionMessage);
        }
        /// <summary>
        /// Processes the publish request.
        /// </summary>
        /// <param name="currentPublishRequest">The current publish request.</param>
        private void ProcessPublishRequest(PublishRequest currentPublishRequest)
        {
            Globals.TraceMessage(TraceEventType.Information, currentPublishRequest.ToString(), string.Format(Properties.Messages.StartedProcessingQueuedPublishRequest, currentPublishRequest.InstanceId));

            // Add the item in the Request Tracker
            // Remove old requests of the same resourcetype from the Request Tracker
            lock (PublishRequestTracker)
            {
                PublishRequestTracker.RemoveWhere(request => request.DataModelNamespace.Equals(currentPublishRequest.DataModelNamespace, StringComparison.OrdinalIgnoreCase) &&
                                                  request.ResourceTypeName.Equals(currentPublishRequest.ResourceTypeName, StringComparison.OrdinalIgnoreCase));
                PublishRequestTracker.Add(currentPublishRequest);
                currentPublishRequest.DeleteFromDatabase(false, true);
                currentPublishRequest.SaveToDatabase(false);
            }

            // If the request is a cancelled request then mark it as AbortedOnDemand and save to database.
            if (currentPublishRequest.IsCancellationRequested)
            {
                currentPublishRequest.CurrentStatus.CurrentStage = PublishStage.AbortedOnDemand;
                currentPublishRequest.SaveToDatabase(false);
                return;
            }

            try
            {
                using (Process zentityCollectionCreator = new Process())
                {
                    zentityCollectionCreator.StartInfo = new ProcessStartInfo()
                    {
                        // Create the Zentity.Pivot.CollectionCreator Process
                        FileName = Path.Combine(Utilities.AssemblyLocation, "Zentity.Pivot.CollectionCreator.exe"),
                        // Pass the specific arguments to the process
                        Arguments = string.Format("/operation:{0} /instanceId:{1} /modelNamespace:{2} /resourceType:{3} {4}",
                                                  currentPublishRequest.Operation,
                                                  currentPublishRequest.InstanceId,
                                                  currentPublishRequest.DataModelNamespace,
                                                  currentPublishRequest.ResourceTypeName,
                                                  currentPublishRequest.Operation == PublishOperation.UpdateCollection
                                                    ? string.Format("/changemessagefilepath:\"{0}\"", currentPublishRequest.ChangeMessageFilePath)
                                                    : string.Empty),
                        UseShellExecute        = false,
                        RedirectStandardOutput = true
                    };

                    currentPublishRequest.CurrentStatus.CurrentStage = PublishStage.Initiating;
                    zentityCollectionCreator.Start();
                    // Read the output stream first and then wait.
                    string output = zentityCollectionCreator.StandardOutput.ReadToEnd();
                    // Thread waits till the process exits
                    zentityCollectionCreator.WaitForExit();

                    // Analyze the ExitCode and throw the correct execption.
                    switch (zentityCollectionCreator.ExitCode)
                    {
                    // CollectionCreator has exited with a ReturnCode
                    case (int)ReturnCode.Error:
                    case (int)ReturnCode.Invalid:
                        throw new ApplicationException(output.Replace("\n", "\r\n"));

                    // User has ended the CollectionCreator process from Task Manager etc.
                    case 1:
                        throw new InvalidOperationException(Properties.Messages.CollectionCreatorProcessKilled);
                    }
                }
            }
            catch (Exception ex)
            {
                Globals.TraceMessage(TraceEventType.Error, ex.ToString(), string.Format(Properties.Messages.ExceptionProcessingPublishRequest, currentPublishRequest.InstanceId));
                currentPublishRequest.CurrentStatus.CurrentStage = PublishStage.AbortedOnError;
                currentPublishRequest.PublishingCallback         = null;
            }

            // Do cleanup, if the CollectionCreator process has not done itself.
            try
            {
                string directoryPath = Path.Combine(Path.GetTempPath(), currentPublishRequest.InstanceId.ToString());
                string imagesPath    = Path.Combine(Path.GetTempPath(), string.Format("{0}_Images", currentPublishRequest.InstanceId));
                if (Directory.Exists(directoryPath))
                {
                    Directory.Delete(directoryPath, true);
                }
                if (Directory.Exists(imagesPath))
                {
                    Directory.Delete(imagesPath, true);
                }
            }
            catch { }

            // If the Collection creator has not been able to report progress (highly unlikely).
            // Assume that the operation completed successfully.
            if (currentPublishRequest.CurrentStatus.CurrentStage == PublishStage.NotStarted ||
                currentPublishRequest.CurrentStatus.CurrentStage == PublishStage.Initiating)
            {
                Globals.TraceMessage(TraceEventType.Information, string.Empty, string.Format(Properties.Messages.CollectionCreatorProgressReportFailure, currentPublishRequest.InstanceId));
                currentPublishRequest.CurrentStatus.CurrentStage = PublishStage.Completed;
            }

            currentPublishRequest.SaveToDatabase(false);
            lock (lockObject) { processedItemCount++; Monitor.Pulse(lockObject); }

            Globals.TraceMessage(TraceEventType.Information, currentPublishRequest.ToString(), string.Format(Properties.Messages.FinishedProcessingQueuedPublishRequest, currentPublishRequest.InstanceId));
        }
        /// <summary>
        /// Called when [thread run].
        /// </summary>
        private void OnThreadRun()
        {
            bool shouldResign = false;

            while ((stopRequested == false) && (shouldResign == false))
            {
                PublishRequest currentRequest = null;
                try
                {
                    if (publishRequestQueue.IsEmpty)
                    {
                        waitHandle.WaitOne();
                        continue;
                    }

                    // Check whether the peeked resource is running in PublishRequestTracker
                    // => If running then set all the requests to add it to the end
                    // => If not then dequeue and process
                    lock (lockObject)
                    {
                        if (!RearrangePublishRequestQueue())
                        {
                            Monitor.Pulse(lockObject);
                            continue;
                        }
                    }

                    if (publishRequestQueue.TryDequeue(out currentRequest))
                    {
                        this.ProcessPublishRequest(currentRequest);
                    }
                }
                catch (OutOfMemoryException)
                {
                    Globals.TraceMessage(TraceEventType.Error, string.Empty, Properties.Messages.OutOfMemoryOnThreadRun);
                    lock (threadPool)
                    {
                        if (threadPool.Count > 1)
                        {
                            shouldResign = true;
                        }
                    }

                    if (currentRequest != null)
                    {
                        publishRequestQueue.Enqueue(currentRequest);
                    }

                    lock (lockObject) { Monitor.Pulse(lockObject); }
                }
                catch (Exception e)
                {
                    Globals.TraceMessage(TraceEventType.Error, e.ToString(), Properties.Messages.ExceptionOnThreadRun);
                    lock (lockObject) { Monitor.Pulse(lockObject); }
                }
            }

            lock (threadPool)
            {
                threadPool.Remove(Thread.CurrentThread);
                Monitor.Pulse(threadPool);
            }
        }