void (final Set<? super PsiTypeParameter> used, final PsiElement element, final Condition<? super PsiTypeParameter> filter) { element.accept(new JavaRecursiveElementVisitor() { @Override public void visitReferenceElement(@NotNull PsiJavaCodeReferenceElement reference) { super.visitReferenceElement(reference); if (!reference.isQualified() && reference.resolve() instanceof PsiTypeParameter typeParameter && PsiTreeUtil.isAncestor(typeParameter.getOwner(), element, false) && filter.value(typeParameter)) { used.add(typeParameter); } } @Override public void visitExpression(final @NotNull PsiExpression expression) { super.visitExpression(expression); final PsiType type = expression.getType(); if (type != null) { final PsiTypesUtil.TypeParameterSearcher searcher = new PsiTypesUtil.TypeParameterSearcher(); type.accept(searcher); for (PsiTypeParameter typeParam : searcher.getTypeParameters()) { if (PsiTreeUtil.isAncestor(typeParam.getOwner(), element, false) && filter.value(typeParam)){ used.add(typeParam); } } } } }); }