/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jetbrains.plugins.groovy.refactoring.convertToJava;

import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.light.LightElement;
import com.intellij.psi.scope.BaseScopeProcessor;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.codeInspection.GrInspectionUtil;
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
import org.jetbrains.plugins.groovy.intentions.conversions.strings.ConvertGStringToStringIntention;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
import org.jetbrains.plugins.groovy.lang.psi.api.formatter.GrControlStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.arithmetic.GrRangeExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrString;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrPropertySelection;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner;
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesProvider;
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.SubtypeConstraint;
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrLiteralClassType;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrRangeType;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrBindingVariable;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.ClosureParameterEnhancer;
import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.refactoring.convertToJava.invocators.CustomMethodInvocator;

/**
 * @author Maxim.Medvedev
 */
public class ExpressionGenerator extends Generator {
  private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.refactoring.convertToJava.ExpressionGenerator");

  private final StringBuilder builder;
  private final GroovyPsiElementFactory factory;

  private final ExpressionContext context;

  public ExpressionGenerator(StringBuilder builder, ExpressionContext context) {
    this.builder = builder;
    this.context = context;

    factory = GroovyPsiElementFactory.getInstance(context.project);
  }

  public ExpressionGenerator(ExpressionContext context) {
    this.builder = new StringBuilder();
    this.context = context;

    factory = GroovyPsiElementFactory.getInstance(context.project);
  }

  @Override
  public StringBuilder getBuilder() {
    return builder;
  }

  @Override
  public ExpressionContext getContext() {
    return context;
  }

  @Override
  public void visitClosure(GrClosableBlock closure) {
    new ClosureGenerator(builder, context).generate(closure);
  }


  @Override
  public void visitExpression(GrExpression expression) {
    LOG.error("this method should not be invoked");
  }

  @Override
  public void visitMethodCallExpression(GrMethodCallExpression methodCallExpression) {
    generateMethodCall(methodCallExpression);
  }

  private void generateMethodCall(GrMethodCall methodCallExpression) {
    final GrExpression invoked = methodCallExpression.getInvokedExpression();
    final GrExpression[] exprs = methodCallExpression.getExpressionArguments();
    final GrNamedArgument[] namedArgs = methodCallExpression.getNamedArguments();
    final GrClosableBlock[] clArgs = methodCallExpression.getClosureArguments();
    if (invoked instanceof GrReferenceExpression) {
      final GroovyResolveResult resolveResult = ((GrReferenceExpression)invoked).advancedResolve();
      final PsiElement resolved = resolveResult.getElement();
      if (resolved instanceof PsiMethod) {
        final GrExpression qualifier = ((GrReferenceExpression)invoked).getQualifier();//todo replace null-qualifier with this-reference

        invokeMethodOn(
          ((PsiMethod)resolved),
          qualifier,
          exprs, namedArgs, clArgs,
          resolveResult.getSubstitutor(),
          methodCallExpression
        );
        return;
      }
      else if (resolved == null) {
        final GrExpression qualifier = ((GrReferenceExpression)invoked).getQualifier();
        final GrExpression[] args =
          generateArgsForInvokeMethod(((GrReferenceExpression)invoked).getReferenceName(), exprs, namedArgs, clArgs, methodCallExpression);
        GenerationUtil.invokeMethodByName(qualifier, "invokeMethod", args, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY, this, methodCallExpression);
        return;
      }
    }

    GenerationUtil.invokeMethodByName(invoked, "call", exprs, namedArgs, clArgs, this, methodCallExpression);
  }

  private GrExpression[] generateArgsForInvokeMethod(String name,
                                                     GrExpression[] exprs,
                                                     GrNamedArgument[] namedArgs,
                                                     GrClosableBlock[] clArgs,
                                                     GroovyPsiElement psiContext) {
    GrExpression[] result = new GrExpression[2];
    result[0] = factory.createExpressionFromText("\"" + name + "\"");
    StringBuilder builder = new StringBuilder();
    builder.append('[');
    if (namedArgs.length > 0) {
      builder.append('[');
      for (GrNamedArgument namedArg : namedArgs) {
        builder.append(namedArg.getText()).append(',');
      }
      builder.delete(builder.length() - 1, builder.length());
      //builder.removeFromTheEnd(1);
      builder.append("],");
    }
    for (GrExpression expr : exprs) {
      builder.append(expr.getText()).append(',');
    }

    for (GrClosableBlock clArg : clArgs) {
      builder.append(clArg.getText()).append(',');
    }
    if (namedArgs.length + exprs.length + clArgs.length > 0) builder.delete(builder.length() - 1, builder.length());
    //if (namedArgs.length + exprs.length + clArgs.length > 0) builder.removeFromTheEnd(1);
    builder.append("] as Object[]");

    result[1] = factory.createExpressionFromText(builder.toString(), psiContext);
    return result;
  }

  @Override
  public void visitNewExpression(GrNewExpression newExpression) {
    boolean hasFieldInitialization = hasFieldInitialization(newExpression);
    StringBuilder builder;

    final PsiType type = newExpression.getType();
    final String varName;
    if (hasFieldInitialization) {
      builder = new StringBuilder();
      varName = GenerationUtil.suggestVarName(type, newExpression, context);
      TypeWriter.writeType(builder, type, newExpression);
      builder.append(' ').append(varName).append(" = ");
    }
    else {
      varName = null;
      builder = this.builder;
    }

    final GrExpression qualifier = newExpression.getQualifier();
    if (qualifier != null) {
      qualifier.accept(this);
      builder.append('.');
    }

    final GrTypeElement typeElement = newExpression.getTypeElement();
    final GrArrayDeclaration arrayDeclaration = newExpression.getArrayDeclaration();
    final GrCodeReferenceElement referenceElement = newExpression.getReferenceElement();

    builder.append("new ");
    if (typeElement != null) {
      final PsiType builtIn = typeElement.getType();
      LOG.assertTrue(builtIn instanceof PsiPrimitiveType);
      final PsiType boxed = TypesUtil.boxPrimitiveType(builtIn, newExpression.getManager(), newExpression.getResolveScope());
      TypeWriter.writeTypeForNew(builder, boxed, newExpression);
    }
    else if (referenceElement != null) {
      GenerationUtil.writeCodeReferenceElement(builder, referenceElement);
    }

    final GrArgumentList argList = newExpression.getArgumentList();
    if (argList != null) {

      GrClosureSignature signature = null;

      final GroovyResolveResult resolveResult = newExpression.advancedResolve();
      final PsiElement constructor = resolveResult.getElement();
      if (constructor instanceof PsiMethod) {
        signature = GrClosureSignatureUtil.createSignature((PsiMethod)constructor, resolveResult.getSubstitutor());
      }
      else if (referenceElement != null) {
        final GroovyResolveResult clazzResult = referenceElement.advancedResolve();
        final PsiElement clazz = clazzResult.getElement();
        if (clazz instanceof PsiClass && ((PsiClass)clazz).getConstructors().length == 0) {
          signature = GrClosureSignatureUtil.createSignature(PsiParameter.EMPTY_ARRAY, null);
        }
      }

      final GrNamedArgument[] namedArgs = hasFieldInitialization ? GrNamedArgument.EMPTY_ARRAY : argList.getNamedArguments();
      new ArgumentListGenerator(builder, context).generate(
        signature,
        argList.getExpressionArguments(),
        namedArgs,
        GrClosableBlock.EMPTY_ARRAY,
        newExpression
      );
    }

    final GrAnonymousClassDefinition anonymous = newExpression.getAnonymousClassDefinition();
    if (anonymous != null) {
      writeTypeBody(builder, anonymous);
    }

    if (arrayDeclaration != null) {
      final GrExpression[] boundExpressions = arrayDeclaration.getBoundExpressions();
      for (GrExpression boundExpression : boundExpressions) {
        builder.append('[');
        boundExpression.accept(this);
        builder.append(']');
      }
      if (boundExpressions.length == 0) {
        builder.append("[]");
      }
    }

    if (hasFieldInitialization) {
      builder.append(';');
      context.myStatements.add(builder.toString());
      final GrNamedArgument[] namedArguments = argList.getNamedArguments();
      for (GrNamedArgument namedArgument : namedArguments) {
        final String fieldName = namedArgument.getLabelName();
        if (fieldName == null) {
          //todo try to initialize field
          final GrArgumentLabel label = namedArgument.getLabel();
          LOG.info("cannot initialize field " + (label == null ? "<null>" : label.getText()));
        }
        else {
          final GroovyResolveResult resolveResult = referenceElement.advancedResolve();
          final PsiElement resolved = resolveResult.getElement();
          LOG.assertTrue(resolved instanceof PsiClass);
          initializeField(varName, type, ((PsiClass)resolved), resolveResult.getSubstitutor(), fieldName, namedArgument.getExpression());
        }
      }
    }
  }

  private void initializeField(String varName,
                               PsiType type,
                               PsiClass resolved,
                               PsiSubstitutor substitutor,
                               String fieldName,
                               GrExpression expression) {
    StringBuilder builder = new StringBuilder();
    final PsiMethod setter = GroovyPropertyUtils.findPropertySetter(resolved, fieldName, false, true);
    if (setter != null) {
      final GrVariableDeclaration var = factory.createVariableDeclaration(ArrayUtil.EMPTY_STRING_ARRAY, "", type, varName);
      final GrReferenceExpression caller = factory.createReferenceExpressionFromText(varName, var);
      invokeMethodOn(setter, caller, new GrExpression[]{expression}, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY, substitutor,
                     expression);
    }
    else {
      builder.append(varName).append('.').append(fieldName).append(" = ");
      expression.accept(new ExpressionGenerator(builder, context));
    }
    context.myStatements.add(builder.toString());
  }

  @Override
  public String toString() {
    return builder.toString();
  }

  private static boolean hasFieldInitialization(GrNewExpression newExpression) {
    final GrArgumentList argumentList = newExpression.getArgumentList();
    if (argumentList == null) return false;
    if (argumentList.getNamedArguments().length == 0) return false;

    final GrCodeReferenceElement refElement = newExpression.getReferenceElement();
    if (refElement == null) return false;
    final GroovyResolveResult resolveResult = newExpression.advancedResolve();
    final PsiElement constructor = resolveResult.getElement();
    if (constructor instanceof PsiMethod) {
      return ((PsiMethod)constructor).getParameterList().getParametersCount() == 0;
    }

    final PsiElement resolved = refElement.resolve();
    return resolved instanceof PsiClass;
  }

  private void writeTypeBody(StringBuilder builder, GrAnonymousClassDefinition anonymous) {
    builder.append("{\n");
    final GeneratorClassNameProvider classNameProvider = new GeneratorClassNameProvider();
    final ClassItemGeneratorImpl classItemGenerator = new ClassItemGeneratorImpl(context.extend());
    new ClassGenerator(classNameProvider, classItemGenerator).writeMembers(builder, anonymous);
    builder.append('}');
  }

  @Override
  public void visitApplicationStatement(GrApplicationStatement applicationStatement) {
    generateMethodCall(applicationStatement);
  }


  @Override
  public void visitConditionalExpression(GrConditionalExpression expression) {
    final GrExpression condition = expression.getCondition();
    final GrExpression thenBranch = expression.getThenBranch();
    final GrExpression elseBranch = expression.getElseBranch();

    final boolean elvis = expression instanceof GrElvisExpression;
    final String var;
    if (elvis) {
      var = createVarByInitializer(condition);
    }
    else {
      var = null;
    }
    final PsiType type = condition.getType();
    if (type == null || TypesUtil.unboxPrimitiveTypeWrapper(type) == PsiType.BOOLEAN) {
      if (elvis) {
        builder.append(var);
      }
      else {
        condition.accept(this);
      }
    }
    else {
      final GroovyResolveResult[] results = ResolveUtil.getMethodCandidates(type, "asBoolean", expression, PsiType.EMPTY_ARRAY);
      final GroovyResolveResult result = PsiImplUtil.extractUniqueResult(results);
      GenerationUtil.invokeMethodByResolveResult(
        elvis ? factory.createReferenceExpressionFromText(var, expression) : condition,
        result,
        "asBoolean",
        GrExpression.EMPTY_ARRAY, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY,
        this,
        expression
      );
    }

    builder.append('?');
    if (thenBranch != null) {
      if (elvis) {
        builder.append(var);
      }
      else {
        thenBranch.accept(this);
      }
    }

    builder.append(':');
    if (elseBranch != null) {
      elseBranch.accept(this);
    }
  }

  /**
   * x= expr ->
   * x = expr
   * x.set(expr)[: x.get()]
   * x+= expr ->
   * x+=expr
   * x= plus(x, expr)
   * x.set(plus(x, expr))[expr]
   * x[a] = 4 ->
   * x[a] = 4
   * x.putAt(a, 4) [4]
   */
  @Override
  public void visitAssignmentExpression(final GrAssignmentExpression expression) {
    final GrExpression lValue = expression.getLValue();
    final GrExpression rValue = expression.getRValue();
    final IElementType token = expression.getOperationTokenType();

    PsiElement realLValue = PsiUtil.skipParentheses(lValue, false);
    if (realLValue instanceof GrReferenceExpression && rValue != null) {
      GroovyResolveResult resolveResult = ((GrReferenceExpression)realLValue).advancedResolve();
      PsiElement resolved = resolveResult.getElement();
      if (resolved instanceof GrVariable && context.analyzedVars.toWrap((GrVariable)resolved)) {
        //write assignment to wrapped local var
        writeAssignmentWithRefSetter((GrExpression)realLValue, expression);
        return;
      }
      else if (resolved instanceof PsiMethod && resolveResult.isInvokedOnProperty()) {
        //write assignment via setter
        writeAssignmentWithSetter(((GrReferenceExpression)realLValue).getQualifier(), (PsiMethod)resolved, expression);
        return;
      }
      else if (resolved == null || resolved instanceof GrBindingVariable) {
        //write unresolved reference assignment via setter GroovyObject.setProperty(String name, Object value)
        final GrExpression qualifier = ((GrReferenceExpression)realLValue).getQualifier();
        final PsiType type = PsiImplUtil.getQualifierType((GrReferenceExpression)realLValue);

        final GrExpression[] args = {
          factory.createExpressionFromText("\"" + ((GrReferenceExpression)realLValue).getReferenceName() + "\""),
          getRValue(expression)
        };
        GroovyResolveResult[] candidates = type != null
                                           ? ResolveUtil.getMethodCandidates(type, "setProperty", expression, args[0].getType(), args[1].getType())
                                           : GroovyResolveResult.EMPTY_ARRAY;
        final PsiMethod method = PsiImplUtil.extractUniqueElement(candidates);
        if (method != null) {
          writeAssignmentWithSetter(qualifier, method, args, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY, PsiSubstitutor.EMPTY, expression);
          return;
        }
      }
    }
    else if (realLValue instanceof GrIndexProperty) {   //qualifier[args] = rValue
      //write assignment via qualifier.putAt(Args, Value) method
      final GroovyResolveResult result = PsiImplUtil.extractUniqueResult(((GrIndexProperty)realLValue).multiResolve(false));
      final PsiElement resolved = result.getElement();
      if (resolved instanceof PsiMethod) {
        final GrExpression[] args = ((GrIndexProperty)realLValue).getArgumentList().getExpressionArguments();
        writeAssignmentWithSetter(((GrIndexProperty)realLValue).getInvokedExpression(), (PsiMethod)resolved,
                                  ArrayUtil.append(args, getRValue(expression)), GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY,
                                  result.getSubstitutor(), expression);
        return;
      }
    }

    final PsiType lType = GenerationUtil.getDeclaredType(lValue, context);

    if (token == GroovyTokenTypes.mASSIGN) {
      //write simple assignment
      lValue.accept(this);
      builder.append(" = ");

      if (rValue != null) {
        final PsiType rType = GenerationUtil.getDeclaredType(rValue, context);
        GenerationUtil.wrapInCastIfNeeded(builder, GenerationUtil.getNotNullType(expression, lType), rType, expression, context, new StatementWriter() {
          @Override
          public void writeStatement(StringBuilder builder, ExpressionContext context) {
            rValue.accept(ExpressionGenerator.this);
          }
        });
      }
    }
    else {
      //write assignment such as +=, -=, etc
      final GroovyResolveResult resolveResult = PsiImplUtil.extractUniqueResult(expression.multiResolve(false));
      final PsiElement resolved = resolveResult.getElement();

      if (resolved instanceof PsiMethod && !shouldNotReplaceOperatorWithMethod(lValue.getType(), rValue, expression.getOperationTokenType())) {
        lValue.accept(this);
        builder.append(" = ");

        final PsiType rType = GenerationUtil.getDeclaredType((PsiMethod)resolved, resolveResult.getSubstitutor(), context);
        GenerationUtil.wrapInCastIfNeeded(builder, GenerationUtil.getNotNullType(expression, lType),  rType, expression, context, new StatementWriter() {
          @Override
          public void writeStatement(StringBuilder builder, ExpressionContext context) {
            invokeMethodOn(
              ((PsiMethod)resolved),
              (GrExpression)lValue.copy(),
              rValue == null ? GrExpression.EMPTY_ARRAY : new GrExpression[]{rValue},
              GrNamedArgument.EMPTY_ARRAY,
              GrClosableBlock.EMPTY_ARRAY,
              resolveResult.getSubstitutor(),
              expression
            );
          }
        });
      }
      else {
        writeSimpleBinaryExpression(expression.getOperationToken(), lValue, rValue);
      }
    }
  }

  private void writeAssignmentWithRefSetter(GrExpression ref, GrAssignmentExpression expression) {
    GrExpression rValue = getRValue(expression);

    if (PsiUtil.isExpressionUsed(expression)) {
      LOG.assertTrue(context.getRefSetterName(expression) != null);
      builder.append(context.getRefSetterName(expression)).append('(');
      ref.accept(this);
      builder.append(", ");
      if (rValue != null) {
        rValue.accept(this);
      }
      builder.append(')');
    }
    else {
      ref.accept(this);
      builder.append(".set(");
      if (rValue != null) {
        rValue.accept(this);
      }
      builder.append(')');
    }
  }

  /**
   * returns rValue         for lValue =  expr
   * lValue+Rvalue  for lValue += rValue
   */
  @Nullable
  private GrExpression getRValue(GrAssignmentExpression expression) {
    GrExpression rValue = expression.getRValue();
    if (rValue == null) return null;

    GrExpression lValue = expression.getLValue();
    IElementType opToken = expression.getOperationTokenType();
    if (opToken == GroovyTokenTypes.mASSIGN) return rValue;
    Pair<String, IElementType> pair = GenerationUtil.getBinaryOperatorType(opToken);
    LOG.assertTrue(pair != null);

    return factory.createExpressionFromText(lValue.getText() + pair.getFirst() + rValue.getText(), expression);
  }

  private void writeAssignmentWithSetter(GrExpression qualifier, PsiMethod setter, GrAssignmentExpression assignment) {
    GrExpression rValue = getRValue(assignment);
    LOG.assertTrue(rValue != null);
    writeAssignmentWithSetter(qualifier, setter, new GrExpression[]{rValue}, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY, PsiSubstitutor.EMPTY, assignment);
  }

  private void writeAssignmentWithSetter(@Nullable GrExpression qualifier,
                                         @NotNull PsiMethod method,
                                         @NotNull GrExpression[] exprs,
                                         @NotNull GrNamedArgument[] namedArgs,
                                         @NotNull GrClosableBlock[] closures,
                                         @NotNull PsiSubstitutor substitutor,
                                         @NotNull GrAssignmentExpression assignment) {
    if (PsiUtil.isExpressionUsed(assignment)) {
      final GrExpression rValue = assignment.getRValue();

      //inline setter method invocation in case of tail statement and simple right value
      if (PsiUtil.isExpressionStatement(assignment) && PsiUtil.isReturnStatement(assignment) && rValue != null && isVarAccess(rValue)) {

        final StringBuilder assignmentBuffer = new StringBuilder();
        new ExpressionGenerator(assignmentBuffer, context).invokeMethodOn(method, qualifier, exprs, namedArgs, closures, substitutor, assignment);
        assignmentBuffer.append(';');
        context.myStatements.add(assignmentBuffer.toString());

        rValue.accept(this);
      }
      else {
        String setterName = context.getSetterName(method, assignment);
        GrExpression[] args;
        if (method.hasModifierProperty(PsiModifier.STATIC)) {
          args = exprs;
        }
        else {
          args = new GrExpression[exprs.length + 1];
          if (qualifier == null) {
            qualifier = factory.createExpressionFromText("this", assignment);
          }
          args[0] = qualifier;
          System.arraycopy(exprs, 0, args, 1, exprs.length);
        }
        GenerationUtil.invokeMethodByName(null, setterName, args, namedArgs, closures, this, assignment);
      }
    }
    else {
      invokeMethodOn(method, qualifier, exprs, namedArgs, closures, substitutor, assignment);
    }
  }

  private static boolean isVarAccess(@Nullable GrExpression expr) {
    if (expr instanceof GrReferenceExpression) {
      final PsiElement resolved = ((GrReferenceExpression)expr).resolve();
      if (resolved instanceof PsiVariable) {
        return true;
      }
    }
    return false;
  }

  @Override
  public void visitBinaryExpression(GrBinaryExpression expression) {
    final GrExpression left = expression.getLeftOperand();
    GrExpression right = expression.getRightOperand();
    final PsiType ltype = left.getType();
    final PsiElement token = expression.getOperationToken();
    final IElementType op = expression.getOperationTokenType();

    if (op == GroovyTokenTypes.mREGEX_FIND) {
      builder.append(GroovyCommonClassNames.JAVA_UTIL_REGEX_PATTERN).append(".compile(");
      if (right != null) {
        right.accept(this);
      }
      builder.append(").matcher(");
      left.accept(this);
      builder.append(')');
      return;
    }
    if (op == GroovyTokenTypes.mREGEX_MATCH) {
      builder.append(GroovyCommonClassNames.JAVA_UTIL_REGEX_PATTERN).append(".matches(");
      if (right != null) {
        right.accept(this);
      }
      builder.append(", ");
      left.accept(this);
      builder.append(')');
      return;
    }
    if ((op == GroovyTokenTypes.mEQUAL || op == GroovyTokenTypes.mNOT_EQUAL) && (GrInspectionUtil.isNull(left) || right != null && GrInspectionUtil.isNull(right))) {
      writeSimpleBinaryExpression(token, left, right);
      return;
    }

    if (op == GroovyTokenTypes.kIN && right instanceof GrReferenceExpression && InheritanceUtil.isInheritor(right.getType(), CommonClassNames.JAVA_LANG_CLASS)) {
      final PsiType type = com.intellij.psi.util.PsiUtil.substituteTypeParameter(right.getType(), CommonClassNames.JAVA_LANG_CLASS, 0, true);
      writeInstanceof(left, type, expression);
      return;
    }

    if (shouldNotReplaceOperatorWithMethod(ltype, right, op)) {
      writeSimpleBinaryExpression(token, left, right);
      return;
    }

    final GroovyResolveResult resolveResult = PsiImplUtil.extractUniqueResult(expression.multiResolve(false));
    final PsiElement resolved = resolveResult.getElement();
    if (resolved instanceof PsiMethod) {
      if (right == null) {
        right = factory.createExpressionFromText("null");
      }

      if (op == GroovyTokenTypes.mNOT_EQUAL && "equals".equals(((PsiMethod)resolved).getName())) {
        builder.append('!');
      }
      invokeMethodOn(
        ((PsiMethod)resolved),
        left,
        new GrExpression[]{right},
        GrNamedArgument.EMPTY_ARRAY,
        GrClosableBlock.EMPTY_ARRAY,
        resolveResult.getSubstitutor(),
        expression
      );
      if (op == GroovyTokenTypes.mGE) {
        builder.append(" >= 0");
      }
      else if (op == GroovyTokenTypes.mGT) {
        builder.append(" > 0");
      }
      else if (op == GroovyTokenTypes.mLT) {
        builder.append(" < 0");
      }
      else if (op == GroovyTokenTypes.mLE) builder.append(" <= 0");
    }
    else {
      writeSimpleBinaryExpression(token, left, right);
    }
  }

  private static boolean shouldNotReplaceOperatorWithMethod(@Nullable PsiType ltype, @Nullable GrExpression right, IElementType op) {
    if (!GenerationSettings.replaceOperatorsWithMethodsForNumbers) {

      //adding something to string
      if ((op == GroovyTokenTypes.mPLUS || op == GroovyTokenTypes.mPLUS_ASSIGN) && ltype != null && TypesUtil.isClassType(ltype, CommonClassNames.JAVA_LANG_STRING)) {
        return true;
      }

      //we think it is number operation if we don't know right argument
      if (TypesUtil.isNumericType(ltype) && (right == null || TypesUtil.isNumericType(right.getType()))) return true;
    }

    if (op == GroovyTokenTypes.mLNOT && isBooleanType(ltype)) {
      return true;
    }

    return false;
  }

  private static boolean isBooleanType(PsiType type) {
    return type == PsiType.BOOLEAN || type != null && type.equalsToText(CommonClassNames.JAVA_LANG_BOOLEAN);
  }

  private void writeSimpleBinaryExpression(PsiElement opToken, GrExpression left, GrExpression right) {
    left.accept(this);
    builder.append(' ');
    builder.append(opToken.getText());
    if (right != null) {
      builder.append(' ');
      right.accept(this);
    }
  }

  @Override
  public void visitUnaryExpression(GrUnaryExpression expression) {
    final boolean postfix = expression.isPostfix();

    final GroovyResolveResult resolveResult = PsiImplUtil.extractUniqueResult(expression.multiResolve(false));
    final PsiElement resolved = resolveResult.getElement();
    final GrExpression operand = expression.getOperand();

    IElementType opType = expression.getOperationTokenType();

    if (resolved instanceof PsiMethod) {

      if (opType == GroovyTokenTypes.mINC || opType == GroovyTokenTypes.mDEC) {
        if (!postfix || expression.getParent() instanceof GrStatementOwner || expression.getParent() instanceof GrControlStatement) {
          if (generatePrefixIncDec((PsiMethod)resolved, operand, expression)) return;
        }
      }

      if (operand != null && shouldNotReplaceOperatorWithMethod(operand.getType(), null, expression.getOperationTokenType())) {
        writeSimpleUnary(operand, expression, this);
      }
      else {
        if (opType == GroovyTokenTypes.mLNOT) {
          builder.append('!');
        }
        invokeMethodOn(
          ((PsiMethod)resolved),
          operand,
          GrExpression.EMPTY_ARRAY,
          GrNamedArgument.EMPTY_ARRAY,
          GrClosableBlock.EMPTY_ARRAY,
          resolveResult.getSubstitutor(),
          expression
        );
      }
    }
    else if (operand != null) {
      if (postfix) {
        operand.accept(this);
        builder.append(expression.getOperationToken().getText());
      }
      else {
        builder.append(expression.getOperationToken().getText());
        operand.accept(this);
      }
    }
  }

  private boolean generatePrefixIncDec(PsiMethod method,
                                       GrExpression operand,
                                       GrUnaryExpression unary) {
    if (!(operand instanceof GrReferenceExpression)) return false;

    final GrExpression qualifier = ((GrReferenceExpression)operand).getQualifier();
    final GroovyResolveResult resolveResult = ((GrReferenceExpression)operand).advancedResolve();
    final PsiElement resolved = resolveResult.getElement();
    if (resolved instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertyGetter((PsiMethod)resolved)) {
      final PsiMethod getter = (PsiMethod)resolved;
      final String propertyName = GroovyPropertyUtils.getPropertyNameByGetter(getter);
      final PsiType type;
      if (qualifier == null) {
        type = null;
      }
      else {
        type = qualifier.getType();
        if (type == null) return false;
      }
      final PsiMethod setter = GroovyPropertyUtils.findPropertySetter(type, propertyName, unary);
      if (setter == null) return false;

      final ExpressionGenerator generator = new ExpressionGenerator(new StringBuilder(), context);

      if (shouldNotReplaceOperatorWithMethod(operand.getType(), null, unary.getOperationTokenType())) {
        writeSimpleUnary(operand, unary, generator);
      }
      else {
        generator.invokeMethodOn(
          method,
          operand,
          GrExpression.EMPTY_ARRAY, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY,
          resolveResult.getSubstitutor(),
          unary
        );
      }
      final GrExpression fromText = factory.createExpressionFromText(generator.toString(), unary);
      invokeMethodOn(
        setter,
        qualifier,
        new GrExpression[]{fromText}, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY,
        resolveResult.getSubstitutor(),
        unary
      );
    }
    else if (resolved instanceof PsiVariable) {
      boolean wrap = context.analyzedVars.toWrap((PsiVariable)resolved);
      boolean doNeedExpression = PsiUtil.isExpressionUsed(unary);
      StringBuilder curBuilder;
      ExpressionGenerator curGenerator;
      if (doNeedExpression && wrap) {
        curBuilder = new StringBuilder();
        curGenerator = new ExpressionGenerator(curBuilder, context);
      }
      else {
        curBuilder = builder;
        curGenerator = this;
      }


      boolean shouldInsertParentheses = !wrap && doNeedExpression;
      if (shouldInsertParentheses) {
        curBuilder.append('(');
      }

      operand.accept(curGenerator);
      if (wrap) {
        curBuilder.append(".set(");
      }
      else {
        curBuilder.append(" = ");
      }
      if (shouldNotReplaceOperatorWithMethod(operand.getType(), null, unary.getOperationTokenType())) {
        writeSimpleUnary((GrExpression)operand.copy(), unary, curGenerator);
      }
      else {
        curGenerator.invokeMethodOn(
          method,
          (GrExpression)operand.copy(),
          GrExpression.EMPTY_ARRAY, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY,
          resolveResult.getSubstitutor(),
          unary
        );
      }
      if (shouldInsertParentheses) {
        curBuilder.append(')');
      }
      if (wrap) {
        curBuilder.append(')');
        if (doNeedExpression) {
          curBuilder.append(';');
          context.myStatements.add(curBuilder.toString());
          operand.accept(this);
          builder.append(".get()");
        }
      }
    }
    return true;
  }

  private static void writeSimpleUnary(GrExpression operand, GrUnaryExpression unary, ExpressionGenerator generator) {
    String opTokenText = unary.getOperationToken().getText();
    boolean isPostfix = unary.isPostfix();
    if (!isPostfix) {
      generator.getBuilder().append(opTokenText);
    }
    operand.accept(generator);
    if (isPostfix) {
      generator.getBuilder().append(opTokenText);
    }
  }

  @Override
  //doesn't visit GrString and regexps
  public void visitLiteralExpression(GrLiteral literal) {
    final TypeConstraint[] constraints = GroovyExpectedTypesProvider.calculateTypeConstraints(literal);

    boolean isChar = false;
    for (TypeConstraint constraint : constraints) {
      if (constraint instanceof SubtypeConstraint && TypesUtil.unboxPrimitiveTypeWrapper(constraint.getDefaultType()) == PsiType.CHAR) {
        isChar = true;
      }
    }

    final String text = literal.getText();
    if (text.startsWith("'''") || text.startsWith("\"\"\"")) {
      String string = GrStringUtil.removeQuotes(text).replace("\n", "\\n").replace("\r", "\\r");
      builder.append('"').append(string).append('"');
    }
    else if (text.startsWith("'")) {
      if (isChar) {
        builder.append(text);
      }
      else {
        builder.append('"').append(StringUtil.escapeQuotes(StringUtil.trimEnd(text.substring(1, text.length()), "'"))).append('"');
      }
    }
    else if (text.startsWith("\"")) {
      if (isChar) {
        builder.append('\'').append(StringUtil.escapeQuotes(StringUtil.trimEnd(text.substring(1, text.length()), "\""))).append('\'');
      }
      else {
        builder.append(text);
      }
    }
    else {
      builder.append(text);
    }
  }

  @Override
  public void visitGStringExpression(GrString gstring) {
    final String newExprText = ConvertGStringToStringIntention.convertGStringLiteralToStringLiteral(gstring);
    final GrExpression newExpr = factory.createExpressionFromText(newExprText, gstring);
    newExpr.accept(this);
  }

  @Override
  public void visitReferenceExpression(GrReferenceExpression referenceExpression) {
    final GrExpression qualifier = referenceExpression.getQualifier();
    final GroovyResolveResult resolveResult = referenceExpression.advancedResolve();
    final PsiElement resolved = resolveResult.getElement();
    final String referenceName = referenceExpression.getReferenceName();

    if (PsiUtil.isThisOrSuperRef(referenceExpression)) {
      writeThisOrSuperRef(referenceExpression, qualifier, referenceName);
      return;
    }

    if (ResolveUtil.isClassReference(referenceExpression)) {
      LOG.assertTrue(qualifier != null);
      qualifier.accept(this);
      builder.append(".class");
      return;
    }

    //class name used as expression. Should be converted to <className>.class
    if (resolved instanceof PsiClass && PsiUtil.isExpressionUsed(referenceExpression)) {
      builder.append(((PsiClass)resolved).getQualifiedName());
      builder.append(".class");
      return;
    }

    //don't try to resolve local vars that are provided my this generator (they are listed in myUsedVarNames)
    if (resolved == null && qualifier == null && context.myUsedVarNames.contains(referenceName)) {
      builder.append(referenceName);
      return;
    }

    //all refs in script that are not resolved are saved in 'binding' of the script
    if (qualifier == null &&
        (resolved == null ||
         resolved instanceof GrBindingVariable ||
         resolved instanceof LightElement && !(resolved instanceof ClosureSyntheticParameter)) &&
        (referenceExpression.getParent() instanceof GrIndexProperty || !(referenceExpression.getParent() instanceof GrCall)) &&
        PsiUtil.getContextClass(referenceExpression) instanceof GroovyScriptClass) {
      final GrExpression thisExpr = factory.createExpressionFromText("this", referenceExpression);
      thisExpr.accept(this);
      builder.append(".getBinding().getProperty(\"").append(referenceExpression.getReferenceName()).append("\")");
      return;
    }

    final IElementType type = referenceExpression.getDotTokenType();

    GrExpression qualifierToUse = qualifier;

    if (type == GroovyTokenTypes.mMEMBER_POINTER) {
      LOG.assertTrue(qualifier != null);
      builder.append("new ").append(GroovyCommonClassNames.ORG_CODEHAUS_GROOVY_RUNTIME_METHOD_CLOSURE).append('(');
      qualifier.accept(this);
      builder.append(", \"").append(referenceName).append("\")");
      return;
    }

    if (type == GroovyTokenTypes.mOPTIONAL_DOT) {
      LOG.assertTrue(qualifier != null);

      String qualifierName = createVarByInitializer(qualifier);
      builder.append('(').append(qualifierName).append(" == null ? null : ");

      qualifierToUse = factory.createReferenceExpressionFromText(qualifierName, referenceExpression);
    }


    if (resolveResult.isInvokedOnProperty()) {
      //property-style access to accessor (e.g. qual.prop should be translated to qual.getProp())
      LOG.assertTrue(resolved instanceof PsiMethod);
      LOG.assertTrue(GroovyPropertyUtils.isSimplePropertyGetter((PsiMethod)resolved));
      invokeMethodOn(
        ((PsiMethod)resolved),
        qualifierToUse,
        GrExpression.EMPTY_ARRAY,
        GrNamedArgument.EMPTY_ARRAY,
        GrClosableBlock.EMPTY_ARRAY,
        resolveResult.getSubstitutor(),
        referenceExpression
      );
    }
    else {
      if (qualifierToUse != null) {
        qualifierToUse.accept(this);
        builder.append('.');
      }

      if (resolved instanceof PsiNamedElement && !(resolved instanceof GrBindingVariable)) {
        final String refName = ((PsiNamedElement)resolved).getName();

        if (resolved instanceof GrVariable && context.analyzedVars.toWrap((GrVariable)resolved)) {
          //this var should be wrapped by groovy.lang.Reference. so we add .get() tail.
          builder.append(context.analyzedVars.toVarName((GrVariable)resolved));
          if (!PsiUtil.isAccessedForWriting(referenceExpression)) {
            builder.append(".get()");
          }
        }
        else if (resolved instanceof PsiClass) {
          TypeWriter.writeType(builder, referenceExpression.getType(), referenceExpression);
        }
        else {
          builder.append(refName);
        }
      }
      else {
        //unresolved reference
        if (referenceName != null) {
          if (PsiUtil.isAccessedForWriting(referenceExpression)) {
            builder.append(referenceName);
          }
          else {
            PsiType stringType = PsiType.getJavaLangString(referenceExpression.getManager(), referenceExpression.getResolveScope());
            PsiType qualifierType = PsiImplUtil.getQualifierType(referenceExpression);
            GroovyResolveResult[] candidates = qualifierType != null
                                               ? ResolveUtil.getMethodCandidates(qualifierType, "getProperty", referenceExpression,
                                                                                 stringType)
                                               : GroovyResolveResult.EMPTY_ARRAY;
            final PsiElement method = PsiImplUtil.extractUniqueElement(candidates);
            if (method != null) {
              builder.append("getProperty(\"").append(referenceName).append("\")");
            }
            else {
              builder.append(referenceName);
            }
          }
        }
        else {
          final PsiElement nameElement = referenceExpression.getReferenceNameElement();
          if (nameElement instanceof GrExpression) {
            ((GrExpression)nameElement).accept(this);
          }
          else if (nameElement != null) {
            builder.append(nameElement.toString());
          }
        }
      }
    }

    if (type == GroovyTokenTypes.mOPTIONAL_DOT) {
      builder.append(')');
    }

  }

  private void writeThisOrSuperRef(GrReferenceExpression referenceExpression, GrExpression qualifier, String referenceName) {
    if (!context.isInAnonymousContext() && qualifier != null) {
      qualifier.accept(this);
      builder.append('.');
      builder.append(referenceName);
    }
    else if (GenerationUtil.getWrappingImplicitClass(referenceExpression) != null) {
      final PsiClass contextClass;
      if ("this".equals(referenceName)) {
        final PsiElement _contextClass = referenceExpression.resolve();
        if (_contextClass instanceof PsiClass) {
          contextClass = (PsiClass)_contextClass;
        }
        else {
          contextClass = null;
        }
        GenerationUtil.writeThisReference(contextClass, builder, context);
      }
      else { //super ref
        //super ref is used without qualifier. So we should use context class as a qualifier
        contextClass = PsiUtil.getContextClass(referenceExpression);
        GenerationUtil.writeSuperReference(contextClass, builder, context);
      }
    }
    else {
      builder.append(referenceName);
    }
  }

  private String createVarByInitializer(@NotNull GrExpression initializer) {
    GrExpression inner = initializer;
    while (inner instanceof GrParenthesizedExpression) inner = ((GrParenthesizedExpression)inner).getOperand();
    if (inner != null) initializer = inner;

    if (initializer instanceof GrReferenceExpression) {
      final GrExpression qualifier = ((GrReferenceExpression)initializer).getQualifier();
      if (qualifier == null) {
        final PsiElement resolved = ((GrReferenceExpression)initializer).resolve();
        if (resolved instanceof GrVariable && !(resolved instanceof GrField)) {

          //don't create new var. it is already exists
          return ((GrVariable)resolved).getName();
        }
      }
    }
    final String name = GenerationUtil.suggestVarName(initializer, context);
    final StringBuilder builder = new StringBuilder();
    builder.append("final ");
    TypeWriter.writeType(builder, initializer.getType(), initializer);
    builder.append(' ').append(name).append(" = ");
    initializer.accept(new ExpressionGenerator(builder, context));
    builder.append(';');
    context.myStatements.add(builder.toString());
    return name;
  }

  @Override
  public void visitCastExpression(GrTypeCastExpression typeCastExpression) {
    final GrTypeElement typeElement = typeCastExpression.getCastTypeElement();
    final GrExpression operand = typeCastExpression.getOperand();
    generateCast(typeElement, operand);
  }

  private void generateCast(GrTypeElement typeElement, GrExpression operand) {
    builder.append('(');
    TypeWriter.writeType(builder, typeElement.getType(), typeElement);
    builder.append(')');

    boolean insertParentheses =
      operand instanceof GrBinaryExpression && ((GrBinaryExpression)operand).getOperationTokenType() == GroovyTokenTypes.mEQUAL;
    if (insertParentheses) builder.append('(');

    if (operand != null) {
      operand.accept(this);
    }
    if (insertParentheses) builder.append(')');
  }

  @Override
  public void visitSafeCastExpression(GrSafeCastExpression typeCastExpression) {
    final GrExpression operand = (GrExpression)PsiUtil.skipParenthesesIfSensibly(typeCastExpression.getOperand(), false);
    final GrTypeElement typeElement = typeCastExpression.getCastTypeElement();

    if (operand instanceof GrListOrMap && ((GrListOrMap)operand).isMap() && typeElement != null) {
      AnonymousFromMapGenerator.writeAnonymousMap((GrListOrMap)operand, typeElement, builder, context);
      return;
    }

    final PsiType type = typeElement.getType();
    if (operand instanceof GrListOrMap && !((GrListOrMap)operand).isMap() && type instanceof PsiArrayType) {
      builder.append("new ");
      final GrExpression[] initializers = ((GrListOrMap)operand).getInitializers();
      if (initializers.length == 0) {
        TypeWriter.writeTypeForNew(builder, ((PsiArrayType)type).getComponentType(), typeCastExpression);
        builder.append("[0]");
      }
      else {
        TypeWriter.writeTypeForNew(builder, type, typeCastExpression);

        builder.append('{');
        for (GrExpression initializer : initializers) {
          initializer.accept(this);
          builder.append(", ");
        }
        if (initializers.length > 0) {
          builder.delete(builder.length() - 2, builder.length());
          //builder.removeFromTheEnd(2);
        }
        builder.append('}');
      }
      return;
    }

    final GroovyResolveResult resolveResult = PsiImplUtil.extractUniqueResult(typeCastExpression.multiResolve(false));
    final PsiElement resolved = resolveResult.getElement();

    if (resolved instanceof PsiMethod) {
      final GrExpression typeParam;
      try {
        typeParam = factory.createExpressionFromText(typeElement.getText(), typeCastExpression);
      }
      catch (IncorrectOperationException e) {
        generateCast(typeElement, operand);
        return;
      }

      invokeMethodOn(
        ((PsiMethod)resolved),
        operand,
        new GrExpression[]{typeParam},
        GrNamedArgument.EMPTY_ARRAY,
        GrClosableBlock.EMPTY_ARRAY,
        resolveResult.getSubstitutor(),
        typeCastExpression
      );
    }
    else {
      generateCast(typeElement, operand);
    }
  }

  @Override
  public void visitInstanceofExpression(GrInstanceOfExpression expression) {
    final GrExpression operand = expression.getOperand();
    final GrTypeElement typeElement = expression.getTypeElement();
    writeInstanceof(operand, typeElement != null ? typeElement.getType() : null, expression);
  }

  private void writeInstanceof(@NotNull GrExpression operand, @Nullable PsiType type, @NotNull PsiElement context) {
    operand.accept(this);
    builder.append(" instanceof ");

    if (type != null) {
      TypeWriter.writeType(builder, type, context);
    }
  }

  @Override
  public void visitBuiltinTypeClassExpression(GrBuiltinTypeClassExpression expression) {
    PsiElement firstChild = expression.getFirstChild();
    LOG.assertTrue(firstChild != null);
    ASTNode node = firstChild.getNode();
    LOG.assertTrue(node != null);
    final IElementType type = node.getElementType();
    final String boxed = TypesUtil.getBoxedTypeName(type);
    builder.append(boxed);
    if (expression.getParent() instanceof GrIndexProperty) {
      builder.append("[]");
    }
    builder.append(".class");
  }

  @Override
  public void visitParenthesizedExpression(GrParenthesizedExpression expression) {
    builder.append('(');
    final GrExpression operand = expression.getOperand();
    if (operand != null) {
      operand.accept(this);
    }
    builder.append(')');
  }

  @Override
  public void visitPropertySelection(GrPropertySelection expression) {
    expression.getQualifier().accept(this);
    builder.append('.');
    builder.append(expression.getReferenceNameElement().getText());
  }

  @Override
  public void visitIndexProperty(GrIndexProperty expression) {
    final GrExpression selectedExpression = expression.getInvokedExpression();
    final PsiType thisType = selectedExpression.getType();

    final GrArgumentList argList = expression.getArgumentList();

    if (argList.getAllArguments().length == 0) {                       // int[] or String[]
      if (selectedExpression instanceof GrBuiltinTypeClassExpression) {
        selectedExpression.accept(this);
        return;
      }
      else if (selectedExpression instanceof GrReferenceExpression) {
        PsiElement resolved = ((GrReferenceExpression)selectedExpression).resolve();
        if (resolved instanceof PsiClass) {
          builder.append(((PsiClass)resolved).getQualifiedName());
          builder.append("[].class");
          return;
        }
      }
    }
    final PsiType[] argTypes = PsiUtil.getArgumentTypes(argList);

    final GrExpression[] exprArgs = argList.getExpressionArguments();
    final GrNamedArgument[] namedArgs = argList.getNamedArguments();

    if (!PsiImplUtil.isSimpleArrayAccess(thisType, argTypes, expression, PsiUtil.isLValue(expression))) {
      final GroovyResolveResult candidate = PsiImplUtil.extractUniqueResult(expression.multiResolve(false));
      PsiElement element = candidate.getElement();
      if (element != null || !PsiUtil.isLValue(expression)) {                     //see the case of l-value in assignment expression
        if (element instanceof GrGdkMethod &&
            ((GrGdkMethod)element).getStaticMethod().getParameterList().getParameters()[0].getType().equalsToText("java.util.Map<K,V>")) {
          PsiClass map = JavaPsiFacade.getInstance(context.project).findClass(CommonClassNames.JAVA_UTIL_MAP, expression.getResolveScope());
          if (map != null) {
            PsiMethod[] gets = map.findMethodsByName("get", false);
            invokeMethodOn(gets[0], selectedExpression, exprArgs, namedArgs, GrClosableBlock.EMPTY_ARRAY, PsiSubstitutor.EMPTY, expression);
            return;
          }
        }
        else if (element instanceof GrGdkMethod &&
                 ((GrGdkMethod)element).getStaticMethod().getParameterList().getParameters()[0].getType()
                   .equalsToText("java.util.List<T>")) {
          PsiClass list =
            JavaPsiFacade.getInstance(context.project).findClass(CommonClassNames.JAVA_UTIL_LIST, expression.getResolveScope());
          if (list != null) {
            PsiMethod[] gets = list.findMethodsByName("get", false);
            invokeMethodOn(gets[0], selectedExpression, exprArgs, namedArgs, GrClosableBlock.EMPTY_ARRAY, PsiSubstitutor.EMPTY, expression);
            return;
          }
        }
        GenerationUtil
          .invokeMethodByResolveResult(selectedExpression, candidate, "getAt", exprArgs, namedArgs, GrClosableBlock.EMPTY_ARRAY, this, expression);
        return;
      }
    }

    selectedExpression.accept(this);
    builder.append('[');
    final GrExpression arg = exprArgs[0];
    arg.accept(this);
    builder.append(']');
  }

  public void invokeMethodOn(@NotNull PsiMethod method,
                             @Nullable GrExpression caller,
                             @NotNull GrExpression[] exprs,
                             @NotNull GrNamedArgument[] namedArgs,
                             @NotNull GrClosableBlock[] closures,
                             @NotNull PsiSubstitutor substitutor,
                             @NotNull GroovyPsiElement context) {
    if (method instanceof GrGdkMethod) {
      if (CustomMethodInvocator.invokeMethodOn(this, (GrGdkMethod)method, caller, exprs, namedArgs, closures, substitutor, context)) return;

      GrExpression[] newArgs = new GrExpression[exprs.length + 1];
      System.arraycopy(exprs, 0, newArgs, 1, exprs.length);
      if (method.hasModifierProperty(PsiModifier.STATIC)) {
        newArgs[0] = factory.createExpressionFromText("null");
      }
      else {
        if (caller == null) {
          caller = factory.createExpressionFromText("this", context);
        }
        newArgs[0] = caller;
      }
      invokeMethodOn(((GrGdkMethod)method).getStaticMethod(), null, newArgs, namedArgs, closures, substitutor, context);
      return;
    }

    if (method.hasModifierProperty(PsiModifier.STATIC) && caller == null) {
      final PsiClass containingClass = method.getContainingClass();
      if (containingClass != null && !PsiTreeUtil.isAncestor(containingClass, context, true)) {
        builder.append(containingClass.getQualifiedName()).append('.');
      }
    }
    else {
      //LOG.assertTrue(caller != null, "instance method call should have caller");

      if (caller != null) {

        final boolean castNeeded = GenerationUtil.isCastNeeded(caller, method, this.context);
        if (castNeeded) {
          writeCastForMethod(caller, method, context);
        }
        caller.accept(this);
        if (castNeeded) {
          builder.append(')');
        }
        builder.append('.');
      }
    }
    builder.append(method.getName());
    final GrClosureSignature signature = GrClosureSignatureUtil.createSignature(method, substitutor);
    new ArgumentListGenerator(builder, this.context).generate(signature, exprs, namedArgs, closures, context);
  }

  private void writeCastForMethod(@NotNull GrExpression caller, @NotNull PsiMethod method, @NotNull GroovyPsiElement context) {
    final PsiType type = inferCastType(caller, method, context);
    if (type == null) return;

    builder.append('(');
    builder.append('(');
    TypeWriter.writeType(builder, type, context);
    builder.append(')');
  }

  @Nullable
  private static PsiType inferCastType(@NotNull GrExpression caller, @NotNull PsiMethod method, @NotNull GroovyPsiElement context) {
    final PsiType type = caller.getType();
    if (type instanceof PsiIntersectionType) {
      final PsiType[] conjuncts = ((PsiIntersectionType)type).getConjuncts();
      for (PsiType conjunct : conjuncts) {
        final GenerationUtil.CheckProcessElement processor = new GenerationUtil.CheckProcessElement(method);
        ResolveUtil.processAllDeclarationsSeparately(conjunct, processor, new BaseScopeProcessor() {
          @Override
          public boolean execute(@NotNull PsiElement element, @NotNull ResolveState state) {
            return false;
          }
        }, ResolveState.initial(), context);
        if (processor.isFound()) return conjunct;
      }
    }
    return type;
  }


  @Override
  public void visitListOrMap(GrListOrMap listOrMap) {
    final PsiType type = listOrMap.getType();

    //can be PsiArrayType or GrLiteralClassType
    LOG.assertTrue(type instanceof GrLiteralClassType || type instanceof PsiArrayType || type instanceof PsiClassType);

    if (listOrMap.isMap()) {
      if (listOrMap.getNamedArguments().length == 0) {
        builder.append("new ");
        TypeWriter.writeTypeForNew(builder, type, listOrMap);
        builder.append("()");
      }
      else {
        String varName = generateMapVariableDeclaration(listOrMap, type);
        generateMapElementInsertions(listOrMap, varName);
        builder.append(varName);
      }
    }
    else {
      builder.append("new ");
      PsiType typeToUse = getTypeToUseByList(listOrMap, type);
      TypeWriter.writeTypeForNew(builder, typeToUse, listOrMap);

      if (typeToUse instanceof PsiArrayType) {
        if (listOrMap.getInitializers().length == 0) {
          builder.replace(builder.length() - 2, builder.length(), "[0]");
        }
        else {
          builder.append('{');
          genInitializers(listOrMap);
          builder.append('}');
        }
      }
      else if (listOrMap.getInitializers().length == 0) {
        builder.append("()");
      }
      else {
        builder.append("(java.util.Arrays.asList(");
        genInitializers(listOrMap);
        builder.append("))");
      }
    }
  }

  private static PsiType getTypeToUseByList(GrListOrMap listOrMap, PsiType type) {
    if (isImplicitlyCastedToArray(listOrMap)) {
      PsiType iterable = ClosureParameterEnhancer.findTypeForIteration(listOrMap, listOrMap);
      if (iterable != null) {
        return new PsiArrayType(iterable);
      }
    }
    return type;
  }

  private static boolean isImplicitlyCastedToArray(GrListOrMap list) {
    PsiElement parent = list.getParent();
    GrControlFlowOwner owner = ControlFlowUtils.findControlFlowOwner(list);
    if (!(owner instanceof GrOpenBlock && owner.getParent() instanceof GrMethod)) return false;
    if (!(parent instanceof GrReturnStatement || ControlFlowUtils.isReturnValue(list, owner))) return false;

    PsiType type = ((GrMethod)owner.getParent()).getReturnType();
    return type instanceof PsiArrayType;
  }

  private void generateMapElementInsertions(GrListOrMap listOrMap, String varName) {
    for (GrNamedArgument arg : listOrMap.getNamedArguments()) {
      StringBuilder insertion = new StringBuilder();
      insertion.append(varName).append(".put(");
      final String stringKey = arg.getLabelName();
      if (stringKey != null) {
        insertion.append('"').append(stringKey).append('"');
      }
      else {
        final GrArgumentLabel label = arg.getLabel();
        final GrExpression expression = label == null ? null : label.getExpression();
        if (expression != null) {
          expression.accept(new ExpressionGenerator(insertion, context));
        }
        else {
          //todo should we generate an exception?
        }
      }
      insertion.append(", ");
      final GrExpression expression = arg.getExpression();
      if (expression != null) {
        expression.accept(new ExpressionGenerator(insertion, context));
      }
      else {
        //todo should we generate an exception?
      }

      insertion.append(");");
      context.myStatements.add(insertion.toString());
    }
  }

  private String generateMapVariableDeclaration(GrListOrMap listOrMap, PsiType type) {
    StringBuilder declaration = new StringBuilder();

    TypeWriter.writeType(declaration, type, listOrMap);
    final String varName = GenerationUtil.suggestVarName(type, listOrMap, this.context);
    declaration.append(' ').append(varName).append(" = new ");
    TypeWriter.writeTypeForNew(declaration, type, listOrMap);

    declaration.append('(');
    //insert count of elements in list or map

    declaration.append(listOrMap.getNamedArguments().length);
    declaration.append(");");
    context.myStatements.add(declaration.toString());
    return varName;
  }

  private void genInitializers(GrListOrMap list) {
    LOG.assertTrue(!list.isMap());

    final GrExpression[] initializers = list.getInitializers();
    for (GrExpression expr : initializers) {
      expr.accept(this);
      builder.append(", ");
    }

    if (initializers.length > 0) {
      builder.delete(builder.length() - 2, builder.length());
      //builder.removeFromTheEnd(2);
    }
  }

  @Override
  public void visitRangeExpression(GrRangeExpression range) {
    final PsiType type = range.getType();
    LOG.assertTrue(type instanceof GrRangeType);
    final PsiClass resolved = ((GrRangeType)type).resolve();
    builder.append("new ");
    if (resolved == null) {
      builder.append(GroovyCommonClassNames.GROOVY_LANG_OBJECT_RANGE);
    }
    else {
      builder.append(resolved.getQualifiedName());
    }
    builder.append('(');
    final GrExpression left = range.getLeftOperand();
    left.accept(this);

    builder.append(", ");

    final GrExpression right = range.getRightOperand();
    if (right != null) {
      right.accept(this);
    }

    builder.append(')');
  }
}
