diff --git a/plugins/IntelliLang/src/intentionDescriptions/InvertIfIntention/after.groovy.template b/plugins/IntelliLang/src/intentionDescriptions/InvertIfIntention/after.groovy.template
new file mode 100644
index 000000000000..19869450ea5d
--- /dev/null
+++ b/plugins/IntelliLang/src/intentionDescriptions/InvertIfIntention/after.groovy.template
@@ -0,0 +1 @@
+if (a) b = false
\ No newline at end of file
diff --git a/plugins/IntelliLang/src/intentionDescriptions/InvertIfIntention/before.groovy.template b/plugins/IntelliLang/src/intentionDescriptions/InvertIfIntention/before.groovy.template
new file mode 100644
index 000000000000..1ef4948fc7da
--- /dev/null
+++ b/plugins/IntelliLang/src/intentionDescriptions/InvertIfIntention/before.groovy.template
@@ -0,0 +1,2 @@
+if (!a) {
+} else b = false;
\ No newline at end of file
diff --git a/plugins/IntelliLang/src/intentionDescriptions/InvertIfIntention/description.html b/plugins/IntelliLang/src/intentionDescriptions/InvertIfIntention/description.html
new file mode 100644
index 000000000000..3823b58a844c
--- /dev/null
+++ b/plugins/IntelliLang/src/intentionDescriptions/InvertIfIntention/description.html
@@ -0,0 +1,10 @@
+
+
+
+This intention replaces if statement with
+another if statement using inverted condition inside.
+
+The intention might be useful to e.g. simplify complex code using multiple nested if statements.
+
+
+
\ No newline at end of file
diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml
index 62095d0baaa8..501149f02a4e 100644
--- a/plugins/groovy/src/META-INF/plugin.xml
+++ b/plugins/groovy/src/META-INF/plugin.xml
@@ -710,6 +710,11 @@
intention.category.groovy/intention.category.control.flow
org.jetbrains.plugins.groovy.intentions.control.SplitIfIntention
+
+ org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle
+ intention.category.groovy/intention.category.control.flow
+ org.jetbrains.plugins.groovy.intentions.control.InvertIfIntention
+
org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle
intention.category.groovy/intention.category.control.flow
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties
index bb841abb0c3d..17988f9cecce 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties
@@ -41,6 +41,8 @@ split.else.if.intention.name=Split else-if
split.else.if.intention.family.name=Split Else If
split.if.intention.name=Split into 2 if's
split.if.intention.family.name=Split into 2 if's
+invert.if.intention.name=Invert If Condition
+invert.if.intention.family.name=Invert If Condition
flip.conditional.intention.name=Flip ?:
flip.conditional.intention.family.name=Flip Conditional
conditional.to.elvis.intention.name=Convert Conditional to Elvis
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/InvertIfIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/InvertIfIntention.java
new file mode 100644
index 000000000000..6b55e4d7938a
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/InvertIfIntention.java
@@ -0,0 +1,100 @@
+package org.jetbrains.plugins.groovy.intentions.control;
+
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.intentions.base.Intention;
+import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrIfStatement;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrParenthesizedExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrUnaryExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression;
+
+/**
+ * @author Niels Harremoes
+ */
+public class InvertIfIntention extends Intention {
+
+ @Override
+ protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException {
+ PsiElement parent = element.getParent();
+
+ if (!"if".equals(element.getText()) || !(parent instanceof GrIfStatement)) {
+ throw new IncorrectOperationException("Not invoked on an if");
+ }
+ GrIfStatement parentIf = (GrIfStatement)parent;
+ GroovyPsiElementFactory groovyPsiElementFactory = GroovyPsiElementFactory.getInstance(project);
+
+ GrStatement thenBranch = parentIf.getThenBranch();
+ GrStatement elseBranch = parentIf.getElseBranch();
+
+ GrExpression condition = parentIf.getCondition();
+ if (condition == null) {
+ throw new IncorrectOperationException("Invoked on an if with empty condition");
+ }
+
+ GrExpression negatedCondition = null;
+ if (condition instanceof GrUnaryExpression) {
+ GrUnaryExpression unaryCondition = (GrUnaryExpression)condition;
+ if ("!".equals(unaryCondition.getOperationToken().getText())) {
+ negatedCondition = stripParenthesis(unaryCondition.getOperand());
+ }
+ }
+
+ if (negatedCondition==null) {
+ // Now check whether this is a simple expression
+ condition = stripParenthesis(condition);
+ String negatedExpressionText;
+ if (condition instanceof GrCallExpression || condition instanceof GrReferenceExpression) {
+ negatedExpressionText = "!" + condition.getText();
+ } else {
+ negatedExpressionText = "!(" + condition.getText() + ")";
+ }
+ negatedCondition = groovyPsiElementFactory.createExpressionFromText(negatedExpressionText, parentIf);
+ }
+
+ GrIfStatement newIf = (GrIfStatement)groovyPsiElementFactory.createStatementFromText(
+ "if (" + negatedCondition.getText() + ") " +
+ (elseBranch != null ? elseBranch.getText() : "{}") + " else " +
+ (thenBranch != null ? thenBranch.getText() : "{}"), parentIf.getContext()
+ );
+
+ parentIf.replace(newIf);
+ }
+
+ private static GrExpression stripParenthesis(GrExpression operand) {
+ while (operand instanceof GrParenthesizedExpression) {
+ operand = ((GrParenthesizedExpression) operand).getOperand();
+ }
+ return operand;
+ }
+
+ @NotNull
+ @Override
+ protected PsiElementPredicate getElementPredicate() {
+ return new PsiElementPredicate() {
+ @Override
+ public boolean satisfiedBy(PsiElement element) {
+
+ if (!"if".equals(element.getText())) {
+ return false;
+ }
+ PsiElement parent = element.getParent();
+ if (!(parent instanceof GrIfStatement)) {
+ return false;
+ }
+
+ if (((GrIfStatement)parent).getCondition() == null) {
+ return false;
+ }
+ return true;
+ }
+ };
+ }
+}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/InvertIfTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/InvertIfTest.groovy
new file mode 100644
index 000000000000..102faf3f5b33
--- /dev/null
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/InvertIfTest.groovy
@@ -0,0 +1,115 @@
+package org.jetbrains.plugins.groovy.intentions
+
+/**
+ * @author Niels Harremoes
+ */
+class InvertIfTest extends GrIntentionTestCase {
+
+ String intentionName = GroovyIntentionsBundle.message("invert.if.intention.name")
+
+ public void testDoNotTriggerOnIncompleteIf() throws Exception {
+ doAntiTest '''
+if () {
+ succes
+} else {
+ no_succes
+}
+''', intentionName
+
+ }
+
+ private void doTest(String before, String after) {
+
+ doTextTest before, intentionName, after
+ }
+
+ public void testSimpleCondition() throws Exception {
+
+ doTest '''
+if (a) {
+ succes
+} else {
+ no_succes
+}
+''', '''if (!a) {
+ no_succes
+} else {
+ succes
+}
+'''
+ }
+
+ public void testCallCondition() throws Exception {
+
+ doTest '''
+if (func()) {
+ succes
+} else {
+ no_succes
+}
+''', '''if (!func()) {
+ no_succes
+} else {
+ succes
+}
+'''
+ }
+
+ public void testComplexCondition() throws Exception {
+ doTest '''
+if (a && b) {
+ succes
+} else {
+ no_succes
+}
+''', '''if (!(a && b)) {
+ no_succes
+} else {
+ succes
+}
+'''
+ }
+
+ public void testNegatedComplexCondition() throws Exception {
+ doTest '''
+if (!(a && b)) {
+ succes
+} else {
+ no_succes
+}
+''', '''if (a && b) {
+ no_succes
+} else {
+ succes
+}
+'''
+ }
+
+ public void testNegatedSimpleCondition() throws Exception {
+ doTest '''
+if (!a) {
+ succes
+} else {
+ no_succes
+}
+''', '''if (a) {
+ no_succes
+} else {
+ succes
+}
+'''
+ }
+
+ public void testNoElseBlock() throws Exception {
+ doTest '''
+if (a) {
+ succes
+}
+''', '''if (!a) {
+} else {
+ succes
+}
+'''
+ }
+
+}