private ReportDataHeaderCollection ParseHeaders(JArray data, string[] tailLabels)
        {
            var headers = new List <ReportDataHeader>();
            int span    = 0;

            for (int i = 0; i < data.Count; i++)
            {
                var header = ParseHeader(data[i], 0, span, tailLabels, i);
                headers.Add(header);
                span += header.Span;
            }

            if (headers.Count == 0)
            {
                return(ReportDataHeaderCollection.Empty);
            }

            // Don't sort the tail columns.

            if (tailLabels != null && headers[0].Children.Count == 0)
            {
                return(ReportDataHeaderCollection.New(headers));
            }

            return(ReportDataHeaderCollection.NewSorted(headers));
        }
        private ReportDataHeader ParseHeader(JToken data, int level, int offset, string[] tailLabels, int tailIndex)
        {
            if (data.Type != JTokenType.Array)
            {
                string label;
                if (tailLabels != null)
                {
                    label = tailLabels[tailIndex];
                }
                else
                {
                    label = (string)data;
                    if (String.IsNullOrEmpty(label))
                    {
                        label = null;
                    }
                }

                return(new ReportDataHeader(
                           label,
                           level,
                           offset,
                           1,
                           ReportDataHeaderCollection.Empty
                           ));
            }

            var subData  = (JArray)data;
            int span     = 0;
            var children = new List <ReportDataHeader>();

            for (int i = 1; i < subData.Count; i++)
            {
                var header = ParseHeader(subData[i], level + 1, offset + span, tailLabels, i - 1);
                children.Add(header);
                span += header.Span;
            }

            if (span == 0)
            {
                span = 1;
            }

            var subLabel = (string)subData[0];

            if (String.IsNullOrEmpty(subLabel))
            {
                subLabel = null;
            }

            // Don't sort the tail columns.

            ReportDataHeaderCollection childHeaders;

            if (children.Count == 0)
            {
                childHeaders = ReportDataHeaderCollection.Empty;
            }
            else if (tailLabels != null && children[0].Children.Count == 0)
            {
                childHeaders = ReportDataHeaderCollection.New(children);
            }
            else
            {
                childHeaders = ReportDataHeaderCollection.NewSorted(children);
            }

            return(new ReportDataHeader(
                       subLabel,
                       level,
                       offset,
                       span,
                       childHeaders
                       ));
        }