public static void collectTypeParameters(final Set<? super PsiTypeParameter> used, @NotNull final GroovyPsiElement element) {
    element.accept(new GroovyRecursiveElementVisitor() {
      @Override
      public void visitCodeReferenceElement(@NotNull GrCodeReferenceElement reference) {
        super.visitCodeReferenceElement(reference);
        if (reference.getQualifier() == null) {
          final PsiElement resolved = reference.resolve();
          if (resolved instanceof PsiTypeParameter typeParameter) {
            if (PsiTreeUtil.isAncestor(typeParameter.getOwner(), element, false)) {
              used.add(typeParameter);
            }
          }
        }
      }

      @Override
      public void visitExpression(@NotNull final GrExpression expression) {
        super.visitExpression(expression);
        final PsiType type = expression.getType();
        if (type != null) {
          final TypeParameterSearcher searcher = new TypeParameterSearcher();
          type.accept(searcher);
          for (PsiTypeParameter typeParam : searcher.myTypeParams) {
            if (PsiTreeUtil.isAncestor(typeParam.getOwner(), element, false)) {
              used.add(typeParam);
            }
          }
        }
      }

      static class TypeParameterSearcher extends PsiTypeVisitor<Boolean> {
        private final Set<PsiTypeParameter> myTypeParams = new HashSet<>();

        @Override
        public Boolean visitType(@NotNull final PsiType type) {
          return false;
        }

        @Override
        public Boolean visitArrayType(@NotNull final PsiArrayType arrayType) {
          return arrayType.getComponentType().accept(this);
        }

        @Override
        public Boolean visitClassType(@NotNull final PsiClassType classType) {
          final PsiClass aClass = classType.resolve();
          if (aClass instanceof PsiTypeParameter) {
            myTypeParams.add((PsiTypeParameter)aClass);
          }

          final PsiType[] types = classType.getParameters();
          for (final PsiType psiType : types) {
            psiType.accept(this);
          }
          return false;
        }

        @Override
        public Boolean visitWildcardType(@NotNull final PsiWildcardType wildcardType) {
          final PsiType bound = wildcardType.getBound();
          if (bound != null) {
            bound.accept(this);
          }
          return false;
        }
      }
    });
  }
public static void collectTypeParameters(final Set<? super PsiTypeParameter> used, @NotNull final GroovyPsiElement element)