/// <summary>
        /// Compares two publications and returns result listing all identical aspects and differences
        /// </summary>
        /// <param name="source">The publication which represents the desired end state</param>
        /// <param name="target">The publication the changes are to be applied to</param>
        /// <returns>Results of the comparison</returns>
        public SqlPublicationCompareResult Compare(Element source, Element target)
        {
            var sourceArticles = source.Articles();
            var targetArticles = target.Articles();

            var articlesEqual   = new Dictionary <Element, Element>();
            var articlesChanged = new Dictionary <Element, SqlPublicationArticleChangeDefinition>();

            foreach (var sourceArticle in sourceArticles.Intersect(targetArticles, x => x.TableName()))
            {
                var matchingTargetArticle = targetArticles.Single(targetArticle => targetArticle.TableName() == sourceArticle.TableName());

                var columnsToAdd    = sourceArticle.Columns().Except(matchingTargetArticle.Columns(), x => x.ColumnName()).ToList();
                var columnsToRemove = matchingTargetArticle.Columns().Except(sourceArticle.Columns(), x => x.ColumnName()).ToList();

                if (!columnsToAdd.Any() && !columnsToRemove.Any())
                {
                    articlesEqual.Add(sourceArticle, matchingTargetArticle);
                }
                else
                {
                    var changeDefinition = new SqlPublicationArticleChangeDefinition
                    {
                        ColumnsAdded       = columnsToAdd,
                        ColumnsDropped     = columnsToRemove,
                        PropertiesEqual    = new List <string>(),
                        PropertiesModified = new List <string>()
                    };

                    articlesChanged.Add(sourceArticle, changeDefinition);
                }
            }

            return(new SqlPublicationCompareResult
            {
                SourceElement = source,
                ElementsToAdd = new ReadOnlyCollection <Element>(sourceArticles.Except(targetArticles, x => x.TableName()).ToList()),
                ElementsToDrop = new ReadOnlyCollection <Element>(targetArticles.Except(sourceArticles, x => x.TableName()).ToList()),
                ElementsEqual = articlesEqual,
                ElementsChanged = articlesChanged
            });
        }
        /// <summary>
        /// Compares two publications and returns result listing all identical aspects and differences
        /// </summary>
        /// <param name="source">The publication which represents the desired end state</param>
        /// <param name="target">The publication the changes are to be applied to</param>
        /// <returns>Results of the comparison</returns>
        public SqlPublicationCompareResult Compare(Element source, Element target)
        {
            var sourceArticles = source.Articles();
            var targetArticles = target.Articles();

            var articlesEqual = new Dictionary<Element, Element>();
            var articlesChanged = new Dictionary<Element, SqlPublicationArticleChangeDefinition>();

            foreach (var sourceArticle in sourceArticles.Intersect(targetArticles, x => x.TableName()))
            {
                var matchingTargetArticle = targetArticles.Single(targetArticle => targetArticle.TableName() == sourceArticle.TableName());

                var columnsToAdd = sourceArticle.Columns().Except(matchingTargetArticle.Columns(), x => x.ColumnName()).ToList();
                var columnsToRemove = matchingTargetArticle.Columns().Except(sourceArticle.Columns(), x => x.ColumnName()).ToList();

                if (!columnsToAdd.Any() && !columnsToRemove.Any())
                    articlesEqual.Add(sourceArticle, matchingTargetArticle);
                else
                {
                    var changeDefinition = new SqlPublicationArticleChangeDefinition
                        {
                            ColumnsAdded = columnsToAdd,
                            ColumnsDropped = columnsToRemove,
                            PropertiesEqual = new List<string>(),
                            PropertiesModified = new List<string>()
                        };

                    articlesChanged.Add(sourceArticle, changeDefinition);
                }
            }

            return new SqlPublicationCompareResult
            {
                SourceElement = source,
                ElementsToAdd = new ReadOnlyCollection<Element>(sourceArticles.Except(targetArticles, x => x.TableName()).ToList()),
                ElementsToDrop = new ReadOnlyCollection<Element>(targetArticles.Except(sourceArticles, x => x.TableName()).ToList()),
                ElementsEqual = articlesEqual,
                ElementsChanged = articlesChanged
            };
        }