anchor.diff:      sdAscending: Result := snpNullLast;
       sdDescending: Result := snpNullFirst;
     end;
  +end;
  +
  +function TCustomDataSource<T>.GetItemDisposePolicy : TDisposePolicy;
  +begin
  +  Result := idpNone;
   end;
   
   function TCustomDataSource<T>.ApplyColumnSort(constref Left, Right : T; constref AFilter: TColumnFilter) : Integer;
  
positive.code:       FClassID : PtrInt;
      protected
        function GetNullPolicy(const AFilter : TColumnFilter) : TSortNullPolicy; virtual;
        function GetItemDisposePolicy : TDisposePolicy; virtual; abstract;
        function GetColumns : TDataColumns; virtual; abstract;
        function ApplyColumnSort(constref Left, Right : T; constref AFilter: TColumnFilter) : Integer; virtual;
        function ApplyColumnFilter(constref AItem: T; constref AFilter: TColumnFilter) : boolean; virtual;
        function GetItemField(constref AItem: T; const ABindingName : AnsiString) : Variant; virtual; abstract;
        procedure DehydrateItem(constref AItem: T; var ADataRow: Variant);
        function FetchPage(constref AParams: TPageFetchParams; var ADataTable: TDataTable): TPageFetchResult;
        function GetEntityKey(constref AItem: T) : Variant; virtual;
        procedure OnBeforeFetchAll(constref AParams: TPageFetchParams); virtual;
        procedure FetchAll(const AContainer : TList<T>); virtual; abstract;
        procedure OnAfterFetchAll(constref AParams: TPageFetchParams); virtual;
  
negative.code: 
    { TDataTable }
  
    TDataTable = record
      Columns: TDataColumns;
      Rows : TArray<Variant>;
    end;
    PDataTable = ^TDataTable;
    EDataTable = class(Exception);
  
    { TColumnFilterPredicate -- should be implementation only }
  
  