anchor.diff:  begin
     inherited;
     FRefCount := 0;
  -  FIsPersistent := false; // Clear the cache when no longer needed
  +  {$ifdef STRINGCACHE_THREADSAFE}
  +    FLock := TCriticalSection.Create;
  +  {$else}
  +    FIsPersistent := false; // Clear the cache when no longer needed
  +  {$endif}
     FStringToId := TDictionary<TStringRec, TStringId>.Create(
       TStringCache.TStringRecValueEqualityComparer.Create);
     FIdToString := TList<TStringRec>.Create;
  
positive.code:   strict private
      FStringToId : TDictionary<TStringRec, TStringId>;
      FRefCount : NativeInt;
      FIsPersistent : Boolean;
  
      class var FInstance : TStringCache;
      class constructor ClassCreate;
      class destructor ClassDestroy;
    private
      FIdToString : TList<TStringRec>; // ID is index
    public
      constructor Create;
      destructor Destroy; override;
  
negative.code: 
  function TStringCache.Get(const ID: TStringId): string;
  begin
    Lock;
    try
      if ID < FIdToString.Count then
        Exit(FIdToString[ID].Value)
      else
        raise Exception.Create(Format('String cache entry with ID %d does not exist', [ID]));
    finally
      Unlock;
    end;
  end;
  
  procedure TStringCache.Clear(const OnDestruction : Boolean);
  var
    I : Integer;
  begin
    // This doesn't need a lock. When threadsafe, never cleared except on destruction
  
    if FRefCount <> 0 then
      raise Exception.Create(Format('Clearing the string cache while objects still rely on it (%d)', [FRefCount]));
  
  