protected override void ReadXmlBase(System.Xml.XmlReader reader)
        {
            base.ReadXmlBase(reader);

            // read for the attributes in this local class
            Check.Assert(reader.LocalName == "uid", "Expected LocalName as uid rather than " + reader.LocalName);
            this.uid = new OpenEhr.RM.Support.Identification.ObjectVersionId();
            this.uid.ReadXml(reader);

            if (reader.LocalName == "data")
            {
                string dataType = reader.GetAttribute("type", RmXmlSerializer.XsiNamespace);

                OpenEhr.RM.Common.Archetyped.Impl.Locatable locatableData =
                    OpenEhr.RM.Common.Archetyped.Impl.Locatable.GetLocatableObjectByType(dataType);
                locatableData.ReadXml(reader);
                this.data = locatableData as T;
            }

            if (reader.LocalName == "preceding_version_uid")
            {
                this.precedingVersionUid = new OpenEhr.RM.Support.Identification.ObjectVersionId();
                this.precedingVersionUid.ReadXml(reader);
            }

            if (reader.LocalName == "other_input_version_uids")
            {
                this.otherInputVersionUids = new AssumedTypes.Set <ObjectVersionId>();
                do
                {
                    ObjectVersionId objectVersionId = new ObjectVersionId();
                    objectVersionId.ReadXml(reader);

                    this.otherInputVersionUids.Add(objectVersionId);
                } while (reader.LocalName == "other_input_version_uids");
            }

            if (reader.LocalName == "attestations")
            {
                this.attestations = new OpenEhr.AssumedTypes.List <OpenEhr.RM.Common.Generic.Attestation>();
                do
                {
                    Generic.Attestation a = new OpenEhr.RM.Common.Generic.Attestation();
                    a.ReadXml(reader);

                    this.attestations.Add(a);
                } while (reader.LocalName == "attestations");
            }

            Check.Assert(reader.LocalName == "lifecycle_state",
                         "Expected LocalName is lifecycle_state not " + reader.LocalName);
            this.lifecycleState = new OpenEhr.RM.DataTypes.Text.DvCodedText();
            this.lifecycleState.ReadXml(reader);
        }
        public override bool ValidValue(object dataValue)
        {
            Check.Require(dataValue != null, string.Format(CommonStrings.XMustNotBeNull, "dataValue"));
            IRmType rmType = dataValue as IRmType;

            Check.Require(rmType != null, string.Format(AmValidationStrings.ValueMustImplementIRmType, dataValue.GetType().ToString()));

            bool result = true;

            rmType.Constraint = this;

            if (!IsSameRmType(rmType))
            {
                result = false;
                ValidationContext.AcceptValidationError(this, string.Format(AmValidationStrings.IncorrectRmType, RmTypeName, rmType.GetRmTypeName()));
            }

            if (!result || !AnyAllowed())
            {
                OpenEhr.RM.Common.Archetyped.Impl.Locatable locatable = dataValue as OpenEhr.RM.Common.Archetyped.Impl.Locatable;

                if (locatable != null)
                {
                    ValidationUtility.PopulateLocatableAttributes(this, locatable);

                    if (Parent != null && ArchetypeNodeId != locatable.ArchetypeNodeId)
                    {
                        result = false;
                        ValidationContext.AcceptValidationError(this, string.Format(AmValidationStrings.IncorrectNodeId, ArchetypeNodeId, locatable.ArchetypeNodeId));
                    }
                }

                System.ComponentModel.PropertyDescriptorCollection propertyDescriptorCollection = System.ComponentModel.TypeDescriptor.GetProperties(dataValue);

                if (Attributes != null)
                {
                    foreach (CAttribute cAttribute in Attributes)
                    {
                        object attributeObject = null;
                        string attributeName   = RmFactory.GetOpenEhrV1RmName(cAttribute.RmAttributeName);
                        System.ComponentModel.PropertyDescriptor property = propertyDescriptorCollection.Find(attributeName, true);

                        // if the attributeName is not a class property, it must be a class function.
                        if (property == null)
                        {
                            System.Reflection.MethodInfo method = dataValue.GetType().GetMethod(attributeName);

                            if (method == null)
                            {
                                result = false;
                                ValidationContext.AcceptValidationError(this, string.Format(AmValidationStrings.UnexpectedAttributeX, attributeName));
                                continue;
                            }
                            else
                            {
                                attributeObject = method.Invoke(dataValue, null);
                            }
                        }
                        else
                        {
                            attributeObject = property.GetValue(dataValue);
                        }

                        if (attributeObject == null)
                        {
                            if (cAttribute.Existence.Lower > 0)
                            {
                                result = false;
                                ValidationContext.AcceptValidationError(this, string.Format(AmValidationStrings.TmExpectedConstraintMissing, cAttribute.RmAttributeName));
                            }
                        }
                        else if (cAttribute.Existence.Upper == 0)
                        {
                            result = false;
                            ValidationContext.AcceptValidationError(this, string.Format(AmValidationStrings.TmForbiddenConstraint, cAttribute.RmAttributeName));
                        }
                        else if (!cAttribute.ValidValue(attributeObject))
                        {
                            result = false;
                        }
                        else
                        {
                            DvCodedText codedText = dataValue as DvCodedText;

                            if (codedText != null && cAttribute.RmAttributeName == "defining_code")
                            {
                                // validate the code string before validating the coded value
                                if (codedText.DefiningCode.TerminologyId.Value == "local")
                                {
                                    CObject        parentObject   = cAttribute.parent;
                                    CArchetypeRoot cArchetypeRoot = ValidationUtility.GetCArchetypeRoot(parentObject);

                                    if (!cArchetypeRoot.TermDefinitions.HasKey(codedText.DefiningCode.CodeString))
                                    {
                                        result = false;
                                        string code = codedText.DefiningCode == null ? "" : codedText.DefiningCode.CodeString;
                                        ValidationContext.AcceptValidationError(this, string.Format("code {0} is not existing archetype term", code));
                                    }
                                }
                                if (result && !ValidationUtility.ValidValueTermDef(codedText, cAttribute, ValidationContext.TerminologyService))
                                {
                                    result = false;
                                    string code = codedText.DefiningCode == null ? "" : codedText.DefiningCode.CodeString;
                                    ValidationContext.AcceptValidationError(this, string.Format(AmValidationStrings.TextValueXInvalidForCodeY, codedText.Value, code));
                                }
                            }
                        }
                    }
                }
            }

            return(result);
        }
        protected override void WriteXmlBase(System.Xml.XmlWriter writer)
        {
            base.WriteXmlBase(writer);

            string prefix    = RmXmlSerializer.UseOpenEhrPrefix(writer);
            string xsiPrefix = RmXmlSerializer.UseXsiPrefix(writer);

            writer.WriteStartElement("uid", RmXmlSerializer.OpenEhrNamespace);
            this.Uid.WriteXml(writer);
            writer.WriteEndElement();

            if (this.Data != null)
            {
                writer.WriteStartElement("data", RmXmlSerializer.OpenEhrNamespace);

                OpenEhr.RM.Common.Archetyped.Impl.Locatable dataLocatable = this.Data
                                                                            as OpenEhr.RM.Common.Archetyped.Impl.Locatable;
                if (dataLocatable == null)
                {
                    throw new NotSupportedException("Only support locatable as version data: "
                                                    + Data.GetType().Name);
                }
                string dataType = ((IRmType)dataLocatable).GetRmTypeName();
                if (!string.IsNullOrEmpty(prefix))
                {
                    dataType = prefix + ":" + dataType;
                }
                writer.WriteAttributeString(xsiPrefix, "type", RmXmlSerializer.XsiNamespace, dataType);
                Composition.Composition com = this.Data as Composition.Composition;
                com.WriteXml(writer);
                writer.WriteEndElement();
            }

            if (this.PrecedingVersionUid != null)
            {
                writer.WriteStartElement("preceding_version_uid", RmXmlSerializer.OpenEhrNamespace);
                this.PrecedingVersionUid.WriteXml(writer);
                writer.WriteEndElement();
            }

            // otherInputVersionUids
            if (this.OtherInputVersionUids != null)
            {
                foreach (ObjectVersionId objectVersionId in this.OtherInputVersionUids)
                {
                    writer.WriteStartElement("other_input_version_uids", RmXmlSerializer.OpenEhrNamespace);
                    objectVersionId.WriteXml(writer);
                    writer.WriteEndElement();
                }
            }

            // attestation
            if (this.Attestations != null)
            {
                foreach (Generic.Attestation a in this.Attestations)
                {
                    writer.WriteStartElement("attestations", RmXmlSerializer.OpenEhrNamespace);
                    a.WriteXml(writer);
                    writer.WriteEndElement();
                }
            }

            writer.WriteStartElement("lifecycle_state", RmXmlSerializer.OpenEhrNamespace);
            this.LifecycleState.WriteXml(writer);
            writer.WriteEndElement();
        }
        internal static void PopulateLocatableAttributes(CComplexObject cComplexObject, OpenEhr.RM.Common.Archetyped.Impl.Locatable locatable)
        {
            Check.Require(locatable != null, "locatable must not be null.");
            Check.Require(cComplexObject != null, "cComplexObject must not be null.");

            string codeString = null;

            if (string.IsNullOrEmpty(locatable.ArchetypeNodeId))
            {
                CArchetypeRoot archetypeRoot = cComplexObject as CArchetypeRoot;

                if (archetypeRoot != null)
                {
                    locatable.ArchetypeNodeId = archetypeRoot.ArchetypeId.Value;
                    codeString = cComplexObject.NodeId;
                }
                else
                {
                    locatable.ArchetypeNodeId = cComplexObject.NodeId;
                    codeString = cComplexObject.NodeId;
                }
            }

            if (locatable.Name == null || string.IsNullOrEmpty(locatable.Name.Value))
            {
                if (string.IsNullOrEmpty(codeString))
                    codeString = cComplexObject.NodeId;
                locatable.Name = new DvText(LocalTermDefText(codeString, cComplexObject));
            }

            Check.Ensure(!string.IsNullOrEmpty(locatable.ArchetypeNodeId), "ArchetypeId must not be null or empty.");
            Check.Ensure(locatable.Name != null && !string.IsNullOrEmpty(locatable.Name.Value), "name must not be null.");
        }