private static void CompareNavigationProperties(ModuleCollectionChange changes, DataModelModuleCollection originalModules, DataModelModuleCollection targetModules)
        {
            List <NavigationProperty> sourceNavigationProperties = originalModules.
                                                                   SelectMany(tuple => tuple.ResourceTypes).
                                                                   SelectMany(tuple => tuple.NavigationProperties).ToList();

            List <NavigationProperty> targetNavigationProperties = targetModules.
                                                                   SelectMany(tuple => tuple.ResourceTypes).
                                                                   SelectMany(tuple => tuple.NavigationProperties).ToList();

            // Compute added navigation properties.
            List <Guid> addedGuids = new List <Guid>();

            addedGuids.AddRange(targetNavigationProperties.Select(tuple => tuple.Id).
                                Except(sourceNavigationProperties.Select(tuple => tuple.Id)));

            changes.AddedNavigationProperties.AddRange(targetNavigationProperties.
                                                       Where(tuple => addedGuids.Contains(tuple.Id)));

            // Compute deleted navigation properties.
            List <Guid> removedGuids = new List <Guid>();

            removedGuids.AddRange(originalModules.SelectMany(tuple => tuple.ResourceTypes).
                                  SelectMany(tuple => tuple.NavigationProperties).Select(tuple => tuple.Id).
                                  Except
                                      (targetModules.SelectMany(tuple => tuple.ResourceTypes).
                                      SelectMany(tuple => tuple.NavigationProperties).Select(tuple => tuple.Id)));

            changes.DeletedNavigationProperties.AddRange(originalModules.
                                                         SelectMany(tuple => tuple.ResourceTypes).
                                                         SelectMany(tuple => tuple.NavigationProperties).
                                                         Where(tuple => removedGuids.Contains(tuple.Id)));

            // Compute updated navigation properties. Parent of the navigation property can change.
            // No need to compare the Association. This will be handled while comparing associations.
            foreach (NavigationProperty property in originalModules.
                     SelectMany(tuple => tuple.ResourceTypes).
                     SelectMany(tuple => tuple.NavigationProperties))
            {
                NavigationProperty newProperty = targetModules.
                                                 SelectMany(tuple => tuple.ResourceTypes).
                                                 SelectMany(tuple => tuple.NavigationProperties).
                                                 Where(tuple => tuple.Id == property.Id).FirstOrDefault();
                if (newProperty != null)
                {
                    if (
                        property.Description != newProperty.Description ||
                        property.Name != newProperty.Name ||
                        property.Parent.Id != newProperty.Parent.Id ||
                        property.Uri != newProperty.Uri
                        )
                    {
                        changes.UpdatedNavigationProperties.Add(property, newProperty);
                    }
                }
            }
        }
        private static void CompareAssociations(ModuleCollectionChange changes, DataModelModuleCollection originalModules, DataModelModuleCollection targetModules)
        {
            List <Association> sourceAssociations = originalModules.
                                                    SelectMany(tuple => tuple.Associations).ToList();

            List <Association> targetAssociations = targetModules.
                                                    SelectMany(tuple => tuple.Associations).ToList();

            // Compute added associations.
            List <Guid> addedGuids = new List <Guid>();

            addedGuids.AddRange(targetAssociations.Select(tuple => tuple.Id).
                                Except(sourceAssociations.Select(tuple => tuple.Id)));

            changes.AddedAssociations.AddRange(targetAssociations.
                                               Where(tuple => addedGuids.Contains(tuple.Id)));

            // Compute deleted associations.
            List <Guid> removedGuids = new List <Guid>();

            removedGuids.AddRange(originalModules.SelectMany(tuple => tuple.Associations).
                                  Select(tuple => tuple.Id).
                                  Except
                                      (targetModules.SelectMany(tuple => tuple.Associations).
                                      Select(tuple => tuple.Id)));

            changes.DeletedAssociations.AddRange(originalModules.
                                                 SelectMany(tuple => tuple.Associations).
                                                 Where(tuple => removedGuids.Contains(tuple.Id)));

            // Compute updated associations.
            foreach (Association originalAssociation in
                     originalModules.SelectMany(tuple => tuple.Associations))
            {
                Association newAssociation = targetModules.
                                             SelectMany(tuple => tuple.Associations).
                                             Where(tuple => tuple.Id == originalAssociation.Id).FirstOrDefault();
                if (newAssociation != null)
                {
                    if (originalAssociation.Name != newAssociation.Name ||
                        originalAssociation.ObjectMultiplicity !=
                        newAssociation.ObjectMultiplicity ||
                        originalAssociation.ObjectNavigationProperty.Id !=
                        newAssociation.ObjectNavigationProperty.Id ||
                        originalAssociation.Parent.Id != newAssociation.Parent.Id ||
                        originalAssociation.SubjectMultiplicity !=
                        newAssociation.SubjectMultiplicity ||
                        originalAssociation.SubjectNavigationProperty.Id !=
                        newAssociation.SubjectNavigationProperty.Id ||
                        originalAssociation.Uri != newAssociation.Uri)
                    {
                        changes.UpdatedAssociations.Add(originalAssociation, newAssociation);
                    }
                }
            }
        }
        private static void CompareResourceTypes(ModuleCollectionChange changes, DataModelModuleCollection originalModules, DataModelModuleCollection targetModules)
        {
            List <ResourceType> sourceResourceTypes = originalModules.
                                                      SelectMany(tuple => tuple.ResourceTypes).ToList();

            List <ResourceType> targetResourceTypes = targetModules.
                                                      SelectMany(tuple => tuple.ResourceTypes).ToList();

            // Compute added resource types.
            List <Guid> addedGuids = new List <Guid>();

            addedGuids.AddRange(targetResourceTypes.Select(tuple => tuple.Id).
                                Except(sourceResourceTypes.Select(tuple => tuple.Id)));

            changes.AddedResourceTypes.AddRange(targetResourceTypes.
                                                Where(tuple => addedGuids.Contains(tuple.Id)));

            // Compute deleted resource types.
            List <Guid> removedGuids = new List <Guid>();

            removedGuids.AddRange(originalModules.SelectMany(tuple => tuple.ResourceTypes).
                                  Select(tuple => tuple.Id).
                                  Except
                                      (targetModules.SelectMany(tuple => tuple.ResourceTypes).
                                      Select(tuple => tuple.Id)));

            changes.DeletedResourceTypes.AddRange(originalModules.
                                                  SelectMany(tuple => tuple.ResourceTypes).
                                                  Where(tuple => removedGuids.Contains(tuple.Id)));

            // Compute updated resource types. Parent module of the resource type can change.
            // However, the new parent MUST be within the same data model.
            foreach (ResourceType originalResourceType in
                     originalModules.SelectMany(tuple => tuple.ResourceTypes))
            {
                ResourceType newResourceType = targetModules.
                                               SelectMany(tuple => tuple.ResourceTypes).
                                               Where(tuple => tuple.Id == originalResourceType.Id).FirstOrDefault();
                if (newResourceType != null)
                {
                    if (originalResourceType.BaseType == null && newResourceType.BaseType != null ||
                        originalResourceType.BaseType != null && newResourceType.BaseType == null ||
                        originalResourceType.BaseType != null && newResourceType.BaseType != null &&
                        originalResourceType.BaseType.Id != newResourceType.BaseType.Id ||
                        originalResourceType.Description != newResourceType.Description ||
                        originalResourceType.Name != newResourceType.Name ||
                        originalResourceType.Parent.Id != newResourceType.Parent.Id ||
                        originalResourceType.Uri != newResourceType.Uri)
                    {
                        changes.UpdatedResourceTypes.Add(originalResourceType, newResourceType);
                    }
                }
            }
        }
        private static void CompareScalarProperties(ModuleCollectionChange changes, DataModelModuleCollection originalModules, DataModelModuleCollection targetModules)
        {
            List <ScalarProperty> sourceScalarProperties = originalModules.
                                                           SelectMany(tuple => tuple.ResourceTypes).
                                                           SelectMany(tuple => tuple.ScalarProperties).ToList();

            List <ScalarProperty> targetScalarProperties = targetModules.
                                                           SelectMany(tuple => tuple.ResourceTypes).
                                                           SelectMany(tuple => tuple.ScalarProperties).ToList();

            // Compute added scalar properties.
            List <Guid> addedGuids = new List <Guid>();

            addedGuids.AddRange(targetScalarProperties.Select(tuple => tuple.Id).
                                Except(sourceScalarProperties.Select(tuple => tuple.Id)));

            changes.AddedScalarProperties.AddRange(targetScalarProperties.
                                                   Where(tuple => addedGuids.Contains(tuple.Id)));

            // Compute deleted scalar properties.
            List <Guid> removedGuids = new List <Guid>();

            removedGuids.AddRange(originalModules.SelectMany(tuple => tuple.ResourceTypes).
                                  SelectMany(tuple => tuple.ScalarProperties).Select(tuple => tuple.Id).
                                  Except
                                      (targetModules.SelectMany(tuple => tuple.ResourceTypes).
                                      SelectMany(tuple => tuple.ScalarProperties).Select(tuple => tuple.Id)));

            changes.DeletedScalarProperties.AddRange(originalModules.
                                                     SelectMany(tuple => tuple.ResourceTypes).
                                                     SelectMany(tuple => tuple.ScalarProperties).
                                                     Where(tuple => removedGuids.Contains(tuple.Id)));

            // Compute updated scalar properties. Parent for the scalar property can change.
            foreach (ScalarProperty property in originalModules.
                     SelectMany(tuple => tuple.ResourceTypes).
                     SelectMany(tuple => tuple.ScalarProperties))
            {
                ScalarProperty newProperty = targetModules.
                                             SelectMany(tuple => tuple.ResourceTypes).
                                             SelectMany(tuple => tuple.ScalarProperties).
                                             Where(tuple => tuple.Id == property.Id).FirstOrDefault();
                if (newProperty != null)
                {
                    if (
                        property.DataType != newProperty.DataType ||
                        property.Description != newProperty.Description ||
                        property.MaxLength != newProperty.MaxLength ||
                        property.Name != newProperty.Name ||
                        property.Nullable != newProperty.Nullable ||
                        property.Parent.Id != newProperty.Parent.Id ||
                        property.Precision != newProperty.Precision ||
                        property.Scale != newProperty.Scale ||
                        property.Uri != newProperty.Uri
                        )
                    {
                        changes.UpdatedScalarProperties.Add(property, newProperty);
                    }
                }
            }
        }