예제 #1
0
        /// <summary>
        /// Validate constraint
        /// </summary>
        private void ValidateConstraint(Constraint constraint)
        {
            if (constraint.Value == null)
                throw new InvalidOperationException("Constraint has no value");

            object expected = null;
            switch (constraint.Type)
            {
                case ConstraintDeltaType.BusinessName:
                case ConstraintDeltaType.SubstituteCmet:
                case ConstraintDeltaType.Datatype:
                case ConstraintDeltaType.DefaultValue:
                case ConstraintDeltaType.Fixed:
                case ConstraintDeltaType.Conformance:
                case ConstraintDeltaType.VocabularyStrength:
                case ConstraintDeltaType.UpdateModeDefault:
                    expected = constraint.Value as ConstraintValue<String>;
                    break;
                case ConstraintDeltaType.UpdateModeValue:
                    expected = constraint.Value as ListConstraintValue;
                    break;
                case ConstraintDeltaType.Length:
                    expected = constraint.Value as ConstraintValue<Int32>;
                    break;
                case ConstraintDeltaType.VocabularyBinding:
                    expected = constraint.Value as VocabularyConstraintValue;
                    break;
                case ConstraintDeltaType.Cardinality:
                    expected = constraint.Value as CardinalityConstraintValue;
                    break;
                case ConstraintDeltaType.Remove:
                    expected = constraint.Value as RemoveConstraintValue;
                    break;
                case ConstraintDeltaType.Annotation:
                    expected = constraint.Value as AnnotationConstraintValue;
                    break;
                default:
                    throw new InvalidOperationException(String.Format("Don't understand '{0}' constraint", constraint.Type));

            }
            if (expected == null)
            {
                throw new InvalidOperationException(String.Format("Constraint value of type '{0}' is not valid for constraint type of '{1}'",
                    constraint.Value.GetType().Name, constraint.Type));
            }
        }
예제 #2
0
        /// <summary>
        /// Apply constraints for the specified feature
        /// </summary>
        private void ApplyConstraint(Feature feature, Constraint constraint)
        {
            // Determine the type of constraint
            switch (constraint.Type)
            {
                case ConstraintDeltaType.Conformance:
                    CreateConformanceChange(feature, constraint);
                    break;
                case ConstraintDeltaType.Annotation:
                    CreateAnnotationChange(feature, constraint);
                    break;
                case ConstraintDeltaType.Remove:
                    CreateRemoveChange(feature, constraint); 
                    break;
                case ConstraintDeltaType.BusinessName:
                    CreateBusinessNameChange(feature, constraint);
                    break;
                case ConstraintDeltaType.Cardinality:
                    CreateCardinalityChange(feature, constraint);
                    break;
                case ConstraintDeltaType.SubstituteCmet:
                case ConstraintDeltaType.Datatype:
                    CreateDatatypeChange(feature, constraint);
                    break;
                case ConstraintDeltaType.Fixed:
                    CreateFixedValueChange(feature, constraint);
                    break;
                case ConstraintDeltaType.DefaultValue:
                    CreateDefaultValueChange(feature, constraint);
                    break;
                case ConstraintDeltaType.Length:
                    CreateLengthValueChange(feature, constraint);
                    break;
                case ConstraintDeltaType.VocabularyStrength:
                    CreateVocabularyStrengthChange(feature, constraint);
                    break;
                case ConstraintDeltaType.VocabularyBinding:
                    CreateVocabularyDomainChange(feature, constraint);
                    break;
                case ConstraintDeltaType.UpdateModeDefault:
                case ConstraintDeltaType.UpdateModeValue:
                    {
                        Trace.WriteLine(String.Format("Delta: Update mode deltas are not supported by this delta engine"));
                        break;
                    }
                default:
                    {
                        Trace.WriteLine(String.Format("Delta: Don't understand constraint of type '{0}'", constraint.Type), "warn");
                        break;
                    }
            }

        }
예제 #3
0
        /// <summary>
        /// Create a vocabulary domain change
        /// </summary>
        private void CreateVocabularyDomainChange(Feature feature, Constraint constraint)
        {

            #region Vocabulary Domain Change
            // 1. Validate the constraint
            var vocConstraint = constraint.Value as VocabularyConstraintValue;
            Property ccFeature = feature as Property;
            if (ccFeature == null)
            {
                Trace.WriteLine(String.Format("Delta: Cannot apply the vocabulary binding constraint against a a feature of type '{0}', skipping...", feature.GetType().Name), "error");
                return;
            }


            // 2. Validate the parameters
            Type originalType = typeof(Enumeration),
                newType = typeof(Enumeration);
            // Type map
            Dictionary<DomainSourceType, Type> typeMap = new Dictionary<DomainSourceType, Type>()
            {
                { DomainSourceType.CodeSystem, typeof(CodeSystem) },
                { DomainSourceType.ConceptDomain, typeof(ConceptDomain) },
                { DomainSourceType.ValueSet, typeof(ValueSet) }
            };

            // Map
            if (!typeMap.TryGetValue(vocConstraint.OriginalSourceType, out originalType))
            {
                Trace.WriteLine(String.Format("Delta: Don't understand the source type of the vocabulary constraint '{0}', skipping", vocConstraint.OriginalSourceType), "error");
                return;
            }
            else if (!typeMap.TryGetValue(vocConstraint.NewSourceType, out newType))
            {
                Trace.WriteLine(String.Format("Delta: Don't understand the destination type of the vocabulary constraint '{0}', skipping", vocConstraint.NewSourceType), "error");
                return;
            }

            // a. Validate original source parameters
            if (!ccFeature.SupplierDomain.Equals(vocConstraint.OriginalDomain) ||
                ccFeature.SupplierDomain != null && !ccFeature.SupplierDomain.GetType().Equals(originalType))
                Trace.WriteLine(String.Format("Delta: Current supplier domain '{2}:{0}' does not match original listed in the delta of '{3}:{1}', will continue processing anyways...", ccFeature.SupplierDomain, vocConstraint.OriginalDomain, ccFeature.SupplierDomain.GetType().Name, originalType.Name), "warn");

            // b. Validate the destination parameters
            
            // Try to get the destination vocabulary domain
            ClassRepository cr = ccFeature.MemberOf ?? ccFeature.Container.MemberOf;
            Feature targetEnum = null;
            if (cr != null && !cr.TryGetValue(vocConstraint.NewDomain, out targetEnum))
                Trace.WriteLine(String.Format("Delta: Could not find vocabulary '{0}' in repository! Cannot verify parameters", vocConstraint.NewDomain), "warn");
            else if (targetEnum != null && !targetEnum.GetType().Equals(newType))
                Trace.WriteLine(String.Format("Delta: Could not verify the destination vocabulary type. Actual type is '{0}:{1}', delta set describes '{2}:{3}'",
                    targetEnum.GetType().Name, targetEnum.Name, vocConstraint.NewSourceType, vocConstraint.NewDomain), "warn");
            
            // Identify the new type
            object newValue = (object)targetEnum ?? (object)vocConstraint.NewDomain;

            // Validate the annotation doesn't already exist
            if (ccFeature.Annotations.Exists(o => o is SupplierDomainConstraintAnnotation && (o as SupplierDomainConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code))
            {
                Trace.WriteLine(String.Format("Delta: Supplier domain constraint has already been applied to '{0}'", feature.Name), "error");
                return;
            }

            // Add the annotation to the feature
            ccFeature.Annotations.Add(new SupplierDomainConstraintAnnotation()
            {
                ChangeType = ChangeType.Edit,
                RealmCode = this.m_deltaSet.Realm.Code,
                NewValue = newValue,
                RealmName = this.m_deltaSet.MetaData.Description
            });
            #endregion

        }
예제 #4
0
        /// <summary>
        /// Create a length value change
        /// </summary>
        // TODO: Find a delta-set example that uses this so we can test.
        // TODO: Can't determine if this changes maximum or minimum length, should bring this 
        //       up with CHI to see if there is a definition for what this attribute changes
        private void CreateLengthValueChange(Feature feature, Constraint constraint)
        {
            #region Length Value

            // Validate the constraint
            var lnConstraint = constraint.Value as ConstraintValue<Int32>;
            Property ccFeature = feature as Property;
            if (ccFeature == null)
            {
                Trace.WriteLine(String.Format("Delta: Cannot apply the length value constraint against a a feature of type '{0}', skipping...", feature.GetType().Name), "error");
                return;
            }

            // Validate the current default value
            if (!lnConstraint.Original.Equals(ccFeature.MaxLength))
                Trace.WriteLine(String.Format("Delta: Current length of '{0}' does not match original listed in the delta of '{1}', will continue processing anyways...", ccFeature.DefaultValue, lnConstraint.Original), "warn");
            // Validate the annotation doesn't already exist
            if (ccFeature.Annotations.Exists(o => o is LengthConstraintAnnotation && (o as LengthConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code))
            {
                Trace.WriteLine(String.Format("Delta: Length constraint has already been applied to '{0}'", feature.Name), "error");
                return;
            }

            // Add the annotation to the feature
            ccFeature.Annotations.Add(new LengthConstraintAnnotation()
            {
                ChangeType = ChangeType.Edit,
                RealmCode = this.m_deltaSet.Realm.Code,
                NewValue = lnConstraint.New,
                RealmName = this.m_deltaSet.MetaData.Description
            });
            #endregion
        }
예제 #5
0
        /// <summary>
        /// Create a vocbulary change strength
        /// </summary>
        private void CreateVocabularyStrengthChange(Feature feature, Constraint constraint)
        {
            #region Default Value

            // Validate the constraint
            var strConstraint = constraint.Value as ConstraintValue<String>;
            Property ccFeature = feature as Property;
            if (ccFeature == null)
            {
                Trace.WriteLine(String.Format("Delta: Cannot apply the vocabulary strength constraint against a a feature of type '{0}', skipping...", feature.GetType().Name), "error");
                return;
            }

            // Default
            Property.CodingStrengthKind newStrength = Property.CodingStrengthKind.CodedNoExtensions;
            // Parse the new value
            switch (strConstraint.New)
            {
                case "CWE":
                    newStrength = Property.CodingStrengthKind.CodedWithExtensions;
                    break;
                case "CNE":
                    break;
                default:
                    Trace.WriteLine(String.Format("Delta: Don't understand coding strength '{0}', ignoring...", strConstraint.New), "warn");
                    return;
            }

            // Validate the annotation doesn't already exist
            if (ccFeature.Annotations.Exists(o => o is SupplierStrengthConstraintAnnotation && (o as SupplierStrengthConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code))
            {
                Trace.WriteLine(String.Format("Delta: Supplier constraint has already been applied to '{0}'", feature.Name), "error");
                return;
            }

            // Add the annotation to the feature
            ccFeature.Annotations.Add(new SupplierStrengthConstraintAnnotation()
            {
                ChangeType = ChangeType.Edit,
                RealmCode = this.m_deltaSet.Realm.Code,
                NewValue = newStrength,
                RealmName = this.m_deltaSet.MetaData.Description
            });
            #endregion
        }
예제 #6
0
        /// <summary>
        /// Create a data type change
        /// </summary>
        private void CreateDatatypeChange(Feature feature, Constraint constraint)
        {
            #region Data Type Change
            // 1. Validate constraint & target
            var stConstriant = constraint.Value as ConstraintValue<String>;
            Property ccFeature = feature as Property;
            if (ccFeature == null)
            {
                Trace.WriteLine(String.Format("Delta: Cannot apply data type change constraint against a feature of type '{0}', skipping...", feature.GetType().Name), "error");
                return;
            }
            TypeReference trNew = this.ParseTypeReference(stConstriant.New),
                trOld = this.ParseTypeReference(stConstriant.Original);

            // 2. Validate current data type
            if (trNew == null || trOld == null)
            {
                Trace.WriteLine(String.Format("Delta: Could not process '{0}' or '{1}', skipping...", stConstriant.Original, stConstriant.New), "error");
                return;
            }
            if (!TypeReferenceEqual(ccFeature.Type, trOld))
                Trace.WriteLine(String.Format("Delta: Current type of '{0}' is not '{1}' as specified in delta, rather it is '{2}', will continue processing anyways...", feature.Name,
                    trOld, ccFeature.Type), "warn");
            // 3. Validate that the cardinality doesn't already exist
            if (ccFeature.Annotations.Exists(o => o is DatatypeChangeConstraintAnnotation && (o as DatatypeChangeConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code))
            {
                Trace.WriteLine(String.Format("Delta: Datatype constraint has already been applied to '{0}'", feature.Name), "error");
                return;
            }
            // 4. Append the annotation
            ccFeature.Annotations.Add(new DatatypeChangeConstraintAnnotation()
            {
                ChangeType = ChangeType.Edit,
                RealmCode = this.m_deltaSet.Realm.Code,
                NewValue = trNew,
                RealmName = this.m_deltaSet.MetaData.Description
            });
            #endregion
        }
예제 #7
0
        /// <summary>
        /// Create a change that modifies the fixed value
        /// </summary>
        private void CreateFixedValueChange(Feature feature, Constraint constraint)
        {
            #region Fixed Value
            // 1. Validate constraint & target
            var stConstriant = constraint.Value as ConstraintValue<String>;
            Property ccFeature = feature as Property;
            if (ccFeature == null)
            {
                Trace.WriteLine(String.Format("Delta: Cannot apply fixed value change constraint against a feature of type '{0}', skipping...", feature.GetType().Name), "error");
                return;
            }

            // 2. Validate current data type
            if (stConstriant.Original != null && !stConstriant.Original.Equals(ccFeature.FixedValue))
                Trace.WriteLine(String.Format("Delta: Current fixed value of '{0}' does not match original listed in delta of '{1}', will continue processing anyways...", ccFeature.FixedValue, stConstriant.Original), "warn");
            // 3. Validate that the annotation doesn't already exist
            if (ccFeature.Annotations.Exists(o => o is FixedValueConstraintAnnotation && (o as FixedValueConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code))
            {
                Trace.WriteLine(String.Format("Delta: Fixed value constraint has already been applied to '{0}'", feature.Name), "error");
                return;
            }
            // 4. Append the annotation
            ccFeature.Annotations.Add(new FixedValueConstraintAnnotation()
            {
                ChangeType = ChangeType.Edit,
                RealmCode = this.m_deltaSet.Realm.Code,
                NewValue = stConstriant.New,
                RealmName = this.m_deltaSet.MetaData.Description
            });
            #endregion
        }
예제 #8
0
 /// <summary>
 /// Create a cardinality change
 /// </summary>
 private void CreateCardinalityChange(Feature feature, Constraint constraint)
 {
     #region Cardinality Change
     // 1. Validate constraint & target
     CardinalityConstraintValue ccv = constraint.Value as CardinalityConstraintValue;
     ClassContent ccFeature = feature as ClassContent;
     if (ccFeature == null)
     {
         Trace.WriteLine(String.Format("Delta: Cannot apply cardinality constraint against a feature of type '{0}', skipping...", feature.GetType().Name), "error");
         return;
     }
     // 2. Validate existing data
     if ((ccv.OriginalMaxValue.HasValue ? ccv.OriginalMaxValue.ToString() != ccFeature.MaxOccurs : ccFeature.MaxOccurs != "*") ||
         (ccv.OriginalMinValue.HasValue ? ccv.OriginalMinValue.ToString() != ccFeature.MinOccurs : ccFeature.MaxOccurs != null))
         Trace.WriteLine(String.Format("Delta: Applying cardinality constraint on '{0}' even though original Min/Max occurs do not match!", feature.Name), "warn");
     // 3. Validate that the cardinality doesn't already exist
     if (ccFeature.Annotations.Exists(o => o is CardinalityConstraintAnnotation && (o as CardinalityConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code))
     {
         Trace.WriteLine(String.Format("Delta: Cardinality constraint has already been applied to '{0}'", feature.Name), "error");
         return;
     }
     // 4. Append the annotation
     ccFeature.Annotations.Add(new CardinalityConstraintAnnotation()
     {
         ChangeType = ChangeType.Edit,
         RealmCode = this.m_deltaSet.Realm.Code,
         MaxOccurs = ccv.NewMaxValue.HasValue ? ccv.NewMaxValue.Value.ToString() : "*",
         MinOccurs = ccv.NewMinValue.HasValue ? ccv.NewMinValue.Value.ToString() : null,
         RealmName = this.m_deltaSet.MetaData.Description
     });
     #endregion
 }
예제 #9
0
        /// <summary>
        /// Create a change that modifies the business name
        /// </summary>
        private void CreateBusinessNameChange(Feature feature, Constraint constraint)
        {
            #region Business Name Change
            // 1. Validate constraint if possible
            BusinessNameConstraintAnnotation bnc = new BusinessNameConstraintAnnotation();
            var stConstraint = constraint.Value as ConstraintValue<String>;
            if (stConstraint.Original != null && !stConstraint.Original.Equals(feature.BusinessName))
                Trace.WriteLine(String.Format("Delta: Business name constraint original text does not match actual business name on feature '{0}'", feature.Name), "warn");

            // 2. Check for duplicates
            if (feature.Annotations.Exists(o => o is BusinessNameConstraintAnnotation && (o as BusinessNameConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code))
            {
                Trace.WriteLine(String.Format("Delta: Business name constraint has already been applied to '{0}'", feature.Name), "error");
                return;
            }

            // 3. Append constraint
            feature.Annotations.Add(new BusinessNameConstraintAnnotation()
            {
                RealmCode = this.m_deltaSet.Realm.Code,
                NewValue = stConstraint.New,
                ChangeType = ChangeType.Edit,
                RealmName = this.m_deltaSet.MetaData.Description
            });
            #endregion
        }
예제 #10
0
        /// <summary>
        /// Create a remove change delta
        /// </summary>
        private void CreateRemoveChange(Feature feature, Constraint constraint)
        {
            #region Remove Change
            // 1. Find the feature that is to be removed
            Feature removeFeature = null;
            ClassContent pFeature = feature as ClassContent;
            RemoveConstraintValue rcv = constraint.Value as RemoveConstraintValue;
            if (rcv.RelationshipName == feature.Name)
                removeFeature = feature;
            else if (!String.IsNullOrEmpty(rcv.OwnedEntryPoint) && !String.IsNullOrEmpty(rcv.ClassName))
            {
                if (feature is Property)
                {
                    var ssContainer = ((feature as Property).Container as Class).ContainerPackage;
                    if (ssContainer != null && ssContainer.Name.Equals(rcv.OwnedEntryPoint))
                        removeFeature = ssContainer.OwnedClasses.Find(o => o.Name.Equals(rcv.ClassName));
                }
            }

            // 2. Validate the feature
            if (removeFeature == null)
            {
                Trace.WriteLine(String.Format("Delta: Cannot apply remove constraint on '{0}.{1}{2}' as the path was not found...",
                    rcv.OwnedEntryPoint, rcv.ClassName, rcv.RelationshipName == null ? "" : "." + rcv.RelationshipName), "error");
                return;
            }

            // 3. Apply the remove constraint
            if (removeFeature.Annotations.Exists(o => o is RemoveConstraintAnnotation && (o as RemoveConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code))
            {
                Trace.WriteLine(String.Format("Delta: Conformance constraint has already been applied to '{0}'", feature.Name), "error");
                return;
            }
            removeFeature.Annotations.Add(
                new RemoveConstraintAnnotation()
                {
                    ChangeType = ChangeType.Remove,
                    RealmCode = this.m_deltaSet.Realm.Code,
                    RealmName = this.m_deltaSet.MetaData.Description
                }
            );

            // 4. Remove the supported constraint
            removeFeature.Annotations.RemoveAll(o => o is SupportedConstraintAnnotation && (o as SupportedConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code);

            #endregion
        }
예제 #11
0
        /// <summary>
        /// Create an annotation change delta
        /// </summary>
        private void CreateAnnotationChange(Feature feature, Constraint constraint)
        {
            #region Annotation Change
            AnnotationConstraintValue acv = constraint.Value as AnnotationConstraintValue;
            if (acv.ChangeType == ChangeType.Remove)
            {

                // Determine modification type
                var modType = AnnotationConstraintAnnotation.ModificationTargetType.Other;
                switch (acv.Type)
                {
                    case AnnotationType.Description:
                        modType = AnnotationConstraintAnnotation.ModificationTargetType.Description;
                        break;
                    case AnnotationType.UseageNotes:
                        modType = AnnotationConstraintAnnotation.ModificationTargetType.Usage;
                        break;
                    case AnnotationType.Rationale:
                        modType = AnnotationConstraintAnnotation.ModificationTargetType.Rationale;
                        break;
                }
                feature.Annotations.Add(new AnnotationConstraintAnnotation()
                {
                    AnnotationType = modType,
                    ChangeType = ChangeType.Remove,
                    RealmCode = this.m_deltaSet.Realm.Code
                });
            }
            else
                switch (acv.Type)
                {
                    case AnnotationType.UseageNotes:
                    case AnnotationType.Description:
                    case AnnotationType.Rationale:
                        // 1. Validate the current value is equal
                        if (feature.Documentation == null ||
                            acv.Type == AnnotationType.Description &&
                            (feature.Documentation.Description == null ||
                            feature.Documentation.Description.Count == 0 ||
                             !feature.Documentation.Description[0].Equals(acv.Original)) ||
                            acv.Type == AnnotationType.UseageNotes &&
                            (feature.Documentation.Usage == null ||
                            feature.Documentation.Usage.Count == 0 ||
                            !feature.Documentation.Usage[0].Equals(acv.Original)) ||
                            acv.Type == AnnotationType.Rationale &&
                            (feature.Documentation.Rationale == null ||
                            feature.Documentation.Rationale.Count == 0 ||
                            !feature.Documentation.Rationale[0].Equals(acv.Original)))
                            Trace.WriteLine(String.Format("Delta: Annotation constraint for '{0}' of type '{1}' does not have the same origial content, this may be an error!", feature.Name, acv.Type), "warn");

                        // 2. Add the annotation
                        feature.Annotations.Add(new AnnotationConstraintAnnotation()
                        {
                            AnnotationType = acv.Type == AnnotationType.Description ? AnnotationConstraintAnnotation.ModificationTargetType.Description : acv.Type == AnnotationType.Rationale ? AnnotationConstraintAnnotation.ModificationTargetType.Rationale : AnnotationConstraintAnnotation.ModificationTargetType.Usage,
                            ChangeType = acv.ChangeType,
                            NewValue = acv.New,
                            RealmCode = this.m_deltaSet.Realm.Code,
                            RealmName = this.m_deltaSet.MetaData.Description
                        });
                        break;
                    case AnnotationType.Constraint:
                        // 1. Create a new titled documentation
                        feature.Annotations.Add(new AnnotationConstraintAnnotation()
                        {
                            AnnotationType = AnnotationConstraintAnnotation.ModificationTargetType.Constraint,
                            ChangeType = acv.ChangeType,
                            NewValue = acv.New,
                            RealmCode = this.m_deltaSet.Realm.Code,
                            RealmName = this.m_deltaSet.MetaData.Description
                        });
                        break;
                    case AnnotationType.DesignComments:
                    case AnnotationType.Mapping:
                    case AnnotationType.OpenIssue:
                    case AnnotationType.OtherNotes:
                        // 1. Create a new titled documentation
                        feature.Annotations.Add(new AnnotationConstraintAnnotation()
                        {
                            AnnotationType = AnnotationConstraintAnnotation.ModificationTargetType.Other,
                            ChangeType = acv.ChangeType,
                            NewValue = acv.New,
                            RealmCode = this.m_deltaSet.Realm.Code,
                            RealmName = this.m_deltaSet.MetaData.Description
                        });
                        break;
                }
            #endregion
        }
예제 #12
0
        /// <summary>
        /// Create a conformance change annotation
        /// </summary>
        private void CreateConformanceChange(Feature feature, Constraint constraint)
        {
            #region Conformance Change
            // 1. Validate the constraint is against a property
            ClassContent pFeature = feature as ClassContent;
            if (pFeature == null)
            {
                Trace.WriteLine(String.Format("Delta: Conformance constraint cannot be applied against a '{1}' named '{0}'", feature.Name, feature.GetType().Name), "error");
                return;
            }

            // 2. Validate the conformance old value is in fact a match
            ConstraintValue<String> stConstraint = constraint.Value as ConstraintValue<string>;
            if (stConstraint == null || stConstraint.Original.ToLower() != pFeature.Conformance.ToString().ToLower())
            {
                Trace.WriteLine(String.Format("Delta: Conformance constraint cannot be applied because the original value of '{0}' does not match the actual original property conformance of '{1}'",
                    stConstraint.Original.ToLower(), pFeature.Conformance.ToString().ToLower()), "error");
                return;
            }

            // Map the SCREAMING CAPS to ScreamingCaps
            string friendlyValue = String.Format("{0}{1}", stConstraint.New[0], stConstraint.New.Substring(1).ToLower());
            if (friendlyValue == "Not_allowed")
                friendlyValue = "NotAllowed";
            // 3. Verify a constraint for the same jurisdication has not already been added
            if (feature.Annotations.Exists(o => o is ConformanceConstraintAnnotation && (o as ConformanceConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code))
            {
                Trace.WriteLine(String.Format("Delta: Conformance constraint has already been applied to '{0}'", feature.Name), "error");
                return;
            }

            feature.Annotations.Add(
                new ConformanceConstraintAnnotation()
                {
                    NewValue = (Property.ConformanceKind)Enum.Parse(typeof(Property.ConformanceKind), friendlyValue),
                    ChangeType = ChangeType.Edit,
                    RealmCode = this.m_deltaSet.Realm.Code,
                    RealmName = this.m_deltaSet.MetaData.Description
                }
            );
            #endregion
        }