package com.siyeh.ig.controlflow;

import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.StatementInspection;
import com.siyeh.ig.StatementInspectionVisitor;
import org.jetbrains.annotations.NotNull;

public class BreakStatementInspection extends StatementInspection {

    public String getDisplayName() {
        return "'break' statement";
    }

    public String getGroupDisplayName() {
        return GroupNames.CONTROL_FLOW_GROUP_NAME;
    }

    public String buildErrorString(PsiElement location) {
        return "#ref statement #loc";
    }

    public BaseInspectionVisitor buildVisitor() {
        return new BreakStatementVisitor();
    }

    private static class BreakStatementVisitor extends StatementInspectionVisitor {

        public void visitBreakStatement(@NotNull PsiBreakStatement statement) {
            super.visitBreakStatement(statement);

            final PsiSwitchStatement switchStatement =
                    PsiTreeUtil.getParentOfType(statement, PsiSwitchStatement.class);
            if (switchStatement != null &&
                    isBreakAtTopLevel(switchStatement, statement)) {
                return;
            }
            registerStatementError(statement);
        }

        private static boolean isBreakAtTopLevel(PsiSwitchStatement switchStatement, PsiBreakStatement statement) {
            final PsiCodeBlock body = switchStatement.getBody();
            if (body == null) {
                return false;
            }
            final PsiStatement[] statements = body.getStatements();
            for(final PsiStatement child : statements){
                if(child.equals(statement)){
                    return true;
                }
            }
            return false;
        }

    }

}

@@ -650,12 +650,14 @@
 rn %22
+'
 #ref
+'
  sta
@@ -1181,64 +1181,33 @@
 l &&
-%0A                    isBreakAtTopLevel(switchStatement, 
+ isTopLevelBreakInSwitch(
 stat
@@ -1349,23 +1349,16 @@
 n is
-BreakAt
 TopLevel
 (Psi
@@ -1357,45 +1357,22 @@
 evel
-(PsiSwitchStatement switchStatement, 
+BreakInSwitch(
 PsiB
@@ -1423,32 +1423,26 @@
  Psi
-CodeBlock body = switchS
+Element parent = s
 tate
@@ -1453,12 +1453,14 @@
 .get
-Body
+Parent
 ();%0A
@@ -1479,20 +1479,41 @@
 if (
-body == null
+!(parent instanceof PsiCodeBlock)
 ) %7B%0A
@@ -1581,51 +1581,48 @@
  Psi
-Stat
+El
 ement
-%5B%5D statem
+ parentsPar
 ent
-s
  = 
-body.getStatem
+parent.getPar
 ent
-s
 ();%0A
@@ -1637,48 +1637,162 @@
     
-for(final PsiStatement child : s
+if (parentsParent instanceof PsiSwitchStatement) %7B%0A                return true;%0A            %7D%0A            if (!(parentsParent instanceof PsiBlockS
 tatement
 s)%7B%0A
@@ -1787,18 +1787,19 @@
 tatement
-s
 )
+) 
 %7B%0A      
@@ -1812,41 +1812,166 @@
     
-if(child.equals(statement))%7B%0A    
+return false;%0A            %7D%0A            final PsiElement blocksParent = parentsParent.getParent();%0A            if (!(blocksParent instanceof PsiCodeBlock)) %7B%0A
     
@@ -1985,34 +1985,31 @@
      return 
-true;%0A    
+false;%0A
             
@@ -2026,34 +2026,141 @@
     
-%7D%0A            return false
+final PsiElement blocksParentsParent = blocksParent.getParent();%0A            return blocksParentsParent instanceof PsiSwitchStatement
 ;%0A  
@@ -2167,18 +2167,16 @@
       %7D%0A
-%0A
     %7D%0A
-%0A
 %7D%0A

Fix for IDEA-3678