/*
 * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
 *
 * 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 com.siyeh.ig.controlflow;

import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.ControlFlowUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;

public class ConfusingElseInspection extends BaseInspection {

    @SuppressWarnings({"PublicField"})
    public boolean reportWhenNoStatementFollow = false;

    @Override
    @NotNull
    public String getID() {
        return "ConfusingElseBranch";
    }

    @Override
    @NotNull
    public String getDisplayName() {
        return InspectionGadgetsBundle.message("confusing.else.display.name");
    }

    @Override
    @NotNull
    protected String buildErrorString(Object... infos) {
        return InspectionGadgetsBundle.message(
                "confusing.else.problem.descriptor");
    }

    @Override
    public JComponent createOptionsPanel() {
        return new SingleCheckboxOptionsPanel(
                InspectionGadgetsBundle.message("confusing.else.option"),
                this, "reportWhenNoStatementFollow");
    }

    @Override
    public BaseInspectionVisitor buildVisitor() {
        return new ConfusingElseVisitor();
    }

    @Override
    @Nullable
    protected InspectionGadgetsFix buildFix(Object... infos) {
        return new ConfusingElseFix();
    }

    private static class ConfusingElseFix extends InspectionGadgetsFix {

        @NotNull
        public String getName() {
            return InspectionGadgetsBundle.message(
                    "confusing.else.unwrap.quickfix");
        }

        @Override
        public void doFix(Project project, ProblemDescriptor descriptor)
                throws IncorrectOperationException {
            final PsiElement ifKeyword = descriptor.getPsiElement();
            final PsiIfStatement ifStatement =
                    (PsiIfStatement)ifKeyword.getParent();
            assert ifStatement != null;
            final PsiExpression condition = ifStatement.getCondition();
            final String conditionText;
            if (condition == null) {
                conditionText = "";
            } else {
                conditionText = condition.getText();
            }
            final PsiStatement thenBranch = ifStatement.getThenBranch();
            if (thenBranch == null) {
                return;
            }
            @NonNls final String text = "if(" + conditionText + ')' +
                    thenBranch.getText();
            final PsiStatement elseBranch = ifStatement.getElseBranch();
            if (elseBranch == null) {
                return;
            }
            if (elseBranch instanceof PsiBlockStatement) {
                final PsiBlockStatement elseBlock =
                        (PsiBlockStatement)elseBranch;
                final PsiCodeBlock block = elseBlock.getCodeBlock();
                final PsiElement[] children = block.getChildren();
                if (children.length > 2) {
                    final PsiElement containingElement =
                            ifStatement.getParent();
                    assert containingElement != null;
                    containingElement.addRangeAfter(children[1],
                            children[children.length - 2], ifStatement);
                }
            } else {
                final PsiElement containingElement = ifStatement.getParent();
                assert containingElement != null;
                containingElement.addAfter(elseBranch, ifStatement);
            }
            replaceStatement(ifStatement, text);
        }
    }

    private class ConfusingElseVisitor
            extends BaseInspectionVisitor {

        @Override public void visitIfStatement(
                @NotNull PsiIfStatement statement) {
            super.visitIfStatement(statement);
            final PsiStatement thenBranch = statement.getThenBranch();
            if (thenBranch == null) {
                return;
            }
            final PsiStatement elseBranch = statement.getElseBranch();
            if (elseBranch == null) {
                return;
            }
            if (elseBranch instanceof PsiIfStatement) {
                return;
            }
            if (ControlFlowUtils.statementMayCompleteNormally(thenBranch)) {
                return;
            }
            if (reportWhenNoStatementFollow) {
                final PsiStatement nextStatement = getNextStatement(statement);
                if (nextStatement == null) {
                    return;
                }
                if (!ControlFlowUtils.statementMayCompleteNormally(
                        elseBranch)) {
                    return;
                    // protecting against an edge case where both branches return
                    // and are followed by a case label
                }
            }
            final PsiElement elseToken = statement.getElseElement();
            if (elseToken == null) {
                return;
            }
            registerError(elseToken);
        }

        private PsiStatement getNextStatement(PsiIfStatement statement) {
            while (true) {
                final PsiElement parent = statement.getParent();
                if (parent instanceof PsiIfStatement) {
                    final PsiIfStatement parentIfStatement =
                            (PsiIfStatement) parent;
                    final PsiStatement elseBranch =
                            parentIfStatement.getElseBranch();
                    if (elseBranch == statement) {
                        statement = parentIfStatement;
                        continue;
                    }
                }
                return PsiTreeUtil.getNextSiblingOfType(statement,
                        PsiStatement.class);
            }
        }
    }
}
@@ -5384,16 +5384,17 @@
     if (
+!
 reportWh

fix test