using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Text.RegularExpressions;
using Au.Gov.Sbr.Xbrl.Document;
using DataContracts;
using Au.Gov.Sbr.Xbrl.Metadata;

namespace Ato.EN.IntegrationServices.CodeGenerationCHTWTHHLDBENTFN
{
    public class CHTWTHHLDBEN2018Consumer
    {

        private static Regex StripWhitespace = new Regex(@"\s*");

        #region Helper/Validation Methods
        private static bool? ToBoolean(string str)
        {
            bool returnValue;
            string value = (str ?? "").Trim();
            if (value == "0" || value == "1")
                return Convert.ToBoolean(Convert.ToInt32(value));
            
            if (Boolean.TryParse(value, out returnValue))
                return returnValue;
            return null;
        }

        private static string GetValueOrEmpty(bool? val)
        {
            return (val.HasValue) ? val.ToString() : string.Empty;
        }

        private static string GetValueOrEmpty(DateTime? val)
        {
            return (val.HasValue) ? val.ToString() : string.Empty;
        }

        /// <summary>
        /// Derives the SBR element location.
        /// </summary>
        /// <param name="sbrElement">The SBR element.</param>
        /// <param name="addOccurrenceIndex">if set to <c>true</c> [add occurrence the occurrence index to the path].</param>
        /// <returns></returns>
        private static string DeriveSbrElementLocation(SBRElement sbrElement, bool addOccurrenceIndex = false)
        {
            if (sbrElement == null) return "/xbrli:xbrl";
            int xpathOccurrence = sbrElement.OccurrenceIndex + 1;
            string location;

            if (addOccurrenceIndex)
            {
                location = "/" + sbrElement.NamespacePrefix + ":" + sbrElement.Name + "[" +
                           xpathOccurrence + "]";
            }
            else
            {
                location = "/" + sbrElement.NamespacePrefix + ":" + sbrElement.Name;
            }

            if (sbrElement.IsInTuple)
            {
                location = DeriveSbrElementLocation(sbrElement.ParentTuple, true) + location;
            }
            else
            {
                location = "/xbrli:xbrl" + location;
            }

            return location;
        }

        private static bool IsMatch(int? field, string expression, RegexOptions options = RegexOptions.None)
        {
            if (field == null)
                return false;
            else
                return Regex.IsMatch(Convert.ToString(field.Value), expression, options);
        }

        private static bool IsMatch(string field, string expression, RegexOptions options = RegexOptions.None)
        {
            if (field == null)
                return false;
            else
                return Regex.IsMatch(field, expression, options);
        }

        public DateTime AsDate(string dateAsString)
        {
            DateTime response = DateTime.MinValue;
            DateTime date;

            if (DateTime.TryParse(dateAsString, out date))
            {
                response = date;
            }

            return response;
        }

         #endregion

        public CHTWTHHLDBEN2018 Consume(SBRDocument sbrDocument)
        {
            List<ProcessMessageDocument> errors;
            return Consume(sbrDocument, false, out errors);
        }

        /// <summary>
        /// Allows for validation of rules that can not be generated and must run at a lower level.
        /// A sub-class will need to be created with an override for this method - which does nothing in its base implementation.
        /// </summary>
        /// <param name="sbrDocument">The SBR document.</param>
        /// <param name="populatedReportElementsMap">The populated report elements map can be used to find data elements and tuples.</param>
        /// <param name="contextArray">The context array can be used to find context values.</param>
        /// <param name="errors">The errors collection is to be populated with validation results.</param>
        protected virtual void ValidateUnsupportedRules(SBRDocument sbrDocument, IDictionary<string, SBRElement> populatedReportElementsMap, SBRContext[] contextArray, List<ProcessMessageDocument> errors)
        {

        }

        public CHTWTHHLDBEN2018 Consume(SBRDocument sbrDocument, bool validationMode, out List<ProcessMessageDocument> errors)
        {
            CHTWTHHLDBEN2018 report;
            report = new CHTWTHHLDBEN2018();
            errors = new List<ProcessMessageDocument>();

            SBRContext[] contextArray;
            IDictionary<string, SBRElement> populatedReportElementsMap;

            contextArray = sbrDocument.ContextsMap.Values.ToArray();
            populatedReportElementsMap = sbrDocument.PopulatedChildElementsMap ?? new Dictionary<string, SBRElement>();

            if (validationMode) ValidateUnsupportedRules(sbrDocument, populatedReportElementsMap, contextArray, errors);

            /// <summary>
            /// Current element being extracted
            /// </summary>
            SBRElement currentValue = null;
            /// <summary>
            /// Current elements being extracted
            /// </summary>
            IList<SBRElement> currentValues = null;
            /// <summary>
            /// Current occurrences being extracted
            /// </summary>
            IList<SBRElement> currentOccurrences = null;
            /// <summary>
            /// Working Variable for date time variables
            /// </summary>
            DateTime currentDateTimeValue;
            /// <summary>
            /// Working Variable for boolean variables
            /// </summary>
            bool currentBooleanValue;
            /// <summary>
            /// Working Variable for decimal variables
            /// </summary>
            decimal currentDecimalValue;
            /// <summary>
            /// Working Variable for integer variables
            /// </summary>
            int currentIntValue;
            /// <summary>
            /// Working Variable for long variables
            /// </summary>
            long currentLongValue;
            XmlDocumentFragment currentSegment;
            XmlNamespaceManager currentNamespaceManager;
            XmlNode currentNode;
    
            #region sbrBeneficiaryContext
            IEnumerable<SBRContext> sbrBeneficiaryContexts = null;
            SBRContext sbrBeneficiaryContext = null;
    
            sbrBeneficiaryContexts = contextArray.Where(
                c => c.Period != null && c.Period.PeriodType == SBRPeriod_PeriodType.DURATION &&
                c.Segment != null && c.Segment.ExplicitOrTypedDimensionDomains.Count == 1 && 
                (c.Segment.ExplicitOrTypedDimensionDomains.Any(dd => dd.DimensionType == SBRExplicitOrTypedDimensionDomain_Type.EXPLICIT && dd.Dimension.EndsWith("}ReportPartyTypeDimension") && ((SBRExplicitDimensionDomain)dd).Domain.EndsWith("}Beneficiary")) ));
            Dictionary<string, IList<SBRElement>> sbrPopulatedBeneficiaryElementsMap = new Dictionary<string, IList<SBRElement>>();
            if (sbrBeneficiaryContexts != null && sbrBeneficiaryContexts.Count() > 0)
            {
                sbrBeneficiaryContext = sbrBeneficiaryContexts.First();
        
                report.BeneficiaryId = sbrBeneficiaryContext.Id;
                report.BeneficiaryIdentifier = sbrBeneficiaryContext.EntityIdentifier;
                report.BeneficiaryIdentifierScheme = sbrBeneficiaryContext.EntityScheme;
        
                report.BeneficiaryCount = sbrBeneficiaryContexts.Count();
                report.BeneficiaryExists = true;
                report.BeneficiaryOccurrenceIndex = Array.IndexOf(contextArray, sbrBeneficiaryContext) + 1;
                report.BeneficiaryLastOccurrenceIndex = Array.IndexOf(contextArray, sbrBeneficiaryContexts.Last()) + 1;
        

                if (report.BeneficiaryIdentifierScheme == "http://www.sbr.gov.au/id") report.BeneficiaryIdentifierID = report.BeneficiaryIdentifier;
    
                report.BeneficiaryStartDate = ((SBRDurationPeriod)sbrBeneficiaryContext.Period).DurationStartAsDateObject;
                report.BeneficiaryEndDate = ((SBRDurationPeriod)sbrBeneficiaryContext.Period).DurationEndAsDateObject;
        
                sbrPopulatedBeneficiaryElementsMap = new System.Collections.Generic.Dictionary<string, IList<SBRElement>>();
                for (int i = 0; i < sbrBeneficiaryContexts.Count(); i++)
                {
                    sbrBeneficiaryContext = sbrBeneficiaryContexts.ElementAt(i);
            
                    IList<SBRElement> elements = sbrDocument.ElementsByContextId[sbrBeneficiaryContext.Id];
                    if (elements != null)
                    {
                        for (int e = 0; e < elements.Count(); e++)
                        {
                            SBRElement currentElement = elements[e];
                            if (currentElement == null || currentElement.IsInTuple) continue; // Don't add tuple elements here, they will be found through a different map.
                            if (sbrPopulatedBeneficiaryElementsMap.ContainsKey("{" + currentElement.Namespace + "}" + currentElement.Name))
                            {
                                sbrPopulatedBeneficiaryElementsMap["{" + currentElement.Namespace + "}" + currentElement.Name].Add(currentElement);
                            }
                            else
                            {
                                sbrPopulatedBeneficiaryElementsMap.Add("{" + currentElement.Namespace + "}" + currentElement.Name, new List<SBRElement> { currentElement } );
                            }
                        }
                    }
                    report.CHTWTHHLDBEN57 = report.BeneficiaryIdentifier;
            
                    if (sbrPopulatedBeneficiaryElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}Identifiers.TaxFileNumber.Identifier", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN52 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}IncomeTax.BeneficiaryEntityType.Code", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN21 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}IncomeTax.PayAsYouGoWithholding.TaxWithheld.Amount", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN45 = decimal.Parse(currentValues[0].Value);
                    }
            
                    if (sbrPopulatedBeneficiaryElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}IncomeTax.PayAsYouGoWithholding.PaymentGross.Amount", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN46 = decimal.Parse(currentValues[0].Value);
                    }
            
                    if (sbrPopulatedBeneficiaryElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}PersonNameDetails.Title.Text", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN22 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}PersonNameDetails.FamilyName.Text", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN23 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}PersonNameDetails.GivenName.Text", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN24 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}PersonNameDetails.OtherGivenName.Text", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN25 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}PersonDemographicDetails.Birth.Date", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN26 = DateTime.Parse(currentValues[0].Value);
                    }
            
                    if (sbrPopulatedBeneficiaryElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}OrganisationNameDetails.OrganisationalName.Text", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN32 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}Identifiers.AustralianBusinessNumber.Identifier", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN33 = currentValues[0].Value;
                    }
                } 
            } 
            #endregion End of Context sbrBeneficiaryContext
    
            #region sbrBeneficiaryPostalContext
            IEnumerable<SBRContext> sbrBeneficiaryPostalContexts = null;
            SBRContext sbrBeneficiaryPostalContext = null;
    
            sbrBeneficiaryPostalContexts = contextArray.Where(
                c => c.Period != null && c.Period.PeriodType == SBRPeriod_PeriodType.DURATION &&
                c.Segment != null && c.Segment.ExplicitOrTypedDimensionDomains.Count == 2 && 
                (c.Segment.ExplicitOrTypedDimensionDomains.Any(dd => dd.DimensionType == SBRExplicitOrTypedDimensionDomain_Type.EXPLICIT && dd.Dimension.EndsWith("}ReportPartyTypeDimension") && ((SBRExplicitDimensionDomain)dd).Domain.EndsWith("}Beneficiary"))  && 
                (c.Segment.ExplicitOrTypedDimensionDomains.Any(dd => dd.DimensionType == SBRExplicitOrTypedDimensionDomain_Type.EXPLICIT && dd.Dimension.EndsWith("}AddressUsageDimension") && ((SBRExplicitDimensionDomain)dd).Domain.EndsWith("}POS")) )));
            Dictionary<string, IList<SBRElement>> sbrPopulatedBeneficiaryPostalElementsMap = new Dictionary<string, IList<SBRElement>>();
            if (sbrBeneficiaryPostalContexts != null && sbrBeneficiaryPostalContexts.Count() > 0)
            {
                sbrBeneficiaryPostalContext = sbrBeneficiaryPostalContexts.First();
        
                report.BeneficiaryPostalId = sbrBeneficiaryPostalContext.Id;
                report.BeneficiaryPostalIdentifier = sbrBeneficiaryPostalContext.EntityIdentifier;
                report.BeneficiaryPostalIdentifierScheme = sbrBeneficiaryPostalContext.EntityScheme;
        
                report.BeneficiaryPostalCount = sbrBeneficiaryPostalContexts.Count();
                report.BeneficiaryPostalExists = true;
                report.BeneficiaryPostalOccurrenceIndex = Array.IndexOf(contextArray, sbrBeneficiaryPostalContext) + 1;
                report.BeneficiaryPostalLastOccurrenceIndex = Array.IndexOf(contextArray, sbrBeneficiaryPostalContexts.Last()) + 1;
        

                if (report.BeneficiaryPostalIdentifierScheme == "http://www.sbr.gov.au/id") report.BeneficiaryPostalIdentifierID = report.BeneficiaryPostalIdentifier;
    
                report.BeneficiaryPostalStartDate = ((SBRDurationPeriod)sbrBeneficiaryPostalContext.Period).DurationStartAsDateObject;
                report.BeneficiaryPostalEndDate = ((SBRDurationPeriod)sbrBeneficiaryPostalContext.Period).DurationEndAsDateObject;
        
                sbrPopulatedBeneficiaryPostalElementsMap = new System.Collections.Generic.Dictionary<string, IList<SBRElement>>();
                for (int i = 0; i < sbrBeneficiaryPostalContexts.Count(); i++)
                {
                    sbrBeneficiaryPostalContext = sbrBeneficiaryPostalContexts.ElementAt(i);
            
                    IList<SBRElement> elements = sbrDocument.ElementsByContextId[sbrBeneficiaryPostalContext.Id];
                    if (elements != null)
                    {
                        for (int e = 0; e < elements.Count(); e++)
                        {
                            SBRElement currentElement = elements[e];
                            if (currentElement == null || currentElement.IsInTuple) continue; // Don't add tuple elements here, they will be found through a different map.
                            if (sbrPopulatedBeneficiaryPostalElementsMap.ContainsKey("{" + currentElement.Namespace + "}" + currentElement.Name))
                            {
                                sbrPopulatedBeneficiaryPostalElementsMap["{" + currentElement.Namespace + "}" + currentElement.Name].Add(currentElement);
                            }
                            else
                            {
                                sbrPopulatedBeneficiaryPostalElementsMap.Add("{" + currentElement.Namespace + "}" + currentElement.Name, new List<SBRElement> { currentElement } );
                            }
                        }
                    }
            
                    if (sbrPopulatedBeneficiaryPostalElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}AddressDetails.Line1.Text", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN62 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryPostalElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}AddressDetails.Line2.Text", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN63 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryPostalElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}AddressDetails.LocalityName.Text", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN64 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryPostalElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}AddressDetails.StateOrTerritory.Code", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN65 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryPostalElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}AddressDetails.Postcode.Text", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN66 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryPostalElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}AddressDetails.Country.Code", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN61 = currentValues[0].Value;
                    }
                } 
            } 
            #endregion End of Context sbrBeneficiaryPostalContext
    
            #region sbrBeneficiaryResidentialContext
            IEnumerable<SBRContext> sbrBeneficiaryResidentialContexts = null;
            SBRContext sbrBeneficiaryResidentialContext = null;
    
            sbrBeneficiaryResidentialContexts = contextArray.Where(
                c => c.Period != null && c.Period.PeriodType == SBRPeriod_PeriodType.DURATION &&
                c.Segment != null && c.Segment.ExplicitOrTypedDimensionDomains.Count == 2 && 
                (c.Segment.ExplicitOrTypedDimensionDomains.Any(dd => dd.DimensionType == SBRExplicitOrTypedDimensionDomain_Type.EXPLICIT && dd.Dimension.EndsWith("}ReportPartyTypeDimension") && ((SBRExplicitDimensionDomain)dd).Domain.EndsWith("}Beneficiary"))  && 
                (c.Segment.ExplicitOrTypedDimensionDomains.Any(dd => dd.DimensionType == SBRExplicitOrTypedDimensionDomain_Type.EXPLICIT && dd.Dimension.EndsWith("}AddressUsageDimension") && ((SBRExplicitDimensionDomain)dd).Domain.EndsWith("}RES")) )));
            Dictionary<string, IList<SBRElement>> sbrPopulatedBeneficiaryResidentialElementsMap = new Dictionary<string, IList<SBRElement>>();
            if (sbrBeneficiaryResidentialContexts != null && sbrBeneficiaryResidentialContexts.Count() > 0)
            {
                sbrBeneficiaryResidentialContext = sbrBeneficiaryResidentialContexts.First();
        
                report.BeneficiaryResidentialId = sbrBeneficiaryResidentialContext.Id;
                report.BeneficiaryResidentialIdentifier = sbrBeneficiaryResidentialContext.EntityIdentifier;
                report.BeneficiaryResidentialIdentifierScheme = sbrBeneficiaryResidentialContext.EntityScheme;
        
                report.BeneficiaryResidentialCount = sbrBeneficiaryResidentialContexts.Count();
                report.BeneficiaryResidentialExists = true;
                report.BeneficiaryResidentialOccurrenceIndex = Array.IndexOf(contextArray, sbrBeneficiaryResidentialContext) + 1;
                report.BeneficiaryResidentialLastOccurrenceIndex = Array.IndexOf(contextArray, sbrBeneficiaryResidentialContexts.Last()) + 1;
        

                if (report.BeneficiaryResidentialIdentifierScheme == "http://www.sbr.gov.au/id") report.BeneficiaryResidentialIdentifierID = report.BeneficiaryResidentialIdentifier;
    
                report.BeneficiaryResidentialStartDate = ((SBRDurationPeriod)sbrBeneficiaryResidentialContext.Period).DurationStartAsDateObject;
                report.BeneficiaryResidentialEndDate = ((SBRDurationPeriod)sbrBeneficiaryResidentialContext.Period).DurationEndAsDateObject;
        
                sbrPopulatedBeneficiaryResidentialElementsMap = new System.Collections.Generic.Dictionary<string, IList<SBRElement>>();
                for (int i = 0; i < sbrBeneficiaryResidentialContexts.Count(); i++)
                {
                    sbrBeneficiaryResidentialContext = sbrBeneficiaryResidentialContexts.ElementAt(i);
            
                    IList<SBRElement> elements = sbrDocument.ElementsByContextId[sbrBeneficiaryResidentialContext.Id];
                    if (elements != null)
                    {
                        for (int e = 0; e < elements.Count(); e++)
                        {
                            SBRElement currentElement = elements[e];
                            if (currentElement == null || currentElement.IsInTuple) continue; // Don't add tuple elements here, they will be found through a different map.
                            if (sbrPopulatedBeneficiaryResidentialElementsMap.ContainsKey("{" + currentElement.Namespace + "}" + currentElement.Name))
                            {
                                sbrPopulatedBeneficiaryResidentialElementsMap["{" + currentElement.Namespace + "}" + currentElement.Name].Add(currentElement);
                            }
                            else
                            {
                                sbrPopulatedBeneficiaryResidentialElementsMap.Add("{" + currentElement.Namespace + "}" + currentElement.Name, new List<SBRElement> { currentElement } );
                            }
                        }
                    }
            
                    if (sbrPopulatedBeneficiaryResidentialElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}AddressDetails.Line1.Text", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN39 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryResidentialElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}AddressDetails.Line2.Text", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN40 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryResidentialElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}AddressDetails.LocalityName.Text", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN41 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryResidentialElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}AddressDetails.StateOrTerritory.Code", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN42 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryResidentialElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}AddressDetails.Postcode.Text", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN43 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryResidentialElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}AddressDetails.Country.Code", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN29 = currentValues[0].Value;
                    }
                } 
            } 
            #endregion End of Context sbrBeneficiaryResidentialContext
    
            #region sbrBeneficiaryBusinessContext
            IEnumerable<SBRContext> sbrBeneficiaryBusinessContexts = null;
            SBRContext sbrBeneficiaryBusinessContext = null;
    
            sbrBeneficiaryBusinessContexts = contextArray.Where(
                c => c.Period != null && c.Period.PeriodType == SBRPeriod_PeriodType.DURATION &&
                c.Segment != null && c.Segment.ExplicitOrTypedDimensionDomains.Count == 2 && 
                (c.Segment.ExplicitOrTypedDimensionDomains.Any(dd => dd.DimensionType == SBRExplicitOrTypedDimensionDomain_Type.EXPLICIT && dd.Dimension.EndsWith("}ReportPartyTypeDimension") && ((SBRExplicitDimensionDomain)dd).Domain.EndsWith("}Beneficiary"))  && 
                (c.Segment.ExplicitOrTypedDimensionDomains.Any(dd => dd.DimensionType == SBRExplicitOrTypedDimensionDomain_Type.EXPLICIT && dd.Dimension.EndsWith("}AddressUsageDimension") && ((SBRExplicitDimensionDomain)dd).Domain.EndsWith("}BUS")) )));
            Dictionary<string, IList<SBRElement>> sbrPopulatedBeneficiaryBusinessElementsMap = new Dictionary<string, IList<SBRElement>>();
            if (sbrBeneficiaryBusinessContexts != null && sbrBeneficiaryBusinessContexts.Count() > 0)
            {
                sbrBeneficiaryBusinessContext = sbrBeneficiaryBusinessContexts.First();
        
                report.BeneficiaryBusinessId = sbrBeneficiaryBusinessContext.Id;
                report.BeneficiaryBusinessIdentifier = sbrBeneficiaryBusinessContext.EntityIdentifier;
                report.BeneficiaryBusinessIdentifierScheme = sbrBeneficiaryBusinessContext.EntityScheme;
        
                report.BeneficiaryBusinessCount = sbrBeneficiaryBusinessContexts.Count();
                report.BeneficiaryBusinessExists = true;
                report.BeneficiaryBusinessOccurrenceIndex = Array.IndexOf(contextArray, sbrBeneficiaryBusinessContext) + 1;
                report.BeneficiaryBusinessLastOccurrenceIndex = Array.IndexOf(contextArray, sbrBeneficiaryBusinessContexts.Last()) + 1;
        

                if (report.BeneficiaryBusinessIdentifierScheme == "http://www.sbr.gov.au/id") report.BeneficiaryBusinessIdentifierID = report.BeneficiaryBusinessIdentifier;
    
                report.BeneficiaryBusinessStartDate = ((SBRDurationPeriod)sbrBeneficiaryBusinessContext.Period).DurationStartAsDateObject;
                report.BeneficiaryBusinessEndDate = ((SBRDurationPeriod)sbrBeneficiaryBusinessContext.Period).DurationEndAsDateObject;
        
                sbrPopulatedBeneficiaryBusinessElementsMap = new System.Collections.Generic.Dictionary<string, IList<SBRElement>>();
                for (int i = 0; i < sbrBeneficiaryBusinessContexts.Count(); i++)
                {
                    sbrBeneficiaryBusinessContext = sbrBeneficiaryBusinessContexts.ElementAt(i);
            
                    IList<SBRElement> elements = sbrDocument.ElementsByContextId[sbrBeneficiaryBusinessContext.Id];
                    if (elements != null)
                    {
                        for (int e = 0; e < elements.Count(); e++)
                        {
                            SBRElement currentElement = elements[e];
                            if (currentElement == null || currentElement.IsInTuple) continue; // Don't add tuple elements here, they will be found through a different map.
                            if (sbrPopulatedBeneficiaryBusinessElementsMap.ContainsKey("{" + currentElement.Namespace + "}" + currentElement.Name))
                            {
                                sbrPopulatedBeneficiaryBusinessElementsMap["{" + currentElement.Namespace + "}" + currentElement.Name].Add(currentElement);
                            }
                            else
                            {
                                sbrPopulatedBeneficiaryBusinessElementsMap.Add("{" + currentElement.Namespace + "}" + currentElement.Name, new List<SBRElement> { currentElement } );
                            }
                        }
                    }
            
                    if (sbrPopulatedBeneficiaryBusinessElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}AddressDetails.Line1.Text", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN60 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryBusinessElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}AddressDetails.Line2.Text", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN59 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryBusinessElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}AddressDetails.LocalityName.Text", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN69 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryBusinessElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}AddressDetails.StateOrTerritory.Code", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN70 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryBusinessElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}AddressDetails.Postcode.Text", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN71 = currentValues[0].Value;
                    }
            
                    if (sbrPopulatedBeneficiaryBusinessElementsMap.TryGetValue("{http://www.sbr.gov.au/ato/chtwthhldben}AddressDetails.Country.Code", out currentValues))
                    {
                        if (!currentValues[0].IsNil) report.CHTWTHHLDBEN30 = currentValues[0].Value;
                    }
                } 
            } 
            #endregion End of Context sbrBeneficiaryBusinessContext
            return report;

        } // Of Consume Method
    } // Of Class
} // Of Namespace
