/// <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 health problem instance from the data in the XML.
        /// </summary>
        /// 
        /// <param name="typeSpecificXml">
        /// The XML to get the health problem data from.
        /// </param>
        /// 
        /// <exception cref="InvalidOperationException">
        /// The first node in <paramref name="typeSpecificXml"/> is not
        /// a health problem node.
        /// </exception>
        /// 
        protected override void ParseXml(IXPathNavigable typeSpecificXml)
        {
            XPathNavigator itemNav =
                typeSpecificXml.CreateNavigator().SelectSingleNode("problem");

            Validator.ThrowInvalidIfNull(itemNav, "ProblemUnexpectedNode");

            _when = new HealthServiceDateTime();
            _when.ParseXml(itemNav.SelectSingleNode("when"));

            // <diagnosis>
            XPathNodeIterator diagnosisIterator =
                itemNav.Select("diagnosis");

            _diagnosis.Clear();
            foreach (XPathNavigator diagnosisNav in diagnosisIterator)
            {
                CodableValue value = new CodableValue();
                value.ParseXml(diagnosisNav);
                _diagnosis.Add(value);
            }

            // <duration>
            XPathNodeIterator durationIterator =
                itemNav.Select("duration");

            _duration.Clear();
            foreach (XPathNavigator durationNav in durationIterator)
            {
                DurationValue value = new DurationValue();
                value.ParseXml(durationNav);
                _duration.Add(value);
            }

            // <importance>
            _importance =
                XPathHelper.GetOptNavValueAsInt(
                    itemNav,
                    "importance");
        }
        /// <summary>
        /// Information related to a medical encounter.
        /// </summary>
        /// 
        /// <param name="typeSpecificXml">
        /// The XML to get the medical encounter data from.
        /// </param>
        /// 
        /// <exception cref="InvalidOperationException">
        /// If the first node in <paramref name="typeSpecificXml"/> is not
        /// a encounter node.
        /// </exception>
        /// 
        protected override void ParseXml(IXPathNavigable typeSpecificXml)
        {
            XPathNavigator itemNav =
                typeSpecificXml.CreateNavigator().SelectSingleNode("encounter");

            Validator.ThrowInvalidIfNull(itemNav, "EncounterUnexpectedNode");

            // when
            _when =
                XPathHelper.GetOptNavValue<HealthServiceDateTime>(itemNav,"when");

            // type
            _type =
                XPathHelper.GetOptNavValue<CodableValue>(itemNav, "type");

            // reason
            _reason =
                XPathHelper.GetOptNavValue(itemNav, "reason");

            // duration
            _duration =
                XPathHelper.GetOptNavValue<DurationValue>(itemNav,"duration");

            // consent-granted
            _consentGranted =
                XPathHelper.GetOptNavValueAsBool(itemNav,"consent-granted");

            // facility
            _facility =
                XPathHelper.GetOptNavValue<Organization>(itemNav, "facility");
        }
        /// <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);
            }
        }
        /// <summary>
        /// Populates this appointment instance from the data in the XML.
        /// </summary>
        /// 
        /// <param name="typeSpecificXml">
        /// The XML to get the appointment data from.
        /// </param>
        /// 
        /// <exception cref="InvalidOperationException">
        /// The first node in <paramref name="typeSpecificXml"/> is not
        /// an appointment node.
        /// </exception>
        /// 
        protected override void ParseXml(IXPathNavigable typeSpecificXml)
        {
            XPathNavigator appointmentNav =
                typeSpecificXml.CreateNavigator().SelectSingleNode("appointment");

            Validator.ThrowInvalidIfNull(appointmentNav, "AppointmentUnexpectedNode");

            // <when>
            _when = new HealthServiceDateTime();
            _when.ParseXml(appointmentNav.SelectSingleNode("when"));

            // <duration>
            _duration =
                XPathHelper.GetOptNavValue<DurationValue>(
                    appointmentNav,
                    "duration");

            // <service>
            XPathNavigator serviceNav =
                appointmentNav.SelectSingleNode("service");
            if (serviceNav != null)
            {
                _service = new CodableValue();
                _service.ParseXml(serviceNav);
            }

            // <clinic>
            XPathNavigator clinicNav =
                appointmentNav.SelectSingleNode("clinic");

            if (clinicNav != null)
            {
                _clinic = new PersonItem();
                _clinic.ParseXml(clinicNav);
            }

            // <specialty>
            XPathNavigator specialtyNav =
                appointmentNav.SelectSingleNode("specialty");
            if (specialtyNav != null)
            {
                _specialty = new CodableValue();
                _specialty.ParseXml(specialtyNav);
            }

            // <status>
            XPathNavigator statusNav =
                appointmentNav.SelectSingleNode("status");
            if (statusNav != null)
            {
                _status = new CodableValue();
                _status.ParseXml(statusNav);
            }

            // <care-class>
            XPathNavigator careClassNav =
                appointmentNav.SelectSingleNode("care-class");
            if (careClassNav != null)
            {
                _careClass = new CodableValue();
                _careClass.ParseXml(careClassNav);
            }
        }