/// <summary>
        /// Adds <see cref="HierarchicalLoop"/> to the current container with the provided segment string
        /// </summary>
        /// <param name="segmentString">String of loop to be added</param>
        /// <returns>Loop created from segment string</returns>
        /// <exception cref="TransactionValidationException">Thrown if the transaction has been previously added
        /// of if the transaction specification is null</exception>
        /// <exception cref="InvalidOperationException">Thrown if the current loop container doesn't have a valid
        /// parent</exception>
        public HierarchicalLoop AddHLoop(string segmentString)
        {
            Transaction transaction = this.Transaction;

            var hl = new HierarchicalLoop(this, this.DelimiterSet, segmentString);

            HierarchicalLoopContainer specContainer = this;

            while (!(specContainer is HierarchicalLoopContainer && specContainer.HasHierachicalSpecs()))
            {
                if (specContainer.Parent is HierarchicalLoopContainer)
                {
                    specContainer = (HierarchicalLoopContainer)specContainer.Parent;
                }
                else
                {
                    throw new InvalidOperationException(
                              string.Format(Resources.InvalidHLSpecError, segmentString));
                }
            }

            if (specContainer is Transaction)
            {
                hl.Specification = transaction.Specification.HierarchicalLoopSpecifications.FirstOrDefault(
                    hls => hls.LevelCode == null || hls.LevelCode.ToString() == hl.LevelCode);
            }

            if (specContainer is HierarchicalLoop hLoopWithSpec)
            {
                hl.Specification = hLoopWithSpec.Specification.HierarchicalLoopSpecifications.FirstOrDefault(
                    hls => hls.LevelCode == null || hls.LevelCode.ToString() == hl.LevelCode);
            }

            if (specContainer is Loop loopWithSpec)
            {
                hl.Specification = loopWithSpec.Specification.HierarchicalLoopSpecifications.FirstOrDefault(
                    hls => hls.LevelCode == null || hls.LevelCode.ToString() == hl.LevelCode);
            }

            if (hl.Specification == null)
            {
                throw new TransactionValidationException(
                          Resources.TransactionHLCodeError,
                          transaction.IdentifierCode,
                          transaction.ControlNumber,
                          "HL03",
                          hl.LevelCode);
            }

            this.hLoops.Add(hl.Id, hl);

            // loop id must be unique throughout the transaction
            try
            {
                specContainer.AddToHLoopDictionary(hl);
            }
            catch (ArgumentException)
            {
                throw new TransactionValidationException(
                          Resources.UnableToAddHLoop,
                          transaction.IdentifierCode,
                          transaction.ControlNumber,
                          "HL01",
                          hl.Id);
            }

            return(hl);
        }
 /// <summary>
 /// Adds a provided <see cref="HierarchicalLoop"/> to the container
 /// </summary>
 /// <param name="hloop">Loop to be added</param>
 /// <exception cref="ArgumentException">Thrown if the loop ID is not unique</exception>
 internal void AddToHLoopDictionary(HierarchicalLoop hloop)
 {
     this.AllHLoops.Add(hloop.Id, hloop);
 }