@NotNull PreCachedDataContext prependProvider(@Nullable Object dataProvider) {
    if (dataProvider == null) return this;
    boolean isEDT = EDT.isCurrentThreadEdt();
    int keyCount;
    FList<ProviderData> cachedData;
    MySink sink = new MySink();
    while (true) {
      Component component = dereference(myComponentRef.ref);
      sink.keys = null;
      sink.hideEditor = hideEditor(component);
      cacheProviderData(sink, dataProvider, myDataManager);
      cachedData = sink.map == null ? myCachedData : myCachedData.prepend(sink.map);
      // do not provide CONTEXT_COMPONENT in BGT
      cachedData = runSnapshotRules(sink, isEDT ? component : null, cachedData);
      keyCount = sink.keys == null ? DataKey.allKeysCount() : sink.keys.length;
      // retry if the provider adds new keys
      if (keyCount == DataKey.allKeysCount()) break;
    }
    AtomicReference<KeyFMap> userData = new AtomicReference<>(KeyFMap.EMPTY_MAP);
    return this instanceof InjectedDataContext
           ? new InjectedDataContext(myComponentRef, cachedData, userData, myDataManager, keyCount)
           : new PreCachedDataContext(myComponentRef, cachedData, userData, myDataManager, keyCount);
  }
@NotNull PreCachedDataContext prependProvider(@Nullable Object dataProvider)