/// <summary>
 /// Creates a new instance of the <see cref="Service"/> class specifying mandatory values.
 /// </summary>
 ///
 /// <remarks>
 /// This item is not added to the health record until the
 /// <see cref="Microsoft.Health.HealthRecordAccessor.NewItem(HealthRecordItem)"/> method
 /// is called.
 /// </remarks>
 ///
 /// <param name="serviceType">
 /// The type of the service.
 /// </param>
 /// <param name="serviceDates">
 /// The dates for this service.
 /// </param>
 /// <param name="claimAmounts">
 /// The financial information for this service.
 /// </param>
 /// <exception cref="ArgumentNullException">
 /// If <paramref name="serviceType"/> is <b> null </b>.
 /// If <paramref name="serviceDates"/> is <b> null </b>.
 /// If <paramref name="claimAmounts"/> is <b> null </b>.
 /// </exception>
 ///
 public Service(
     CodableValue serviceType,    
     DurationValue serviceDates,    
     ClaimAmounts claimAmounts)
 {
     ServiceType = serviceType;
     ServiceDates = serviceDates;
     ClaimAmounts = claimAmounts;
 }
        /// <summary>
        /// Populates this <see cref="ExplanationOfBenefits"/> instance from the data in the specified XML.
        /// </summary>
        ///
        /// <param name="typeSpecificXml">
        /// The XML to get the ExplanationOfBenefits data from.
        /// </param>
        ///
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="typeSpecificXml"/> parameter is <b>null</b>.
        /// </exception>
        /// 
        /// <exception cref="InvalidOperationException">
        /// If the first node in <paramref name="typeSpecificXml"/> is not
        /// a ExplanationOfBenefits node.
        /// </exception>
        /// 
        protected override void ParseXml(IXPathNavigable typeSpecificXml)
        {
            Validator.ThrowIfArgumentNull(typeSpecificXml, "typeSpecificXml", "ParseXmlNavNull");

            XPathNavigator itemNav =
                typeSpecificXml.CreateNavigator().SelectSingleNode("explanation-of-benefits");

            Validator.ThrowInvalidIfNull(itemNav, "ExplanationOfBenefitsUnexpectedNode");

            _dateSubmitted = XPathHelper.GetOptNavValue<HealthServiceDateTime>(itemNav, "date-submitted");
            _patient = XPathHelper.GetOptNavValue<PersonItem>(itemNav, "patient");
            _relationshipToMember = XPathHelper.GetOptNavValue<CodableValue>(itemNav, "relationship-to-member");
            _plan = XPathHelper.GetOptNavValue<Organization>(itemNav, "plan");
            _groupId = XPathHelper.GetOptNavValue(itemNav, "group-id");
            _memberId = itemNav.SelectSingleNode("member-id").Value;
            _claimType = XPathHelper.GetOptNavValue<CodableValue>(itemNav, "claim-type");
            _claimId = itemNav.SelectSingleNode("claim-id").Value;
            _submittedBy = XPathHelper.GetOptNavValue<Organization>(itemNav, "submitted-by");
            _provider = XPathHelper.GetOptNavValue<Organization>(itemNav, "provider");
            _currency = XPathHelper.GetOptNavValue<CodableValue>(itemNav, "currency");
            _claimTotals = XPathHelper.GetOptNavValue<ClaimAmounts>(itemNav, "claim-totals");

            _services.Clear();
            foreach(XPathNavigator servicesNav in itemNav.Select("services"))
            {
                Service service = new Service();
                service.ParseXml(servicesNav);
                _services.Add(service);
            }
        }
        /// <summary>
        /// Creates a new instance of the <see cref="ExplanationOfBenefits"/> class specifying mandatory values.
        /// </summary>
        ///
        /// <remarks>
        /// This item is not added to the health record until the
        /// <see cref="Microsoft.Health.HealthRecordAccessor.NewItem(HealthRecordItem)"/> method
        /// is called.
        /// </remarks>
        ///
        /// <param name="dateSubmitted">
        /// The date when the claim was submitted.
        /// </param>
        /// <param name="patient">
        /// The name of the patient.
        /// </param>
        /// <param name="plan">
        /// The plan covering this claim.
        /// </param>
        /// <param name="memberId">
        /// The member id of the plan member.
        /// </param>
        /// <param name="claimType">
        /// The type of the claim (medical, dental, etc.)
        /// </param>
        /// <param name="claimId">
        /// The claim id.
        /// </param>
        /// <param name="submittedBy">
        /// The organization that submitted this claim.
        /// </param>
        /// <param name="provider">
        /// The provider that performed the services.
        /// </param>
        /// <param name="currency">
        /// The currency used.
        /// </param>
        /// <param name="claimTotals">
        /// A summary of the financial information about this claim.
        /// </param>
        /// <param name="services">
        /// The service included in this claim.
        /// </param>
        ///
        /// <exception cref="ArgumentException">
        /// If <paramref name="memberId"/> is empty or contains only whitespace.
        /// If <paramref name="claimId"/> is empty or contains only whitespace.
        /// If <paramref name="services"/> is <b>null</b> or doesn't contain any values.            
        /// </exception>
        ///
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="memberId"/> is <b>null</b>.
        /// If <paramref name="claimId"/> is <b>null</b>.
        /// If <paramref name="dateSubmitted"/> is <b>null</b>.            
        /// If <paramref name="patient"/> is <b>null</b>.            
        /// If <paramref name="plan"/> is <b>null</b>.            
        /// If <paramref name="claimType"/> is <b>null</b>.            
        /// If <paramref name="submittedBy"/> is <b>null</b>.            
        /// If <paramref name="provider"/> is <b>null</b>.            
        /// If <paramref name="currency"/> is <b>null</b>.            
        /// If <paramref name="claimTotals"/> is <b>null</b>.            
        /// </exception>
        ///
        public ExplanationOfBenefits(
            HealthServiceDateTime dateSubmitted,
            PersonItem patient,    
            Organization plan,    
            string memberId,    
            CodableValue claimType,    
            string claimId,    
            Organization submittedBy,    
            Organization provider,    
            CodableValue currency,    
            ClaimAmounts claimTotals,    
            IEnumerable<Service> services)
            : base(TypeId)
        {
            DateSubmitted = dateSubmitted;
            Patient = patient;
            Plan = plan;
            MemberId = memberId;
            ClaimType = claimType;
            ClaimId = claimId;
            SubmittedBy = submittedBy;
            Provider = provider;
            Currency = currency;
            ClaimTotals = claimTotals;

            Validator.ThrowIfArgumentNull(services, "services", "ServicesMandatory");

            foreach (Service val in services)
            {
                Services.Add(val);
            }

            if (Services.Count == 0)
            {
                throw Validator.ArgumentException("services", "ServicesMandatory");
            }
        }
        /// <summary>
        /// Populates this <see cref="Service"/> instance from the data in the specified XML.
        /// </summary>
        ///
        /// <param name="navigator">
        /// The XML to get the Service data from.
        /// </param>
        ///
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="navigator"/> parameter is <b>null</b>.
        /// </exception>
        ///
        public override void ParseXml(XPathNavigator navigator)
        {
            Validator.ThrowIfNavigatorNull(navigator);

            _serviceType = XPathHelper.GetOptNavValue<CodableValue>(navigator, "service-type");
            _diagnosis = XPathHelper.GetOptNavValue<CodableValue>(navigator, "diagnosis");
            _billingCode = XPathHelper.GetOptNavValue<CodableValue>(navigator, "billing-code");
            _serviceDates = XPathHelper.GetOptNavValue<DurationValue>(navigator, "service-dates");

            _claimAmounts = new ClaimAmounts();
            _claimAmounts.ParseXml(navigator.SelectSingleNode("claim-amounts"));

            _notes.Clear();
            foreach(XPathNavigator notesNav in navigator.Select("notes"))
            {
                _notes.Add(notesNav.Value);
            }
        }