@NotNull
 private static PsiExpression getTopLevel(Project project, @NotNull PsiExpression expression) {
   int i = 0;
   while (expression.getParent() instanceof PsiExpression) {
     i++;
     final PsiExpression parent = (PsiExpression) expression.getParent();
     if (parent instanceof PsiConditionalExpression
         && ((PsiConditionalExpression) parent).getCondition() == expression) break;
     expression = parent;
     if (expression instanceof PsiAssignmentExpression) break;
     if (i > 10 && expression instanceof PsiBinaryExpression) {
       ParameterizedCachedValue<PsiExpression, Pair<Project, PsiExpression>> value =
           expression.getUserData(TOP_LEVEL_EXPRESSION);
       if (value != null && value.hasUpToDateValue()) {
         return getToplevelExpression(
             project, expression); // optimization: use caching for big hierarchies
       }
     }
   }
   return expression;
 }
 @Override
 public CachedValueProvider.Result<PsiExpression> compute(
     Pair<Project, PsiExpression> pair) {
   PsiExpression param = pair.second;
   Project project = pair.first;
   PsiExpression topLevel = getTopLevel(project, param);
   ParameterizedCachedValue<PsiExpression, Pair<Project, PsiExpression>> cachedValue =
       param.getUserData(TOP_LEVEL_EXPRESSION);
   assert cachedValue != null;
   int i = 0;
   for (PsiElement element = param;
       element != topLevel;
       element = element.getParent(), i++) {
     if (i % 10
         == 0) { // optimization: store up link to the top level expression in each 10nth
                 // element
       element.putUserData(TOP_LEVEL_EXPRESSION, cachedValue);
     }
   }
   return CachedValueProvider.Result.create(
       topLevel, PsiManager.getInstance(project).getModificationTracker());
 }