public override void CompareTabularModels()

in BismNormalizer/BismNormalizer/TabularCompare/TabularMetadata/Comparison.cs [71:637]


        public override void CompareTabularModels()
        {
            _comparisonObjectCount = 0;

            #region Model

            if (_comparisonInfo.TargetCompatibilityLevel >= 1460) //Target compat level is always >= source one.
            {
                // check if Model object definition is different
                ComparisonObject comparisonObjectModel;
                if (_sourceTabularModel.Model.ObjectDefinition != _targetTabularModel.Model.ObjectDefinition)
                {
                    comparisonObjectModel = new ComparisonObject(ComparisonObjectType.Model, ComparisonObjectStatus.DifferentDefinitions, _sourceTabularModel.Model, _targetTabularModel.Model, MergeAction.Update);
                    _comparisonObjects.Add(comparisonObjectModel);
                    _comparisonObjectCount += 1;
                }
                else
                {
                    // they are equal, ...
                    comparisonObjectModel = new ComparisonObject(ComparisonObjectType.Model, ComparisonObjectStatus.SameDefinition, _sourceTabularModel.Model, _targetTabularModel.Model, MergeAction.Skip);
                    _comparisonObjects.Add(comparisonObjectModel);
                    _comparisonObjectCount += 1;
                }
            }

            #endregion

            #region DataSources

            foreach (DataSource dataSourceSource in _sourceTabularModel.DataSources)
            {
                // check if source is not in target
                if (!_targetTabularModel.DataSources.ContainsName(dataSourceSource.Name))
                {
                    ComparisonObject comparisonObjectDataSource = new ComparisonObject(ComparisonObjectType.DataSource, ComparisonObjectStatus.MissingInTarget, dataSourceSource, null, MergeAction.Create);
                    _comparisonObjects.Add(comparisonObjectDataSource);
                    _comparisonObjectCount += 1;
                }
                else
                {
                    // there is a DataSource in the target with the same name at least
                    DataSource dataSourceTarget = _targetTabularModel.DataSources.FindByName(dataSourceSource.Name);
                    ComparisonObject comparisonObjectDataSource;

                    // check if DataSource object definition is different
                    if (dataSourceSource.ObjectDefinition != dataSourceTarget.ObjectDefinition)
                    {
                        comparisonObjectDataSource = new ComparisonObject(ComparisonObjectType.DataSource, ComparisonObjectStatus.DifferentDefinitions, dataSourceSource, dataSourceTarget, MergeAction.Update);
                        _comparisonObjects.Add(comparisonObjectDataSource);
                        _comparisonObjectCount += 1;
                    }
                    else
                    {
                        // they are equal, ...
                        comparisonObjectDataSource = new ComparisonObject(ComparisonObjectType.DataSource, ComparisonObjectStatus.SameDefinition, dataSourceSource, dataSourceTarget, MergeAction.Skip);
                        _comparisonObjects.Add(comparisonObjectDataSource);
                        _comparisonObjectCount += 1;
                    }
                }
            }

            foreach (DataSource dataSourceTarget in _targetTabularModel.DataSources)
            {
                // if target DataSource is Missing in Source, offer deletion
                if (!_sourceTabularModel.DataSources.ContainsName(dataSourceTarget.Name))
                {
                    ComparisonObject comparisonObjectDataSource = new ComparisonObject(ComparisonObjectType.DataSource, ComparisonObjectStatus.MissingInSource, null, dataSourceTarget, MergeAction.Delete);
                    _comparisonObjects.Add(comparisonObjectDataSource);
                    _comparisonObjectCount += 1;
                }
            }

            #endregion

            #region Tables

            foreach (Table tblSource in _sourceTabularModel.Tables)
            {
                // check if source is not in target
                TableCollection targetTablesForComparison = _targetTabularModel.Tables;

                if (!targetTablesForComparison.ContainsName(tblSource.Name))
                {
                    ComparisonObject comparisonObjectTable = new ComparisonObject(ComparisonObjectType.Table, ComparisonObjectStatus.MissingInTarget, tblSource, null, MergeAction.Create);
                    _comparisonObjects.Add(comparisonObjectTable);
                    _comparisonObjectCount += 1;

                    #region Relationships for table Missing in Target

                    // all relationships in source are not in target (the target table doesn't even exist)
                    foreach (Relationship relSource in tblSource.Relationships)
                    {
                        ComparisonObject comparisonObjectRelation = new ComparisonObject(ComparisonObjectType.Relationship, ComparisonObjectStatus.MissingInTarget, relSource, null, MergeAction.Create);
                        comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectRelation);
                        _comparisonObjectCount += 1;
                    }

                    #endregion

                    #region Measures / KPIs for Table that is Missing in Target

                    foreach (Measure measureSource in tblSource.Measures.FilterByTableName(tblSource.Name))
                    {
                        ComparisonObjectType comparisonObjectType = measureSource.IsKpi ? ComparisonObjectType.Kpi : ComparisonObjectType.Measure;
                        ComparisonObject comparisonObjectMeasure = new ComparisonObject(comparisonObjectType, ComparisonObjectStatus.MissingInTarget, measureSource, null, MergeAction.Create);
                        comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectMeasure);
                        _comparisonObjectCount += 1;
                    }

                    #endregion

                    #region CalculationItems for Table that is Missing in Target

                    foreach (CalculationItem calculationItemSource in tblSource.CalculationItems.FilterByTableName(tblSource.Name))
                    {
                        ComparisonObjectType comparisonObjectType = ComparisonObjectType.CalculationItem;
                        ComparisonObject comparisonObjectCalculationItem = new ComparisonObject(comparisonObjectType, ComparisonObjectStatus.MissingInTarget, calculationItemSource, null, MergeAction.Create);
                        comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectCalculationItem);
                        _comparisonObjectCount += 1;
                    }

                    #endregion
                }
                else
                {
                    //table name is in source and target

                    Table tblTarget = _targetTabularModel.Tables.FindByName(tblSource.Name);
                    ComparisonObject comparisonObjectTable;

                    if (tblSource.ObjectDefinition == tblTarget.ObjectDefinition)
                    {
                        comparisonObjectTable = new ComparisonObject(ComparisonObjectType.Table, ComparisonObjectStatus.SameDefinition, tblSource, tblTarget, MergeAction.Skip);
                        _comparisonObjects.Add(comparisonObjectTable);
                        _comparisonObjectCount += 1;
                    }
                    else
                    {
                        comparisonObjectTable = new ComparisonObject(ComparisonObjectType.Table, ComparisonObjectStatus.DifferentDefinitions, tblSource, tblTarget, MergeAction.Update);
                        _comparisonObjects.Add(comparisonObjectTable);
                        _comparisonObjectCount += 1;
                    }

                    #region Relationships source/target tables exist

                    foreach (Relationship relSource in tblSource.Relationships)
                    {
                        // check if source is not in target
                        if (!tblTarget.Relationships.ContainsName(relSource.Name)) //Using Name, not InternalName in case internal name is different
                        {
                            ComparisonObject comparisonObjectRelation = new ComparisonObject(ComparisonObjectType.Relationship, ComparisonObjectStatus.MissingInTarget, relSource, null, MergeAction.Create);
                            comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectRelation);
                            _comparisonObjectCount += 1;
                        }
                        else
                        {
                            //relationship is in source and target

                            Relationship relTarget = tblTarget.Relationships.FindByName(relSource.Name);
                            ComparisonObject comparisonObjectRelationship;

                            if (relSource.ObjectDefinition == relTarget.ObjectDefinition)
                            {
                                comparisonObjectRelationship = new ComparisonObject(ComparisonObjectType.Relationship, ComparisonObjectStatus.SameDefinition, relSource, relTarget, MergeAction.Skip);
                                comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectRelationship);
                                _comparisonObjectCount += 1;
                            }
                            else
                            {
                                comparisonObjectRelationship = new ComparisonObject(ComparisonObjectType.Relationship, ComparisonObjectStatus.DifferentDefinitions, relSource, relTarget, MergeAction.Update);
                                comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectRelationship);
                                _comparisonObjectCount += 1;
                            }
                        }
                    }

                    // see if relationships in target table that don't exist in source table
                    foreach (Relationship relTarget in tblTarget.Relationships)
                    {
                        // check if source is not in target
                        if (!tblSource.Relationships.ContainsName(relTarget.Name)) //Using Name, not InternalName in case internal name is different
                        {
                            ComparisonObject comparisonObjectRelation = new ComparisonObject(ComparisonObjectType.Relationship, ComparisonObjectStatus.MissingInSource, null, relTarget, MergeAction.Delete);
                            comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectRelation);
                            _comparisonObjectCount += 1;
                        }
                    }

                    #endregion

                    #region Measures / KPIs (table in source and target)

                    // see if matching measure in source and target
                    foreach (Measure measureSource in tblSource.Measures.FilterByTableName(tblSource.Name))
                    {
                        ComparisonObjectType comparisonObjectType = measureSource.IsKpi ? ComparisonObjectType.Kpi : ComparisonObjectType.Measure;

                        if (tblTarget.Measures.FilterByTableName(tblTarget.Name).ContainsName(measureSource.Name))
                        {
                            //Measure in source and target, so check definition
                            Measure measureTarget = tblTarget.Measures.FilterByTableName(tblTarget.Name).FindByName(measureSource.Name);
                            if (measureSource.ObjectDefinition == measureTarget.ObjectDefinition)
                            {
                                //Measure has same definition
                                ComparisonObject comparisonObjectMeasure = new ComparisonObject(comparisonObjectType, ComparisonObjectStatus.SameDefinition, measureSource, measureTarget, MergeAction.Skip);
                                comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectMeasure);
                                _comparisonObjectCount += 1;
                            }
                            else
                            {
                                //Measure has different definition
                                ComparisonObject comparisonObjectMeasure = new ComparisonObject(comparisonObjectType, ComparisonObjectStatus.DifferentDefinitions, measureSource, measureTarget, MergeAction.Update);
                                comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectMeasure);
                                _comparisonObjectCount += 1;
                            }
                        }
                        else
                        {
                            ComparisonObject comparisonObjectMeasure = new ComparisonObject(comparisonObjectType, ComparisonObjectStatus.MissingInTarget, measureSource, null, MergeAction.Create);
                            comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectMeasure);
                            _comparisonObjectCount += 1;
                        }
                    }
                    //now check if target contains measures Missing in Source
                    foreach (Measure measureTarget in tblTarget.Measures.FilterByTableName(tblTarget.Name))
                    {
                        ComparisonObjectType comparisonObjectType = measureTarget.IsKpi ? ComparisonObjectType.Kpi : ComparisonObjectType.Measure;
                        if (!tblSource.Measures.FilterByTableName(tblSource.Name).ContainsName(measureTarget.Name))
                        {
                            ComparisonObject comparisonObjectMeasure = new ComparisonObject(comparisonObjectType, ComparisonObjectStatus.MissingInSource, null, measureTarget, MergeAction.Delete);
                            comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectMeasure);
                            _comparisonObjectCount += 1;
                        }
                    }

                    #endregion

                    #region CalculationItems (table in source and target)

                    // see if matching calculationItem in source and target
                    foreach (CalculationItem calculationItemSource in tblSource.CalculationItems.FilterByTableName(tblSource.Name))
                    {
                        ComparisonObjectType comparisonObjectType = ComparisonObjectType.CalculationItem;

                        if (tblTarget.CalculationItems.FilterByTableName(tblTarget.Name).ContainsName(calculationItemSource.Name))
                        {
                            //CalculationItem in source and target, so check definition
                            CalculationItem calculationItemTarget = tblTarget.CalculationItems.FilterByTableName(tblTarget.Name).FindByName(calculationItemSource.Name);
                            if (calculationItemSource.ObjectDefinition == calculationItemTarget.ObjectDefinition)
                            {
                                //CalculationItem has same definition
                                ComparisonObject comparisonObjectCalculationItem = new ComparisonObject(comparisonObjectType, ComparisonObjectStatus.SameDefinition, calculationItemSource, calculationItemTarget, MergeAction.Skip);
                                comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectCalculationItem);
                                _comparisonObjectCount += 1;
                            }
                            else
                            {
                                //CalculationItem has different definition
                                ComparisonObject comparisonObjectCalculationItem = new ComparisonObject(comparisonObjectType, ComparisonObjectStatus.DifferentDefinitions, calculationItemSource, calculationItemTarget, MergeAction.Update);
                                comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectCalculationItem);
                                _comparisonObjectCount += 1;
                            }
                        }
                        else
                        {
                            ComparisonObject comparisonObjectCalculationItem = new ComparisonObject(comparisonObjectType, ComparisonObjectStatus.MissingInTarget, calculationItemSource, null, MergeAction.Create);
                            comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectCalculationItem);
                            _comparisonObjectCount += 1;
                        }
                    }
                    //now check if target contains calculationItems Missing in Source
                    foreach (CalculationItem calculationItemTarget in tblTarget.CalculationItems.FilterByTableName(tblTarget.Name))
                    {
                        ComparisonObjectType comparisonObjectType = ComparisonObjectType.CalculationItem;
                        if (!tblSource.CalculationItems.FilterByTableName(tblSource.Name).ContainsName(calculationItemTarget.Name))
                        {
                            ComparisonObject comparisonObjectCalculationItem = new ComparisonObject(comparisonObjectType, ComparisonObjectStatus.MissingInSource, null, calculationItemTarget, MergeAction.Delete);
                            comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectCalculationItem);
                            _comparisonObjectCount += 1;
                        }
                    }

                    #endregion
                }
            }

            foreach (Table tblTarget in _targetTabularModel.Tables)
            {
                // check if target is not in source
                if (!_sourceTabularModel.Tables.ContainsName(tblTarget.Name))
                {
                    ComparisonObject comparisonObjectTable = new ComparisonObject(ComparisonObjectType.Table, ComparisonObjectStatus.MissingInSource, null, tblTarget, MergeAction.Delete);
                    _comparisonObjects.Add(comparisonObjectTable);
                    _comparisonObjectCount += 1;

                    #region Relationships for table Missing in Source

                    // all relationships in target are not in source (the source table doesn't even exist)
                    foreach (Relationship relTarget in tblTarget.Relationships)
                    {
                        ComparisonObject comparisonObjectRelation = new ComparisonObject(ComparisonObjectType.Relationship, ComparisonObjectStatus.MissingInSource, null, relTarget, MergeAction.Delete);
                        comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectRelation);
                        _comparisonObjectCount += 1;
                    }

                    #endregion

                    #region Measures for Table that is Missing in Source

                    foreach (Measure measureTarget in tblTarget.Measures.FilterByTableName(tblTarget.Name))
                    {
                        ComparisonObjectType comparisonObjectType = measureTarget.IsKpi ? ComparisonObjectType.Kpi : ComparisonObjectType.Measure;
                        ComparisonObject comparisonObjectMeasure = new ComparisonObject(comparisonObjectType, ComparisonObjectStatus.MissingInSource, null, measureTarget, MergeAction.Delete);
                        comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectMeasure);
                        _comparisonObjectCount += 1;
                    }

                    #endregion

                    #region CalculationItems for Table that is Missing in Source

                    foreach (CalculationItem calculationItemTarget in tblTarget.CalculationItems.FilterByTableName(tblTarget.Name))
                    {
                        ComparisonObjectType comparisonObjectType = ComparisonObjectType.CalculationItem;
                        ComparisonObject comparisonObjectCalculationItem = new ComparisonObject(comparisonObjectType, ComparisonObjectStatus.MissingInSource, null, calculationItemTarget, MergeAction.Delete);
                        comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectCalculationItem);
                        _comparisonObjectCount += 1;
                    }

                    #endregion
                }
            }
            
            #endregion

            #region Expressions

            foreach (Expression expressionSource in _sourceTabularModel.Expressions)
            {
                // check if source is not in target
                if (!_targetTabularModel.Expressions.ContainsName(expressionSource.Name))
                {
                    ComparisonObject comparisonObjectExpression = new ComparisonObject(ComparisonObjectType.Expression, ComparisonObjectStatus.MissingInTarget, expressionSource, null, MergeAction.Create);
                    _comparisonObjects.Add(comparisonObjectExpression);
                    _comparisonObjectCount += 1;
                }
                else
                {
                    // there is a expression in the target with the same name at least
                    Expression expressionTarget = _targetTabularModel.Expressions.FindByName(expressionSource.Name);
                    ComparisonObject comparisonObjectExpression;

                    // check if expression object definition is different
                    if (expressionSource.ObjectDefinition != expressionTarget.ObjectDefinition)
                    {
                        comparisonObjectExpression = new ComparisonObject(ComparisonObjectType.Expression, ComparisonObjectStatus.DifferentDefinitions, expressionSource, expressionTarget, MergeAction.Update);
                        _comparisonObjects.Add(comparisonObjectExpression);
                        _comparisonObjectCount += 1;
                    }
                    else
                    {
                        // they are equal, ...
                        comparisonObjectExpression = new ComparisonObject(ComparisonObjectType.Expression, ComparisonObjectStatus.SameDefinition, expressionSource, expressionTarget, MergeAction.Skip);
                        _comparisonObjects.Add(comparisonObjectExpression);
                        _comparisonObjectCount += 1;
                    }
                }
            }

            foreach (Expression expressionTarget in _targetTabularModel.Expressions)
            {
                // if target expression is Missing in Source, offer deletion
                if (!_sourceTabularModel.Expressions.ContainsName(expressionTarget.Name))
                {
                    ComparisonObject comparisonObjectExpression = new ComparisonObject(ComparisonObjectType.Expression, ComparisonObjectStatus.MissingInSource, null, expressionTarget, MergeAction.Delete);
                    _comparisonObjects.Add(comparisonObjectExpression);
                    _comparisonObjectCount += 1;
                }
            }

            #endregion

            #region Perspectives

            if (_comparisonInfo.OptionsInfo.OptionPerspectives)
            {
                foreach (Perspective perspectiveSource in _sourceTabularModel.Perspectives)
                {
                    // check if source is not in target
                    if (!_targetTabularModel.Perspectives.ContainsName(perspectiveSource.Name))
                    {
                        ComparisonObject comparisonObjectPerspective = new ComparisonObject(ComparisonObjectType.Perspective, ComparisonObjectStatus.MissingInTarget, perspectiveSource, null, MergeAction.Create);
                        _comparisonObjects.Add(comparisonObjectPerspective);
                        _comparisonObjectCount += 1;
                    }
                    else
                    {
                        // there is a perspective in the target with the same name at least
                        Perspective perspectiveTarget = _targetTabularModel.Perspectives.FindByName(perspectiveSource.Name);
                        ComparisonObject comparisonObjectPerspective;

                        // check if perspective object definition is different
                        //if (perspectiveSource.ObjectDefinition != perspectiveTarget.ObjectDefinition)
                        if ( (_comparisonInfo.OptionsInfo.OptionMergePerspectives && perspectiveTarget.ContainsOtherPerspectiveSelections(perspectiveSource)) ||
                             (!_comparisonInfo.OptionsInfo.OptionMergePerspectives && perspectiveTarget.ContainsOtherPerspectiveSelections(perspectiveSource) && perspectiveSource.ContainsOtherPerspectiveSelections(perspectiveTarget)) )
                        {
                            // they are equal, ...
                            comparisonObjectPerspective = new ComparisonObject(ComparisonObjectType.Perspective, ComparisonObjectStatus.SameDefinition, perspectiveSource, perspectiveTarget, MergeAction.Skip);
                            _comparisonObjects.Add(comparisonObjectPerspective);
                            _comparisonObjectCount += 1;
                        }
                        else
                        {
                            comparisonObjectPerspective = new ComparisonObject(ComparisonObjectType.Perspective, ComparisonObjectStatus.DifferentDefinitions, perspectiveSource, perspectiveTarget, MergeAction.Update);
                            _comparisonObjects.Add(comparisonObjectPerspective);
                            _comparisonObjectCount += 1;
                        }
                    }
                }

                foreach (Perspective perspectiveTarget in _targetTabularModel.Perspectives)
                {
                    // if target perspective is Missing in Source, offer deletion
                    if (!_sourceTabularModel.Perspectives.ContainsName(perspectiveTarget.Name))
                    {
                        ComparisonObject comparisonObjectPerspective = new ComparisonObject(ComparisonObjectType.Perspective, ComparisonObjectStatus.MissingInSource, null, perspectiveTarget, MergeAction.Delete);
                        _comparisonObjects.Add(comparisonObjectPerspective);
                        _comparisonObjectCount += 1;
                    }
                }
            }

            #endregion

            #region Cultures

            if (_comparisonInfo.OptionsInfo.OptionCultures)
            {
                foreach (Culture cultureSource in _sourceTabularModel.Cultures)
                {
                    // check if source is not in target
                    if (!_targetTabularModel.Cultures.ContainsName(cultureSource.Name))
                    {
                        ComparisonObject comparisonObjectCulture = new ComparisonObject(ComparisonObjectType.Culture, ComparisonObjectStatus.MissingInTarget, cultureSource, null, MergeAction.Create);
                        _comparisonObjects.Add(comparisonObjectCulture);
                        _comparisonObjectCount += 1;
                    }
                    else
                    {
                        // there is a culture in the target with the same name at least
                        Culture cultureTarget = _targetTabularModel.Cultures.FindByName(cultureSource.Name);
                        ComparisonObject comparisonObjectCulture;

                        string sourceLinguisticMetadata = String.Empty;
                        string targetLinguisticMetadata = String.Empty;
                        if (cultureSource.TomCulture?.LinguisticMetadata?.Content != null)
                            sourceLinguisticMetadata = Newtonsoft.Json.Linq.JToken.Parse(cultureSource.TomCulture.LinguisticMetadata.Content).ToString();
                        if (cultureTarget.TomCulture?.LinguisticMetadata?.Content != null)
                            targetLinguisticMetadata = Newtonsoft.Json.Linq.JToken.Parse(cultureTarget.TomCulture.LinguisticMetadata.Content).ToString();

                        // check if culture object definition is different
                        //if (cultureSource.ObjectDefinition != cultureTarget.ObjectDefinition)
                        if ( (
                                 (_comparisonInfo.OptionsInfo.OptionMergeCultures && cultureTarget.ContainsOtherCultureTranslations(cultureSource)) ||
                                 (!_comparisonInfo.OptionsInfo.OptionMergeCultures && cultureTarget.ContainsOtherCultureTranslations(cultureSource) && cultureSource.ContainsOtherCultureTranslations(cultureTarget))
                             ) &&
                             (sourceLinguisticMetadata == targetLinguisticMetadata)
                           )
                        {
                            // they are equal, ...
                            comparisonObjectCulture = new ComparisonObject(ComparisonObjectType.Culture, ComparisonObjectStatus.SameDefinition, cultureSource, cultureTarget, MergeAction.Skip);
                            _comparisonObjects.Add(comparisonObjectCulture);
                            _comparisonObjectCount += 1;
                        }
                        else
                        {
                            comparisonObjectCulture = new ComparisonObject(ComparisonObjectType.Culture, ComparisonObjectStatus.DifferentDefinitions, cultureSource, cultureTarget, MergeAction.Update);
                            _comparisonObjects.Add(comparisonObjectCulture);
                            _comparisonObjectCount += 1;
                        }
                    }
                }

                foreach (Culture cultureTarget in _targetTabularModel.Cultures)
                {
                    // if target culture is Missing in Source, offer deletion
                    if (!_sourceTabularModel.Cultures.ContainsName(cultureTarget.Name))
                    {
                        ComparisonObject comparisonObjectCulture = new ComparisonObject(ComparisonObjectType.Culture, ComparisonObjectStatus.MissingInSource, null, cultureTarget, MergeAction.Delete);
                        _comparisonObjects.Add(comparisonObjectCulture);
                        _comparisonObjectCount += 1;
                    }
                }
            }

            #endregion

            #region Roles

            if (_comparisonInfo.OptionsInfo.OptionRoles)
            {
                foreach (Role roleSource in _sourceTabularModel.Roles)
                {
                    // check if source is not in target
                    if (!_targetTabularModel.Roles.ContainsName(roleSource.Name))
                    {
                        ComparisonObject comparisonObjectRole = new ComparisonObject(ComparisonObjectType.Role, ComparisonObjectStatus.MissingInTarget, roleSource, null, MergeAction.Create);
                        _comparisonObjects.Add(comparisonObjectRole);
                        _comparisonObjectCount += 1;
                    }
                    else
                    {
                        // there is a role in the target with the same name at least
                        Role roleTarget = _targetTabularModel.Roles.FindByName(roleSource.Name);
                        ComparisonObject comparisonObjectRole;

                        // check if role object definition is different
                        if (roleSource.ObjectDefinition != roleTarget.ObjectDefinition)
                        {
                            comparisonObjectRole = new ComparisonObject(ComparisonObjectType.Role, ComparisonObjectStatus.DifferentDefinitions, roleSource, roleTarget, MergeAction.Update);
                            _comparisonObjects.Add(comparisonObjectRole);
                            _comparisonObjectCount += 1;
                        }
                        else
                        {
                            // they are equal, ...
                            comparisonObjectRole = new ComparisonObject(ComparisonObjectType.Role, ComparisonObjectStatus.SameDefinition, roleSource, roleTarget, MergeAction.Skip);
                            _comparisonObjects.Add(comparisonObjectRole);
                            _comparisonObjectCount += 1;
                        }
                    }
                }

                foreach (Role roleTarget in _targetTabularModel.Roles)
                {
                    // if target role is Missing in Source, offer deletion
                    if (!_sourceTabularModel.Roles.ContainsName(roleTarget.Name))
                    {
                        ComparisonObject comparisonObjectRole = new ComparisonObject(ComparisonObjectType.Role, ComparisonObjectStatus.MissingInSource, null, roleTarget, MergeAction.Delete);
                        _comparisonObjects.Add(comparisonObjectRole);
                        _comparisonObjectCount += 1;
                    }
                }
            }

            #endregion

            #region Sorting

            _comparisonObjects.Sort();
            foreach (ComparisonObject childComparisonObject in _comparisonObjects)
            {
                childComparisonObject.ChildComparisonObjects.Sort();
                foreach (ComparisonObject grandChildComparisonObject in childComparisonObject.ChildComparisonObjects)
                {
                    grandChildComparisonObject.ChildComparisonObjects.Sort();
                }
            }

            #endregion

            this.RefreshComparisonObjectsFromSkipSelections();

            _uncommitedChanges = false;
            _lastSourceSchemaUpdate = _sourceTabularModel.TomDatabase.LastSchemaUpdate;
            _lastTargetSchemaUpdate = _targetTabularModel.TomDatabase.LastSchemaUpdate;
        }