void (ClassInstanceReferenceVisitor visitor, PsiExpression expression, PsiElement referencedElement) { expression = CommonJavaRefactoringUtil.outermostParenthesizedExpression(expression); PsiElement parent = expression.getParent(); if(parent instanceof PsiReferenceExpression && expression == ((PsiReferenceExpression) parent).getQualifierExpression()) { visitor.visitQualifier((PsiReferenceExpression) parent, expression, referencedElement); } else if (parent instanceof PsiTypeCastExpression) { visitor.visitTypeCast((PsiTypeCastExpression)parent, expression, referencedElement); } else if (parent instanceof PsiReturnStatement returnStatement) { PsiType returnType = PsiTreeUtil.getParentOfType(returnStatement, PsiMethod.class, PsiLambdaExpression.class) instanceof PsiMethod method ? method.getReturnType() : null; visitor.visitReadUsage(expression, returnType, referencedElement); } else if (parent instanceof PsiStatement) { visitor.visitReadUsage(expression, null, referencedElement); } else if (parent instanceof PsiExpressionList expressionList) { PsiElement pparent = expressionList.getParent(); if (pparent instanceof PsiStatement) { visitor.visitReadUsage(expression, null, referencedElement); } else if (pparent instanceof PsiCallExpression callExpression) { PsiExpression[] arguments = callExpression.getArgumentList().getExpressions(); PsiMethod method = callExpression.resolveMethod(); if (method != null) { int index = ArrayUtil.indexOf(arguments, expression); if (index >= 0) { PsiParameter[] parameters = method.getParameterList().getParameters(); if (parameters.length > index) { visitor.visitReadUsage(expression, parameters[index].getType(), referencedElement); } } } } } else if (parent instanceof PsiAssignmentExpression assignmentExpression) { if (expression.equals(assignmentExpression.getRExpression())) { visitor.visitReadUsage(expression, assignmentExpression.getLExpression().getType(), referencedElement); } else { // LExpression visitor.visitWriteUsage(expression, assignmentExpression.getRExpression().getType(), referencedElement); } } else if (RefactoringUtil.isAssignmentLHS(expression)) { visitor.visitWriteUsage(expression, null, referencedElement); } else if(parent instanceof PsiVariable) { visitor.visitReadUsage(expression, ((PsiVariable) parent).getType(), referencedElement); } else if(parent instanceof PsiExpression) { // for usages in expressions other than above, we do not care about the type visitor.visitReadUsage(expression, null, referencedElement); } else { LOG.error("Unknown variation of class instance usage"); } }