/// <summary>
        /// Search for a given segment in subtree of currentPluglet
        /// </summary>
        /// <param name="currentPluglet"></param>
        /// <param name="segmentName"></param>
        /// <param name="missingMandatorySegments"></param>
        /// <returns></returns>
        public static IPluglet FindInSubTree(this IPluglet currentPluglet, string segmentName, string[] segmentDetails, bool ignoreOccurrenceCheck, out string missingMandatorySegments)
        {
            missingMandatorySegments = string.Empty;

            if (currentPluglet == null)
            {
                throw new ArgumentNullException("currentPluglet");
            }

            if (currentPluglet.IsSameSegment(segmentName, segmentDetails, ignoreOccurrenceCheck))
            {
                return(currentPluglet);
            }

            if (currentPluglet.IsMandatory && currentPluglet.IsIgnore == false && currentPluglet.PlugletType == PlugletType.Segment)
            {
                missingMandatorySegments = currentPluglet.Name;
            }

            //if all child nodes are data element then return null
            if (currentPluglet.Children == null ||
                currentPluglet.Children.All(n => n.PlugletType == PlugletType.Data))
            {
                return(null);
            }

            string tmpMissingMandatorySegments;

            foreach (IPluglet child in currentPluglet.Children)
            {
                IPluglet node = child.FindInSubTree(segmentName, segmentDetails, ignoreOccurrenceCheck, out tmpMissingMandatorySegments);

                if ((child.IsMandatory && child.IsIgnore == false) || node != null)
                {
                    missingMandatorySegments = JoinCSVList(missingMandatorySegments, tmpMissingMandatorySegments);
                }

                if (node != null)
                {
                    return(node);
                }
            }

            return(null);
        }
        /// <summary>Get segment pluglet for given segmentName from currentPluglet. Also report missing mandatory segments.</summary>
        /// <param name="currentPluglet"></param>
        /// <param name="segmentName"></param>
        /// <param name="missingMandatorySegments"></param>
        /// <returns></returns>
        public static IPluglet GetSegmentPluglet(this IPluglet currentPluglet, string segmentName, string[] segmentDetails, string firstSegmentName, out string missingMandatorySegments)
        {
            IPluglet nextPluglet = currentPluglet;

            missingMandatorySegments = string.Empty;

            // Special case for first time - Only first time CurrentPluglet will be Loop, otherwise it will be segment always
            if (nextPluglet.PlugletType == PlugletType.Loop)
            {
                nextPluglet = nextPluglet.GetFirstSegment(firstSegmentName);

                // Since below code assume that nextPluglet points to already consumed segment
                // before moving to that check if it matches given segment name
                if (nextPluglet.IsSameSegment(segmentName, segmentDetails, false))
                {
                    return(nextPluglet);
                }
                else if (nextPluglet.IsIgnore == false)
                {
                    missingMandatorySegments = nextPluglet.Name;
                }
            }
            else
            if (nextPluglet.IsSameSegment(segmentName, segmentDetails, false))
            {
                return(nextPluglet);
            }

            IPluglet tmpPluglet;
            string   tmpMissingMandatorySegments;
            int      currentOccur;

            while (nextPluglet != null)
            {
                tmpPluglet = FindPlugletAfter(nextPluglet, segmentName, segmentDetails, out tmpMissingMandatorySegments);

                if ((nextPluglet.IsMandatory && nextPluglet.IsIgnore == false) || tmpPluglet != null)
                {
                    missingMandatorySegments = JoinCSVList(missingMandatorySegments, tmpMissingMandatorySegments);
                }

                if (tmpPluglet != null)
                {
                    return(tmpPluglet);
                }

                tmpPluglet = nextPluglet.Parent;

                if (tmpPluglet != null && tmpPluglet.IsRepeatable)
                {
                    // TODO: Set currentOccur based on number of occurances
                    currentOccur = tmpPluglet.CurrentOccurrences;

                    if (tmpPluglet.RepetitionInfo.MaxOccurs == -1 || tmpPluglet.RepetitionInfo.MaxOccurs > currentOccur)
                    {
                        tmpPluglet = FindPlugletBefore(nextPluglet, segmentName, segmentDetails, out tmpMissingMandatorySegments);
                        if (tmpPluglet != null)
                        {
                            // Reset max occurrences for all childs as we are going back to loop
                            nextPluglet.Parent.ResetCurrentOccurances();
                            missingMandatorySegments = JoinCSVList(missingMandatorySegments, tmpMissingMandatorySegments);

                            return(tmpPluglet);
                        }
                    }
                }

                nextPluglet = nextPluglet.Parent;
            }

            return(nextPluglet);
        }