public Schema.Model.MessageStructure Run(XDocument xDocument, Dictionary <string, Schema.Model.SegmentStructure> oSegmentDic)
        {
            oSegmentDictionary = oSegmentDic;
            oMessageStructure  = new Model.MessageStructure();

            foreach (var detail in xDocument.Root.DescendantsAndSelf().Elements().Where(d => d.Name == HL7v2Xsd.Elements.ComplexType))
            {
                if (String.IsNullOrWhiteSpace(oMessageStructure.MessageType))
                {
                    ResolveMessageTypeAndEvent(oMessageStructure, detail);
                }

                //Covers some errors in the standard which render some message types as not implementable.
                if (EdgeCaseResolution(oMessageStructure, detail))
                {
                    return(oMessageStructure);
                }

                if (detail.Attribute(HL7v2Xsd.Attributes.Name).Value.Split('.')[1].Trim() == "CONTENT")
                {
                    foreach (var element in detail.Elements(HL7v2Xsd.Elements.Sequence).Elements(HL7v2Xsd.Elements.Element))
                    {
                        if (element.Attribute(HL7v2Xsd.Attributes.Ref).Value.Contains('.'))
                        {
                            oMessageStructure.MessageItemList.Add(
                                MessageSegmentGroupDic[element.Attribute(HL7v2Xsd.Attributes.Ref).Value.Split('.')[1].Trim()]);
                        }
                        else
                        {
                            oMessageStructure.MessageItemList.Add(ResolveMessageSegment(element));
                        }
                    }
                }
                else if (detail.Attribute(HL7v2Xsd.Attributes.Name).Value.Split('.')[1].Trim() != "CONTENT")
                {
                    if (detail.Element(HL7v2Xsd.Elements.Sequence) != null)
                    {
                        ResolveMessageSegmentGroup(detail.Attribute(HL7v2Xsd.Attributes.Name).Value.Split('.')[1].Trim(),
                                                   detail.Element(HL7v2Xsd.Elements.Sequence));
                    }
                    else
                    {
                        ResolveMessageSegmentGroup(detail.Attribute(HL7v2Xsd.Attributes.Name).Value.Split('.')[1].Trim(),
                                                   detail.Element(HL7v2Xsd.Elements.Choice));
                    }
                }
                else
                {
                    throw new Exception("Unexpected name value found: " + HL7v2Xsd.Attributes.Name.ToString() + "=" + detail.Attribute(HL7v2Xsd.Attributes.Name).Value);
                }
            }
            return(oMessageStructure);
        }
        private static void ResolveMessageTypeAndEvent(Schema.Model.MessageStructure oMessageStructure, XElement detail)
        {
            string MessageTypeAndEvent = string.Empty;

            MessageTypeAndEvent = detail.Attribute(HL7v2Xsd.Attributes.Name).Value.Split('.')[0].Trim();

            //Work out the MessageType and Event from the first group found,
            if (MessageTypeAndEvent.Contains('_'))
            {
                oMessageStructure.MessageType  = MessageTypeAndEvent.Split('_')[0].Trim();
                oMessageStructure.MessageEvent = MessageTypeAndEvent.Split('_')[1].Trim();
            }
            else
            {
                oMessageStructure.MessageType  = MessageTypeAndEvent;
                oMessageStructure.MessageEvent = String.Empty;
            }
        }