@NotNull
  private static Node createNode(@NotNull PsiExpression expression, @NotNull PsiExpression root) {
    Node result = new Expr(expression);
    PsiExpression parent;
    while (expression != root) {
      PsiElement parentElement = expression.getParent();
      if (parentElement instanceof PsiExpressionList || parentElement instanceof PsiTemplate) {
        parentElement = parentElement.getParent();
      }
      if (parentElement instanceof PsiStatement) {
        PsiSwitchExpression switchExpression =
          PsiTreeUtil.getParentOfType(parentElement, PsiSwitchExpression.class, true, PsiMember.class, PsiLambdaExpression.class);
        if (switchExpression != null && PsiTreeUtil.isAncestor(root, switchExpression, false)) {
          boolean isYield =
            parentElement instanceof PsiYieldStatement && ((PsiYieldStatement)parentElement).findEnclosingExpression() == switchExpression;
          boolean isRuleExpression =
            parentElement instanceof PsiExpressionStatement && parentElement.getParent() instanceof PsiSwitchLabeledRuleStatement &&
            ((PsiSwitchLabeledRuleStatement)parentElement.getParent()).getEnclosingSwitchBlock() == switchExpression;
          if (isYield || isRuleExpression) {
            result = new Switch(switchExpression, Collections.singletonMap((PsiStatement)parentElement, result));
          }
          else {
            result = new Switch(switchExpression, Collections.emptyMap());
          }
          expression = switchExpression;
          continue;
        }
      }
      parent = ObjectUtils.tryCast(parentElement, PsiExpression.class);
      if (parent == null) {
        String message = PsiTreeUtil.isAncestor(root, expression, false) ?
                         "Expected to have expression parent, got " + parentElement.getClass() :
                         "Supplied root is not the expression ancestor";
        throw new RuntimeExceptionWithAttachments(message,
                                                  new Attachment("expression.txt", expression.getText()),
                                                  new Attachment("root.txt", root.getText()));
      }
      result = foldNode(result, expression, parent);
      expression = parent;
    }
    return result;
  }
@NotNull
  private static Node createNode(@NotNull PsiExpression expression, @NotNull PsiExpression root)