anchor.diff:  
   { TmPivoter }
   
  -function TmPivoter.GetIndexKeyValue(aValue: Variant; aGroupByDef: TmGroupByDef): string;
  +function TmPivoter.GetIndexKeyValue(const aValue: Variant; out aActualValue : Variant; const aGroupByDef: TmGroupByDef): string;
     function TryToConvertToDate (aSource : Variant) : TDateTime;
     begin
       try
  
positive.code:       tmpValue := FDataProvider.GetDatum(i).GetPropertyByFieldName(FVerticalGroupByDefs.Get(k).FieldName);
        // tmpKeyValue is the calculate value based on tmpValue which is the actual value
        // GetIndexKeyValue apply the GroupByOperator of the GroupByDef to the actual value
        tmpKeyValue := GetIndexKeyValue(tmpValue, FVerticalGroupByDefs.Get(k));
        FVerticalValues.Get(k).AddValueIfMissing(tmpKeyValue);
        if parentKeyValue <> EMPTY_STRING_VALUE then
          tmpIndex := tmpIndex.AddSubIndexForKey(parentKeyValue);
        parentKeyValue := tmpKeyValue;
        tmpIndex.AddValueIfMissing(tmpKeyValue);
  
        currentCoord := BuildKey(currentCoord, tmpKeyValue);
      end;
  
      tmpIndex := FHorizontalKeysIndex;
      parentKeyValue := EMPTY_STRING_VALUE;
      for k := 0 to FHorizontalGroupByDefs.Count -1 do
      begin
        tmpValue := FDataProvider.GetDatum(i).GetPropertyByFieldName(FHorizontalGroupByDefs.Get(k).FieldName);
        tmpKeyValue := GetIndexKeyValue(tmpValue, FHorizontalGroupByDefs.Get(k));
        FHorizontalValues.Get(k).AddValueIfMissing(tmpKeyValue);
        if parentKeyValue <> EMPTY_STRING_VALUE then
          tmpIndex := tmpIndex.AddSubIndexForKey(parentKeyValue);
        parentKeyValue := tmpKeyValue;
        tmpIndex.AddValueIfMissing(tmpKeyValue);
  
        currentCoord := BuildKey(currentCoord, tmpKeyValue);
      end;
  
      tmpList := FRecordCoordinates.Find(currentCoord) as TCardinalList;
  
negative.code: 
  var
    y, m, d : word;
    tmpInt : Integer;
    tmpDouble : double;
  begin
    aActualValue:= Null;
  
    case aGroupByDef.OperationKind of
      gpoDistinct:
      begin
        Result := VarToStr(aValue);
        aActualValue:= aValue;
      end;
      gpoDateYear:
      begin
        tmpInt := YearOf(TryToConvertToDate(aValue));
        aActualValue:= tmpInt;
        Result := IntToStr(tmpInt);
      end;
      gpoDateMonth:
      begin
        tmpInt := MonthOf(TryToConvertToDate(aValue));
        aActualValue:= tmpInt;
        Result := IntToStr(tmpInt);
      end;
      gpoDateTheMonth:
      begin
        DecodeDate(TryToConvertToDate(aValue), y, m, d);
        aActualValue:= EncodeDate(y, m, 1);
        Result := IntToStr(y) + '-' + IntToStr(m);
      end;
      gpoDateDay:
      begin
        tmpInt := DayOf(TryToConvertToDate(aValue));
        aActualValue:= tmpInt;
        Result := IntToStr(tmpInt);
      end;
      gpoDateTheDay:
      begin
        DecodeDate(TryToConvertToDate(aValue), y, m, d);
        aActualValue:= aValue;
        Result := IntToStr(y) + '-' + IntToStr(m) + '-' + IntToStr(d);
      end;
      gpoDateQuarter:
      begin
        tmpInt := ((MonthOf(TryToConvertToDate(aValue)) - 1) div 3) + 1;
        aActualValue:= tmpInt;
        Result := IntToStr(tmpInt);
      end;
      gpoDateTheQuarter:
      begin
        DecodeDate(TryToConvertToDate(aValue), y, m, d);
        tmpInt := ((m - 1) div 3) + 1;
        Result := IntToStr(y) + '-' + IntToStr(tmpInt);
        aActualValue:= EncodeDate(y, (tmpInt -1) * 3, 1);
      end;
      gpoFirstLetter:
        begin
          Result := VarToStr(aValue);
          if Length(Result) > 0 then
            Result := Copy(Result,1,1);
          aActualValue:= Result;
        end;
      else
        raise Exception.Create('[TmPivoter.GetIndexKeyValue] Unknown operation kind');
    end;
  end;
  
  procedure TmPivoter.DoSortIndex(aIndex: TmKeysIndex; const aGroupByDefs: TmGroupByDefs);
  var
    i : integer;
  begin
    if not Assigned(aIndex) then
      exit;
  
    if aGroupByDefs.Count <= aIndex.Level then
      exit;
  
    if aGroupByDefs.Get(aIndex.Level).SortBy = stAscending then
      aIndex.SortAscending
    else
    if aGroupByDefs.Get(aIndex.Level).SortBy = stDescending then
      aIndex.SortDescending;
  
    for i := 0 to aIndex.KeyValuesCount - 1 do
      DoSortIndex(aIndex.GetSubIndex(i), aGroupByDefs);
  end;
  
  constructor TmPivoter.Create;
  