public override void CompareTabularModels()

in BismNormalizer/BismNormalizer/TabularCompare/MultidimensionalMetadata/Comparison.cs [80:659]


        public override void CompareTabularModels()
        {
            _comparisonObjectCount = 0;

            #region Data Sources

            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, dataSourceSource.Name, dataSourceSource.Id, dataSourceSource.ObjectDefinition, MergeAction.Create, null, "", "", "");
                    _comparisonObjects.Add(comparisonObjectDataSource);
                    _comparisonObjectCount += 1;

                    #region Tables for DataSource that is Missing in Target

                    foreach (Table tblSource in _sourceTabularModel.Tables.FilterByDataSourceId(dataSourceSource.Id))
                    {
                        ComparisonObject comparisonObjectTable = new ComparisonObject(ComparisonObjectType.Table, ComparisonObjectStatus.MissingInTarget, tblSource, tblSource.Name, tblSource.Id, tblSource.ObjectDefinition, MergeAction.Create, null, "", "", "");
                        comparisonObjectDataSource.ChildComparisonObjects.Add(comparisonObjectTable);
                        _comparisonObjectCount += 1;

                        #region Relationships for Table that is Missing in Target

                        foreach (Relationship relSource in tblSource.Relationships)
                        {
                            ComparisonObject comparisonObjectRelation = new ComparisonObject(ComparisonObjectType.Relationship, ComparisonObjectStatus.MissingInTarget, relSource, "        " + relSource.Name, relSource.Id, relSource.ObjectDefinition, MergeAction.Create, null, "", "", "");
                            comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectRelation);
                            _comparisonObjectCount += 1;
                        }

                        #endregion

                        #region Measures for Table that is Missing in Target

                        foreach (Measure measureSource in _sourceTabularModel.Measures.FilterByTableName(tblSource.Name))
                        {
                            ComparisonObject comparisonObjectMeasure = new ComparisonObject(ComparisonObjectType.Measure, ComparisonObjectStatus.MissingInTarget, measureSource, "        " + measureSource.Name, measureSource.Id, measureSource.ObjectDefinition, MergeAction.Create, null, "", "", "");
                            comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectMeasure);
                            _comparisonObjectCount += 1;
                        }

                        #endregion

                        #region KPIs for Table that is Missing in Target

                        foreach (Kpi kpiSource in _sourceTabularModel.Kpis.FilterByTableName(tblSource.Name))
                        {
                            ComparisonObject comparisonObjectKpi = new ComparisonObject(ComparisonObjectType.Kpi, ComparisonObjectStatus.MissingInTarget, kpiSource, "        " + kpiSource.Name, kpiSource.Id, kpiSource.ObjectDefinition, MergeAction.Create, null, "", "", "");
                            comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectKpi);
                            _comparisonObjectCount += 1;
                        }

                        #endregion
                    }

                    #endregion
                }
                else
                {
                    // there is a datasource in the target with the same name at least
                    DataSource dataSourceTarget = _targetTabularModel.DataSources.FindByName(dataSourceSource.Name);
                    if (dataSourceSource.Id != dataSourceTarget.Id)
                    {
                        dataSourceSource.SubstituteId = dataSourceTarget.Id;
                    }
                    ComparisonObject comparisonObjectDataSource;
                    
                    // check if datasource object definition is different
                    if (dataSourceSource.ObjectDefinition != dataSourceTarget.ObjectDefinition)
                    {
                        comparisonObjectDataSource = new ComparisonObject(ComparisonObjectType.DataSource, ComparisonObjectStatus.DifferentDefinitions, dataSourceSource, dataSourceSource.Name, dataSourceSource.Id, dataSourceSource.ObjectDefinition, MergeAction.Update, dataSourceTarget, dataSourceTarget.Name, dataSourceTarget.Id, dataSourceTarget.ObjectDefinition);
                        _comparisonObjects.Add(comparisonObjectDataSource);
                        _comparisonObjectCount += 1;
                    }
                    else
                    {
                        // they are equal, ...
                        comparisonObjectDataSource = new ComparisonObject(ComparisonObjectType.DataSource, ComparisonObjectStatus.SameDefinition, dataSourceSource, dataSourceSource.Name, dataSourceSource.Id, dataSourceSource.ObjectDefinition, MergeAction.Skip, dataSourceTarget, dataSourceTarget.Name, dataSourceTarget.Id, dataSourceTarget.ObjectDefinition);
                        _comparisonObjects.Add(comparisonObjectDataSource);
                        _comparisonObjectCount += 1;
                    }

                    #region Tables where source/target datasources exist

                    foreach (Table tblSource in _sourceTabularModel.Tables.FilterByDataSourceId(dataSourceSource.Id))
                    {
                        // check if source is not in target
                        if (!_targetTabularModel.Tables.FilterByDataSourceId(dataSourceTarget.Id).ContainsName(tblSource.Name))
                        {
                            ComparisonObject comparisonObjectTable = new ComparisonObject(ComparisonObjectType.Table, ComparisonObjectStatus.MissingInTarget, tblSource, tblSource.Name, tblSource.Id, tblSource.ObjectDefinition, MergeAction.Create, null, "", "", "");
                            comparisonObjectDataSource.ChildComparisonObjects.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, "        " + relSource.Name, relSource.Id, relSource.ObjectDefinition, MergeAction.Create, null, "", "", "");
                                comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectRelation);
                                _comparisonObjectCount += 1;
                            }

                            #endregion

                            #region Measures for Table that is Missing in Target

                            foreach (Measure measureSource in _sourceTabularModel.Measures.FilterByTableName(tblSource.Name))
                            {
                                ComparisonObject comparisonObjectMeasure = new ComparisonObject(ComparisonObjectType.Measure, ComparisonObjectStatus.MissingInTarget, measureSource, "        " + measureSource.Name, measureSource.Id, measureSource.ObjectDefinition, MergeAction.Create, null, "", "", "");
                                comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectMeasure);
                                _comparisonObjectCount += 1;
                            }

                            #endregion

                            #region Kpis for Table that is Missing in Target

                            foreach (Kpi kpiSource in _sourceTabularModel.Kpis.FilterByTableName(tblSource.Name))
                            {
                                ComparisonObject comparisonObjectKpi = new ComparisonObject(ComparisonObjectType.Kpi, ComparisonObjectStatus.MissingInTarget, kpiSource, "        " + kpiSource.Name, kpiSource.Id, kpiSource.ObjectDefinition, MergeAction.Create, null, "", "", "");
                                comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectKpi);
                                _comparisonObjectCount += 1;
                            }

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

                            Table tblTarget = _targetTabularModel.Tables.FindByName(tblSource.Name);
                            if (tblSource.Id != tblTarget.Id)
                            {
                                tblSource.SubstituteId = tblTarget.Id;
                            }
                            ComparisonObject comparisonObjectTable;

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

                            #region Relationships (table in source and target)

                            // see if matching relationhip in source and target
                            foreach (Relationship relSource in tblSource.Relationships)
                            {
                                bool foundMatch = false;
                                foreach (Relationship relTarget in tblTarget.Relationships)
                                {
                                    if (relSource.ObjectDefinition == relTarget.ObjectDefinition)
                                    {
                                        ComparisonObject comparisonObjectRelation = new ComparisonObject(ComparisonObjectType.Relationship, ComparisonObjectStatus.SameDefinition, relSource, "        " + relSource.Name, relSource.Id, relSource.ObjectDefinition, MergeAction.Skip, relTarget, "        " + relTarget.Name, relTarget.Id, relTarget.ObjectDefinition);
                                        comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectRelation);
                                        _comparisonObjectCount += 1;
                                        foundMatch = true;
                                        break;
                                    }
                                }
                                //the relationship in the source table doesnt' exist in the target table
                                if (!foundMatch)
                                {
                                    ComparisonObject comparisonObjectRelation = new ComparisonObject(ComparisonObjectType.Relationship, ComparisonObjectStatus.MissingInTarget, relSource, "        " + relSource.Name, relSource.Id, relSource.ObjectDefinition, MergeAction.Create, null, "", "", "");
                                    comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectRelation);
                                    _comparisonObjectCount += 1;
                                }
                            }

                            // see if relationships in target table that don't exist in source table
                            foreach (Relationship relTarget in tblTarget.Relationships)
                            {
                                bool foundMatch = false;
                                foreach (Relationship relSource in tblSource.Relationships)
                                {
                                    if (relSource.ObjectDefinition == relTarget.ObjectDefinition)
                                    {
                                        foundMatch = true;
                                        break;
                                    }
                                }
                                if (!foundMatch)
                                {
                                    ComparisonObject comparisonObjectRelation = new ComparisonObject(ComparisonObjectType.Relationship, ComparisonObjectStatus.MissingInSource, null, "", "", "", MergeAction.Delete, relTarget, "        " + relTarget.Name, relTarget.Id, relTarget.ObjectDefinition);
                                    comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectRelation);
                                    _comparisonObjectCount += 1;
                                }
                            }

                            #endregion

                            #region Measures (table in source and target)

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

                            #endregion

                            #region Kpis (table in source and target)

                            // see if matching kpi in source and target
                            foreach (Kpi kpiSource in _sourceTabularModel.Kpis.FilterByTableName(tblSource.Name))
                            {
                                if (_targetTabularModel.Kpis.FilterByTableName(tblTarget.Name).ContainsName(kpiSource.Name))
                                {
                                    //Kpi in source and target, so check definition
                                    Kpi kpiTarget = _targetTabularModel.Kpis.FilterByTableName(tblTarget.Name).FindByName(kpiSource.Name);
                                    if (kpiSource.ObjectDefinition == kpiTarget.ObjectDefinition)
                                    {
                                        //Kpi has same definition
                                        ComparisonObject comparisonObjectKpi = new ComparisonObject(ComparisonObjectType.Kpi, ComparisonObjectStatus.SameDefinition, kpiSource, "        " + kpiSource.Name, kpiSource.Id, kpiSource.ObjectDefinition, MergeAction.Skip, kpiTarget, "        " + kpiTarget.Name, kpiTarget.Id, kpiTarget.ObjectDefinition);
                                        comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectKpi);
                                        _comparisonObjectCount += 1;
                                    }
                                    else
                                    {
                                        //Kpi has different definition
                                        ComparisonObject comparisonObjectKpi = new ComparisonObject(ComparisonObjectType.Kpi, ComparisonObjectStatus.DifferentDefinitions, kpiSource, "        " + kpiSource.Name, kpiSource.Id, kpiSource.ObjectDefinition, MergeAction.Update, kpiTarget, "        " + kpiTarget.Name, kpiTarget.Id, kpiTarget.ObjectDefinition);
                                        comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectKpi);
                                        _comparisonObjectCount += 1;
                                    }
                                }
                                else
                                {
                                    ComparisonObject comparisonObjectKpi = new ComparisonObject(ComparisonObjectType.Kpi, ComparisonObjectStatus.MissingInTarget, kpiSource, "        " + kpiSource.Name, kpiSource.Id, kpiSource.ObjectDefinition, MergeAction.Create, null, "", "", "");
                                    comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectKpi);
                                    _comparisonObjectCount += 1;
                                }
                            }
                            //now check if target contains kpis Missing in Source
                            foreach (Kpi kpiTarget in _targetTabularModel.Kpis.FilterByTableName(tblTarget.Name))
                            {
                                if (!_sourceTabularModel.Kpis.FilterByTableName(tblSource.Name).ContainsName(kpiTarget.Name))
                                {
                                    ComparisonObject comparisonObjectKpi = new ComparisonObject(ComparisonObjectType.Kpi, ComparisonObjectStatus.MissingInSource, null, "", "", "", MergeAction.Delete, kpiTarget, "        " + kpiTarget.Name, kpiTarget.Id, kpiTarget.ObjectDefinition);
                                    comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectKpi);
                                    _comparisonObjectCount += 1;
                                }
                            }

                            #endregion
                        }
                    }

                    foreach (Table tblTarget in _targetTabularModel.Tables.FilterByDataSourceId(dataSourceTarget.Id))
                    {
                        // check if target is not in source
                        if (!_sourceTabularModel.Tables.FilterByDataSourceId(dataSourceSource.Id).ContainsName(tblTarget.Name))
                        {
                            ComparisonObject comparisonObjectTable = new ComparisonObject(ComparisonObjectType.Table, ComparisonObjectStatus.MissingInSource, null, "", "", "", MergeAction.Delete, tblTarget, tblTarget.Name, tblTarget.Id, tblTarget.ObjectDefinition);
                            comparisonObjectDataSource.ChildComparisonObjects.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, "", "", "", MergeAction.Delete, relTarget, "        " + relTarget.Name, relTarget.Id, relTarget.ObjectDefinition);
                                comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectRelation);
                                _comparisonObjectCount += 1;
                            }

                            #endregion

                            #region Measures for Table that is Missing in Source

                            foreach (Measure measureTarget in _targetTabularModel.Measures.FilterByTableName(tblTarget.Name))
                            {
                                ComparisonObject comparisonObjectMeasure = new ComparisonObject(ComparisonObjectType.Measure, ComparisonObjectStatus.MissingInSource, null, "", "", "", MergeAction.Delete, measureTarget, "        " + measureTarget.Name, measureTarget.Id, measureTarget.ObjectDefinition);
                                comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectMeasure);
                                _comparisonObjectCount += 1;
                            }

                            #endregion

                            #region Kpis for Table that is Missing in Source

                            foreach (Kpi kpiTarget in _targetTabularModel.Kpis.FilterByTableName(tblTarget.Name))
                            {
                                ComparisonObject comparisonObjectKpi = new ComparisonObject(ComparisonObjectType.Kpi, ComparisonObjectStatus.MissingInSource, null, "", "", "", MergeAction.Delete, kpiTarget, "        " + kpiTarget.Name, kpiTarget.Id, kpiTarget.ObjectDefinition);
                                comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectKpi);
                                _comparisonObjectCount += 1;
                            }

                            #endregion
                        }
                    }
                    #endregion
                }
            }

            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, "", "", "", MergeAction.Delete, dataSourceTarget, dataSourceTarget.Name, dataSourceTarget.Id, dataSourceTarget.ObjectDefinition);
                    _comparisonObjects.Add(comparisonObjectDataSource);
                    _comparisonObjectCount += 1;

                    #region Tables for DataSource that is Missing in Source

                    foreach (Table tblTarget in _targetTabularModel.Tables.FilterByDataSourceId(dataSourceTarget.Id))
                    {
                        ComparisonObject comparisonObjectTable = new ComparisonObject(ComparisonObjectType.Table, ComparisonObjectStatus.MissingInSource, null, "", "", "", MergeAction.Delete, tblTarget, tblTarget.Name, tblTarget.Id, tblTarget.ObjectDefinition);
                        comparisonObjectDataSource.ChildComparisonObjects.Add(comparisonObjectTable);
                        _comparisonObjectCount += 1;

                        #region Relationships for Table that is Missing in Source

                        foreach (Relationship relTarget in tblTarget.Relationships)
                        {
                            ComparisonObject comparisonObjectRelation = new ComparisonObject(ComparisonObjectType.Relationship, ComparisonObjectStatus.MissingInSource, null, "", "", "", MergeAction.Delete, relTarget, "        " + relTarget.Name, relTarget.Id, relTarget.ObjectDefinition);
                            comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectRelation);
                            _comparisonObjectCount += 1;
                        }

                        #endregion

                        #region Measures for Table that is Missing in Source

                        foreach (Measure measureTarget in _targetTabularModel.Measures.FilterByTableName(tblTarget.Name))
                        {
                            ComparisonObject comparisonObjectMeasure = new ComparisonObject(ComparisonObjectType.Measure, ComparisonObjectStatus.MissingInSource, null, "", "", "", MergeAction.Delete, measureTarget, "        " + measureTarget.Name, measureTarget.Id, measureTarget.ObjectDefinition);
                            comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectMeasure);
                            _comparisonObjectCount += 1;
                        }

                        #endregion

                        #region Kpis for Table that is Missing in Source

                        foreach (Kpi kpiTarget in _targetTabularModel.Kpis.FilterByTableName(tblTarget.Name))
                        {
                            ComparisonObject comparisonObjectKpi = new ComparisonObject(ComparisonObjectType.Kpi, ComparisonObjectStatus.MissingInSource, null, "", "", "", MergeAction.Delete, kpiTarget, "        " + kpiTarget.Name, kpiTarget.Id, kpiTarget.ObjectDefinition);
                            comparisonObjectTable.ChildComparisonObjects.Add(comparisonObjectKpi);
                            _comparisonObjectCount += 1;
                        }

                        #endregion
                    }

                    #endregion
                }
            }

            #endregion

            #region Actions

            if (_comparisonInfo.OptionsInfo.OptionActions)
            {
                foreach (Action actionSource in _sourceTabularModel.Actions)
                {
                    // check if source is not in target
                    if (!_targetTabularModel.Actions.ContainsName(actionSource.Name))
                    {
                        ComparisonObject comparisonObjectAction = new ComparisonObject(ComparisonObjectType.Action, ComparisonObjectStatus.MissingInTarget, actionSource, actionSource.Name, actionSource.Id, actionSource.ObjectDefinition, MergeAction.Create, null, "", "", "");
                        _comparisonObjects.Add(comparisonObjectAction);
                        _comparisonObjectCount += 1;
                    }
                    else
                    {
                        // there is a Action in the target with the same name at least
                        Action actionTarget = _targetTabularModel.Actions.FindByName(actionSource.Name);
                        if (actionSource.Id != actionTarget.Id)
                        {
                            actionSource.SubstituteId = actionTarget.Id;
                        }
                        ComparisonObject comparisonObjectAction;

                        // check if Action object definition is different
                        if (actionSource.ObjectDefinition != actionTarget.ObjectDefinition)
                        {
                            comparisonObjectAction = new ComparisonObject(ComparisonObjectType.Action, ComparisonObjectStatus.DifferentDefinitions, actionSource, actionSource.Name, actionSource.Id, actionSource.ObjectDefinition, MergeAction.Update, actionTarget, actionTarget.Name, actionTarget.Id, actionTarget.ObjectDefinition);
                            _comparisonObjects.Add(comparisonObjectAction);
                            _comparisonObjectCount += 1;
                        }
                        else
                        {
                            // they are equal, ...
                            comparisonObjectAction = new ComparisonObject(ComparisonObjectType.Action, ComparisonObjectStatus.SameDefinition, actionSource, actionSource.Name, actionSource.Id, actionSource.ObjectDefinition, MergeAction.Skip, actionTarget, actionTarget.Name, actionTarget.Id, actionTarget.ObjectDefinition);
                            _comparisonObjects.Add(comparisonObjectAction);
                            _comparisonObjectCount += 1;
                        }
                    }
                }

                foreach (Action actionTarget in _targetTabularModel.Actions)
                {
                    // if target Action is Missing in Source, offer deletion
                    if (!_sourceTabularModel.Actions.ContainsName(actionTarget.Name))
                    {
                        ComparisonObject comparisonObjectAction = new ComparisonObject(ComparisonObjectType.Action, ComparisonObjectStatus.MissingInSource, null, "", "", "", MergeAction.Delete, actionTarget, actionTarget.Name, actionTarget.Id, actionTarget.ObjectDefinition);
                        _comparisonObjects.Add(comparisonObjectAction);
                        _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, perspectiveSource.Name, perspectiveSource.Id, perspectiveSource.ObjectDefinition, MergeAction.Create, null, "", "", "");
                        _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);
                        if (perspectiveSource.Id != perspectiveTarget.Id)
                        {
                            perspectiveSource.SubstituteId = perspectiveTarget.Id;
                        }
                        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, perspectiveSource.Name, perspectiveSource.Id, perspectiveSource.ObjectDefinition, MergeAction.Skip, perspectiveTarget, perspectiveTarget.Name, perspectiveTarget.Id, perspectiveTarget.ObjectDefinition);
                            _comparisonObjects.Add(comparisonObjectPerspective);
                            _comparisonObjectCount += 1;
                        }
                        else
                        {
                            comparisonObjectPerspective = new ComparisonObject(ComparisonObjectType.Perspective, ComparisonObjectStatus.DifferentDefinitions, perspectiveSource, perspectiveSource.Name, perspectiveSource.Id, perspectiveSource.ObjectDefinition, MergeAction.Update, perspectiveTarget, perspectiveTarget.Name, perspectiveTarget.Id, perspectiveTarget.ObjectDefinition);
                            _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, "", "", "", MergeAction.Delete, perspectiveTarget, perspectiveTarget.Name, perspectiveTarget.Id, perspectiveTarget.ObjectDefinition);
                        _comparisonObjects.Add(comparisonObjectPerspective);
                        _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, roleSource.Name, roleSource.Id, roleSource.ObjectDefinition, MergeAction.Create, null, "", "", "");
                        _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);
                        if (roleSource.Id != roleTarget.Id)
                        {
                            roleSource.SubstituteId = roleTarget.Id;
                        }
                        ComparisonObject comparisonObjectRole;

                        // check if role object definition is different
                        if (roleSource.ObjectDefinition != roleTarget.ObjectDefinition)
                        {
                            comparisonObjectRole = new ComparisonObject(ComparisonObjectType.Role, ComparisonObjectStatus.DifferentDefinitions, roleSource, roleSource.Name, roleSource.Id, roleSource.ObjectDefinition, MergeAction.Update, roleTarget, roleTarget.Name, roleTarget.Id, roleTarget.ObjectDefinition);
                            _comparisonObjects.Add(comparisonObjectRole);
                            _comparisonObjectCount += 1;
                        }
                        else
                        {
                            // they are equal, ...
                            comparisonObjectRole = new ComparisonObject(ComparisonObjectType.Role, ComparisonObjectStatus.SameDefinition, roleSource, roleSource.Name, roleSource.Id, roleSource.ObjectDefinition, MergeAction.Skip, roleTarget, roleTarget.Name, roleTarget.Id, roleTarget.ObjectDefinition);
                            _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, "", "", "", MergeAction.Delete, roleTarget, roleTarget.Name, roleTarget.Id, roleTarget.ObjectDefinition);
                        _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.AmoDatabase.LastSchemaUpdate;
            _lastTargetSchemaUpdate = _targetTabularModel.AmoDatabase.LastSchemaUpdate;
        }