anchor.diff:      , fun mnesia:dirty_next/2
       }.
   
  -
  -%% Generic backend function for folding through tables
  +%% Generic backend function for folding through tables via accessors
   fold_tab(Fun, Acc0, Type, Tab, Spec0, Limit) ->
       {FirstF, _ReadF, _NextF} = Accessors = accessors(Type),
  -    Progress = ds_opts:getopt(progress),
  +    Progress = progress_new(),
       progress_init_output(Progress),
       Spec = normalize_spec(Spec0),
  -    fold_tab(Fun, Acc0, Accessors, Tab, Spec, Limit, Progress, 0, FirstF(Tab)).
  -
  -fold_tab(_Fun, Acc, _Accessors, _Tab, _FieldSpec, 0, Progress, Count, _Key) ->
  -    progress_final_output(Progress, Count),
  +    fold_tab(Fun, Acc0, Accessors, Tab, Spec, Limit, Progress, FirstF(Tab)).
  +
  +fold_tab(_Fun, Acc, _Accessors, _Tab, _Spec, 0, Progress, _Key) ->
  +    progress_final_output(Progress),
       dump_acc(Acc),
       Acc;
  -fold_tab(_Fun, Acc, _Accessors, _Tab, _FieldSpec, _Limit, Progress, Count, '$end_of_table') ->
  -    progress_final_output(Progress, Count),
  +fold_tab(_Fun, Acc, _Accessors, _Tab, _Spec, _Limit, Progress, '$end_of_table') ->
  +    progress_final_output(Progress),
       dump_acc(Acc),
       Acc;
   fold_tab(Fun, Acc0, {_FirstF, ReadF, NextF} = Accessors,
  -         Tab, {FieldSpec, AttrSpecs}=ValueSpecs, Limit, Progress0, Count, Key) ->
  -    Progress = progress_output(Progress0, Acc0, Count+1),
  +         Tab, Spec, Limit, Progress0, Key) ->
       RecL = ReadF(Tab, Key),
  -    FoldF = fun(Rec, FoldAcc) ->
  -                %% The element accessor might crash or throw an error
  -                %% to exclude this instance from the spec.
  -                try Field = elem(FieldSpec, Rec),
  -                    Attrs = [{Attr, elem(AttrSpec, Rec)} || {Attr, AttrSpec} <- AttrSpecs],
  -                    Fun({Field, Attrs}, FoldAcc)
  -                catch _:_ -> FoldAcc
  -                end
  -            end,
  -    Acc = lists:foldl(FoldF, Acc0, RecL),
  -    fold_tab(Fun, Acc, Accessors, Tab, ValueSpecs,
  -             counter_dec(Limit), Progress, Count+1, NextF(Tab, Key)).
  +    RecN = length(RecL),
  +    Progress = progress_update(Progress0, Acc0, RecN),
  +    Acc = fold_kernel(Fun, Acc0, RecL, Spec),
  +    fold_tab(Fun, Acc, Accessors, Tab, Spec,
  +             counter_dec(Limit, RecN), Progress, NextF(Tab, Key)).
  +
  +%% The kernel for folding a list of records into the accumulated spec
  +fold_kernel(Fun, Acc0, RecL, {FieldSpec, AttrSpecs}) ->
  +    FoldF =
  +        fun(Rec, FoldAcc) ->
  +            %% The element accessor might crash or throw an error
  +            %% to exclude this instance from the spec.
  +            try Field = elem(FieldSpec, Rec),
  +                 Attrs = [{Attr, elem(AttrSpec, Rec)} || {Attr, AttrSpec} <- AttrSpecs],
  +                 Fun({Field, Attrs}, FoldAcc)
  +            catch _:_ -> FoldAcc
  +            end
  +        end,
  +    lists:foldl(FoldF, Acc0, RecL).
   
   elem(0, Rec) -> Rec;
   elem(F, Rec) when is_integer(F) -> element(F, Rec);
  
positive.code: spec_tab(Type, Tab, FieldSpec, Limit, Opts) ->
      ds_opts:setopts(Opts),
      fold_tab(fun ds:add/2, ds:new(), Type, Tab, FieldSpec, Limit).
  
  
  %% tuple of accessor funs to iterate tables:
  
negative.code: -module(ds_drv).
  -author("Tom Szilagyi <tomszilagyi@gmail.com>").
  
  -export([ %% ets, dets, mnesia
            spec_tab/4
          , spec_tab/5
          , fold_tab/6
  
            %% disk_log
          , spec_disk_log/3
          , spec_disk_log/4
          , fold_disk_log/5
          ]).
  
  -include_lib("eunit/include/eunit.hrl").
  