anchor.diff:  { TWeakReferencedObject }
   
   procedure TWeakReferencedObject.AddWeakRef(value: Pointer);
  -var
  -  l : integer;
   begin
     MonitorEnter(Self);
     try
  -    l := Length(FWeakReferences);
  -    Inc(l);
  -    SetLength(FWeakReferences,l);
  -    FWeakReferences[l-1] := Value;
  +    if FWeakReferences = nil then
  +      FWeakReferences := TList<Pointer>.Create;
  +    FWeakReferences.Add(value);
     finally
       MonitorExit(Self);
     end;
   end;
   
   procedure TWeakReferencedObject.RemoveWeakRef(value: Pointer);
  -var
  -  l : integer;
  -  i : integer;
  -  idx : integer;
   begin
     MonitorEnter(Self);
     try
  -    l := Length(FWeakReferences);
  -    if l > 0 then
  +    if FWeakReferences = nil then // should never happen
  +      {$IFDEF DEBUG}
  +      raise Exception.Create('FWeakReferences = nil');
  +      {$ELSE}
  +      exit;
  +      {$ENDIF}
  +    FWeakReferences.Remove(value);
  +    if FWeakReferences.Count = 0 then
  +      FreeAndNil(FWeakReferences);
  +  finally
  +    MonitorExit(Self);
  +  end;
  +end;
  +
  +procedure TWeakReferencedObject.AfterConstruction;
  +begin
  +  // Release the constructor's implicit refcount
  +  TInterlocked.Decrement(FRefCount);
  +  //spin for short period of time before
  +  TMonitor.SetSpinCount(Self, 200); //default is 1000
  +end;
  +
  +procedure TWeakReferencedObject.BeforeDestruction;
  +var
  +  value : pointer;
  +  i: Integer;
  +begin
  +  if FRefCount <> 0 then
  +    System.Error(reInvalidPtr);
  +  MonitorEnter(Self);
  +  try
  +    if FWeakReferences <> nil then
       begin
  -      idx := -1;
  -      for i := 0 to l - 1 do
  +      for i := 0 to FWeakReferences.Count -1 do
         begin
  -        if idx <> -1 then
  -        begin
  -          FWeakReferences[i -1] := FWeakReferences[i];
  -        end;
  -        if FWeakReferences[i] = Value then
  -        begin
  -          FWeakReferences[i] := nil;
  -          idx := i;
  -        end;
  +        value := FWeakReferences.Items[i];
  +        TObject(value^) := nil;
         end;
  -      Dec(l);
  -      SetLength(FWeakReferences,l);
  +        FreeAndNil(FWeakReferences);
       end;
     finally
       MonitorExit(Self);
     end;
  -end;
  -
  -procedure TWeakReferencedObject.AfterConstruction;
  -begin
  -  // Release the constructor's implicit refcount
  -  TInterlocked.Decrement(FRefCount);
  -end;
  -
  -procedure TWeakReferencedObject.BeforeDestruction;
  -var
  -  i: Integer;
  -begin
  -  if RefCount <> 0 then
  -    System.Error(reInvalidPtr);
  -  MonitorEnter(Self);
  -  try
  -    for i := 0 to Length(FWeakReferences) - 1 do
  -       TObject(FWeakReferences[i]^) := nil;
  -    SetLength(FWeakReferences,0);
  -  finally
  -    MonitorExit(Self);
  -  end;
  +  inherited;
  +end;
  +
  +destructor TWeakReferencedObject.Destroy;
  +begin
  +  if FDestroyed then
  +    raise Exception.Create('Destroy called when Object already destroyed!');
  +  FDestroyed := true;
  +  inherited;
   end;
   
   function TWeakReferencedObject.GetRefCount: integer;
  
positive.code: 
  function TWeakReferencedObject._AddRef: Integer;
  begin
    Result := TInterlocked.Increment(FRefCount);
  end;
  
  function TWeakReferencedObject._Release: Integer;
  begin
    Result := TInterlocked.Decrement(FRefCount);
    if Result = 0  then
      Destroy;
  end;
  
  
  
negative.code:     destructor Destroy;override;
    end;
  
  //only here to work around compiler limitation.
  function SafeMonitorTryEnter(const AObject: TObject): Boolean;
  
  implementation
  
  