/// <summary>
        /// Parse DocumentInformation
        /// </summary>
        public static DocumentInformation ParseDocumentInformation(IFhirReader reader, ErrorList errors, DocumentInformation existingInstance = null )
        {
            DocumentInformation result = existingInstance != null ? existingInstance : new DocumentInformation();
            try
            {
                string currentElementName = reader.CurrentElementName;
                reader.EnterElement();

                while (reader.HasMoreElements())
                {
                    // Parse element extension
                    if( ParserUtils.IsAtFhirElement(reader, "extension") )
                    {
                        result.Extension = new List<Extension>();
                        reader.EnterArray();

                        while( ParserUtils.IsAtArrayElement(reader, "extension") )
                            result.Extension.Add(ExtensionParser.ParseExtension(reader, errors));

                        reader.LeaveArray();
                    }

                    // Parse element internalId
                    else if( reader.IsAtRefIdElement() )
                        result.InternalId = Id.Parse(reader.ReadRefIdContents());

                    // Parse element id
                    else if( ParserUtils.IsAtFhirElement(reader, "id") )
                        result.Id = IdentifierParser.ParseIdentifier(reader, errors);

                    // Parse element versionId
                    else if( ParserUtils.IsAtFhirElement(reader, "versionId") )
                        result.VersionId = IdentifierParser.ParseIdentifier(reader, errors);

                    // Parse element created
                    else if( ParserUtils.IsAtFhirElement(reader, "created") )
                        result.Created = InstantParser.ParseInstant(reader, errors);

                    // Parse element class
                    else if( ParserUtils.IsAtFhirElement(reader, "class") )
                        result.Class = CodingParser.ParseCoding(reader, errors);

                    // Parse element type
                    else if( ParserUtils.IsAtFhirElement(reader, "type") )
                        result.Type = CodeableConceptParser.ParseCodeableConcept(reader, errors);

                    // Parse element title
                    else if( ParserUtils.IsAtFhirElement(reader, "title") )
                        result.Title = FhirStringParser.ParseFhirString(reader, errors);

                    // Parse element confidentiality
                    else if( ParserUtils.IsAtFhirElement(reader, "confidentiality") )
                        result.Confidentiality = CodingParser.ParseCoding(reader, errors);

                    // Parse element subject
                    else if( ParserUtils.IsAtFhirElement(reader, "subject") )
                        result.Subject = ResourceReferenceParser.ParseResourceReference(reader, errors);

                    // Parse element author
                    else if( ParserUtils.IsAtFhirElement(reader, "author") )
                    {
                        result.Author = new List<ResourceReference>();
                        reader.EnterArray();

                        while( ParserUtils.IsAtArrayElement(reader, "author") )
                            result.Author.Add(ResourceReferenceParser.ParseResourceReference(reader, errors));

                        reader.LeaveArray();
                    }

                    // Parse element attester
                    else if( ParserUtils.IsAtFhirElement(reader, "attester") )
                    {
                        result.Attester = new List<DocumentInformation.DocumentInformationAttesterComponent>();
                        reader.EnterArray();

                        while( ParserUtils.IsAtArrayElement(reader, "attester") )
                            result.Attester.Add(DocumentInformationParser.ParseDocumentInformationAttesterComponent(reader, errors));

                        reader.LeaveArray();
                    }

                    // Parse element custodian
                    else if( ParserUtils.IsAtFhirElement(reader, "custodian") )
                        result.Custodian = ResourceReferenceParser.ParseResourceReference(reader, errors);

                    // Parse element event
                    else if( ParserUtils.IsAtFhirElement(reader, "event") )
                        result.Event = DocumentInformationParser.ParseDocumentInformationEventComponent(reader, errors);

                    // Parse element encounter
                    else if( ParserUtils.IsAtFhirElement(reader, "encounter") )
                        result.Encounter = ResourceReferenceParser.ParseResourceReference(reader, errors);

                    // Parse element facilityType
                    else if( ParserUtils.IsAtFhirElement(reader, "facilityType") )
                        result.FacilityType = CodeableConceptParser.ParseCodeableConcept(reader, errors);

                    // Parse element practiceSetting
                    else if( ParserUtils.IsAtFhirElement(reader, "practiceSetting") )
                        result.PracticeSetting = CodeableConceptParser.ParseCodeableConcept(reader, errors);

                    else
                    {
                        errors.Add(String.Format("Encountered unknown element {0} while parsing {1}", reader.CurrentElementName, currentElementName), reader);
                        reader.SkipSubElementsFor(currentElementName);
                        result = null;
                    }
                }

                reader.LeaveElement();
            }
            catch (Exception ex)
            {
                errors.Add(ex.Message, reader);
            }
            return result;
        }
        /// <summary>
        /// Parse DocumentInformationEventComponent
        /// </summary>
        public static DocumentInformation.DocumentInformationEventComponent ParseDocumentInformationEventComponent(IFhirReader reader, ErrorList errors, DocumentInformation.DocumentInformationEventComponent existingInstance = null )
        {
            DocumentInformation.DocumentInformationEventComponent result = existingInstance != null ? existingInstance : new DocumentInformation.DocumentInformationEventComponent();
            try
            {
                string currentElementName = reader.CurrentElementName;
                reader.EnterElement();

                while (reader.HasMoreElements())
                {
                    // Parse element extension
                    if( ParserUtils.IsAtFhirElement(reader, "extension") )
                    {
                        result.Extension = new List<Extension>();
                        reader.EnterArray();

                        while( ParserUtils.IsAtArrayElement(reader, "extension") )
                            result.Extension.Add(ExtensionParser.ParseExtension(reader, errors));

                        reader.LeaveArray();
                    }

                    // Parse element internalId
                    else if( reader.IsAtRefIdElement() )
                        result.InternalId = Id.Parse(reader.ReadRefIdContents());

                    // Parse element code
                    else if( ParserUtils.IsAtFhirElement(reader, "code") )
                    {
                        result.Code = new List<CodeableConcept>();
                        reader.EnterArray();

                        while( ParserUtils.IsAtArrayElement(reader, "code") )
                            result.Code.Add(CodeableConceptParser.ParseCodeableConcept(reader, errors));

                        reader.LeaveArray();
                    }

                    // Parse element period
                    else if( ParserUtils.IsAtFhirElement(reader, "period") )
                        result.Period = PeriodParser.ParsePeriod(reader, errors);

                    // Parse element detail
                    else if( ParserUtils.IsAtFhirElement(reader, "detail") )
                    {
                        result.Detail = new List<ResourceReference>();
                        reader.EnterArray();

                        while( ParserUtils.IsAtArrayElement(reader, "detail") )
                            result.Detail.Add(ResourceReferenceParser.ParseResourceReference(reader, errors));

                        reader.LeaveArray();
                    }

                    else
                    {
                        errors.Add(String.Format("Encountered unknown element {0} while parsing {1}", reader.CurrentElementName, currentElementName), reader);
                        reader.SkipSubElementsFor(currentElementName);
                        result = null;
                    }
                }

                reader.LeaveElement();
            }
            catch (Exception ex)
            {
                errors.Add(ex.Message, reader);
            }
            return result;
        }
        /// <summary>
        /// Parse DocumentInformationAttesterComponent
        /// </summary>
        public static DocumentInformation.DocumentInformationAttesterComponent ParseDocumentInformationAttesterComponent(IFhirReader reader, ErrorList errors, DocumentInformation.DocumentInformationAttesterComponent existingInstance = null )
        {
            DocumentInformation.DocumentInformationAttesterComponent result = existingInstance != null ? existingInstance : new DocumentInformation.DocumentInformationAttesterComponent();
            try
            {
                string currentElementName = reader.CurrentElementName;
                reader.EnterElement();

                while (reader.HasMoreElements())
                {
                    // Parse element extension
                    if( ParserUtils.IsAtFhirElement(reader, "extension") )
                    {
                        result.Extension = new List<Extension>();
                        reader.EnterArray();

                        while( ParserUtils.IsAtArrayElement(reader, "extension") )
                            result.Extension.Add(ExtensionParser.ParseExtension(reader, errors));

                        reader.LeaveArray();
                    }

                    // Parse element internalId
                    else if( reader.IsAtRefIdElement() )
                        result.InternalId = Id.Parse(reader.ReadRefIdContents());

                    // Parse element mode
                    else if( ParserUtils.IsAtFhirElement(reader, "mode") )
                        result.Mode = CodeParser.ParseCode<DocumentInformation.DocumentAttestationMode>(reader, errors);

                    // Parse element time
                    else if( ParserUtils.IsAtFhirElement(reader, "time") )
                        result.Time = FhirDateTimeParser.ParseFhirDateTime(reader, errors);

                    // Parse element party
                    else if( ParserUtils.IsAtFhirElement(reader, "party") )
                        result.Party = ResourceReferenceParser.ParseResourceReference(reader, errors);

                    else
                    {
                        errors.Add(String.Format("Encountered unknown element {0} while parsing {1}", reader.CurrentElementName, currentElementName), reader);
                        reader.SkipSubElementsFor(currentElementName);
                        result = null;
                    }
                }

                reader.LeaveElement();
            }
            catch (Exception ex)
            {
                errors.Add(ex.Message, reader);
            }
            return result;
        }
        public static void SerializeDocumentInformation(DocumentInformation value, IFhirWriter writer)
        {
            writer.WriteStartComplexContent();

            // Serialize element's localId attribute
            if( value.InternalId != null && !String.IsNullOrEmpty(value.InternalId.Contents) )
                writer.WriteRefIdContents(value.InternalId.Contents);

            // Serialize element extension
            if(value.Extension != null && value.Extension.Count > 0)
            {
                writer.WriteStartArrayElement("extension");
                foreach(var item in value.Extension)
                {
                    writer.WriteStartArrayMember("extension");
                    ExtensionSerializer.SerializeExtension(item, writer);
                    writer.WriteEndArrayMember();
                }
                writer.WriteEndArrayElement();
            }

            // Serialize element id
            if(value.Id != null)
            {
                writer.WriteStartElement("id");
                IdentifierSerializer.SerializeIdentifier(value.Id, writer);
                writer.WriteEndElement();
            }

            // Serialize element versionId
            if(value.VersionId != null)
            {
                writer.WriteStartElement("versionId");
                IdentifierSerializer.SerializeIdentifier(value.VersionId, writer);
                writer.WriteEndElement();
            }

            // Serialize element created
            if(value.Created != null)
            {
                writer.WriteStartElement("created");
                InstantSerializer.SerializeInstant(value.Created, writer);
                writer.WriteEndElement();
            }

            // Serialize element class
            if(value.Class != null)
            {
                writer.WriteStartElement("class");
                CodingSerializer.SerializeCoding(value.Class, writer);
                writer.WriteEndElement();
            }

            // Serialize element type
            if(value.Type != null)
            {
                writer.WriteStartElement("type");
                CodeableConceptSerializer.SerializeCodeableConcept(value.Type, writer);
                writer.WriteEndElement();
            }

            // Serialize element title
            if(value.Title != null)
            {
                writer.WriteStartElement("title");
                FhirStringSerializer.SerializeFhirString(value.Title, writer);
                writer.WriteEndElement();
            }

            // Serialize element confidentiality
            if(value.Confidentiality != null)
            {
                writer.WriteStartElement("confidentiality");
                CodingSerializer.SerializeCoding(value.Confidentiality, writer);
                writer.WriteEndElement();
            }

            // Serialize element subject
            if(value.Subject != null)
            {
                writer.WriteStartElement("subject");
                ResourceReferenceSerializer.SerializeResourceReference(value.Subject, writer);
                writer.WriteEndElement();
            }

            // Serialize element author
            if(value.Author != null && value.Author.Count > 0)
            {
                writer.WriteStartArrayElement("author");
                foreach(var item in value.Author)
                {
                    writer.WriteStartArrayMember("author");
                    ResourceReferenceSerializer.SerializeResourceReference(item, writer);
                    writer.WriteEndArrayMember();
                }
                writer.WriteEndArrayElement();
            }

            // Serialize element attester
            if(value.Attester != null && value.Attester.Count > 0)
            {
                writer.WriteStartArrayElement("attester");
                foreach(var item in value.Attester)
                {
                    writer.WriteStartArrayMember("attester");
                    DocumentInformationSerializer.SerializeDocumentInformationAttesterComponent(item, writer);
                    writer.WriteEndArrayMember();
                }
                writer.WriteEndArrayElement();
            }

            // Serialize element custodian
            if(value.Custodian != null)
            {
                writer.WriteStartElement("custodian");
                ResourceReferenceSerializer.SerializeResourceReference(value.Custodian, writer);
                writer.WriteEndElement();
            }

            // Serialize element event
            if(value.Event != null)
            {
                writer.WriteStartElement("event");
                DocumentInformationSerializer.SerializeDocumentInformationEventComponent(value.Event, writer);
                writer.WriteEndElement();
            }

            // Serialize element encounter
            if(value.Encounter != null)
            {
                writer.WriteStartElement("encounter");
                ResourceReferenceSerializer.SerializeResourceReference(value.Encounter, writer);
                writer.WriteEndElement();
            }

            // Serialize element facilityType
            if(value.FacilityType != null)
            {
                writer.WriteStartElement("facilityType");
                CodeableConceptSerializer.SerializeCodeableConcept(value.FacilityType, writer);
                writer.WriteEndElement();
            }

            // Serialize element practiceSetting
            if(value.PracticeSetting != null)
            {
                writer.WriteStartElement("practiceSetting");
                CodeableConceptSerializer.SerializeCodeableConcept(value.PracticeSetting, writer);
                writer.WriteEndElement();
            }

            writer.WriteEndComplexContent();
        }
        public static void SerializeDocumentInformationEventComponent(DocumentInformation.DocumentInformationEventComponent value, IFhirWriter writer)
        {
            writer.WriteStartComplexContent();

            // Serialize element's localId attribute
            if( value.InternalId != null && !String.IsNullOrEmpty(value.InternalId.Contents) )
                writer.WriteRefIdContents(value.InternalId.Contents);

            // Serialize element extension
            if(value.Extension != null && value.Extension.Count > 0)
            {
                writer.WriteStartArrayElement("extension");
                foreach(var item in value.Extension)
                {
                    writer.WriteStartArrayMember("extension");
                    ExtensionSerializer.SerializeExtension(item, writer);
                    writer.WriteEndArrayMember();
                }
                writer.WriteEndArrayElement();
            }

            // Serialize element code
            if(value.Code != null && value.Code.Count > 0)
            {
                writer.WriteStartArrayElement("code");
                foreach(var item in value.Code)
                {
                    writer.WriteStartArrayMember("code");
                    CodeableConceptSerializer.SerializeCodeableConcept(item, writer);
                    writer.WriteEndArrayMember();
                }
                writer.WriteEndArrayElement();
            }

            // Serialize element period
            if(value.Period != null)
            {
                writer.WriteStartElement("period");
                PeriodSerializer.SerializePeriod(value.Period, writer);
                writer.WriteEndElement();
            }

            // Serialize element detail
            if(value.Detail != null && value.Detail.Count > 0)
            {
                writer.WriteStartArrayElement("detail");
                foreach(var item in value.Detail)
                {
                    writer.WriteStartArrayMember("detail");
                    ResourceReferenceSerializer.SerializeResourceReference(item, writer);
                    writer.WriteEndArrayMember();
                }
                writer.WriteEndArrayElement();
            }

            writer.WriteEndComplexContent();
        }
        public static void SerializeDocumentInformationAttesterComponent(DocumentInformation.DocumentInformationAttesterComponent value, IFhirWriter writer)
        {
            writer.WriteStartComplexContent();

            // Serialize element's localId attribute
            if( value.InternalId != null && !String.IsNullOrEmpty(value.InternalId.Contents) )
                writer.WriteRefIdContents(value.InternalId.Contents);

            // Serialize element extension
            if(value.Extension != null && value.Extension.Count > 0)
            {
                writer.WriteStartArrayElement("extension");
                foreach(var item in value.Extension)
                {
                    writer.WriteStartArrayMember("extension");
                    ExtensionSerializer.SerializeExtension(item, writer);
                    writer.WriteEndArrayMember();
                }
                writer.WriteEndArrayElement();
            }

            // Serialize element mode
            if(value.Mode != null)
            {
                writer.WriteStartElement("mode");
                CodeSerializer.SerializeCode<DocumentInformation.DocumentAttestationMode>(value.Mode, writer);
                writer.WriteEndElement();
            }

            // Serialize element time
            if(value.Time != null)
            {
                writer.WriteStartElement("time");
                FhirDateTimeSerializer.SerializeFhirDateTime(value.Time, writer);
                writer.WriteEndElement();
            }

            // Serialize element party
            if(value.Party != null)
            {
                writer.WriteStartElement("party");
                ResourceReferenceSerializer.SerializeResourceReference(value.Party, writer);
                writer.WriteEndElement();
            }

            writer.WriteEndComplexContent();
        }