/// <summary>
        /// Actually calls into Control.dll to perform comparison. This call fires DataSent event and
        /// ComparisonStarted event. We need to set the client credentials for the call before it's executed.
        /// </summary>
        /// <param name="originalFile"></param>
        /// <param name="modifiedFile"></param>
        /// <param name="optionSet"></param>
        /// <param name="responseOptions"></param>
        /// <param name="uploadInfo"></param>
        /// <returns></returns>
        private CompareResults DoComparison(HttpPostedFile originalPostedFile, HttpPostedFile modifiedPostedFile, string optionSet, ResponseOptions responseOptions, ref UploadInfo uploadInfo)
        {
            ICompareService compareService = CreateAppropriateService();

            compareService.ComparisonStarted += new EventHandler(CompareService_OnComparisonStarted);
            compareService.DataSent          += new EventHandler <DataSentArgs>(CompareService_OnDataSent);

            uploadInfo.IsReady         = true;
            uploadInfo.PercentComplete = 10;
            uploadInfo.Message         = "Authenticating request ...";

            string username = (string)Session["UserName"];
            string domain   = (string)Session["Domain"];
            string password = (string)Session["Passw"];

            password = CodePassword(password);
            compareService.SetClientCredentials(username, password, domain);

            string serviceVersion;
            string compositorVersion;

            if (!compareService.VerifyConnection(out serviceVersion, out compositorVersion))
            {
                uploadInfo.IsReady = false;
                return(null);
            }

            uploadInfo.PercentComplete = 15;
            uploadInfo.Message         = "Authentication was successful ... reading files";

            uploadInfo.PercentComplete = 20;
            uploadInfo.Message         = "Chunking files ...";

            compareService.CompareOptions   = optionSet;
            compareService.ComparisonOutput = responseOptions;
            compareService.UseChunking      = true;
            compareService.ChunkSize        = _chunkSize;

            var originalFile = originalPostedFile.InputStream;
            var modifiedFile = modifiedPostedFile.InputStream;

            originalFile.Seek(0, SeekOrigin.Begin);
            modifiedFile.Seek(0, SeekOrigin.Begin);

            // As _lastModifiedFileIndex is zero-based, so increment it befor displaying
            uploadInfo.PairInfo = "Comparing File Pair " + (_lastModifiedFileIndex + 1).ToString();

            CompareResults results = compareService.CompareEx(originalFile, modifiedFile, CreateDocumentInfo(originalPostedFile.FileName), CreateDocumentInfo(modifiedPostedFile.FileName));

            uploadInfo.PercentComplete = 100;
            uploadInfo.Message         = "Comparison completed ...";
            uploadInfo.IsReady         = false;

            return(results);
        }
        // Results are shown in an ASP Table, which is dynamically populated based on the number
        // of modified files provided. For each set of result files, which includes the modified file itself,
        // output file (.rtf/.wdf etc) and summary file (.xml), a separate row is created in the table.

        /// <summary>
        /// Prepares and stores the result objects for use by HandleFinalResults, based on output format
        /// selected by user, e.g. .rtf or .wdf etc.
        /// </summary>
        /// <param name="results"></param>
        /// <param name="responseOptions"></param>
        /// <param name="modifiedFileVirtualPath"></param>
        /// <param name="modifiedFileSizeInKB"></param>
        private void HandleIntermediateResults(CompareResults results, ResponseOptions responseOptions, string modifiedFileVirtualPath, double modifiedFileSizeInKB)
        {
            string outputFileVirtualPath  = string.Empty;
            string summaryFileVirtualPath = string.Empty;

            double outputFileSizeInKB  = 0;
            double summaryFileSizeInKB = 0;

            if (results.Redline != null)
            {
                outputFileVirtualPath = Path.GetDirectoryName(modifiedFileVirtualPath);
                outputFileSizeInKB    = (double)results.Redline.Length / 1024;
                switch (responseOptions)
                {
                case ResponseOptions.Rtf:
                case ResponseOptions.RtfWithSummary:
                    outputFileVirtualPath = Path.Combine(outputFileVirtualPath, "redline.rtf");
                    break;

                case ResponseOptions.Wdf:
                case ResponseOptions.WdfWithSummary:
                    outputFileVirtualPath = Path.Combine(outputFileVirtualPath, "redline.wdf");
                    break;

                case ResponseOptions.Doc:
                case ResponseOptions.DocWithSummary:
                    outputFileVirtualPath = Path.Combine(outputFileVirtualPath, "redline.doc");
                    break;

                case ResponseOptions.DocX:
                case ResponseOptions.DocXWithSummary:
                    outputFileVirtualPath = Path.Combine(outputFileVirtualPath, "redline.docx");
                    break;

                case ResponseOptions.Pdf:
                case ResponseOptions.PdfWithSummary:
                    outputFileVirtualPath = Path.Combine(outputFileVirtualPath, "redline.pdf");
                    break;
                }

                string filePhysicalPath = Server.MapPath(outputFileVirtualPath);
                if (File.Exists(filePhysicalPath))
                {
                    File.Delete(filePhysicalPath);
                }

                File.WriteAllBytes(filePhysicalPath, results.Redline);
            }

            if ((responseOptions & ResponseOptions.Xml) == ResponseOptions.Xml)
            {
                if (results.ChangeSummary != null)
                {
                    summaryFileVirtualPath = Path.GetDirectoryName(modifiedFileVirtualPath);
                    summaryFileVirtualPath = Path.Combine(summaryFileVirtualPath, "redline.xml");
                    summaryFileSizeInKB    = (double)results.ChangeSummary.Length / 1024;

                    string filePhysicalPath = Server.MapPath(summaryFileVirtualPath);
                    if (File.Exists(filePhysicalPath))
                    {
                        File.Delete(filePhysicalPath);
                    }

                    File.WriteAllText(filePhysicalPath, results.ChangeSummary);
                }
            }

            modifiedFileVirtualPath = Server.HtmlEncode(modifiedFileVirtualPath);
            outputFileVirtualPath   = Server.HtmlEncode(outputFileVirtualPath);
            summaryFileVirtualPath  = Server.HtmlEncode(summaryFileVirtualPath);

            ResultantFiles resultantFiles = new ResultantFiles(modifiedFileVirtualPath, outputFileVirtualPath, summaryFileVirtualPath,
                                                               modifiedFileSizeInKB, outputFileSizeInKB, summaryFileSizeInKB);

            _resultantFiles.Add(resultantFiles);
        }
        /// <summary>
        /// Makes calls to process files and do Comparison.
        /// The files are placed in Files collection in the order of appearance on the HTML form.
        /// First of all Original file is saved. Then for each modified file, file is saved and compared
        /// against the original file. Modified files can be more than one.
        /// </summary>
        private void ProcessFilesAndDoComparison()
        {
            UploadInfo uploadInfo = null;

            try
            {
                // Validate the data.
                if (!IsDataValid())
                {
                    UpdatePageUI();
                    return;
                }

                // Upload object used by Default.aspx to report progress to the user
                uploadInfo = Session["UploadInfo"] as UploadInfo;

                uploadInfo.IsReady            = false;
                uploadInfo.UsePercentComplete = false;

                // Read output format
                ResponseOptions responseOptions = (ResponseOptions)Enum.Parse(typeof(ResponseOptions), ResponseOptionsDropDownList.SelectedValue);

                // Read rendering set from file
                string renderingSet            = RenderingSetDropDownList.SelectedValue;
                string optionSet               = File.ReadAllText(Request.MapPath(Path.Combine(_renderSetPath, renderingSet)));
                string originalFileVirtualPath = string.Empty;
                double originalFileSizeInKB    = 0;

                _resultantFiles.Clear();

                // Process original file first.
                HttpPostedFile originalPostedFile = Request.Files["OriginalFile"];
                if (originalPostedFile != null)
                {
                    originalFileVirtualPath = ProcessFile(originalPostedFile, true, ref uploadInfo);
                    _originalFileName       = Path.GetFileName(originalFileVirtualPath);
                    originalFileSizeInKB    = (double)originalPostedFile.ContentLength / 1024;
                }

                foreach (string postedFile in Request.Files.Keys)
                {
                    if (postedFile == "OriginalFile")
                    {
                        // We have already had it.
                        continue;
                    }
                    // Now the modified ones.
                    HttpPostedFile modifiedPostedFile = Request.Files[postedFile];
                    if (modifiedPostedFile.ContentLength <= 0)
                    {
                        continue;
                    }

                    string modifiedFileVirtualPath = ProcessFile(modifiedPostedFile, false, ref uploadInfo);
                    _modifiedFileName = Path.GetFileName(modifiedFileVirtualPath);
                    double modifiedFileSizeInKB = (double)modifiedPostedFile.ContentLength / 1024;

                    // Update progress
                    uploadInfo.IsReady            = true;
                    uploadInfo.UsePercentComplete = true;
                    uploadInfo.PercentComplete    = 3;
                    uploadInfo.Message            = "Starting comparison ...";

                    // Perform comparison
                    CompareResults results = DoComparison(originalPostedFile, modifiedPostedFile, optionSet, responseOptions, ref uploadInfo);

                    if (results != null)
                    {
                        ShowMessage(GenerateScriptID("comp"), "success", " Comparison completed successfully. Displaying results.");

                        // We save results for each modified file during the process, and sum up these
                        // intermediate results after we are done with comparing all the modified files
                        // provided by user.
                        HandleIntermediateResults(results, responseOptions, modifiedFileVirtualPath, modifiedFileSizeInKB);
                        _lastModifiedFileIndex++;

                        ShowMessage(GenerateScriptID("comp"), "success", " Comparison completed successfully.");
                    }
                    else
                    {
                        ShowMessage(GenerateScriptID("comp"), "error", " Comparison failed. One possible reason is failure of document format conversion.");
                    }
                }

                // Prepare final result structs
                ComparisonResult comparisonResult = HandleFinalResults(originalFileVirtualPath, originalFileSizeInKB, renderingSet);

                // Show the results.
                DisplayResults(comparisonResult);
            }
            catch (System.Security.SecurityException ex)
            {
                if (uploadInfo != null)
                {
                    uploadInfo.IsReady = false;
                }

                string message = " Credentials provided are either empty or invalid. " + ex.Message;
                ShowMessage(GenerateScriptID("comp"), "error", message);
                ToggleUploadButtonAndStatusPane(true);
            }
            catch (System.ServiceModel.EndpointNotFoundException ex)
            {
                if (uploadInfo != null)
                {
                    uploadInfo.IsReady = false;
                }

                string message = " Either Compare Service is not running or host/port address is invalid. " + ex.Message;
                ShowMessage(GenerateScriptID("comp"), "error", message);
                ToggleUploadButtonAndStatusPane(true);
            }
            catch (TimeoutException ex)
            {
                if (uploadInfo != null)
                {
                    uploadInfo.IsReady = false;
                }

                string message = " The connection between server and client is lost because of a timeout. " + ex.Message;
                ShowMessage(GenerateScriptID("comp"), "error", message);
                ToggleUploadButtonAndStatusPane(true);
            }
            catch (InvalidDataException ex)
            {
                if (uploadInfo != null)
                {
                    uploadInfo.IsReady = false;
                }

                string message = " There was an error processing the data. This might be because a document could not be converted. " + ex.Message;
                ShowMessage(GenerateScriptID("comp"), "error", message);
                ToggleUploadButtonAndStatusPane(true);
            }
            catch (System.ServiceModel.ServerTooBusyException ex)
            {
                if (uploadInfo != null)
                {
                    uploadInfo.IsReady = false;
                }

                string message = " Too many simultaneous requests. Try again after a while. " + ex.Message;
                ShowMessage(GenerateScriptID("comp"), "error", message);
                ToggleUploadButtonAndStatusPane(true);
            }
            catch (System.ServiceModel.FaultException <string> ex)
            {
                if (uploadInfo != null)
                {
                    uploadInfo.IsReady = false;
                }

                string message = " An error occurred while comparing documents. " + ex.Detail;
                ShowMessage(GenerateScriptID("comp"), "error", message);
                ToggleUploadButtonAndStatusPane(true);
            }
            catch (Exception ex)
            {
                if (uploadInfo != null)
                {
                    uploadInfo.IsReady = false;
                }

                string message = " An error occurred while comparing documents. " + ex.Message;
                ShowMessage(GenerateScriptID("comp"), "error", message);
                ToggleUploadButtonAndStatusPane(true);
            }
        }