public final <T> T createStableValue(final Factory<T> provider, final Condition<T> validator) {
    final T initial = provider.create();
    assert initial != null;
    final StableInvocationHandler handler =
        new StableInvocationHandler<T>(initial, provider, validator);

    final Set<Class> intf = new HashSet<Class>();
    ContainerUtil.addAll(intf, initial.getClass().getInterfaces());
    intf.add(StableElement.class);
    //noinspection unchecked

    return (T)
        AdvancedProxy.createProxy(
            initial.getClass().getSuperclass(), intf.toArray(new Class[intf.size()]), handler);
  }
  @NotNull
  public static <T extends PsiJavaCodeReferenceElement> JavaResolveResult[] multiResolveImpl(
      @NotNull T element,
      boolean incompleteCode,
      @NotNull ResolveCache.PolyVariantContextResolver<? super T> resolver) {

    FileASTNode fileElement = SharedImplUtil.findFileElement(element.getNode());
    if (fileElement == null) {
      PsiUtilCore.ensureValid(element);
      LOG.error("fileElement == null!");
      return JavaResolveResult.EMPTY_ARRAY;
    }
    PsiFile psiFile = SharedImplUtil.getContainingFile(fileElement);
    PsiManager manager = psiFile == null ? null : psiFile.getManager();
    if (manager == null) {
      PsiUtilCore.ensureValid(element);
      LOG.error("getManager() == null!");
      return JavaResolveResult.EMPTY_ARRAY;
    }
    boolean valid = psiFile.isValid();
    if (!valid) {
      PsiUtilCore.ensureValid(element);
      LOG.error("psiFile.isValid() == false!");
      return JavaResolveResult.EMPTY_ARRAY;
    }
    if (element instanceof PsiMethodReferenceExpression) {
      // method refs: do not cache results during parent conflict resolving, acceptable checks, etc
      final Map<PsiElement, PsiType> map = LambdaUtil.ourFunctionTypes.get();
      if (map != null && map.containsKey(element)) {
        return (JavaResolveResult[]) resolver.resolve(element, psiFile, incompleteCode);
      }
    }

    return multiResolveImpl(manager.getProject(), psiFile, element, incompleteCode, resolver);
  }
  @SuppressWarnings({"unchecked"})
  @NotNull
  public static <T extends PsiType> T originalize(@NotNull T type) {
    if (!type.isValid()) {
      return type;
    }

    T result =
        new PsiTypeMapper() {
          private final Set<PsiClassType> myVisited = ContainerUtil.newIdentityTroveSet();

          @Override
          public PsiType visitClassType(final PsiClassType classType) {
            if (!myVisited.add(classType)) return classType;

            final PsiClassType.ClassResolveResult classResolveResult = classType.resolveGenerics();
            final PsiClass psiClass = classResolveResult.getElement();
            final PsiSubstitutor substitutor = classResolveResult.getSubstitutor();
            if (psiClass == null) return classType;

            return new PsiImmediateClassType(
                CompletionUtil.getOriginalOrSelf(psiClass), originalizeSubstitutor(substitutor));
          }

          private PsiSubstitutor originalizeSubstitutor(final PsiSubstitutor substitutor) {
            PsiSubstitutor originalSubstitutor = PsiSubstitutor.EMPTY;
            for (final Map.Entry<PsiTypeParameter, PsiType> entry :
                substitutor.getSubstitutionMap().entrySet()) {
              final PsiType value = entry.getValue();
              originalSubstitutor =
                  originalSubstitutor.put(
                      CompletionUtil.getOriginalOrSelf(entry.getKey()),
                      value == null ? null : mapType(value));
            }
            return originalSubstitutor;
          }

          @Override
          public PsiType visitType(PsiType type) {
            return type;
          }
        }.mapType(type);
    if (result == null) {
      throw new AssertionError("Null result for type " + type + " of class " + type.getClass());
    }
    return result;
  }
 private <T extends InstructionImpl> T addNode(T instruction) {
   instruction.setNumber(myInstructionNumber++);
   myInstructions.add(instruction);
   if (myHead != null) {
     addEdge(myHead, instruction);
   }
   myHead = instruction;
   return instruction;
 }
 public static <T extends PsiElement> void setQualifier(
     @NotNull GrQualifiedReference<T> ref, @Nullable T newQualifier) {
   final T oldQualifier = ref.getQualifier();
   final ASTNode node = ref.getNode();
   final PsiElement refNameElement = ref.getReferenceNameElement();
   if (newQualifier == null) {
     if (oldQualifier != null && refNameElement != null) {
       ref.deleteChildRange(ref.getFirstChild(), refNameElement.getPrevSibling());
     }
   } else {
     if (oldQualifier == null) {
       if (refNameElement != null) {
         node.addLeaf(mDOT, ".", refNameElement.getNode());
         ref.addBefore(newQualifier, refNameElement.getPrevSibling());
       }
     } else {
       oldQualifier.replace(newQualifier);
     }
   }
 }
  @NotNull
  protected String doExtract(
      final PsiDirectory targetDirectory,
      final String targetfileName,
      final T first,
      final T last,
      final Language includingLanguage)
      throws IncorrectOperationException {
    final PsiFile file = targetDirectory.createFile(targetfileName);
    Project project = targetDirectory.getProject();
    final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
    final Document document = documentManager.getDocument(file);
    document.replaceString(0, document.getTextLength(), first.getText().trim());
    documentManager.commitDocument(document);
    CodeStyleManager.getInstance(PsiManager.getInstance(project).getProject())
        .reformat(file); // TODO: adjustLineIndent

    final String relativePath =
        PsiFileSystemItemUtil.getRelativePath(first.getContainingFile(), file);
    if (relativePath == null) throw new IncorrectOperationException("Cannot extract!");
    return relativePath;
  }
 @NotNull
 public <T extends PsiPolyVariantReference> ResolveResult[] resolveWithCaching(
     @NotNull T ref,
     @NotNull PolyVariantResolver<T> resolver,
     boolean needToPreventRecursion,
     boolean incompleteCode) {
   return resolveWithCaching(
       ref,
       resolver,
       needToPreventRecursion,
       incompleteCode,
       ref.getElement().getContainingFile());
 }
 public static <T extends GrCondition> T replaceBody(
     T newBody, GrStatement body, ASTNode node, Project project) {
   if (body == null || newBody == null) {
     throw new IncorrectOperationException();
   }
   ASTNode oldBodyNode = body.getNode();
   if (oldBodyNode.getTreePrev() != null
       && mNLS.equals(oldBodyNode.getTreePrev().getElementType())) {
     ASTNode whiteNode = GroovyPsiElementFactory.getInstance(project).createWhiteSpace().getNode();
     node.replaceChild(oldBodyNode.getTreePrev(), whiteNode);
   }
   node.replaceChild(oldBodyNode, newBody.getNode());
   return newBody;
 }
  @Nullable
  public <T extends PsiType> T correctType(@NotNull T type) {
    if (type instanceof PsiClassType) {
      PsiClassType classType = (PsiClassType) type;
      if (classType.getParameterCount() == 0) {
        final PsiClassType.ClassResolveResult classResolveResult = classType.resolveGenerics();
        final PsiClass psiClass = classResolveResult.getElement();
        if (psiClass != null && classResolveResult.getSubstitutor() == PsiSubstitutor.EMPTY) {
          final PsiClass mappedClass = mapClass(psiClass);
          if (mappedClass == null || mappedClass == psiClass) return (T) classType;
        }
      }
    }

    return (T) type.accept(this);
  }
  @Nullable
  public <T extends PsiExpression> PsiType getType(
      @NotNull T expr, @NotNull Function<T, PsiType> f) {
    PsiType type = getCachedType(expr);
    if (type == null) {
      final RecursionGuard.StackStamp dStackStamp = PsiDiamondType.ourDiamondGuard.markStack();
      final RecursionGuard.StackStamp gStackStamp = PsiResolveHelper.ourGraphGuard.markStack();
      type = f.fun(expr);
      if (!dStackStamp.mayCacheNow() || !gStackStamp.mayCacheNow()) {
        return type;
      }
      if (type == null) type = TypeConversionUtil.NULL_TYPE;
      Reference<PsiType> ref = new SoftReference<PsiType>(type);
      myCalculatedTypes.put(expr, ref);

      if (type instanceof PsiClassReferenceType) {
        // convert reference-based class type to the PsiImmediateClassType, since the reference may
        // become invalid
        PsiClassType.ClassResolveResult result = ((PsiClassReferenceType) type).resolveGenerics();
        PsiClass psiClass = result.getElement();
        type =
            psiClass == null
                ? type // for type with unresolved reference, leave it in the cache
                // for clients still might be able to retrieve its getCanonicalText() from the
                // reference text
                : new PsiImmediateClassType(
                    psiClass,
                    result.getSubstitutor(),
                    ((PsiClassReferenceType) type).getLanguageLevel(),
                    type.getAnnotations());
      }
    }

    if (!type.isValid()) {
      if (expr.isValid()) {
        PsiJavaCodeReferenceElement refInside =
            type instanceof PsiClassReferenceType
                ? ((PsiClassReferenceType) type).getReference()
                : null;
        @NonNls
        String typeinfo =
            type
                + " ("
                + type.getClass()
                + ")"
                + (refInside == null
                    ? ""
                    : "; ref inside: "
                        + refInside
                        + " ("
                        + refInside.getClass()
                        + ") valid:"
                        + refInside.isValid());
        LOG.error(
            "Type is invalid: "
                + typeinfo
                + "; expr: '"
                + expr
                + "' ("
                + expr.getClass()
                + ") is valid");
      } else {
        LOG.error("Expression: '" + expr + "' is invalid, must not be used for getType()");
      }
    }

    return type == TypeConversionUtil.NULL_TYPE ? null : type;
  }
 protected Object getDescriptor(T element) {
   PsiElement parent = element.getParent();
   return parent instanceof XmlAttribute ? ((XmlAttribute) parent).getDescriptor() : null;
 }