anchor.diff:    Result := 0;
     Item := TStringRec.Create(Value);
   
  -  if FStringToId.TryGetValue(Item, Result) then begin
  -    // Already exists. Increment the usage count of the existing one, and return
  -    FIdToString[Result].IncUsageCount;
  -    Item.Free; // Already exists, Item was search key only
  -    Exit;
  -  end;
  -
  -  // Item does not yet exist
  -  Result := FIdToString.Add(Item);
  -  FStringToId.Add(Item, Result);
  +  Lock;
  +  try
  +    if FStringToId.TryGetValue(Item, Result) then begin
  +      // Already exists. Increment the usage count of the existing one, and return
  +      FIdToString[Result].IncUsageCount;
  +      Item.Free; // Already exists, Item was search key only
  +      Exit;
  +    end;
  +
  +    // Item does not yet exist
  +    Result := FIdToString.Add(Item);
  +    FStringToId.Add(Item, Result);
  +  finally
  +    Unlock;
  +  end;
   end;
   
   function TStringCache.AddAndGet(const P : PChar; const Length : Integer) : string;
  
positive.code: begin
    inherited;
    FRefCount := 0;
    FIsPersistent := false; // Clear the cache when no longer needed
    FStringToId := TDictionary<TStringRec, TStringId>.Create(
      TStringCache.TStringRecValueEqualityComparer.Create);
    FIdToString := TList<TStringRec>.Create;
  
negative.code:   // they are no longer needed. (The alternative, controlled by Persistent,
    // is to keep them - ie make the cache persistent over multiple runs - useful
    // for parsing the same or similar files over and over.)
    AtomicIncrement(FRefCount);
  end;
  
  procedure TStringCache.DecRef;
  begin
    if AtomicDecrement(FRefCount) < 0 then
      raise Exception.Create('String cache refcount cannot be decremented below zero');
  
    // When threadsafe, synchronizing clearing while ensuring the refcount is 0
    // (ie an addref dosn't occur while clearing) is hard without locking around
    // IncRef and DecRef, which is expensive. So just don't clear.
    {$ifndef STRINGCACHE_THREADSAFE}
      // Unless want to keep the strings around for next parse, clear now nothing is
      // using any of them.
      if (FRefCount = 0) and (not Persistent) then
        Clear;
    {$endif}
  end;
  
  procedure TStringCache.Lock;
  begin
    // If not threadsafe, nothing to do here
    {$ifdef STRINGCACHE_THREADSAFE}
      FLock.Acquire;
    {$endif}
  end;
  
  procedure TStringCache.Unlock;
  begin
    // If not threadsafe, nothing to do here
    {$ifdef STRINGCACHE_THREADSAFE}
      FLock.Release;
    {$endif}
  end;
  
  
  { TStringCache.TStringRec }
  
  