public ClsJavaCodeReferenceElementImpl(PsiElement parent, String canonicalText) {
    myParent = parent;

    myCanonicalText = canonicalText;
    final String[] classParametersText = PsiNameHelper.getClassParametersText(canonicalText);
    int length = classParametersText.length;
    myTypeParameters = length == 0 ? EMPTY_ARRAY : new ClsTypeElementImpl[length];
    for (int i = 0; i < length; i++) {
      String s = classParametersText[length - i - 1];
      char variance = ClsTypeElementImpl.VARIANCE_NONE;
      if (s.startsWith(EXTENDS_PREFIX)) {
        variance = ClsTypeElementImpl.VARIANCE_EXTENDS;
        s = s.substring(EXTENDS_PREFIX.length());
      } else if (s.startsWith(SUPER_PREFIX)) {
        variance = ClsTypeElementImpl.VARIANCE_SUPER;
        s = s.substring(SUPER_PREFIX.length());
      } else if (StringUtil.startsWithChar(s, '?')) {
        variance = ClsTypeElementImpl.VARIANCE_INVARIANT;
        s = s.substring(1);
      }

      myTypeParameters[i] = new ClsTypeElementImpl(this, s, variance);
    }

    myQualifiedName = PsiNameHelper.getQualifiedClassName(myCanonicalText, false);
  }