private void SortKeysByValues(string[] keyDims, ValueKey[] keys, object[] values, ListSortDirection sortDirection)
 {
     if (PreserveGroupOrder && keyDims.Length > 1)
     {
         int grpIdx   = keyDims.Length - 2;
         int startIdx = 0;
         for (int i = 1; i < values.Length; i++)
         {
             if (!keys[i].DimKeys[grpIdx].Equals(keys[i - 1].DimKeys[grpIdx]))
             {
                 ArraySortRange(values, keys, startIdx, i - startIdx, sortDirection == ListSortDirection.Descending);
                 startIdx = i;
             }
         }
         // last group
         ArraySortRange(values, keys, startIdx, values.Length - startIdx, sortDirection == ListSortDirection.Descending);
     }
     else
     {
         var comparer = ValuesComparer;
         if (comparer == null && ListValuesComparer.HasListValue(values))
         {
             comparer = new ListValuesComparer();
         }
         Array.Sort(values, keys, comparer);
         if (sortDirection == ListSortDirection.Descending)
         {
             Array.Reverse(keys);
         }
     }
 }
        private void ArraySortRange(object[] values, object[] keys, int start, int len, bool reverse)
        {
            if (len <= 1)
            {
                return;
            }
            var comparer = ValuesComparer;

            if (comparer == null && ListValuesComparer.HasListValue(values))
            {
                comparer = new ListValuesComparer();
            }
            Array.Sort(values, keys, start, len, comparer);
            if (reverse)
            {
                Array.Reverse(keys, start, len);
            }
        }