/// <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
            };
        }
 public CreatePublicationStep(Element sourceElement)
 {
     SourceElement = sourceElement;
 }
 public DropPublicationStep(Element targetElement)
 {
     TargetElement = targetElement;
 }