private void AddNewDocumentGroup(
            XmlDocumentGroup xmlDocumentGroup,
            UploadDocumentGroup uploadDocumentGroup,
            Dictionary<string, MemoryStream> documentsData)
        {
            DocumentGroup newDocumentGroup = new DocumentGroup();
            newDocumentGroup.CrawlerId = this.db.GetOrCreateCrawlerId(xmlDocumentGroup.Crawler);
            newDocumentGroup.Identifier = xmlDocumentGroup.Identifier;
            newDocumentGroup.DocumentGroupName = xmlDocumentGroup.FileName;
            newDocumentGroup.DocumentGroupFormat = xmlDocumentGroup.Format;
            newDocumentGroup.Lang = xmlDocumentGroup.Lang;
            newDocumentGroup.Operation = (int)xmlDocumentGroup.Operation;
            newDocumentGroup.DocumentGroupDate = xmlDocumentGroup.Date;

            // Byte Array Data
            newDocumentGroup.DataContent = uploadDocumentGroup.Data;

            List<Document> documents = this.AddDocuments(xmlDocumentGroup.Document, documentsData);
            foreach (Document document in documents)
            {
                newDocumentGroup.Documents.Add(document);
            }

            this.db.AddDocumentGroup(newDocumentGroup);
        }
        /// <summary>
        /// Method that is used to upload XmlDocumentGroup to web service
        /// </summary>
        /// <param name="uploadDocumentGroup">Complex type XmlDocumentGroup</param>
        /// <returns>- If there is no errors the return string is "Ok" 
        /// - If error the return string will be in following format: 
        /// Error: <error description>
        /// </returns>
        public string UploadFile(UploadDocumentGroup uploadDocumentGroup)
        {
            CrawlerLog crawlerLog = new CrawlerLog();
            try
            {
                RemoteEndpointMessageProperty msg = null;
                if (OperationContext.Current != null)
                {
                    msg = OperationContext.Current.IncomingMessageProperties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
                    crawlerLog.IpAddress = msg.Address;
                }
                else
                {
                    crawlerLog.IpAddress = "localhost";
                }

                crawlerLog.IsSuccess = false;
                crawlerLog.LogDate = DateTime.Now;
                crawlerLog.MetaXml = uploadDocumentGroup.MetaInfo;

                // ValidateDeserializeXml
                this.isValidXml = true;
                this.validationErrorLog.Clear();
                this.XmlValidate(uploadDocumentGroup.MetaInfo);
                if (!this.isValidXml)
                {
                    return this.validationErrorLog.ToString();
                }

                XmlDocumentGroup xmlDocumentGroup = null;
                XmlSerializer deserializer = new XmlSerializer(typeof(XmlDocumentGroup));
                using (TextReader textReader = new StringReader(uploadDocumentGroup.MetaInfo))
                {
                    xmlDocumentGroup = (XmlDocumentGroup)deserializer.Deserialize(textReader);
                }

                crawlerLog.Identifier = xmlDocumentGroup.Identifier;
                crawlerLog.Operation = (int)xmlDocumentGroup.Operation;
                crawlerLog.CrawlerName = xmlDocumentGroup.Crawler;

                // ValidateReadZip
                Dictionary<string, MemoryStream> documentsData = new Dictionary<string, MemoryStream>();
                if (xmlDocumentGroup.Operation != Operation.Del)
                {
                    if (uploadDocumentGroup.Data == null || uploadDocumentGroup.Data.Length == 0)
                    {
                        this.validationErrorLog.Append("Error: Validation Exception - ZipData length is zero or ZipData is NULL, document idenfier: " + xmlDocumentGroup.Identifier + " and Operation: " + xmlDocumentGroup.Operation);
                        return this.validationErrorLog.ToString();
                    }
                    else
                    {
                        crawlerLog.ZipLength = uploadDocumentGroup.Data.Length;
                        documentsData = this.UnZipToMemory(uploadDocumentGroup.Data);
                    }
                }

                // AddUpdDel
                var documentGroupIdentifier = this.db.GetIdentifier(xmlDocumentGroup.Identifier);

                if (xmlDocumentGroup.Operation == Operation.Add)
                {
                    if (string.IsNullOrEmpty(documentGroupIdentifier))
                    {
                        // Add new XmlDocumentGroup
                        this.AddNewDocumentGroup(xmlDocumentGroup, uploadDocumentGroup, documentsData);
                    }
                    else
                    {
                        this.validationErrorLog.Append("Error: Validation Exception - There is a document identifier: " + xmlDocumentGroup.Identifier + " You can't use Оperation: " + xmlDocumentGroup.Operation);
                        return this.validationErrorLog.ToString();
                    }
                }
                else if (xmlDocumentGroup.Operation == Operation.Upd || xmlDocumentGroup.Operation == Operation.Del)
                {
                    if (!string.IsNullOrEmpty(documentGroupIdentifier))
                    {
                        // Update/Delete
                        this.UpdateDeleteDocumentGroup(xmlDocumentGroup, uploadDocumentGroup, documentsData, documentGroupIdentifier);
                    }
                    else
                    {
                        this.validationErrorLog.Append("Error: Validation Exception - No document idenfier: " + xmlDocumentGroup.Identifier + " .You can't use Operation: " + xmlDocumentGroup.Operation);
                        return this.validationErrorLog.ToString();
                    }
                }
                else
                {
                    this.validationErrorLog.Append("Error: Validation Exception - Document idenfier: " + xmlDocumentGroup.Identifier + " .Invalid Operation: " + xmlDocumentGroup.Operation);
                    return this.validationErrorLog.ToString();
                }

                crawlerLog.IsSuccess = true;
            }
            catch (Exception ex)
            {
                crawlerLog.IsSuccess = false;
                crawlerLog.Error += ex.ToString();
                return "Error: Service Exception - " + ex.ToString();
            }
            finally
            {
                crawlerLog.Error += this.validationErrorLog.ToString();

                try
                {
                    this.db.AddNewLog(crawlerLog);
                    LockHelper.PushLocalLogToDb();
                }
                catch (Exception ex)
                {
                    // There is a problem with the connection to the database, so we recorded a log in a text file
                    crawlerLog.Error += ex.ToString();
                    LockHelper.WriteToFileLog(crawlerLog);
                }
            }

            return "Ok";
        }
        private void UpdateDeleteDocumentGroup(
            XmlDocumentGroup xmlDocumentGroup,
            UploadDocumentGroup uploadDocumentGroup,
            Dictionary<string, MemoryStream> documentsData,
            string documentGroupIdentifier)
        {
            // Delete
            this.db.DeleteDocumentGroup(documentGroupIdentifier);

            // Update
            if (xmlDocumentGroup.Operation == Operation.Upd)
            {
                this.AddNewDocumentGroup(xmlDocumentGroup, uploadDocumentGroup, documentsData);
            }
        }