public XElement Generate(Profile profile)
        {
            write("<div xmlns=\"" + Hl7.Fhir.Support.XmlNs.XHTML + "\">");

            if (profile.ExtensionDefn != null && profile.ExtensionDefn.Any())
            {
                write("<p><a name=\"i0\"><b>Extensions</b></a></p>\r\n");
                write("<table class=\"dict\">\r\n");

                foreach (var e in profile.ExtensionDefn)
                {
                    generateExtension(profile, e);
                }

                write("</table>\r\n");
            }

            //if(profile.Structure != null && profile.Structure.Any())
            int i = 1;

            foreach (var s in profile.Structure)
            {
                generateStructure(profile, i, s);
                i++;
            }

            write("</div>");
            return XElement.Parse(xhtml.ToString());
        }
        public Profile.ProfileStructureComponent Expand(Profile.ProfileStructureComponent differential)
        {
            var baseStructure = _loader.LocateBaseStructure(differential.TypeElement);
            if (baseStructure == null) throw Error.InvalidOperation("Could not locate the base profile for type {0}", differential.TypeElement.ToString());

            var baseUri = StructureLoader.BuildBaseStructureUri(differential.TypeElement).ToString();

            var snapshot = (Profile.ProfileStructureComponent)baseStructure.DeepCopy();
            snapshot.SetStructureForm(StructureForm.Snapshot);
            snapshot.SetStructureBaseUri(baseUri.ToString());

            mergeStructure(snapshot, differential);

            var fullDifferential = new DifferentialTreeConstructor(differential).MakeTree();

            var snapNav = new ElementNavigator(snapshot);
            snapNav.MoveToFirstChild();

            var diffNav = new ElementNavigator(fullDifferential);
            diffNav.MoveToFirstChild();

            merge(snapNav, diffNav);

            //TODO: Merge search params?

            snapNav.CommitChanges();
            return snapshot;
        }
 private void HarvestCardinality(Profile.ElementDefinitionComponent source, Element target)
 {
     Cardinality cardinality = new Cardinality();
     cardinality.Min = source.Min.ToString();
     cardinality.Max = source.Max;
     target.Cardinality = cardinality;
 }
        private static Profile.ProfileStructureComponent locate(Profile profile, string anchor, Code type)
        {
            if(String.IsNullOrEmpty(anchor)) anchor = null;

            IEnumerable<Profile.ProfileStructureComponent> results = null;

            if (anchor == null && type == null)
            {
                // We have NO structure name and NO type hint. This is only unambiguous if there's just 1 structure in the profile
                results = profile.Structure;
            }
            else if(anchor != null && type == null)
            {
                // We have a structure name but NO specific type. This is normally unambiguous, since the name should be unique
                results = profile.Structure.Where(str => str.Name == anchor);
            }
            else if (anchor == null && type != null)
            {
                // We don't know the structure name but have it's type. This is unambiguous if there's just one structure of the given type
                results = profile.Structure.Where(str => str.Type == type.Value);
            }
            else
            {
                // We have both the name and the type, this should also normally be unique
                results = profile.Structure.Where(str => str.Name == anchor && str.Type == type.Value);
            }
            
            if (results.Count() <= 1)
                return results.SingleOrDefault();
            else
                throw Error.InvalidOperation("Cannot unambiguously determine structure to locate based on the given combination of url, anchor and structure type");
        }
        public void Expand(Profile.ProfileStructureComponent structure)
        {
            if (structure.Differential == null) throw Error.Argument("structure", "structure does not contain a differential specification");
            var differential = structure.Differential;
            
            var baseStructure = _loader.LocateBaseStructure(structure.TypeElement);
            if (baseStructure == null) throw Error.InvalidOperation("Could not locate the base profile for type {0}", structure.TypeElement.ToString());
            if(baseStructure.Snapshot == null) throw Error.InvalidOperation("Base definition to use for expansion lacks a snapshot representation");

         //   var baseUri = StructureLoader.BuildBaseStructureUri(structure.TypeElement).ToString();

            var snapshot = (Profile.ConstraintComponent)baseStructure.Snapshot.DeepCopy();

            //DSTU1
            //snapshot.SetStructureForm(StructureForm.Snapshot);
            //snapshot.SetStructureBaseUri(baseUri.ToString());
            //mergeStructure(snapshot, differential);

            var fullDifferential = new DifferentialTreeConstructor(differential).MakeTree();

            var snapNav = new ElementNavigator(snapshot);
            snapNav.MoveToFirstChild();

            var diffNav = new ElementNavigator(fullDifferential);
            diffNav.MoveToFirstChild();

            merge(snapNav, diffNav);

            //TODO: Merge search params?

            snapNav.CommitChanges();
            structure.Snapshot = snapNav.Elements;
        }
 private void stashDifferentialStructure(Profile differential, Profile.ProfileStructureComponent structure)
 {
     structure.Name += "-differential";
     structure.SetStructureForm(StructureForm.Differential);
     structure.SetStructureBaseUri(StructureLoader.BuildBaseStructureUri(structure.TypeElement).ToString());
     structure.Publish = false;
 }
        public XElement Generate(Profile profile, bool extensionsOnly)
        {
            var gen = new HierarchicalTableGenerator(_pkp);
            var model = TableModel.CreateNormalTable();

            genProfile(model.Rows, profile, extensionsOnly);

            return gen.generate(model);
        }
        public XElement generate(Profile p, bool extensionsOnly)
        {
            var gen = new HierarchicalTableGenerator(OutputPath, InlineGraphics);
            TableModel model = gen.initNormalTable();

            genProfile(model.getRows(), p, extensionsOnly);

            return gen.generate(model);
        }
        public XElement generateStructureTable(Profile.ProfileStructureComponent structure, bool diff, Profile profile) 
        {
            HierarchicalTableGenerator gen = new HierarchicalTableGenerator(_pkp);
            var model = TableModel.CreateNormalTable();

            // List<Profile.ElementComponent> list = diff ? structure.getDifferential().getElement() : structure.getSnapshot().getElement();   DSTU2
            var list = structure.Element;
            var nav = new ElementNavigator(structure);
            nav.MoveToFirstChild();
    
            genElement(gen, model.Rows, nav, profile, true);
            return gen.generate(model);
        }
        private void finalizeExtensions(Profile snapshot)
        {
            // Just a friendly helper method to add mandatory fields that are more or less boilerplate

            foreach (var extensionDefn in snapshot.ExtensionDefn)
            {
                if (extensionDefn.Definition != null)
                {
                    if (extensionDefn.Definition.Min == null) extensionDefn.Definition.Min = 0;
                    if (extensionDefn.Definition.Max == null) extensionDefn.Definition.Max = "1";
                    if (extensionDefn.Definition.IsModifier == null) extensionDefn.Definition.IsModifier = false;
                }
            }
        }
        public XElement generateStructureTable(String defFile, Profile.ProfileStructureComponent structure, bool diff, String imageFolder, 
                    bool inlineGraphics, Profile profile, string profileUrl, String profileBaseFileName) 
        {
            HierarchicalTableGenerator gen = new HierarchicalTableGenerator(imageFolder, inlineGraphics);
            TableModel model = gen.initNormalTable();

            // List<Profile.ElementComponent> list = diff ? structure.getDifferential().getElement() : structure.getSnapshot().getElement();   DSTU2
            var list = structure.Element;
            var nav = new ElementNavigator(structure);
            nav.MoveToFirstChild();
    
            genElement(defFile == null ? null : defFile+"#"+structure.Name+".", gen, model.getRows(), nav, profile, diff, profileUrl, profileBaseFileName);
            return gen.generate(model);
        }
        private void HarvestConstraints(Profile.ElementDefinitionComponent source, Element target)
        {
            if (source.Constraint == null)
                return;

            foreach(Profile.ElementDefinitionConstraintComponent c in source.Constraint)
            {
                Constraint constraint = new Constraint();
                constraint.Name = c.Name ?? c.Key;
                constraint.XPath = c.Xpath;
                constraint.HumanReadable = c.Human;
                target.Constraints.Add(constraint);
            }
        }
        private void genProfile(List<Row> rows, Profile profile, bool extensionsOnly)
        {
            if (!extensionsOnly)
            {
                var r = new  Row();
                rows.Add(r);
                r.setIcon("icon_profile.png");
                r.getCells().Add(new  Cell(null, null, profile.Name, null, null));
                r.getCells().Add(new  Cell());
                r.getCells().Add(new  Cell(null, null, "Profile", null, null));
                r.getCells().Add(new  Cell(null, null, profile.Description, null, null));

                foreach (var s in profile.Structure)
                {
                    var re = new  Row();
                    r.getSubRows().Add(re);
                    re.setIcon("icon_resource.png");

                    var structureUrl = _pkp.GetLinkForLocalStructure(profile, s);
                    
                    re.getCells().Add(new  Cell(null, structureUrl, s.Name, null, null));
                    re.getCells().Add(new  Cell(null, null, "", null, null));
                    re.getCells().Add(new  Cell(null, _pkp.GetLinkForTypeDocu(s.Type), s.Type, null, null));
                    re.getCells().Add(new  Cell(null, null, s.Element[0].Definition.Short, null, null));     // DSTU1
                    //re.getCells().Add(new  Cell(null, null, s.Base, null, null));       // DSTU2
                }
            }

            if (profile.ExtensionDefn != null && (profile.ExtensionDefn.Any() || extensionsOnly))
            {
                var re = new  Row();
                rows.Add(re);
                re.setIcon("icon_profile.png");
                re.getCells().Add(new  Cell(null, null, "Extensions", null, null));
                re.getCells().Add(new  Cell());
                re.getCells().Add(new  Cell());

                re.getCells().Add(new  Cell(null, null, "Extensions defined by this profile", null, null)); // DSTU1
                //re.getCells().Add(new  Cell(null, null, "Extensions defined by the URL \"" + profile.Url + "\"", null, null)); // DSTU2

                foreach (var ext in profile.ExtensionDefn)
                {
                    genExtension(re.getSubRows(), profile, ext, true);
                }
            }

        }
        public static bool AppendChild(this BaseElementNavigator nav, Profile.ElementComponent child)
        {
            var bm = nav.Bookmark();

            if (nav.MoveToFirstChild())
            {
                while (nav.MoveToNext()) ;
                var result = nav.InsertAfter(child);
                
                if(!result) nav.ReturnToBookmark(bm);
                return result;
            }
            else
            {
                return nav.InsertFirstChild(child);
            }
        }
        private static String conf(Profile.ElementDefinitionBindingComponent def) 
        {
            if (def.Conformance == null)
                return "For codes, see ";

            switch (def.Conformance)
            {
                case Profile.BindingConformance.Example:
                    return "For example codes, see ";
                case Profile.BindingConformance.Preferred:
                    return "The codes SHOULD be taken from ";
                case Profile.BindingConformance.Required:
                    return "The codes SHALL be taken from ";
                default:
                    return "??";
            }
        }
        private void HarvestBinding(Profile.ElementDefinitionComponent source, Element target)
        {

            if (source.Binding != null)
            {
                var reference = source.Binding.Reference;

                if (reference is ResourceReference)
                {
                    // todo: dit deel is nog niet getest.
                    target.BindingUri = (reference as ResourceReference).Url.ToString();
                }
                else if (reference is FhirUri)
                {
                    target.BindingUri = (reference as FhirUri).Value;
                }
            }

        }
        public void Expand(Profile profile)
        {
            // Assure there's a text element, even if there's none in the differential
            if (profile.Text == null)
            {
                profile.Text = new Narrative() { Status = Narrative.NarrativeStatus.Empty };
                profile.Text.Div = "<div xmlns='http://www.w3.org/1999/xhtml'>No narrative was supplied for this Profile</div>";
            }

            // We leave the globally defined Queries, Extensions and Mappings alone, the
            // only thing we expand are the Structures
            if (profile.Structure != null)
            {
                foreach (var structureToExpand in profile.Structure)
                {
                    expandStructure(structureToExpand);                   
                }
            }

            finalizeExtensions(profile);
        }
        public Profile Expand(Profile differential)
        {
            // Start by making a full copy of the differential
            var snapshot = (Profile)differential.DeepCopy();

            // Assure there's a text element, even if there's none in the differential
            if (snapshot.Text == null)
            {
                snapshot.Text = new Narrative() { Status = Narrative.NarrativeStatus.Empty };
                snapshot.Text.Div = "<div xmlns='http://www.w3.org/1999/xhtml'>No narrative was supplied for this Profile</div>";
            }

            // We leave the globally defined Queries, Extensions and Mappings alone, the
            // only thing we expand are the Structures
            if (snapshot.Structure != null)
            {
                var differentialStructures = snapshot.Structure.ToList();

                foreach (var differentialStructure in differentialStructures)
                {
                    // keep the differential form in the snapshot profile, as an unpublished copy
                    //stashDifferentialStructure(snapshot, differentialStructure);
                    
                    // Instead of keeping it, remove the original differential form
                    snapshot.Structure.Remove(differentialStructure);

                    // add the expanded differential structure in the new snapshot form
                    snapshot.Structure.Add( expandStructure(differentialStructure) );
                    
                }
            }

            finalizeExtensions(snapshot);

            return snapshot;
        }
        /// <summary>
        /// Inserts the element passed in as a child of the element the navigator is currently on. 
        /// The navigator will move to the inserted element.
        /// </summary>
        /// <param name="sibling"></param>
        /// <returns></returns>
        /// <remarks>You can only insert a child for an element does not have children yet.</remarks>
        public override bool InsertFirstChild(Profile.ElementComponent child)
        {
            if(Count == 0)
            {
                // Special case, insert a new root
                _elements.Add(child);
                child.Path = child.GetNameFromPath();
                OrdinalPosition = 0;
                return true;
            }
            else if(HasChildren)
                return false;       // Cannot insert another child, there's already one.
            else
            {
                var newSiblingPath = Path + "." + child.GetNameFromPath();
                
                if (OrdinalPosition == Count - 1) // At last position
                    _elements.Add(child);
                else
                    _elements.Insert(OrdinalPosition.Value + 1, child);

                // Set the name to be a true child -> this actually creates a child
                child.Path = newSiblingPath;

                // Navigate to newly inserted child
                OrdinalPosition += 1;

                return true;
            }
        }
 private static ElementNavigator resolveNameReference(Profile.ProfileStructureComponent structure, string nameReference)
 {
     return structure.JumpToNameReference(nameReference);
 }
 private static String confTail(Profile.ElementDefinitionBindingComponent def) 
 {
     //TODO: Note: I think the Java implmentation assumes a default of "false" here for IsExtensible...
     if (def.Conformance == Profile.BindingConformance.Preferred || (def.Conformance == Profile.BindingConformance.Required && def.IsExtensible.GetValueOrDefault(false)))
         return "; other codes may be used where these codes are not suitable";
     else
      return "";
 }
 private static bool isSlicedToOne(Profile.ElementComponent element)
 {
     // Note that in DSTU1, Slicing and Definition cannot both be non-null, but this is an error, and we really
     // need an Definition on a Slice entry element as well.
     return element.Slicing != null && 
            element.Definition != null && 
            element.Definition.Max == "1";
 }
        private void mergeElementDefnAttributes(Profile.ElementDefinitionComponent snap, Profile.ElementDefinitionComponent diff)
        {
            if (diff.ShortElement != null) snap.ShortElement = (FhirString)diff.ShortElement.DeepCopy();
            if (diff.FormalElement != null) snap.FormalElement = (FhirString)diff.FormalElement.DeepCopy();
            if (diff.CommentsElement != null) snap.CommentsElement = (FhirString)diff.CommentsElement.DeepCopy();
            if (diff.RequirementsElement != null) snap.RequirementsElement = (FhirString)diff.RequirementsElement.DeepCopy();

            if(diff.SynonymElement != null)
            {
                if(snap.SynonymElement == null) snap.SynonymElement = new List<FhirString>();

                // Add new synonyms to the snap, and replace existing ones
                foreach(var dsyn in diff.SynonymElement)
                {
                    snap.SynonymElement.Remove(snap.SynonymElement.FirstOrDefault(ssyn => ssyn.Value == dsyn.Value));
                    snap.SynonymElement.Add((FhirString)dsyn.DeepCopy());
                }
                // Original code from Java leaves snapshot untouched when encountering an existing synonym,but
                // this means differential can not override e.g. extensions in such synonyms.
                //var newSynonyms = from dsyn in diff.SynonymElement
                //                  where !snap.SynonymElement.Any(ssyn => ssyn.Value == dsyn.Value)
                //                  select (FhirString)dsyn.DeepCopy();
                //snap.SynonymElement.AddRange(newSynonyms);
            }

            if (diff.MinElement != null) snap.MinElement =  (Integer)diff.MinElement.DeepCopy();
            if (diff.MaxElement != null) snap.MaxElement =  (FhirString)diff.MaxElement.DeepCopy();

            // ElementDefinition.nameReference cannot be overridden by a derived profile

            if(diff.Fixed != null) snap.Fixed = (Element)diff.Fixed.DeepCopy();            
            if (diff.Pattern != null) snap.Pattern = (Element)diff.Pattern.DeepCopy();
            if(diff.Example != null) snap.Example = (Element)diff.Example.DeepCopy();
            if(diff.MaxLengthElement != null) snap.MaxLengthElement =  (Integer)diff.MaxLengthElement.DeepCopy();

            // todo: [GG] what to do about conditions?  [EK] Since me made ElementDefinition.Constrain cumulative, these need to be cumulative too?
            if (diff.ConditionElement != null && diff.ConditionElement.Any())
            {
                if (snap.ConditionElement == null) snap.ConditionElement = new List<Id>();
                snap.ConditionElement.AddRange(diff.ConditionElement.DeepCopy());
            }

            if(diff.MustSupportElement != null) snap.MustSupportElement = (FhirBoolean)diff.MustSupportElement.DeepCopy();

            // ElementDefinition.isModifier cannot be overridden by a derived profle
            if (diff.IsSummaryElement != null) snap.IsSummaryElement = (FhirBoolean)diff.IsSummaryElement.DeepCopy();

            if(diff.Binding != null) snap.Binding = (Profile.ElementDefinitionBindingComponent)diff.Binding.DeepCopy();

            // todo: [GG] is this actually right?  [EK] I think it is, at least this is what Forge expects as well
            if(diff.Type != null && diff.Type.Any())
                snap.Type = new List<Profile.TypeRefComponent>(diff.Type.DeepCopy());
            
            // todo: [GG] mappings are cumulative - or does one replace another?
            if(diff.Mapping != null && diff.Mapping.Any())
            {
                if(snap.Mapping == null) snap.Mapping = new List<Profile.ElementDefinitionMappingComponent>();
                snap.Mapping.AddRange(diff.Mapping.DeepCopy());
            }

            // todo: constraints are cumulative - or does one replace another?
            if(diff.Constraint != null && diff.Constraint.Any())
            {
                if(snap.Constraint == null) snap.Constraint = new List<Profile.ElementDefinitionConstraintComponent>();
                snap.Constraint.AddRange(diff.Constraint.DeepCopy());
            }
        }
        private Profile.ElementComponent createSliceEntry(Profile.ElementComponent baseDefn, Profile.ElementComponent diff)
        {
            var slicingEntry = new Profile.ElementComponent();

            slicingEntry.PathElement = (FhirString)baseDefn.PathElement.DeepCopy();
            if (diff.Name != null) slicingEntry.NameElement = (FhirString)diff.NameElement.DeepCopy();

            if (diff.Slicing != null) slicingEntry.Slicing = (Profile.ElementSlicingComponent)diff.Slicing.DeepCopy();
            
            slicingEntry.Definition = (Profile.ElementDefinitionComponent)baseDefn.Definition.DeepCopy();

            // If the differential overrides the elementdefn, only some of the fields go into the slicing entry
            if (diff.Definition != null)
            {
                if (diff.Definition.CommentsElement != null) slicingEntry.Definition.CommentsElement = (FhirString)diff.Definition.CommentsElement.DeepCopy();
                if (diff.Definition.ShortElement != null) slicingEntry.Definition.ShortElement = (FhirString)diff.Definition.ShortElement.DeepCopy();
                if (diff.Definition.FormalElement != null) slicingEntry.Definition.FormalElement = (FhirString)diff.Definition.FormalElement.DeepCopy();
                if (diff.Definition.MinElement != null) slicingEntry.Definition.MinElement = (Integer)diff.Definition.MinElement.DeepCopy();
                if (diff.Definition.MaxElement != null) slicingEntry.Definition.MaxElement = (FhirString)diff.Definition.MaxElement.DeepCopy();
            }

            return slicingEntry;
        }
        private void mergeElementAttributes(Profile.ElementComponent dest, Profile.ElementComponent src)
        {
            // Check whether this is an empty parent inserted into the differential form to create a full tree representation
            // without skips
            var isFillerParent = src.Definition == null && src.Slicing == null;
            if (isFillerParent) return;   // nothing to do, parent remains unchanged

            if (src.Name != null) dest.Name = src.Name;

            // You cannot change Element.representation in a derived profile

            if (src.Definition != null)
            {
                if (dest.Definition == null) dest.Definition = new Profile.ElementDefinitionComponent();

                mergeElementDefnAttributes(dest.Definition, src.Definition);
            }

            if(src.Slicing != null) dest.Slicing = (Profile.ElementSlicingComponent)src.Slicing.DeepCopy();
        }
        private Profile.ElementComponent createExtensionSlicingEntry(string path, Profile.ElementComponent template)
        {
            // Create a pre-fab extension slice, filled with sensible defaults
            // Extensions will repeat their definitions in their slicing entry
            var result = (Profile.ElementComponent)template.DeepCopy();
            //var result = new Profile.ElementComponent();
            //result.Path = path;
            result.Slicing = new Profile.ElementSlicingComponent();
            result.Slicing.Discriminator = new[] {"url"};
            result.Slicing.Ordered = false;
            result.Slicing.Rules = Profile.SlicingRules.Open;

            return result;
        }
        /// <summary>
        /// Parse Profile
        /// </summary>
        public static Hl7.Fhir.Model.Profile ParseProfile(IFhirReader reader, ErrorList errors, Hl7.Fhir.Model.Profile existingInstance = null)
        {
            Hl7.Fhir.Model.Profile result = existingInstance != null ? existingInstance : new Hl7.Fhir.Model.Profile();
            string currentElementName     = reader.CurrentElementName;

            reader.EnterElement();

            while (reader.HasMoreElements())
            {
                var atName = reader.CurrentElementName;
                // Parse element extension
                if (atName == "extension")
                {
                    result.Extension = new List <Hl7.Fhir.Model.Extension>();
                    reader.EnterArray();

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

                    reader.LeaveArray();
                }

                // Parse element language
                else if (atName == "language")
                {
                    result.LanguageElement = CodeParser.ParseCode(reader, errors);
                }

                // Parse element text
                else if (atName == "text")
                {
                    result.Text = NarrativeParser.ParseNarrative(reader, errors);
                }

                // Parse element contained
                else if (atName == "contained")
                {
                    result.Contained = new List <Hl7.Fhir.Model.Resource>();
                    reader.EnterArray();

                    while (ParserUtils.IsAtArrayElement(reader, "contained"))
                    {
                        result.Contained.Add(ParserUtils.ParseContainedResource(reader, errors));
                    }

                    reader.LeaveArray();
                }

                // Parse element _id
                else if (atName == "_id")
                {
                    result.LocalIdElement = Id.Parse(reader.ReadPrimitiveContents(typeof(Id)));
                }

                // Parse element identifier
                else if (atName == "identifier")
                {
                    result.IdentifierElement = FhirStringParser.ParseFhirString(reader, errors);
                }

                // Parse element version
                else if (atName == "version")
                {
                    result.VersionElement = FhirStringParser.ParseFhirString(reader, errors);
                }

                // Parse element name
                else if (atName == "name")
                {
                    result.NameElement = FhirStringParser.ParseFhirString(reader, errors);
                }

                // Parse element publisher
                else if (atName == "publisher")
                {
                    result.PublisherElement = FhirStringParser.ParseFhirString(reader, errors);
                }

                // Parse element telecom
                else if (atName == "telecom")
                {
                    result.Telecom = new List <Hl7.Fhir.Model.Contact>();
                    reader.EnterArray();

                    while (ParserUtils.IsAtArrayElement(reader, "telecom"))
                    {
                        result.Telecom.Add(ContactParser.ParseContact(reader, errors));
                    }

                    reader.LeaveArray();
                }

                // Parse element description
                else if (atName == "description")
                {
                    result.DescriptionElement = FhirStringParser.ParseFhirString(reader, errors);
                }

                // Parse element code
                else if (atName == "code")
                {
                    result.Code = new List <Hl7.Fhir.Model.Coding>();
                    reader.EnterArray();

                    while (ParserUtils.IsAtArrayElement(reader, "code"))
                    {
                        result.Code.Add(CodingParser.ParseCoding(reader, errors));
                    }

                    reader.LeaveArray();
                }

                // Parse element status
                else if (atName == "status")
                {
                    result.StatusElement = CodeParser.ParseCode <Hl7.Fhir.Model.Profile.ResourceProfileStatus>(reader, errors);
                }

                // Parse element experimental
                else if (atName == "experimental")
                {
                    result.ExperimentalElement = FhirBooleanParser.ParseFhirBoolean(reader, errors);
                }

                // Parse element date
                else if (atName == "date")
                {
                    result.DateElement = FhirDateTimeParser.ParseFhirDateTime(reader, errors);
                }

                // Parse element fhirVersion
                else if (atName == "fhirVersion")
                {
                    result.FhirVersionElement = IdParser.ParseId(reader, errors);
                }

                // Parse element structure
                else if (atName == "structure")
                {
                    result.Structure = new List <Hl7.Fhir.Model.Profile.ProfileStructureComponent>();
                    reader.EnterArray();

                    while (ParserUtils.IsAtArrayElement(reader, "structure"))
                    {
                        result.Structure.Add(ProfileParser.ParseProfileStructureComponent(reader, errors));
                    }

                    reader.LeaveArray();
                }

                // Parse element extensionDefn
                else if (atName == "extensionDefn")
                {
                    result.ExtensionDefn = new List <Hl7.Fhir.Model.Profile.ProfileExtensionDefnComponent>();
                    reader.EnterArray();

                    while (ParserUtils.IsAtArrayElement(reader, "extensionDefn"))
                    {
                        result.ExtensionDefn.Add(ProfileParser.ParseProfileExtensionDefnComponent(reader, errors));
                    }

                    reader.LeaveArray();
                }

                // Parse element binding
                else if (atName == "binding")
                {
                    result.Binding = new List <Hl7.Fhir.Model.Profile.ProfileBindingComponent>();
                    reader.EnterArray();

                    while (ParserUtils.IsAtArrayElement(reader, "binding"))
                    {
                        result.Binding.Add(ProfileParser.ParseProfileBindingComponent(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();
            return(result);
        }
        private String describeExtensionContext(Profile.ProfileExtensionDefnComponent ext)
        {
            switch (ext.ContextType)
            {
                case Profile.ExtensionContext.Datatype:
                    return "Use on data type: " + ext.DescribeContext();
                case Profile.ExtensionContext.Extension:
                    return "Use on extension: " + ext.DescribeContext();
                case Profile.ExtensionContext.Resource:
                    return "Use on resource: " + ext.DescribeContext();
                case Profile.ExtensionContext.Mapping:
                    return "Use where element has mapping: " + ext.DescribeContext();
            }

            return null;
        }
 public void Prepare()
 {
     var str = this.GetType().Assembly.GetManifestResourceStream("Hl7.Fhir.Test.profile.profile.xml");
     profile = (Profile)FhirParser.ParseResource(XmlReader.Create(str));
 }
        /// <summary>
        /// Inserts the element passed in as a sibling to the element the navigator is currently on. 
        /// The navigator will move to the inserted element.
        /// </summary>
        /// <param name="sibling"></param>
        /// <returns></returns>
        public override bool InsertAfter(Profile.ElementComponent sibling)
        {
            if (!canInsertSiblingHere()) return false;

            var insertPosition = positionAfter();
            var newSiblingPath = ParentPath + "." + sibling.GetNameFromPath();

            if (insertPosition == Count) // At last position
                _elements.Add(sibling);
            else
                _elements.Insert(insertPosition, sibling);

            // Adjust the sibling's path so it's parent is the same as the current node
            sibling.Path = newSiblingPath;

            // Navigate to newly inserted node
            OrdinalPosition = insertPosition;

            return true;
        }
        public static void SerializeProfile(Hl7.Fhir.Model.Profile value, IFhirWriter writer, bool summary)
        {
            writer.WriteStartRootObject("Profile");
            writer.WriteStartComplexContent();

            // Serialize element _id
            if (value.LocalIdElement != null)
            {
                writer.WritePrimitiveContents("_id", value.LocalIdElement, XmlSerializationHint.Attribute);
            }

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

            // Serialize element language
            if (value.LanguageElement != null && !summary)
            {
                writer.WriteStartElement("language");
                CodeSerializer.SerializeCode(value.LanguageElement, writer, summary);
                writer.WriteEndElement();
            }

            // Serialize element text
            if (value.Text != null && !summary)
            {
                writer.WriteStartElement("text");
                NarrativeSerializer.SerializeNarrative(value.Text, writer, summary);
                writer.WriteEndElement();
            }

            // Serialize element contained
            if (value.Contained != null && !summary && value.Contained.Count > 0)
            {
                writer.WriteStartArrayElement("contained");
                foreach (var item in value.Contained)
                {
                    writer.WriteStartArrayMember("contained");
                    FhirSerializer.SerializeResource(item, writer, summary);
                    writer.WriteEndArrayMember();
                }
                writer.WriteEndArrayElement();
            }

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

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

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

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

            // Serialize element telecom
            if (value.Telecom != null && value.Telecom.Count > 0)
            {
                writer.WriteStartArrayElement("telecom");
                foreach (var item in value.Telecom)
                {
                    writer.WriteStartArrayMember("telecom");
                    ContactSerializer.SerializeContact(item, writer, summary);
                    writer.WriteEndArrayMember();
                }
                writer.WriteEndArrayElement();
            }

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

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

            // Serialize element status
            if (value.StatusElement != null)
            {
                writer.WriteStartElement("status");
                CodeSerializer.SerializeCode <Hl7.Fhir.Model.Profile.ResourceProfileStatus>(value.StatusElement, writer, summary);
                writer.WriteEndElement();
            }

            // Serialize element experimental
            if (value.ExperimentalElement != null)
            {
                writer.WriteStartElement("experimental");
                FhirBooleanSerializer.SerializeFhirBoolean(value.ExperimentalElement, writer, summary);
                writer.WriteEndElement();
            }

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

            // Serialize element fhirVersion
            if (value.FhirVersionElement != null)
            {
                writer.WriteStartElement("fhirVersion");
                IdSerializer.SerializeId(value.FhirVersionElement, writer, summary);
                writer.WriteEndElement();
            }

            // Serialize element structure
            if (value.Structure != null && !summary && value.Structure.Count > 0)
            {
                writer.WriteStartArrayElement("structure");
                foreach (var item in value.Structure)
                {
                    writer.WriteStartArrayMember("structure");
                    ProfileSerializer.SerializeProfileStructureComponent(item, writer, summary);
                    writer.WriteEndArrayMember();
                }
                writer.WriteEndArrayElement();
            }

            // Serialize element extensionDefn
            if (value.ExtensionDefn != null && !summary && value.ExtensionDefn.Count > 0)
            {
                writer.WriteStartArrayElement("extensionDefn");
                foreach (var item in value.ExtensionDefn)
                {
                    writer.WriteStartArrayMember("extensionDefn");
                    ProfileSerializer.SerializeProfileExtensionDefnComponent(item, writer, summary);
                    writer.WriteEndArrayMember();
                }
                writer.WriteEndArrayElement();
            }

            // Serialize element binding
            if (value.Binding != null && !summary && value.Binding.Count > 0)
            {
                writer.WriteStartArrayElement("binding");
                foreach (var item in value.Binding)
                {
                    writer.WriteStartArrayMember("binding");
                    ProfileSerializer.SerializeProfileBindingComponent(item, writer, summary);
                    writer.WriteEndArrayMember();
                }
                writer.WriteEndArrayElement();
            }


            writer.WriteEndComplexContent();
            writer.WriteEndRootObject();
        }
        private void genExtension(List<Row> rows, Profile profile, Profile.ProfileExtensionDefnComponent ext, bool root)
        {
            var r = new  Row();
            rows.Add(r);
            r.setAnchor(ext.Code);

            r.setIcon("icon_extension_simple.png");     // DSTU1
            //if (ext.getChildren().isEmpty())    // DSTU2
            //  r.setIcon("icon_extension_simple.png");
            //else
            //r.setIcon("icon_extension_complex.png");

            var extensionUrl = _pkp.GetLinkForExtensionDefinition(profile, ext);

            r.getCells().Add(new  Cell(null, null, ext.Code, null, null));
            r.getCells().Add(new  Cell(null, null, ext.Definition.DescribeCardinality(), null, null));   //TODO: create rendering extension
            r.getCells().Add(new  Cell(null, null, ext.Definition.DescribeTypeCode(), null, null));       //TODO: create rendering extension
            //    r.getCells().add(gen.new Cell(null, null, ext.getDefinition().getShortDefn(), null, null));
            //    if (root)
            //      r.getCells().add(gen.new Cell(null, null, describeExtensionContext(ext), null, null));
            //    else
            //      r.getCells().add(gen.new Cell());
            if (root)
            {
                r.getCells().Add(new  Cell(null, null, ext.Definition.Short, null, null)
                      .addPiece(new  Piece("br"))
                      .addPiece(new  Piece(null, describeExtensionContext(ext), null)));
            }
            else
            {
                r.getCells().Add(new  Cell(null, null, ext.Definition.Short, null, null));
            }

            //foreach (var child in ext.Children)    // DSTU2
            //{
            //  genExtension(gen, r.getSubRows(), child, false);
            //}
        }