/*******************************************************************************
 * Copyright (c) 2020 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Fabrice TIERCELIN - initial API and implementation from AutoRefactor
 *******************************************************************************/
package org.eclipse.jdt.internal.corext.dom;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.jdt.core.dom.ASTMatcher;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.AssertStatement;
import org.eclipse.jdt.core.dom.Assignment;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.BreakStatement;
import org.eclipse.jdt.core.dom.ConditionalExpression;
import org.eclipse.jdt.core.dom.ConstructorInvocation;
import org.eclipse.jdt.core.dom.ContinueStatement;
import org.eclipse.jdt.core.dom.DoStatement;
import org.eclipse.jdt.core.dom.EmptyStatement;
import org.eclipse.jdt.core.dom.EnhancedForStatement;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ExpressionStatement;
import org.eclipse.jdt.core.dom.ForStatement;
import org.eclipse.jdt.core.dom.IfStatement;
import org.eclipse.jdt.core.dom.InfixExpression;
import org.eclipse.jdt.core.dom.LabeledStatement;
import org.eclipse.jdt.core.dom.ParenthesizedExpression;
import org.eclipse.jdt.core.dom.PostfixExpression;
import org.eclipse.jdt.core.dom.PrefixExpression;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
import org.eclipse.jdt.core.dom.SwitchStatement;
import org.eclipse.jdt.core.dom.SynchronizedStatement;
import org.eclipse.jdt.core.dom.ThrowStatement;
import org.eclipse.jdt.core.dom.TryStatement;
import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.core.dom.WhileStatement;

/**
 * Matches two pieces of code on semantic (not on syntax).
 * ASTSemanticMatcher.java matches more cases than ASTMatcher.java:
 * - Inverted commutative operations:
 *   k + 1
 *   1 + k
 *
 * - Mirrored boolean expressions:
 *   k > 1
 *   1 < k
 *
 * - Neutral operands:
 *   i + j
 *   i + j + 0
 *
 * - Pushed down negations:
 *   !(k > 0)
 *   (k <= 0)
 *
 * - Integer identical operations:
 *   i >= 1
 *   i > 0
 *
 * - Identical statements (not expressions):
 *   i++;
 *   ++i;
 *   i += 1;
 *   i = i + 1;
 *
 * - Blocked vs lone statements:
 *   if (isValid) {i++;}
 *   if (isValid) i++;
 *
 * - Parentherized vs unparentherized expression:
 *   if ((isValid)) {i++;}
 *   if (isValid) {i++;}
 *
 * - Inverted if statements or ternary expressions:
 *   if (isValid) k++; else m--;
 *   if (!isValid) m--; else k++;
 *
 * You can also match opposite boolean expressions:
 * ASTSemanticMatcher.matchOpposite()
 */
public class ASTSemanticMatcher extends ASTMatcher {
	/**
	 * Singleton.
	 */
	public static final ASTSemanticMatcher INSTANCE= new ASTSemanticMatcher();

	private static final Map<PrefixExpression.Operator, InfixExpression.Operator> PREFIX_TO_INFIX_OPERATOR= new HashMap<PrefixExpression.Operator, InfixExpression.Operator>() {
		private static final long serialVersionUID= -8949107654517355855L;

		{
			put(PrefixExpression.Operator.INCREMENT, InfixExpression.Operator.PLUS);
			put(PrefixExpression.Operator.DECREMENT, InfixExpression.Operator.MINUS);
		}
	};

	private static final Map<PrefixExpression.Operator, Assignment.Operator> PREFIX_TO_ASSIGN_OPERATOR= new HashMap<PrefixExpression.Operator, Assignment.Operator>() {
		private static final long serialVersionUID= -8949107654517355856L;

		{
			put(PrefixExpression.Operator.INCREMENT, Assignment.Operator.PLUS_ASSIGN);
			put(PrefixExpression.Operator.DECREMENT, Assignment.Operator.MINUS_ASSIGN);
		}
	};

	private static final Map<PostfixExpression.Operator, InfixExpression.Operator> POSTFIX_TO_INFIX_OPERATOR= new HashMap<PostfixExpression.Operator, InfixExpression.Operator>() {
		private static final long serialVersionUID= -8949107654517355857L;

		{
			put(PostfixExpression.Operator.INCREMENT, InfixExpression.Operator.PLUS);
			put(PostfixExpression.Operator.DECREMENT, InfixExpression.Operator.MINUS);
		}
	};

	private static final Map<PostfixExpression.Operator, Assignment.Operator> POSTFIX_TO_ASSIGN_OPERATOR= new HashMap<PostfixExpression.Operator, Assignment.Operator>() {
		private static final long serialVersionUID= -8949107654517355858L;

		{
			put(PostfixExpression.Operator.INCREMENT, Assignment.Operator.PLUS_ASSIGN);
			put(PostfixExpression.Operator.DECREMENT, Assignment.Operator.MINUS_ASSIGN);
		}
	};

	private static final Map<PrefixExpression.Operator, PostfixExpression.Operator> PREFIX_TO_POSTFIX_OPERATOR= new HashMap<PrefixExpression.Operator, PostfixExpression.Operator>() {
		private static final long serialVersionUID= -8949107654517355859L;

		{
			put(PrefixExpression.Operator.INCREMENT, PostfixExpression.Operator.INCREMENT);
			put(PrefixExpression.Operator.DECREMENT, PostfixExpression.Operator.DECREMENT);
		}
	};

	private static final Map<Assignment.Operator, InfixExpression.Operator> ASSIGN_TO_INFIX_OPERATOR= new HashMap<Assignment.Operator, InfixExpression.Operator>() {
		private static final long serialVersionUID= -8949107654517355859L;

		{
			put(Assignment.Operator.PLUS_ASSIGN, InfixExpression.Operator.PLUS);
			put(Assignment.Operator.MINUS_ASSIGN, InfixExpression.Operator.MINUS);
			put(Assignment.Operator.TIMES_ASSIGN, InfixExpression.Operator.TIMES);
			put(Assignment.Operator.DIVIDE_ASSIGN, InfixExpression.Operator.DIVIDE);
			put(Assignment.Operator.BIT_AND_ASSIGN, InfixExpression.Operator.AND);
			put(Assignment.Operator.BIT_OR_ASSIGN, InfixExpression.Operator.OR);
			put(Assignment.Operator.BIT_XOR_ASSIGN, InfixExpression.Operator.XOR);
			put(Assignment.Operator.REMAINDER_ASSIGN, InfixExpression.Operator.REMAINDER);
			put(Assignment.Operator.LEFT_SHIFT_ASSIGN, InfixExpression.Operator.LEFT_SHIFT);
			put(Assignment.Operator.RIGHT_SHIFT_SIGNED_ASSIGN, InfixExpression.Operator.RIGHT_SHIFT_SIGNED);
			put(Assignment.Operator.RIGHT_SHIFT_UNSIGNED_ASSIGN, InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED);
		}
	};

	private static final Map<InfixExpression.Operator, InfixExpression.Operator> INFIX_TO_MIRROR_OPERATOR= new HashMap<InfixExpression.Operator, InfixExpression.Operator>() {
		private static final long serialVersionUID= -8949107654517355857L;

		{
			put(InfixExpression.Operator.EQUALS, InfixExpression.Operator.EQUALS);
			put(InfixExpression.Operator.NOT_EQUALS, InfixExpression.Operator.NOT_EQUALS);
			put(InfixExpression.Operator.CONDITIONAL_AND, InfixExpression.Operator.CONDITIONAL_AND);
			put(InfixExpression.Operator.CONDITIONAL_OR, InfixExpression.Operator.CONDITIONAL_OR);
			put(InfixExpression.Operator.AND, InfixExpression.Operator.AND);
			put(InfixExpression.Operator.OR, InfixExpression.Operator.OR);
			put(InfixExpression.Operator.XOR, InfixExpression.Operator.XOR);
			put(InfixExpression.Operator.PLUS, InfixExpression.Operator.PLUS);
			put(InfixExpression.Operator.TIMES, InfixExpression.Operator.TIMES);

			put(InfixExpression.Operator.GREATER, InfixExpression.Operator.LESS);
			put(InfixExpression.Operator.LESS, InfixExpression.Operator.GREATER);
			put(InfixExpression.Operator.LESS_EQUALS, InfixExpression.Operator.GREATER_EQUALS);
			put(InfixExpression.Operator.GREATER_EQUALS, InfixExpression.Operator.LESS_EQUALS);
		}
	};

	@Override
	public boolean match(final InfixExpression node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof PrefixExpression) {
			PrefixExpression pe= (PrefixExpression) other;

			if (ASTNodes.hasOperator(pe, PrefixExpression.Operator.NOT)) {
				return matchNegative(node, pe.getOperand());
			}
		}

		if (other instanceof InfixExpression) {
			InfixExpression infixExpression= (InfixExpression) other;

			if (!ASTNodes.hasOperator(infixExpression, InfixExpression.Operator.PLUS)
					|| ASTNodes.hasType(node.getLeftOperand(), short.class.getSimpleName(), int.class.getSimpleName(), long.class.getSimpleName(), float.class.getSimpleName(), double.class.getSimpleName(), Short.class.getCanonicalName(),
							Integer.class.getCanonicalName(), Long.class.getCanonicalName(), Float.class.getCanonicalName(), Double.class.getCanonicalName())
							&& ASTNodes.hasType(node.getRightOperand(), short.class.getSimpleName(), int.class.getSimpleName(), long.class.getSimpleName(), float.class.getSimpleName(), double.class.getSimpleName(), Short.class.getCanonicalName(),
									Integer.class.getCanonicalName(), Long.class.getCanonicalName(), Float.class.getCanonicalName(), Double.class.getCanonicalName())) {
				if (!node.hasExtendedOperands() && !infixExpression.hasExtendedOperands()
						&& node.getOperator().equals(INFIX_TO_MIRROR_OPERATOR.get(infixExpression.getOperator()))
						&& ASTNodes.isPassiveWithoutFallingThrough(node.getLeftOperand())
						&& ASTNodes.isPassiveWithoutFallingThrough(node.getRightOperand())
						&& safeSubtreeMatch(node.getLeftOperand(), infixExpression.getRightOperand())
						&& safeSubtreeMatch(node.getRightOperand(), infixExpression.getLeftOperand())) {
					return true;
				}

				if (node.getOperator().equals(infixExpression.getOperator()) && ASTNodes.hasOperator(infixExpression, InfixExpression.Operator.PLUS, InfixExpression.Operator.TIMES, InfixExpression.Operator.AND,
								InfixExpression.Operator.CONDITIONAL_AND, InfixExpression.Operator.OR,
								InfixExpression.Operator.CONDITIONAL_OR, InfixExpression.Operator.XOR)
						&& isOperandsMatching(node, infixExpression, true)) {
					return true;
				}
			}
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final ParenthesizedExpression node, final Object otherObject) {
		Object other= unbracket(otherObject);

		return safeSubtreeMatch(node.getExpression(), other);
	}

	private Object unbracket(final Object otherObject) {
		if (otherObject instanceof ParenthesizedExpression) {
			return ((ParenthesizedExpression) otherObject).getExpression();
		}

		return otherObject;
	}

	@Override
	public boolean match(final PrefixExpression node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (!(other instanceof PrefixExpression) && ASTNodes.hasOperator(node, PrefixExpression.Operator.NOT)) {
			return matchNegative(node.getOperand(), other);
		}

		if (node.getParent() instanceof Statement) {
			if (other instanceof Assignment) {
				return match0(node, (Assignment) other);
			}
			if (other instanceof PostfixExpression) {
				return match0(node, (PostfixExpression) other);
			}
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final PostfixExpression node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (node.getParent() instanceof Statement) {
			if (other instanceof Assignment) {
				return match0(node, (Assignment) other);
			}
			if (other instanceof PrefixExpression) {
				return match0((PrefixExpression) other, node);
			}
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final Assignment node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof PrefixExpression && ((PrefixExpression) other).getParent() instanceof Statement) {
			return match0((PrefixExpression) other, node);
		}
		if (other instanceof PostfixExpression && ((PostfixExpression) other).getParent() instanceof Statement) {
			return match0((PostfixExpression) other, node);
		}
		if (other instanceof Assignment) {
			return matchAssignmentWithAndWithoutEqual(node, (Assignment) other)
					|| matchAssignmentWithAndWithoutEqual((Assignment) other, node) || super.match(node, other);
		}

		return super.match(node, other);
	}

	private boolean matchAssignmentWithAndWithoutEqual(final Assignment node, final Assignment assignment) {
		if (ASTNodes.hasOperator(node, Assignment.Operator.ASSIGN)
				&& node.getRightHandSide() instanceof InfixExpression) {
			InfixExpression infixExpression= (InfixExpression) node.getRightHandSide();

			if (!infixExpression.hasExtendedOperands()
					&& ASTNodes.hasOperator(assignment, Assignment.Operator.PLUS_ASSIGN, Assignment.Operator.MINUS_ASSIGN,
							Assignment.Operator.TIMES_ASSIGN, Assignment.Operator.DIVIDE_ASSIGN,
							Assignment.Operator.BIT_AND_ASSIGN, Assignment.Operator.BIT_OR_ASSIGN,
							Assignment.Operator.BIT_XOR_ASSIGN, Assignment.Operator.REMAINDER_ASSIGN,
							Assignment.Operator.LEFT_SHIFT_ASSIGN, Assignment.Operator.RIGHT_SHIFT_SIGNED_ASSIGN,
							Assignment.Operator.RIGHT_SHIFT_UNSIGNED_ASSIGN)
					&& ASSIGN_TO_INFIX_OPERATOR.get(assignment.getOperator()).equals(infixExpression.getOperator())) {
				return safeSubtreeMatch(node.getLeftHandSide(), assignment.getLeftHandSide())
						&& safeSubtreeMatch(infixExpression.getLeftOperand(), assignment.getLeftHandSide())
						&& safeSubtreeMatch(infixExpression.getRightOperand(), assignment.getRightHandSide());
			}
		}

		return false;
	}

	private boolean match0(final PrefixExpression prefixExpression, final PostfixExpression postfixExpression) {
		return postfixExpression.getOperator().equals(PREFIX_TO_POSTFIX_OPERATOR.get(prefixExpression.getOperator()))
				&& safeSubtreeMatch(prefixExpression.getOperand(), postfixExpression.getOperand());
	}

	private boolean match0(final PrefixExpression prefixExpression, final Assignment assignment) {
		return match0(assignment, prefixExpression.getOperand(), PREFIX_TO_INFIX_OPERATOR.get(prefixExpression.getOperator()),
				PREFIX_TO_ASSIGN_OPERATOR.get(prefixExpression.getOperator()));
	}

	private boolean match0(final PostfixExpression postfixExpression, final Assignment assignment) {
		return match0(assignment, postfixExpression.getOperand(), POSTFIX_TO_INFIX_OPERATOR.get(postfixExpression.getOperator()),
				POSTFIX_TO_ASSIGN_OPERATOR.get(postfixExpression.getOperator()));
	}

	private boolean match0(final Assignment assignment, final Expression prefixOrPostfixOperand,
			final InfixExpression.Operator infixAssociatedOperator, final Assignment.Operator assignmentAssociatedOperator) {
		if (ASTNodes.hasOperator(assignment, Assignment.Operator.ASSIGN)
				&& assignment.getRightHandSide() instanceof InfixExpression) {
			InfixExpression infixExpression= (InfixExpression) assignment.getRightHandSide();

			if (!infixExpression.hasExtendedOperands() && infixAssociatedOperator.equals(infixExpression.getOperator())) {
				if (isOneLiteral(infixExpression.getRightOperand())) {
					return safeSubtreeMatch(prefixOrPostfixOperand, assignment.getLeftHandSide())
							&& safeSubtreeMatch(prefixOrPostfixOperand, infixExpression.getLeftOperand());
				}

				if (ASTNodes.hasOperator(infixExpression, InfixExpression.Operator.PLUS) && isOneLiteral(infixExpression.getLeftOperand())) {
					return safeSubtreeMatch(prefixOrPostfixOperand, assignment.getLeftHandSide())
							&& safeSubtreeMatch(prefixOrPostfixOperand, infixExpression.getRightOperand());
				}
			}
		} else if (ASTNodes.hasOperator(assignment, Assignment.Operator.PLUS_ASSIGN, Assignment.Operator.MINUS_ASSIGN) && assignmentAssociatedOperator.equals(assignment.getOperator())
				&& isOneLiteral(assignment)) {
			return safeSubtreeMatch(prefixOrPostfixOperand, assignment.getLeftHandSide());
		}

		return false;
	}

	private boolean isOneLiteral(final Expression operand) {
		return Long.valueOf(1).equals(ASTNodes.getIntegerLiteral(operand));
	}

	@Override
	public boolean match(final Block node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof AssertStatement || other instanceof BreakStatement
				|| other instanceof ConstructorInvocation || other instanceof ContinueStatement
				|| other instanceof DoStatement || other instanceof EmptyStatement
				|| other instanceof EnhancedForStatement || other instanceof ExpressionStatement
				|| other instanceof ForStatement || other instanceof IfStatement || other instanceof LabeledStatement
				|| other instanceof ReturnStatement || other instanceof SuperConstructorInvocation
				|| other instanceof SwitchStatement || other instanceof SynchronizedStatement
				|| other instanceof ThrowStatement || other instanceof TryStatement
				|| other instanceof TypeDeclarationStatement || other instanceof VariableDeclarationStatement
				|| other instanceof WhileStatement) {
			return match0(node, (Statement) other);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final AssertStatement node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final BreakStatement node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final ConstructorInvocation node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final ContinueStatement node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final DoStatement node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final EmptyStatement node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final EnhancedForStatement node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final ExpressionStatement node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final ConditionalExpression node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (super.match(node, other)) {
			return true;
		}

		if (other instanceof ConditionalExpression) {
			ConditionalExpression ce= (ConditionalExpression) other;

			if (node.getElseExpression() != null && ce.getElseExpression() != null) {
				return matchNegative(node.getExpression(), ce.getExpression())
						&& safeSubtreeMatch(node.getThenExpression(), ce.getElseExpression())
						&& safeSubtreeMatch(node.getElseExpression(), ce.getThenExpression());
			}
		}

		return false;
	}

	@Override
	public boolean match(final ForStatement node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final IfStatement node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		if (super.match(node, other)) {
			return true;
		}

		if (other instanceof IfStatement) {
			IfStatement is= (IfStatement) other;

			if (node.getElseStatement() != null && is.getElseStatement() != null) {
				return matchNegative(node.getExpression(), is.getExpression())
						&& safeSubtreeMatch(node.getThenStatement(), is.getElseStatement())
						&& safeSubtreeMatch(node.getElseStatement(), is.getThenStatement());
			}
		}

		return false;
	}

	@Override
	public boolean match(final LabeledStatement node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final ReturnStatement node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final SuperConstructorInvocation node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final SwitchStatement node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final SynchronizedStatement node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final ThrowStatement node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final TryStatement node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final TypeDeclarationStatement node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final VariableDeclarationStatement node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	@Override
	public boolean match(final WhileStatement node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (other instanceof Block) {
			return match0((Block) other, (Statement) node);
		}

		return super.match(node, other);
	}

	private boolean match0(final Block node, final Statement other) {
		if ((node.getParent() instanceof IfStatement || node.getParent() instanceof ForStatement
				|| node.getParent() instanceof EnhancedForStatement || node.getParent() instanceof WhileStatement
				|| node.getParent() instanceof DoStatement) && node.statements().size() == 1) {
			return safeSubtreeMatch(node.statements().get(0), other) || super.match(node, other);
		}

		return super.match(node, other);
	}

	/**
	 * Match the negative boolean.
	 *
	 * @param node        Node to check
	 * @param otherObject Node to compare
	 * @return True if it is the negative boolean.
	 */
	public boolean matchNegative(final ASTNode node, final Object otherObject) {
		Object other= unbracket(otherObject);

		if (node instanceof ParenthesizedExpression) {
			return matchNegative(((ParenthesizedExpression) node).getExpression(), other);
		}

		if (node instanceof PrefixExpression) {
			PrefixExpression pe= (PrefixExpression) node;

			if (ASTNodes.hasOperator(pe, PrefixExpression.Operator.NOT)) {
				if (other instanceof PrefixExpression
						&& ASTNodes.hasOperator((PrefixExpression) other, PrefixExpression.Operator.NOT)) {
					return matchNegative(pe.getOperand(), ((PrefixExpression) other).getOperand());
				}

				return safeSubtreeMatch(pe.getOperand(), other);
			}
		} else if (other instanceof PrefixExpression
				&& ASTNodes.hasOperator((PrefixExpression) other, PrefixExpression.Operator.NOT)) {
			return safeSubtreeMatch(node, ((PrefixExpression) other).getOperand());
		}

		if (other instanceof ASTNode) {
			Boolean value= ASTNodes.getBooleanLiteral(node);
			Boolean otherValue= ASTNodes.getBooleanLiteral((ASTNode) other);

			if (value != null && otherValue != null) {
				return value ^ otherValue;
			}
		}

		if (!(node instanceof InfixExpression) || !(other instanceof InfixExpression)) {
			return false;
		}

		InfixExpression infixExpression1= (InfixExpression) node;
		InfixExpression infixExpression2= (InfixExpression) other;

		Expression leftOperand1= infixExpression1.getLeftOperand();
		Expression rightOperand1= infixExpression1.getRightOperand();
		Expression leftOperand2= infixExpression2.getLeftOperand();
		Expression rightOperand2= infixExpression2.getRightOperand();

		if (infixExpression1.getOperator().equals(infixExpression2.getOperator())
				&& !infixExpression1.hasExtendedOperands() && !infixExpression2.hasExtendedOperands()
				&& ASTNodes.hasOperator(infixExpression1, InfixExpression.Operator.EQUALS, InfixExpression.Operator.NOT_EQUALS,
						InfixExpression.Operator.XOR)) {
			return matchOneNegativeOther(leftOperand1, leftOperand2, rightOperand2, rightOperand1)
					|| matchOneNegativeOther(rightOperand2, rightOperand1, leftOperand1, leftOperand2) || ASTNodes.isPassiveWithoutFallingThrough(leftOperand1) && ASTNodes.isPassiveWithoutFallingThrough(rightOperand1) && ASTNodes.isPassiveWithoutFallingThrough(leftOperand2)
					&& ASTNodes.isPassiveWithoutFallingThrough(rightOperand2)
					&& (matchOneNegativeOther(leftOperand1, leftOperand2, rightOperand2, rightOperand1)
							|| matchOneNegativeOther(rightOperand2, rightOperand1, leftOperand1,
									leftOperand2));
		}

		InfixExpression.Operator negatedOperator= ASTNodes.negatedInfixOperator(infixExpression1.getOperator());

		if (infixExpression2.getOperator().equals(negatedOperator)) {
			if (ASTNodes.hasOperator(infixExpression1, InfixExpression.Operator.CONDITIONAL_AND, InfixExpression.Operator.CONDITIONAL_OR,
					InfixExpression.Operator.AND, InfixExpression.Operator.OR)) {
				return isOperandsMatching(infixExpression1, infixExpression2, false);
			}
			if (ASTNodes.hasOperator(infixExpression1, InfixExpression.Operator.EQUALS, InfixExpression.Operator.NOT_EQUALS)) {
				return isOperandsMatching(infixExpression1, infixExpression2, true);
			}
			if (ASTNodes.hasOperator(infixExpression1, InfixExpression.Operator.GREATER, InfixExpression.Operator.GREATER_EQUALS,
					InfixExpression.Operator.LESS, InfixExpression.Operator.LESS_EQUALS)
					&& ASTNodes.isPassiveWithoutFallingThrough(leftOperand1)
					&& ASTNodes.isPassiveWithoutFallingThrough(rightOperand1)
					&& ASTNodes.isPassiveWithoutFallingThrough(leftOperand2)
					&& ASTNodes.isPassiveWithoutFallingThrough(rightOperand2)) {
				return safeSubtreeMatch(leftOperand1, leftOperand2) && safeSubtreeMatch(rightOperand1, rightOperand2);
			}

			return false;
		}

		return (ASTNodes.hasOperator(infixExpression1, InfixExpression.Operator.GREATER) && ASTNodes.hasOperator(infixExpression2, InfixExpression.Operator.GREATER_EQUALS) || ASTNodes.hasOperator(infixExpression1, InfixExpression.Operator.GREATER_EQUALS) && ASTNodes.hasOperator(infixExpression2, InfixExpression.Operator.GREATER) || ASTNodes.hasOperator(infixExpression1, InfixExpression.Operator.LESS) && ASTNodes.hasOperator(infixExpression2, InfixExpression.Operator.LESS_EQUALS) || ASTNodes.hasOperator(infixExpression1, InfixExpression.Operator.LESS_EQUALS) && ASTNodes.hasOperator(infixExpression2, InfixExpression.Operator.LESS))
				&& !infixExpression1.hasExtendedOperands()
				&& !infixExpression2.hasExtendedOperands()
				&& ASTNodes.isPassiveWithoutFallingThrough(leftOperand1)
				&& ASTNodes.isPassiveWithoutFallingThrough(rightOperand1)
				&& ASTNodes.isPassiveWithoutFallingThrough(leftOperand2)
				&& ASTNodes.isPassiveWithoutFallingThrough(rightOperand2)
				&& safeSubtreeMatch(leftOperand1, rightOperand2)
				&& safeSubtreeMatch(rightOperand1, leftOperand2);
	}

	private boolean matchOneNegativeOther(final Expression equalOperand1, final Expression equalOperand2,
			final Expression negativeOperand1, final Expression negativeOperand2) {
		return safeSubtreeMatch(equalOperand1, equalOperand2) && matchNegative(negativeOperand1, negativeOperand2);
	}

	private boolean isOperandsMatching(final InfixExpression infixExpression1, final InfixExpression infixExpression2, final boolean equal) {
		List<Expression> operands1 = getConsistentOperands(infixExpression1);
		List<Expression> operands2 = getConsistentOperands(infixExpression2);

		if (operands1.size() != operands2.size()) {
			return false;
		}

		boolean isMatching= true;
		Iterator<Expression> iterator1= operands1.iterator();
		Iterator<Expression> iterator2= operands2.iterator();

		while (iterator1.hasNext() && iterator2.hasNext()) {
			Expression expression= iterator1.next();
			Expression otherExpression= iterator2.next();

			if (equal ? !safeSubtreeMatch(expression, otherExpression) : !matchNegative(expression, otherExpression)) {
				isMatching= false;
				break;
			}
		}

		if (isMatching) {
			return true;
		}

		for (Expression expression : operands1) {
			if (!ASTNodes.isPassiveWithoutFallingThrough(expression)) {
				return false;
			}
		}

		for (Expression expression : operands2) {
			if (!ASTNodes.isPassiveWithoutFallingThrough(expression)) {
				return false;
			}
		}

		for (Iterator<Expression> iterator3= operands1.iterator(); iterator3.hasNext();) {
			Expression expression= iterator3.next();

			for (Iterator<Expression> iterator4= operands2.iterator(); iterator4.hasNext();) {
				Expression otherExpression= iterator4.next();

				if (equal ? safeSubtreeMatch(expression, otherExpression) : matchNegative(expression, otherExpression)) {
					iterator3.remove();
					iterator4.remove();
					break;
				}
			}
		}

		return operands1.isEmpty() && operands2.isEmpty();
	}

	private List<Expression> getConsistentOperands(final InfixExpression infixExpression) {
		List<Expression> operands= ASTNodes.allOperands(infixExpression);

		for (Iterator<Expression> iterator= operands.iterator(); iterator.hasNext() && operands.size() > 1;) {
			Expression operand= iterator.next();

			Long numberLiteral= ASTNodes.getIntegerLiteral(operand);
			Boolean booleanValue= ASTNodes.getBooleanLiteral(operand);

			if (ASTNodes.hasOperator(infixExpression, InfixExpression.Operator.CONDITIONAL_AND)) {
				if (Boolean.TRUE.equals(booleanValue)) {
					iterator.remove();
				}
			} else if (ASTNodes.hasOperator(infixExpression, InfixExpression.Operator.CONDITIONAL_OR)) {
				if (Boolean.FALSE.equals(booleanValue)) {
					iterator.remove();
				}
			} else if (ASTNodes.hasOperator(infixExpression, InfixExpression.Operator.PLUS)) {
				if (Long.valueOf(0).equals(numberLiteral)) {
					iterator.remove();
				}
			} else if (ASTNodes.hasOperator(infixExpression, InfixExpression.Operator.TIMES) && Long.valueOf(1).equals(numberLiteral)) {
				iterator.remove();
			}
		}

		return operands;
	}
}
