public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
    if (isReferenceTo(element)) return getElement();

    final String newName;
    if (element instanceof PsiClass) {
      PsiClass psiClass = (PsiClass) element;
      final boolean jvmFormat =
          Boolean.TRUE.equals(JavaClassReferenceProvider.JVM_FORMAT.getValue(getOptions()));
      newName = jvmFormat ? ClassUtil.getJVMClassName(psiClass) : psiClass.getQualifiedName();
    } else if (element instanceof PsiPackage) {
      PsiPackage psiPackage = (PsiPackage) element;
      newName = psiPackage.getQualifiedName();
    } else {
      throw new IncorrectOperationException("Cannot bind to " + element);
    }
    assert newName != null;

    TextRange range =
        new TextRange(
            myJavaClassReferenceSet.getReference(0).getRangeInElement().getStartOffset(),
            getRangeInElement().getEndOffset());
    final ElementManipulator<PsiElement> manipulator = getManipulator(getElement());
    if (manipulator != null) {
      final PsiElement finalElement = manipulator.handleContentChange(getElement(), range, newName);
      range = new TextRange(range.getStartOffset(), range.getStartOffset() + newName.length());
      myJavaClassReferenceSet.reparse(finalElement, range);
      return finalElement;
    }
    return element;
  }
  private void reparse(
      String str, PsiElement element, final boolean isStaticImport, JavaClassReferenceSet context) {
    myElement = element;
    myContext = context;
    final List<JavaClassReference> referencesList = new ArrayList<JavaClassReference>();
    int currentDot = -1;
    int referenceIndex = 0;
    boolean allowDollarInNames = isAllowDollarInNames();
    boolean allowGenerics = false;
    boolean allowGenericsCalculated = false;
    boolean parsingClassNames = true;

    while (parsingClassNames) {
      int nextDotOrDollar = -1;
      for (int curIndex = currentDot + 1; curIndex < str.length(); ++curIndex) {
        final char ch = str.charAt(curIndex);

        if (ch == SEPARATOR || (ch == SEPARATOR2 && allowDollarInNames)) {
          nextDotOrDollar = curIndex;
          break;
        }

        if (((ch == SEPARATOR3 || ch == SEPARATOR4))) {
          if (!allowGenericsCalculated) {
            allowGenerics =
                !isStaticImport && PsiUtil.getLanguageLevel(element).hasEnumKeywordAndAutoboxing();
            allowGenericsCalculated = true;
          }

          if (allowGenerics) {
            nextDotOrDollar = curIndex;
            break;
          }
        }
      }

      if (nextDotOrDollar == -1) {
        nextDotOrDollar = currentDot + 1;
        for (int i = nextDotOrDollar;
            i < str.length() && Character.isJavaIdentifierPart(str.charAt(i));
            ++i) nextDotOrDollar++;
        parsingClassNames = false;
        int j = nextDotOrDollar;
        while (j < str.length() && Character.isWhitespace(str.charAt(j))) ++j;

        if (j < str.length()) {
          char ch = str.charAt(j);
          boolean recognized = false;

          if (ch == '[') {
            j++;
            while (j < str.length() && Character.isWhitespace(str.charAt(j))) ++j;

            if (j < str.length()) {
              ch = str.charAt(j);

              if (ch == ']') {
                j++;
                while (j < str.length() && Character.isWhitespace(str.charAt(j))) ++j;

                recognized = j == str.length();
              }
            }
          }

          final Boolean aBoolean = JavaClassReferenceProvider.JVM_FORMAT.getValue(getOptions());
          if (aBoolean == null || !aBoolean.booleanValue()) {
            if (!recognized)
              nextDotOrDollar = -1; // nonsensible characters anyway, don't do resolve
          }
        }
      }

      if (nextDotOrDollar != -1 && nextDotOrDollar < str.length()) {
        final char c = str.charAt(nextDotOrDollar);
        if (c == SEPARATOR3) {
          int end = str.lastIndexOf('>');
          if (end != -1 && end > nextDotOrDollar) {
            if (myNestedGenericParameterReferences == null)
              myNestedGenericParameterReferences = new ArrayList<JavaClassReferenceSet>(1);
            myNestedGenericParameterReferences.add(
                new JavaClassReferenceSet(
                    str.substring(nextDotOrDollar + 1, end),
                    myElement,
                    myStartInElement + nextDotOrDollar + 1,
                    isStaticImport,
                    myProvider,
                    this));
            parsingClassNames = false;
          } else {
            nextDotOrDollar = -1; // nonsensible characters anyway, don't do resolve
          }
        } else if (SEPARATOR4 == c && myContext != null) {
          if (myContext.myNestedGenericParameterReferences == null)
            myContext.myNestedGenericParameterReferences = new ArrayList<JavaClassReferenceSet>(1);
          myContext.myNestedGenericParameterReferences.add(
              new JavaClassReferenceSet(
                  str.substring(nextDotOrDollar + 1),
                  myElement,
                  myStartInElement + nextDotOrDollar + 1,
                  isStaticImport,
                  myProvider,
                  this));
          parsingClassNames = false;
        }
      }

      int beginIndex = currentDot + 1;
      while (beginIndex < nextDotOrDollar && Character.isWhitespace(str.charAt(beginIndex)))
        beginIndex++;

      final String subreferenceText =
          nextDotOrDollar > 0
              ? str.substring(beginIndex, nextDotOrDollar)
              : str.substring(beginIndex);

      TextRange textRange =
          new TextRange(
              myStartInElement + beginIndex,
              myStartInElement + (nextDotOrDollar > 0 ? nextDotOrDollar : str.length()));
      JavaClassReference currentContextRef =
          createReference(referenceIndex, subreferenceText, textRange, isStaticImport);
      referenceIndex++;
      referencesList.add(currentContextRef);
      if ((currentDot = nextDotOrDollar) < 0) {
        break;
      }
    }

    myReferences = referencesList.toArray(new JavaClassReference[referencesList.size()]);
  }