public async Task <OpResult> UpsertArticle(ArticleModel article, bool importFlag = false)
        {
            var          retvalue        = new OpResult();
            ArticleModel existingArticle = null;

            if (article == null)
            {
                retvalue.LogError(ARTICLE_ERROR_DATA_MUST_BE_PROVIDED);
                return(retvalue);
            }
            if (!importFlag && article.Guid != Guid.Empty)
            {
                existingArticle = await _articleDal.GetArticleById(article.Guid, null, null);

                if (existingArticle == null)
                {
                    retvalue.LogError(ARTICLE_ERROR_INVALID_RECORD);
                }
                else
                {
                    article.UniqueName  = existingArticle.UniqueName;
                    article.CreatedUTC  = existingArticle.CreatedUTC;
                    article.ModifiedUTC = existingArticle.ModifiedUTC;
                }
            }
            if (string.IsNullOrWhiteSpace(article.Name))
            {
                retvalue.LogError(ARTICLE_ERROR_TITLE_IS_REQUIRED);
            }
            if (string.IsNullOrEmpty(article.Description))
            {
                retvalue.LogError(ARTICLE_ERROR_DESCRIPTION_IS_REQUIRED);
            }
            if (string.IsNullOrEmpty(article.Category))
            {
                retvalue.LogError(ARTICLE_ERROR_CATEGORY_IS_REQUIRED);
            }
            if (!string.IsNullOrEmpty(article.DefaultSection) && article.Sections != null &&
                !article.Sections.Any(s => s.Name != null && s.Name.Equals(article.DefaultSection, StringComparison.OrdinalIgnoreCase)))
            {
                retvalue.LogError(ARTICLE_ERROR_DEFAULT_SECTION_INVALID);
            }
            if (article.Sections != null)
            {
                var counter = 0;
                foreach (var section in article.Sections)
                {
                    counter++;
                    if (string.IsNullOrEmpty(section.Name))
                    {
                        retvalue.LogError(string.Format(SECTION_ERROR_NAME_IS_REQUIRED, counter));
                    }
                    if (string.IsNullOrEmpty(section.Data))
                    {
                        retvalue.LogError(string.Format(SECTION_ERROR_CONTENT_IS_REQUIRED, counter));
                    }
                }
            }
            if ((article.Sections == null || article.Sections.Count <= 0) && string.IsNullOrEmpty(article.ContentURL))
            {
                retvalue.LogError(ARTICLE_ERROR_EITHER_URL_OR_SECTION_REQUIRED);
            }
            if (retvalue.Successful)
            {
                Dictionary <string, bool> existingUniqueNames = (await _articleDal.ListArticles(null))
                                                                .ToDictionary(a => a.UniqueName, a => true, StringComparer.OrdinalIgnoreCase);
                article.GenerateUniqueName(existingUniqueNames);

                var existingSectionGuids = new List <Guid>();
                if (existingArticle != null && existingArticle.Sections != null)
                {
                    existingSectionGuids = existingArticle.Sections.Select(s => s.Guid).ToList();
                }
                _articleDal.AddTransaction(DatabaseType.PEngine, Database.OpenTransaction(DatabaseType.PEngine, false));
                try
                {
                    if (importFlag || article.Guid == Guid.Empty)
                    {
                        await _articleDal.InsertArticle(article, importFlag);
                    }
                    else
                    {
                        await _articleDal.UpdateArticle(article);
                    }
                    if (article.Sections != null)
                    {
                        var previousSectionUniqueNames = new Dictionary <string, bool>(StringComparer.OrdinalIgnoreCase);
                        foreach (var section in article.Sections)
                        {
                            if (!importFlag && section.Guid != Guid.Empty && !existingSectionGuids.Contains(section.Guid))
                            {
                                section.Guid = Guid.Empty;
                            }
                            section.ArticleGuid = article.Guid;
                            section.GenerateUniqueName(previousSectionUniqueNames);
                            previousSectionUniqueNames.Add(section.UniqueName, true);

                            if (importFlag || section.Guid == Guid.Empty || !existingSectionGuids.Contains(section.Guid))
                            {
                                await _articleDal.InsertArticleSection(section, importFlag);
                            }
                            else
                            {
                                await _articleDal.UpdateArticleSection(section);
                            }
                            existingSectionGuids.Remove(section.Guid);
                        }
                    }
                    foreach (var sectionGuidToDelete in existingSectionGuids)
                    {
                        await _articleDal.DeleteArticleSection(sectionGuidToDelete);
                    }
                    _articleDal.CommitTransaction(DatabaseType.PEngine);
                }
                catch (Exception ex)
                {
                    _articleDal.RollBackTransaction(DatabaseType.PEngine);
                    throw new Exception("Article Transaction Failed", ex);
                }
            }
            return(retvalue);
        }