@Override
  public void applyTransformation(@NotNull TransformationContext context) {
    Map<PsiType, PsiAnnotation> declaredTypes = new LinkedHashMap<>();
    GrTypeDefinition codeClass = context.getCodeClass();
    for (GrField field : context.getFields()) {
      final PsiAnnotation annotation = PsiImplUtil.getAnnotation(field, GroovyCommonClassNames.GROOVY_LANG_DELEGATE);
      if (annotation == null) continue;
      declaredTypes.putIfAbsent(field.getDeclaredType(), annotation);
    }
    for (PsiMethod method : context.getMethods()) {
      final PsiAnnotation annotation = PsiImplUtil.getAnnotation(method, GroovyCommonClassNames.GROOVY_LANG_DELEGATE);
      if (annotation == null) continue;
      if (!method.getParameterList().isEmpty()) continue;
      declaredTypes.putIfAbsent(method.getReturnType(), annotation);
    }

    declaredTypes.forEach((type, annotation) -> {
      if (!(type instanceof PsiClassType)) return;

      final PsiClassType.ClassResolveResult delegateResult = ((PsiClassType)type).resolveGenerics();
      final PsiClass delegate = delegateResult.getElement();
      if (delegate == null) return;

      DelegateProcessor processor = new DelegateProcessor(context, delegate, annotation);
      delegate.processDeclarations(
        processor,
        ResolveState.initial().put(PsiSubstitutor.KEY, delegateResult.getSubstitutor()),
        null,
        codeClass
      );

      if (!processor.myInterfaces) return;

      Set<PsiClass> visited = new HashSet<>();
      Queue<Pair<PsiClass, PsiSubstitutor>> queue = ContainerUtil.newLinkedList(Pair.create(delegate, delegateResult.getSubstitutor()));

      while (!queue.isEmpty()) {
        Pair<PsiClass, PsiSubstitutor> pair = queue.poll();
        PsiClass currentClass = pair.first;
        PsiSubstitutor substitutor = pair.second;
        if (visited.add(currentClass) && currentClass.isInterface()) {
          context.addInterface(new PsiImmediateClassType(currentClass, substitutor));
          continue;
        }

        for (PsiClassType superType : currentClass.getSuperTypes()) {
          PsiClassType.ClassResolveResult resolveResult = superType.resolveGenerics();
          PsiClass superClass = resolveResult.getElement();
          if (superClass != null) {
            queue.offer(Pair.create(superClass, TypeConversionUtil.getSuperClassSubstitutor(superClass, currentClass, substitutor)));
          }
        }
      }
    });
  }
@Override
  public void applyTransformation(@NotNull TransformationContext context)