@Override
  public void visitCaseSection(GrCaseSection caseSection) {
    for (GrCaseLabel label : caseSection.getCaseLabels()) {
      GrExpression value = label.getValue();
      if (value != null) {
        value.accept(this);
      }
    }

    final GrStatement[] statements = caseSection.getStatements();

    // infer 'may be return' position
    int i;
    for (i = statements.length - 1; i >= 0 && statements[i] instanceof GrBreakStatement; i--) {}

    for (int j = 0; j < statements.length; j++) {
      GrStatement statement = statements[j];
      statement.accept(this);
      if (j == i) handlePossibleReturn(statement);
    }

    if (myHead != null) {
      addPendingEdge(caseSection, myHead);
    }
  }
 private static boolean caseClausesAreEquivalent(GrCaseSection clause1, GrCaseSection clause2) {
   final GrCaseLabel label1 = clause1.getCaseLabel();
   final GrCaseLabel label2 = clause2.getCaseLabel();
   if (!expressionsAreEquivalent(label1.getValue(), label2.getValue())) {
     return false;
   }
   final GrStatement[] statements1 = clause1.getStatements();
   final GrStatement[] statements2 = clause2.getStatements();
   if (statements1.length != statements2.length) {
     return false;
   }
   for (int i = 0; i < statements1.length; i++) {
     if (!statementsAreEquivalent(statements1[i], statements2[i])) {
       return false;
     }
   }
   return false;
 }
 @Nullable
 private static GrExpression getExpressionForCaseLabel(GrCaseLabel label) {
   for (PsiElement child : label.getChildren()) {
     if (child instanceof GrExpression) {
       return (GrExpression) child;
     }
   }
   return null;
 }
    @Override
    public void visitCaseLabel(GrCaseLabel caseLabel) {
      final PsiElement parent = caseLabel.getParent().getParent();
      assert parent instanceof GrSwitchStatement : parent + " of class " + parent.getClass();
      final GrExpression condition = ((GrSwitchStatement) parent).getCondition();
      if (condition == null) return;

      final PsiType type = condition.getType();
      if (type == null) return;

      myResult = new TypeConstraint[] {SubtypeConstraint.create(type)};
    }