private CauseItem findRelationCause(MemoryStateChange change, DfaVariableValue value,
                                      Relation relation, MemoryStateChange counterPartChange) {
    Instruction instruction = change.myInstruction;
    String condition = value + " " + relation;
    if (instruction instanceof AssignInstruction) {
      DfaValue target = change.myTopOfStack;
      PsiExpression rValue = ((AssignInstruction)instruction).getRExpression();
      CauseItem item = createAssignmentCause((AssignInstruction)instruction, target);
      if (target == value) {
        MemoryStateChange rValuePush = change.findSubExpressionPush(rValue);
        if (rValuePush != null) {
          item.addChildren(findRelationCause(relation.myRelationType, rValuePush, counterPartChange));
        }
        return item;
      }
      if (target == relation.myCounterpart) {
        return item;
      }
    }
    PsiExpression expression = change.getExpression();
    if (expression != null) {
      Collection<DfaRelation> relations = Collections.emptyList();
      if (expression instanceof PsiBinaryExpression) {
        DfaRelation rel = getBinaryExpressionRelation(change, (PsiBinaryExpression)expression);
        if (rel != null) {
          if (isSameRelation(rel, value, relation)) {
            return new CauseItem(new CustomDfaProblemType(
              JavaAnalysisBundle.message("dfa.find.cause.condition.was.checked.before", condition)), expression);
          }
          relations = Collections.singleton(rel);
        }
      }
      if (expression instanceof PsiCallExpression) {
        relations = getCallRelations((PsiCallExpression)expression);
      }
      List<DfaRelation> chain = findDeductionChain(change, relations, value, relation);
      if (!chain.isEmpty()) {
        CauseItem[] result = new CauseItem[0];
        for (DfaRelation deduced : chain) {
          CauseItem[] cause =
            findRelationCause(deduced.relationType(), change, deduced.leftOperand(), change, deduced.rightOperand());
          result = ArrayUtil.mergeArrays(result, cause);
        }
        if (result.length > 1) {
          CauseItem item = new CauseItem(new CustomDfaProblemType(
            JavaAnalysisBundle.message("dfa.find.cause.condition.was.deduced", condition)), (PsiElement)null);
          item.addChildren(result);
          return item;
        }
      }
      return new CauseItem(new CustomDfaProblemType(JavaAnalysisBundle.message("dfa.find.cause.condition.is.known.from.place", condition)),
                           expression);
    }
    return null;
  }
private CauseItem findRelationCause(MemoryStateChange change, DfaVariableValue value,
                                      Relation relation, MemoryStateChange counterPartChange)