anchor.diff:  
   procedure TAppStringSeparator.Init(const AStr: string; ASep: char);
   begin
  -  Str:= AStr;
  -  Sep:= ASep;
  -  N1:= 0;
  -  N2:= 0;
  +  FStr:= AStr;
  +  FSep:= ASep;
  +  FPos:= 1;
   end;
   
   function TAppStringSeparator.GetItemStr(out AValue: string): boolean;
  -begin
  -  N2:= PosEx(Sep, Str, N1+1);
  -  if N2=0 then
  -    N2:= Length(Str)+1;
  -  AValue:= Copy(Str, N1+1, N2-N1-1);
  -  N1:= N2;
  -  Result:= AValue<>'';
  +var
  +  N: integer;
  +begin
  +  if FPos>Length(FStr) then
  +  begin
  +    AValue:= '';
  +    exit(false);
  +  end;
  +  N:= PosEx(FSep, FStr, FPos);
  +  if N=0 then
  +    N:= Length(FStr)+1;
  +  AValue:= Copy(FStr, FPos, N-FPos);
  +  FPos:= N+1;
  +  Result:= true;
   end;
   
   function TAppStringSeparator.GetItemInt(out AValue: integer; const ADefault: integer): boolean;
  
positive.code: 
    TAppStringSeparator = record
    private
      Sep: char;
      Str: string;
      N1, N2: integer;
    public
      procedure Init(const AStr: string; ASep: char=',');
      function GetItemStr(out AValue: string): boolean;
      function GetItemInt(out AValue: integer; const ADefault: integer): boolean;
    end;
  
  implementation
  
  
negative.code:     AValue:= ADefault;
  end;
  
  procedure TestStringSeparator;
  var
    sep: TAppStringSeparator;
    res, item: string;
  begin
    sep.init(',,1,,,4', ',');
    res:= '';
    while sep.GetItemStr(item) do
      res+= item+','#10;
    ShowMessage(res);
  end;
  
  end.
  
  