anchor.diff:      procedure Calculate;
       function Count : integer;
       procedure Clear;
  -
  -    procedure GetMinMaxValues(var aMin, aMax : double);
  -  end;
  +    function GetDatum(const aIndex : integer) : IVDDatum;
  +    function FindDatumByKey (const aKey : IVDDatumKey): IVDDatum;
  +    function FindDatumByStringKey (const aStringKey : string): IVDDatum;
  +  end;
  +
  +  function TmUprightHighlightTypeToVariant (const aValue : TmUprightHighlightType): Variant;
   
   implementation
   
   uses
  -  Math;
  +  sysutils;
  +
  +function TmUprightHighlightTypeToVariant(const aValue: TmUprightHighlightType): Variant;
  +begin
  +  if aValue = uhMax then
  +    Result := 'MAX'
  +  else if aValue = uhMin then
  +    Result := 'MIN'
  +  else
  +    Result := Null;
  +end;
  +
  +{ TmUprightValueKey }
  +
  +procedure TmUprightValueKey.Assign(aSource: TObject);
  +begin
  +  FPosition := (aSource as TmUprightValueKey).Position;
  +end;
  +
  +function TmUprightValueKey.AsString: string;
  +begin
  +  Result := IntToStr(FPosition);
  +end;
   
   { TmUprightEvent }
  +
  +function TmUprightDatum.GetPosition: integer;
  +begin
  +  Result := FKey.Position;
  +end;
  +
  +constructor TmUprightDatum.Create;
  +begin
  +  FUpright:= 0;
  +  FHighlight:= uhNone;
  +  FKey := TmUprightValueKey.Create;
  +  FLimit := TNullableDouble.Create;
  +  FRemaining := TNullableDouble.Create;
  +end;
  +
  +destructor TmUprightDatum.Destroy;
  +begin
  +  FKey.Free;
  +  FLimit.Free;
  +  FRemaining.Free;
  +end;
   
   constructor TmUprightEvent.Create;
   begin
     EventDate:= 0;
     DatumKey:= '';
  -  Delta:= 0;
  -  Description:= '';
  -  FUpright:= 0;
  +  Value:= 0;
  +  EventType:= etuValue;
  +
  +  FAttribute1 := TNullableString.Create;
  +  FAttribute2 := TNullableString.Create();
   end;
   
   destructor TmUprightEvent.Destroy;
   begin
  +  FAttribute1.Free;
  +  FAttribute2.Free;
     inherited Destroy;
   end;
   
  
positive.code:     Result := 1;
  end;
  
  { TmUpright }
  
  function TmUpright.OnCompare(Item1, Item2: Pointer): Integer;
  begin
    Result := TmUprightEvent(Item1).CompareTo(TmUprightEvent(Item2)) ;
  end;
  
  constructor TmUpright.Create;
  begin
    FList := TFPList.Create;
    FGarbage := TObjectList.Create(true);
  end;
  
  destructor TmUpright.Destroy;
  begin
    FList.Free;
    FGarbage.Free;
    inherited Destroy;
  end;
  
  function TmUpright.Add: TmUprightEvent;
  begin
    Result := TmUprightEvent.Create;
    FList.Add(Result);
    FGarbage.Add(Result);
  end;
  
  procedure TmUpright.Calculate;
  var
    i : integer;
    tmp : TmUprightEvent;
    lastValue : double;
  begin
    MergeSort(FList, OnCompare);
    lastValue := 0;
    for i := 0 to FList.Count -1 do
    begin
      tmp:= TmUprightEvent(FList.Items[i]);
      if i = 0 then
        tmp.FUpright:= tmp.Delta
      else
        tmp.FUpright:= lastValue + tmp.Delta;
      lastValue := tmp.FUpright;
    end;
  end;
  
  function TmUpright.Count: integer;
  begin
    Result := FList.Count;
  end;
  
  procedure TmUpright.Clear;
  begin
    FList.Clear;
    FGarbage.Clear;
  end;
  
  procedure TmUpright.GetMinMaxValues (var aMin, aMax : double);
  var
    i : integer;
    tmp : TmUprightEvent;
  begin
    aMin := 0;
    aMax := 0;
  
    for i := 0 to FList.Count -1 do
    begin
      tmp:= TmUprightEvent(FList.Items[i]);
      if i = 0 then
      begin
        aMin := tmp.FUpright;
        aMax := tmp.FUpright;
      end
      else
      begin
        aMin := Min(aMin, tmp.FUpright);
        aMax := Max(aMax, tmp.FUpright);
      end;
    end;
  end;
  
  end.
  
negative.code: 
  uses
    Classes, contnrs,
    mUtility, mFloatsManagement, mNullables,
    mVirtualDataSetInterfaces, mVirtualFieldDefs;
  
  type
  
    TmUprightHighlightType = (uhNone, uhMax, uhMin);
  
    { TmUprightValueKey }
  
    TmUprightValueKey = class (IVDDatumKey)
    private
      FPosition : integer;
    public
      procedure Assign(aSource : TObject);
      function AsString : string;
  
      property Position : integer read FPosition;
    end;
  
    TmUprightEventType = (etuValue, etuLimit);
  
    { TmUprightEvent }
  
    TmUprightEvent = class
    strict private
      FEventDate : TDateTime;
      FValue : double;
      FAttribute1 : TNullableString;
      FAttribute2 : TNullableString;
      FEventType : TmUprightEventType;
  
      FDatumKey : String;
    public
      constructor Create;
      destructor Destroy; override;
      function CompareTo (aOther : TmUprightEvent) : integer;
  
      property EventDate: TDateTime read FEventDate write FEventDate;
      property Value: double read FValue write FValue;
      property Attribute1 : TNullableString read FAttribute1;
      property Attribute2 : TNullableString read FAttribute2;
      property DatumKey: string read FDatumKey write FDatumKey;
      property EventType : TmUprightEventType read FEventType write FEventType;
    end;
  
    { TmUprightDatum }
  
    TmUprightDatum= class (IVDDatum)
    private
      FEvent : TmUprightEvent;
      FKey : TmUprightValueKey;
      FUpright : double;
      FHighlight : TmUprightHighlightType;
      FLimit : TNullableDouble;
      FRemaining : TNullableDouble;
      function GetPosition: integer;
    public
      const FLD_POSITION = 'POSITION';
      const FLD_DATE = 'DATE';
      const FLD_DELTA = 'DELTA';
      const FLD_UPRIGHT = 'UPRIGHT';
      const FLD_HIGHLIGHT = 'HIGHLIGHT';
      const FLD_LIMIT = 'LIMIT';
      const FLD_REMAINING = 'REMAINING';
      const FLD_ATTRIBUTE1 = 'ATTRIBUTE_1';
      const FLD_ATTRIBUTE2 = 'ATTRIBUTE_2';
    public
      constructor Create;
      destructor Destroy; override;
  
      function GetDatumKey : IVDDatumKey;
      function GetPropertyByFieldName(const aFieldName : String) : Variant;
  
      class procedure FillVirtualFieldDefs (aFieldDefs : TmVirtualFieldDefs; aPrefix : String);
      class function GetKeyField : String;
  
      property Position : integer read GetPosition;
      property Upright: double read FUpright;
      property Highlight : TmUprightHighlightType read FHighlight;
    end;
  
    { TmUpright }
  
    TmUpright = class (IVDListDataProvider)
    strict private
      FGarbage : TObjectList;
      FDataList : TFPList;
      FEventsList : TObjectList;
      FLimitsList : TFPList;
  
      function OnCompareData (Item1, Item2: Pointer): Integer;
      function OnCompareEvents (Item1, Item2: Pointer): Integer;
      procedure CalculateHighlights;
    public
      constructor Create;
      destructor Destroy; override;
  