anchor.diff:      property FileSystem : TAbGzFileSystem {Default: osFat (Windows); osUnix (Linux)}
         read GetFileSystem write SetFileSystem;
   
  -    property ExtraField : AnsiString
  -      read FExtraField write SetExtraField;
  +    property ExtraField : TAbGzipExtraField
  +      read FExtraField;
   
       property IsEncrypted : Boolean
         read GetIsEncrypted;
  
positive.code: {$ENDIF MSWINDOWS }
  end;
  
  function TAbGzipItem.GetExternalFileAttributes: LongInt;
  begin
    { GZip has no provision for storing attributes }
  
negative.code:   end;
  end;
  
  { TAbGzipExtraField }
  
  constructor TAbGzipExtraField.Create(aGZHeader : PAbGzHeader);
  begin
    inherited Create;
    FGZHeader := aGZHeader;
  end;
  
  procedure TAbGzipExtraField.Clear;
  begin
    FBuffer := nil;
    FGzHeader.Flags := FGzHeader.Flags and not AB_GZ_FLAG_FEXTRA;
  end;
  
  procedure TAbGzipExtraField.Delete(aID : TAbGzExtraFieldSubID);
  var
    SubField : PAbGzExtraSubField;
  begin
    if FindField(aID, SubField) then begin
      DeleteField(SubField);
      if FBuffer = nil then
        FGzHeader.Flags := FGzHeader.Flags and not AB_GZ_FLAG_FEXTRA;
    end;
  end;
  
  procedure TAbGzipExtraField.DeleteField(aSubField : PAbGzExtraSubField);
  var
    Len, Offset : Integer;
  begin
    Len := SizeOf(TAbGzExtraSubField) + aSubField.Len;
    Offset := Cardinal(aSubField) - Cardinal(FBuffer);
    if Offset + Len < Length(FBuffer) then
      Move(FBuffer[Offset + Len], aSubField^, Length(FBuffer) - Offset - Len);
    SetLength(FBuffer, Length(FBuffer) - Len);
  end;
  
  function TAbGzipExtraField.FindField(aID : TAbGzExtraFieldSubID;
    out aSubField : PAbGzExtraSubField) : Boolean;
  begin
    Result := False;
    aSubField := nil;
    while FindNext(aSubField) do
      if aSubField.ID = aID then begin
        Result := True;
        Break;
      end;
  end;
  
  function TAbGzipExtraField.FindNext(var aCurField : PAbGzExtraSubField) : Boolean;
  var
    BytesLeft : Integer;
  begin
    if aCurField = nil then begin
      aCurField := PAbGzExtraSubField(FBuffer);
      BytesLeft := Length(FBuffer);
    end
    else begin
      BytesLeft := Length(FBuffer) -
        Integer(Cardinal(aCurField) - Cardinal(FBuffer)) -
        SizeOf(TAbGzExtraSubField) - aCurField.Len;
      Inc(Cardinal(aCurField), aCurField.Len + SizeOf(TAbGzExtraSubField));
    end;
    Result := (BytesLeft >= SizeOf(TAbGzExtraSubField));
    if Result and (BytesLeft < SizeOf(TAbGzExtraSubField) + aCurField.Len) then
      aCurField.Len := BytesLeft - SizeOf(TAbGzExtraSubField);
  end;
  
  function TAbGzipExtraField.Get(aID : TAbGzExtraFieldSubID; out aData : Pointer;
    out aDataSize : Word) : Boolean;
  var
    SubField : PAbGzExtraSubField;
  begin
    Result := FindField(aID, SubField);
    if Result then begin
      aData := @SubField.Data;
      aDataSize := SubField.Len;
    end
    else begin
      aData := nil;
      aDataSize := 0;
    end;
  end;
  
  function TAbGzipExtraField.GetCount : Integer;
  var
    SubField : PAbGzExtraSubField;
  begin
    Result := 0;
    SubField := nil;
    while FindNext(SubField) do
      Inc(Result);
  end;
  
  function TAbGzipExtraField.GetID(aIndex : Integer): TAbGzExtraFieldSubID;
  var
    i: Integer;
    SubField : PAbGzExtraSubField;
  begin
    i := 0;
    SubField := nil;
    while FindNext(SubField) do
      if i = aIndex then begin
        Result := SubField.ID;
        Exit;
      end
      else
        Inc(i);
    raise EListError.CreateFmt(SListIndexError, [aIndex]);
  end;
  
  procedure TAbGzipExtraField.Put(aID : TAbGzExtraFieldSubID; const aData;
    aDataSize : Word);
  var
    Offset : Cardinal;
    SubField : PAbGzExtraSubField;
  begin
    FGzHeader.Flags := FGzHeader.Flags or AB_GZ_FLAG_FEXTRA;
    if FindField(aID, SubField) then begin
      if SubField.Len = aDataSize then begin
        Move(aData, SubField.Data, aDataSize);
        Exit;
      end
      else DeleteField(SubField);
    end;
    Offset := Length(FBuffer);
    SetLength(FBuffer, Length(FBuffer) + SizeOf(TAbGzExtraSubField) + aDataSize);
    SubField := PAbGzExtraSubField(@FBuffer[Offset]);
    SubField.ID := aID;
    SubField.Len := aDataSize;
    Move(aData, SubField.Data, aDataSize);
  end;
  
  procedure TAbGzipExtraField.SetBuffer(const aValue : TByteDynArray);
  begin
    SetLength(FBuffer, Length(aValue));
    if Length(FBuffer) > 0 then begin
      Move(aValue[0], FBuffer[0], Length(FBuffer));
      FGzHeader.Flags := FGzHeader.Flags or AB_GZ_FLAG_FEXTRA;
    end
    else
      FGzHeader.Flags := FGzHeader.Flags and not AB_GZ_FLAG_FEXTRA;
  end;
  
  
  { TAbGzipStreamHelper }
  
  