public static CqmSolutionDateRange GetDateRange(this IVL_TS ivlts)
        {
            TS low    = null;
            TS high   = null;
            TS center = null;

            if (ivlts?.ItemsElementName == null || ivlts.Items == null || ivlts.ItemsElementName.Length != ivlts.Items.Length)
            {
                center = ivlts; //if there are no items, just use the main value of the IVL_TS, essentially treating it as a single TS
            }
            else
            {
                for (int i = 0; i < ivlts.ItemsElementName.Length; i++)
                {
                    switch (ivlts.ItemsElementName[i])
                    {
                    case ItemsChoiceType2.low:
                        low = ivlts.Items[i] as TS;
                        break;

                    case ItemsChoiceType2.high:
                        high = ivlts.Items[i] as TS;
                        break;

                    case ItemsChoiceType2.center:
                        center = ivlts.Items[i] as TS;
                        break;
                    }
                }
            }

            //Some of our sample data files have effectiveTime nodes with only a single value, not low & high values.
            //If that happens, it represents a Point In Time, so we take that to be both the low and the high value. //TODO: is that correct?
            return(new CqmSolutionDateRange(low?.GetDate() ?? center?.GetDate(), high?.GetDate() ?? center?.GetDate()));
        }
        public static CqmSolutionDateRange GetDateRangeFromArray(this SXCM_TS[] sxcmts)
        {
            if (sxcmts == null || sxcmts.Length == 0)
            {
                return(null);
            }

            //TODO: is this correct?
            TS low  = sxcmts[0];
            TS high = (sxcmts.Length == 1) ? sxcmts[0] : sxcmts[1];

            return(new CqmSolutionDateRange(low?.GetDate(), high?.GetDate()));
        }