public <T extends PsiElement> void registerReferenceProvider(@NotNull ElementPattern<T> pattern,
                                                               @NotNull PsiReferenceProvider provider,
                                                               double priority,
                                                               @Nullable Disposable parentDisposable) {
    if (myInitialized && !ApplicationManager.getApplication().isUnitTestMode() && parentDisposable == null) {
      LOG.error("Reference provider registration is only allowed from PsiReferenceContributor");
    }

    Class<?> scope = pattern.getCondition().getInitialCondition().getAcceptedClass();
    List<PatternCondition<? super T>> conditions = pattern.getCondition().getConditions();
    for (PatternCondition<? super T> _condition : conditions) {
      if (!(_condition instanceof PsiNamePatternCondition)) {
        continue;
      }
      PsiNamePatternCondition<?> nameCondition = (PsiNamePatternCondition<?>)_condition;
      List<PatternCondition<? super String>> conditions1 = nameCondition.getNamePattern().getCondition().getConditions();
      for (PatternCondition<? super String> condition1 : conditions1) {
        if (condition1 instanceof ValuePatternCondition) {
          Collection<String> strings = ((ValuePatternCondition)condition1).getValues();
          registerNamedReferenceProvider(ArrayUtilRt.toStringArray(strings), nameCondition, scope, true, provider, priority, pattern,
                                         parentDisposable);
          return;
        }
        if (condition1 instanceof CaseInsensitiveValuePatternCondition) {
          String[] strings = ((CaseInsensitiveValuePatternCondition)condition1).getValues();
          registerNamedReferenceProvider(strings, nameCondition, scope, false, provider, priority, pattern, parentDisposable);
          return;
        }
      }
      break;
    }

    SimpleProviderBinding providerBinding = myBindingsMap.get(scope);
    if (providerBinding == null) {
      myBindingsMap.put(scope, providerBinding = new SimpleProviderBinding());
    }
    providerBinding.registerProvider(provider, pattern, priority);
    if (parentDisposable != null) {
      Disposable disposable = new Disposable() {
        @Override
        public void dispose() {
          PsiReferenceRegistrarImpl.this.unregisterReferenceProvider(scope, provider);
          myCleanupDisposables.remove(this);
        }

        @Override
        public String toString() {
          return "PsiReferenceRegistrarImpl cleanuper for " + provider +" ("+provider.getClass()+")";
        }
      };
      Disposer.register(parentDisposable, disposable);
      myCleanupDisposables.add(disposable);
    }

    clearBindingsCache();
  }
public <T extends PsiElement> void registerReferenceProvider(@NotNull ElementPattern<T> pattern,
                                                               @NotNull PsiReferenceProvider provider,
                                                               double priority,
                                                               @Nullable Disposable parentDisposable)