package org.eclipse.xtend.lib.annotations;

import com.google.common.annotations.Beta;
import com.google.common.base.Objects;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import org.eclipse.xtend.lib.macro.TransformationContext;
import org.eclipse.xtend.lib.macro.TransformationParticipant;
import org.eclipse.xtend.lib.macro.declaration.AnnotationReference;
import org.eclipse.xtend.lib.macro.declaration.FieldDeclaration;
import org.eclipse.xtend.lib.macro.declaration.InterfaceDeclaration;
import org.eclipse.xtend.lib.macro.declaration.MemberDeclaration;
import org.eclipse.xtend.lib.macro.declaration.MethodDeclaration;
import org.eclipse.xtend.lib.macro.declaration.MutableMemberDeclaration;
import org.eclipse.xtend.lib.macro.declaration.MutableMethodDeclaration;
import org.eclipse.xtend.lib.macro.declaration.MutableTypeParameterDeclaration;
import org.eclipse.xtend.lib.macro.declaration.ParameterDeclaration;
import org.eclipse.xtend.lib.macro.declaration.ResolvedMethod;
import org.eclipse.xtend.lib.macro.declaration.ResolvedParameter;
import org.eclipse.xtend.lib.macro.declaration.ResolvedTypeParameter;
import org.eclipse.xtend.lib.macro.declaration.Type;
import org.eclipse.xtend.lib.macro.declaration.TypeDeclaration;
import org.eclipse.xtend.lib.macro.declaration.TypeReference;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtend2.lib.StringConcatenationClient;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.Functions.Function2;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;

/**
 * @since 2.7
 * @noextend
 * @noreference
 */
@Beta
@SuppressWarnings("all")
public class DelegateProcessor implements TransformationParticipant<MutableMemberDeclaration> {
  /**
   * @since 2.7
   * @noextend
   * @noreference
   */
  @Beta
  public static class Util {
    @Extension
    private TransformationContext context;
    
    public Util(final TransformationContext context) {
      this.context = context;
    }
    
    protected boolean _isValidDelegate(final FieldDeclaration it) {
      return ((this.hasValidType(it) && (!this.hasDelegationConflicts(it))) && this.areListedInterfacesValid(it));
    }
    
    protected boolean _isValidDelegate(final MethodDeclaration it) {
      return (((this.hasValidType(it) && this.hasValidSignature(it)) && (!this.hasDelegationConflicts(it))) && this.areListedInterfacesValid(it));
    }
    
    public boolean hasValidType(final MemberDeclaration it) {
      boolean _xifexpression = false;
      if (((this.getType(it) == null) || this.getType(it).isInferred())) {
        boolean _xblockexpression = false;
        {
          this.context.addError(it, "Cannot use inferred types on delegates");
          _xblockexpression = false;
        }
        _xifexpression = _xblockexpression;
      } else {
        _xifexpression = true;
      }
      return _xifexpression;
    }
    
    protected TypeReference _getType(final FieldDeclaration it) {
      return it.getType();
    }
    
    protected TypeReference _getType(final MethodDeclaration it) {
      return it.getReturnType();
    }
    
    public boolean hasValidSignature(final MethodDeclaration it) {
      boolean _switchResult = false;
      final Function1<ParameterDeclaration, TypeReference> _function = (ParameterDeclaration it_1) -> {
        return it_1.getType();
      };
      List<TypeReference> _list = IterableExtensions.<TypeReference>toList(IterableExtensions.map(it.getParameters(), _function));
      boolean _matched = false;
      if (Objects.equal(_list, Collections.<Object>unmodifiableList(CollectionLiterals.<Object>newArrayList()))) {
        _matched=true;
      }
      if (!_matched) {
        TypeReference _string = this.context.getString();
        if (Objects.equal(_list, Collections.<TypeReference>unmodifiableList(CollectionLiterals.<TypeReference>newArrayList(_string)))) {
          _matched=true;
        }
      }
      if (!_matched) {
        TypeReference _string_1 = this.context.getString();
        TypeReference _newArrayTypeReference = this.context.newArrayTypeReference(this.context.newTypeReference(Class.class, this.context.newWildcardTypeReference()));
        TypeReference _newArrayTypeReference_1 = this.context.newArrayTypeReference(this.context.getObject());
        if (Objects.equal(_list, Collections.<TypeReference>unmodifiableList(CollectionLiterals.<TypeReference>newArrayList(_string_1, _newArrayTypeReference, _newArrayTypeReference_1)))) {
          _matched=true;
        }
      }
      if (_matched) {
        _switchResult = true;
      }
      if (!_matched) {
        boolean _xblockexpression = false;
        {
          this.context.addError(it, "Not a valid delegate signature, use () or (String methodName) or (String methodName, Class<?>[] argumentTypes, Object[] arguments)");
          _xblockexpression = false;
        }
        _switchResult = _xblockexpression;
      }
      return _switchResult;
    }
    
    public boolean hasDelegationConflicts(final MemberDeclaration delegate) {
      boolean _xblockexpression = false;
      {
        boolean conflict = false;
        Iterable<? extends MemberDeclaration> _otherDelegates = this.otherDelegates(delegate);
        for (final MemberDeclaration other : _otherDelegates) {
          {
            final Set<TypeReference> otherInterfaces = this.getDelegatedInterfaces(other);
            Set<TypeReference> _delegatedInterfaces = this.getDelegatedInterfaces(delegate);
            for (final TypeReference iface : _delegatedInterfaces) {
              boolean _contains = otherInterfaces.contains(iface);
              if (_contains) {
                conflict = true;
                StringConcatenation _builder = new StringConcatenation();
                _builder.append("The interface ");
                String _simpleName = iface.getSimpleName();
                _builder.append(_simpleName);
                _builder.append(" is also implemented by the delegate ");
                String _simpleName_1 = other.getSimpleName();
                _builder.append(_simpleName_1);
                this.context.addError(delegate, _builder.toString());
              }
            }
          }
        }
        _xblockexpression = conflict;
      }
      return _xblockexpression;
    }
    
    public Iterable<? extends MemberDeclaration> otherDelegates(final MemberDeclaration delegate) {
      final Function1<MemberDeclaration, Boolean> _function = (MemberDeclaration it) -> {
        return Boolean.valueOf((!Objects.equal(it, delegate)));
      };
      return IterableExtensions.filter(this.getDelegates(delegate.getDeclaringType()), _function);
    }
    
    public boolean areListedInterfacesValid(final MemberDeclaration delegate) {
      boolean _xblockexpression = false;
      {
        final TypeReference declaringType = this.context.newSelfTypeReference(delegate.getDeclaringType());
        final Set<TypeReference> interfacesOfDeclaringType = this.getImplementedInterfaces(declaringType);
        final Set<TypeReference> availableInterfaces = this.getImplementedInterfaces(this.getType(delegate));
        final Set<TypeReference> listedInterfaces = this.listedInterfaces(delegate);
        boolean valid = true;
        for (final TypeReference iface : listedInterfaces) {
          {
            final Function1<TypeReference, Boolean> _function = (TypeReference it) -> {
              Type _type = it.getType();
              Type _type_1 = iface.getType();
              return Boolean.valueOf(Objects.equal(_type, _type_1));
            };
            boolean _exists = IterableExtensions.<TypeReference>exists(availableInterfaces, _function);
            boolean _not = (!_exists);
            if (_not) {
              StringConcatenation _builder = new StringConcatenation();
              String _simpleName = this.getType(delegate).getSimpleName();
              _builder.append(_simpleName);
              _builder.append(" does not implement ");
              String _simpleName_1 = iface.getSimpleName();
              _builder.append(_simpleName_1);
              this.context.addError(delegate, _builder.toString());
              valid = false;
            }
            final Function1<TypeReference, Boolean> _function_1 = (TypeReference it) -> {
              Type _type = it.getType();
              Type _type_1 = iface.getType();
              return Boolean.valueOf(Objects.equal(_type, _type_1));
            };
            boolean _exists_1 = IterableExtensions.<TypeReference>exists(interfacesOfDeclaringType, _function_1);
            boolean _not_1 = (!_exists_1);
            if (_not_1) {
              StringConcatenation _builder_1 = new StringConcatenation();
              String _simpleName_2 = declaringType.getSimpleName();
              _builder_1.append(_simpleName_2);
              _builder_1.append(" does not implement ");
              String _simpleName_3 = iface.getSimpleName();
              _builder_1.append(_simpleName_3);
              this.context.addError(delegate, _builder_1.toString());
              valid = false;
            }
          }
        }
        if ((listedInterfaces.isEmpty() && Sets.<TypeReference>intersection(interfacesOfDeclaringType, availableInterfaces).isEmpty())) {
          StringConcatenation _builder = new StringConcatenation();
          String _simpleName = this.getType(delegate).getSimpleName();
          _builder.append(_simpleName);
          _builder.append(" and ");
          String _simpleName_1 = declaringType.getSimpleName();
          _builder.append(_simpleName_1);
          _builder.append(" have no interfaces in common");
          this.context.addError(delegate, _builder.toString());
          valid = false;
        }
        _xblockexpression = valid;
      }
      return _xblockexpression;
    }
    
    public Iterable<? extends MemberDeclaration> getDelegates(final TypeDeclaration it) {
      final Function1<MemberDeclaration, Boolean> _function = (MemberDeclaration it_1) -> {
        AnnotationReference _findAnnotation = it_1.findAnnotation(this.context.findTypeGlobally(Delegate.class));
        return Boolean.valueOf((_findAnnotation != null));
      };
      return IterableExtensions.filter(it.getDeclaredMembers(), _function);
    }
    
    public Set<TypeReference> listedInterfaces(final MemberDeclaration it) {
      return IterableExtensions.<TypeReference>toSet(((Iterable<TypeReference>)Conversions.doWrapArray(it.findAnnotation(this.context.findTypeGlobally(Delegate.class)).getClassArrayValue("value"))));
    }
    
    public Set<TypeReference> getImplementedInterfaces(final TypeReference it) {
      Set<TypeReference> _xblockexpression = null;
      {
        final LinkedHashSet<TypeReference> seen = CollectionLiterals.<TypeReference>newLinkedHashSet();
        this.collectAllSuperTypes(it, seen);
        final Function1<TypeReference, Boolean> _function = (TypeReference it_1) -> {
          Type _type = it_1.getType();
          return Boolean.valueOf((_type instanceof InterfaceDeclaration));
        };
        _xblockexpression = IterableExtensions.<TypeReference>toSet(IterableExtensions.<TypeReference>filter(seen, _function));
      }
      return _xblockexpression;
    }
    
    private void collectAllSuperTypes(final TypeReference it, final Set<TypeReference> seen) {
      boolean _add = seen.add(it);
      final boolean cycle = (!_add);
      if (cycle) {
        return;
      }
      final Consumer<TypeReference> _function = (TypeReference it_1) -> {
        this.collectAllSuperTypes(it_1, seen);
      };
      it.getDeclaredSuperTypes().forEach(_function);
    }
    
    public Set<TypeReference> getDelegatedInterfaces(final MemberDeclaration delegate) {
      Set<TypeReference> _xblockexpression = null;
      {
        final Set<TypeReference> interfacesOfDeclaringType = this.getImplementedInterfaces(this.context.newSelfTypeReference(delegate.getDeclaringType()));
        final Set<TypeReference> listedInterfaces = this.listedInterfaces(delegate);
        final Set<TypeReference> availableInterfaces = this.getImplementedInterfaces(this.getType(delegate));
        final Function1<TypeReference, Boolean> _function = (TypeReference iface) -> {
          return Boolean.valueOf((interfacesOfDeclaringType.contains(iface) && (listedInterfaces.isEmpty() || IterableExtensions.<TypeReference>exists(listedInterfaces, ((Function1<TypeReference, Boolean>) (TypeReference it) -> {
            return Boolean.valueOf(iface.isAssignableFrom(it));
          })))));
        };
        _xblockexpression = IterableExtensions.<TypeReference>toSet(IterableExtensions.<TypeReference>filter(availableInterfaces, _function));
      }
      return _xblockexpression;
    }
    
    public Set<ResolvedMethod> getMethodsToImplement(final MemberDeclaration delegate) {
      final Function1<TypeReference, Iterable<? extends ResolvedMethod>> _function = (TypeReference it) -> {
        return it.getDeclaredResolvedMethods();
      };
      final Function1<ResolvedMethod, Boolean> _function_1 = (ResolvedMethod it) -> {
        final Function1<ResolvedParameter, TypeReference> _function_2 = (ResolvedParameter it_1) -> {
          return it_1.getResolvedType();
        };
        MethodDeclaration _findDeclaredMethod = delegate.getDeclaringType().findDeclaredMethod(it.getDeclaration().getSimpleName(), ((TypeReference[])Conversions.unwrapArray(IterableExtensions.map(it.getResolvedParameters(), _function_2), TypeReference.class)));
        return Boolean.valueOf((_findDeclaredMethod == null));
      };
      final Function1<ResolvedMethod, Boolean> _function_2 = (ResolvedMethod it) -> {
        boolean _isObjectMethod = this.isObjectMethod(it);
        return Boolean.valueOf((!_isObjectMethod));
      };
      final Function1<ResolvedMethod, Boolean> _function_3 = (ResolvedMethod it) -> {
        boolean _isStatic = this.isStatic(it);
        return Boolean.valueOf((!_isStatic));
      };
      final Function1<ResolvedMethod, String> _function_4 = (ResolvedMethod it) -> {
        return it.getSimpleSignature();
      };
      final Function1<List<ResolvedMethod>, ResolvedMethod> _function_5 = (List<ResolvedMethod> it) -> {
        return IterableExtensions.<ResolvedMethod>head(it);
      };
      final Function1<ResolvedMethod, String> _function_6 = (ResolvedMethod it) -> {
        return it.getSimpleSignature();
      };
      return IterableExtensions.<ResolvedMethod>toSet(IterableExtensions.<ResolvedMethod, String>sortBy(IterableExtensions.<List<ResolvedMethod>, ResolvedMethod>map(IterableExtensions.<String, ResolvedMethod>groupBy(IterableExtensions.<ResolvedMethod>filter(IterableExtensions.<ResolvedMethod>filter(IterableExtensions.<ResolvedMethod>filter(Iterables.<ResolvedMethod>concat(IterableExtensions.<TypeReference, Iterable<? extends ResolvedMethod>>map(this.getDelegatedInterfaces(delegate), _function)), _function_1), _function_2), _function_3), _function_4).values(), _function_5), _function_6));
    }
    
    public boolean isObjectMethod(final ResolvedMethod it) {
      boolean _xblockexpression = false;
      {
        final String name = it.getDeclaration().getSimpleName();
        final Function1<ResolvedParameter, TypeReference> _function = (ResolvedParameter it_1) -> {
          return it_1.getResolvedType();
        };
        final List<TypeReference> parameterTypes = IterableExtensions.<TypeReference>toList(IterableExtensions.map(it.getResolvedParameters(), _function));
        _xblockexpression = (((((Objects.equal(name, "hashCode") && parameterTypes.isEmpty()) || (Objects.equal(name, "toString") && parameterTypes.isEmpty())) || (Objects.equal(name, "equals") && Objects.equal(parameterTypes, Collections.<TypeReference>unmodifiableList(CollectionLiterals.<TypeReference>newArrayList(this.context.getObject()))))) || (Objects.equal(name, "finalize") && parameterTypes.isEmpty())) || (Objects.equal(name, "clone") && parameterTypes.isEmpty()));
      }
      return _xblockexpression;
    }
    
    public boolean isStatic(final ResolvedMethod it) {
      return it.getDeclaration().isStatic();
    }
    
    public MutableMethodDeclaration implementMethod(final MutableMemberDeclaration delegate, final ResolvedMethod resolvedMethod) {
      MutableMethodDeclaration _xblockexpression = null;
      {
        delegate.markAsRead();
        final MethodDeclaration declaration = resolvedMethod.getDeclaration();
        final Procedure1<MutableMethodDeclaration> _function = (MutableMethodDeclaration impl) -> {
          this.context.setPrimarySourceElement(impl, this.context.getPrimarySourceElement(delegate));
          final HashMap<TypeReference, TypeReference> typeParameterMappings = CollectionLiterals.<TypeReference, TypeReference>newHashMap();
          final Consumer<ResolvedTypeParameter> _function_1 = (ResolvedTypeParameter param) -> {
            final MutableTypeParameterDeclaration copy = impl.addTypeParameter(param.getDeclaration().getSimpleName(), ((TypeReference[])Conversions.unwrapArray(param.getResolvedUpperBounds(), TypeReference.class)));
            typeParameterMappings.put(this.context.newTypeReference(param.getDeclaration()), this.context.newTypeReference(copy));
            final Function1<TypeReference, TypeReference> _function_2 = (TypeReference it) -> {
              return this.replace(it, typeParameterMappings);
            };
            copy.setUpperBounds(IterableExtensions.map(copy.getUpperBounds(), _function_2));
          };
          resolvedMethod.getResolvedTypeParameters().forEach(_function_1);
          final Function1<TypeReference, TypeReference> _function_2 = (TypeReference it) -> {
            return this.replace(it, typeParameterMappings);
          };
          impl.setExceptions(((TypeReference[])Conversions.unwrapArray(IterableExtensions.map(resolvedMethod.getResolvedExceptionTypes(), _function_2), TypeReference.class)));
          impl.setVarArgs(declaration.isVarArgs());
          impl.setReturnType(this.replace(resolvedMethod.getResolvedReturnType(), typeParameterMappings));
          final Consumer<ResolvedParameter> _function_3 = (ResolvedParameter p) -> {
            impl.addParameter(p.getDeclaration().getSimpleName(), this.replace(p.getResolvedType(), typeParameterMappings));
          };
          resolvedMethod.getResolvedParameters().forEach(_function_3);
          StringConcatenationClient _client = new StringConcatenationClient() {
            @Override
            protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
              String _returnIfNeeded = Util.this.returnIfNeeded(resolvedMethod);
              _builder.append(_returnIfNeeded);
              CharSequence _delegateAccess = Util.this.delegateAccess(delegate, declaration);
              _builder.append(_delegateAccess);
              _builder.append(".");
              String _simpleName = declaration.getSimpleName();
              _builder.append(_simpleName);
              _builder.append("(");
              final Function1<ParameterDeclaration, CharSequence> _function = (ParameterDeclaration it) -> {
                return it.getSimpleName();
              };
              String _join = IterableExtensions.join(declaration.getParameters(), ", ", _function);
              _builder.append(_join);
              _builder.append(");");
              _builder.newLineIfNotEmpty();
            }
          };
          impl.setBody(_client);
        };
        _xblockexpression = delegate.getDeclaringType().addMethod(declaration.getSimpleName(), _function);
      }
      return _xblockexpression;
    }
    
    public TypeReference replace(final TypeReference target, final Map<? extends TypeReference, ? extends TypeReference> mappings) {
      final Function2<TypeReference, Map.Entry<? extends TypeReference, ? extends TypeReference>, TypeReference> _function = (TypeReference result, Map.Entry<? extends TypeReference, ? extends TypeReference> mapping) -> {
        return this.replace(result, mapping.getKey(), mapping.getValue());
      };
      return IterableExtensions.fold(mappings.entrySet(), target, _function);
    }
    
    public TypeReference replace(final TypeReference target, final TypeReference oldType, final TypeReference newType) {
      boolean _equals = Objects.equal(target, oldType);
      if (_equals) {
        return newType;
      }
      boolean _isEmpty = target.getActualTypeArguments().isEmpty();
      boolean _not = (!_isEmpty);
      if (_not) {
        final Function1<TypeReference, TypeReference> _function = (TypeReference it) -> {
          return this.replace(it, oldType, newType);
        };
        return this.context.newTypeReference(target.getType(), ((TypeReference[])Conversions.unwrapArray(ListExtensions.<TypeReference, TypeReference>map(target.getActualTypeArguments(), _function), TypeReference.class)));
      }
      boolean _isWildCard = target.isWildCard();
      if (_isWildCard) {
        TypeReference _upperBound = target.getUpperBound();
        TypeReference _object = this.context.getObject();
        boolean _notEquals = (!Objects.equal(_upperBound, _object));
        if (_notEquals) {
          return this.context.newWildcardTypeReference(this.replace(target.getUpperBound(), oldType, newType));
        } else {
          boolean _isAnyType = target.getLowerBound().isAnyType();
          boolean _not_1 = (!_isAnyType);
          if (_not_1) {
            return this.context.newWildcardTypeReferenceWithLowerBound(this.replace(target.getLowerBound(), oldType, newType));
          }
        }
      }
      boolean _isArray = target.isArray();
      if (_isArray) {
        return this.context.newArrayTypeReference(this.replace(target.getArrayComponentType(), oldType, newType));
      }
      return target;
    }
    
    protected CharSequence _delegateAccess(final FieldDeclaration it, final MethodDeclaration method) {
      StringConcatenation _builder = new StringConcatenation();
      _builder.append("this.");
      String _simpleName = it.getSimpleName();
      _builder.append(_simpleName);
      return _builder;
    }
    
    protected CharSequence _delegateAccess(final MethodDeclaration it, final MethodDeclaration method) {
      CharSequence _switchResult = null;
      final Function1<ParameterDeclaration, TypeReference> _function = (ParameterDeclaration it_1) -> {
        return it_1.getType();
      };
      List<TypeReference> _list = IterableExtensions.<TypeReference>toList(IterableExtensions.map(it.getParameters(), _function));
      boolean _matched = false;
      if (Objects.equal(_list, Collections.<Object>unmodifiableList(CollectionLiterals.<Object>newArrayList()))) {
        _matched=true;
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("this.");
        String _simpleName = it.getSimpleName();
        _builder.append(_simpleName);
        _builder.append("()");
        _switchResult = _builder;
      }
      if (!_matched) {
        TypeReference _string = this.context.getString();
        if (Objects.equal(_list, Collections.<TypeReference>unmodifiableList(CollectionLiterals.<TypeReference>newArrayList(_string)))) {
          _matched=true;
          StringConcatenation _builder_1 = new StringConcatenation();
          _builder_1.append("this.");
          String _simpleName_1 = it.getSimpleName();
          _builder_1.append(_simpleName_1);
          _builder_1.append("(\"");
          String _simpleName_2 = method.getSimpleName();
          _builder_1.append(_simpleName_2);
          _builder_1.append("\")");
          _switchResult = _builder_1;
        }
      }
      if (!_matched) {
        TypeReference _string_1 = this.context.getString();
        TypeReference _newArrayTypeReference = this.context.newArrayTypeReference(this.context.newTypeReference(Class.class, this.context.newWildcardTypeReference()));
        TypeReference _newArrayTypeReference_1 = this.context.newArrayTypeReference(this.context.getObject());
        if (Objects.equal(_list, Collections.<TypeReference>unmodifiableList(CollectionLiterals.<TypeReference>newArrayList(_string_1, _newArrayTypeReference, _newArrayTypeReference_1)))) {
          _matched=true;
          StringConcatenation _builder_2 = new StringConcatenation();
          _builder_2.append("this.");
          String _simpleName_3 = it.getSimpleName();
          _builder_2.append(_simpleName_3);
          _builder_2.append("(\"");
          String _simpleName_4 = method.getSimpleName();
          _builder_2.append(_simpleName_4);
          _builder_2.append("\", new Class[]{");
          final Function1<ParameterDeclaration, CharSequence> _function_1 = (ParameterDeclaration it_1) -> {
            String _simpleName_5 = it_1.getType().getType().getSimpleName();
            return (_simpleName_5 + ".class");
          };
          String _join = IterableExtensions.join(method.getParameters(), ", ", _function_1);
          _builder_2.append(_join);
          _builder_2.append("}, new Object[]{");
          final Function1<ParameterDeclaration, CharSequence> _function_2 = (ParameterDeclaration it_1) -> {
            return it_1.getSimpleName();
          };
          String _join_1 = IterableExtensions.join(method.getParameters(), ", ", _function_2);
          _builder_2.append(_join_1);
          _builder_2.append("})");
          _switchResult = _builder_2;
        }
      }
      if (!_matched) {
        throw new IllegalArgumentException("delegate signature");
      }
      return _switchResult;
    }
    
    public String returnIfNeeded(final ResolvedMethod it) {
      String _xifexpression = null;
      boolean _isVoid = it.getResolvedReturnType().isVoid();
      if (_isVoid) {
        _xifexpression = "";
      } else {
        _xifexpression = "return ";
      }
      return _xifexpression;
    }
    
    public boolean isValidDelegate(final MemberDeclaration it) {
      if (it instanceof MethodDeclaration) {
        return _isValidDelegate((MethodDeclaration)it);
      } else if (it instanceof FieldDeclaration) {
        return _isValidDelegate((FieldDeclaration)it);
      } else {
        throw new IllegalArgumentException("Unhandled parameter types: " +
          Arrays.<Object>asList(it).toString());
      }
    }
    
    public TypeReference getType(final MemberDeclaration it) {
      if (it instanceof MethodDeclaration) {
        return _getType((MethodDeclaration)it);
      } else if (it instanceof FieldDeclaration) {
        return _getType((FieldDeclaration)it);
      } else {
        throw new IllegalArgumentException("Unhandled parameter types: " +
          Arrays.<Object>asList(it).toString());
      }
    }
    
    public CharSequence delegateAccess(final MemberDeclaration it, final MethodDeclaration method) {
      if (it instanceof MethodDeclaration) {
        return _delegateAccess((MethodDeclaration)it, method);
      } else if (it instanceof FieldDeclaration) {
        return _delegateAccess((FieldDeclaration)it, method);
      } else {
        throw new IllegalArgumentException("Unhandled parameter types: " +
          Arrays.<Object>asList(it, method).toString());
      }
    }
  }
  
  @Override
  public void doTransform(final List<? extends MutableMemberDeclaration> elements, @Extension final TransformationContext context) {
    @Extension
    final DelegateProcessor.Util util = new DelegateProcessor.Util(context);
    final Consumer<MutableMemberDeclaration> _function = (MutableMemberDeclaration it) -> {
      boolean _isValidDelegate = util.isValidDelegate(it);
      if (_isValidDelegate) {
        final Consumer<ResolvedMethod> _function_1 = (ResolvedMethod method) -> {
          util.implementMethod(it, method);
        };
        util.getMethodsToImplement(it).forEach(_function_1);
      }
    };
    elements.forEach(_function);
  }
}
