@NotNull
  private ReturnValue findValueBeforeStatement(LighterASTNode statement, LighterASTNode target) {
    LighterASTNode parent = tree.getParent(statement);
    if (parent == null) {
      return ReturnValue.UNKNOWN;
    }
    if (parent.getTokenType() == CODE_BLOCK) {
      List<LighterASTNode> children = tree.getChildren(parent);
      for (int i = children.lastIndexOf(statement) - 1; i >= 0; i--) {
        LighterASTNode child = children.get(i);
        if (ElementType.JAVA_STATEMENT_BIT_SET.contains(child.getTokenType())) {
          ReturnValue value = findValueInStatement(child, target);
          if (value != null) {
            return value;
          }
        }
      }
      LighterASTNode grandParent = tree.getParent(parent);
      if (grandParent == null || grandParent.getTokenType() != BLOCK_STATEMENT) return ReturnValue.UNKNOWN;
      return findValueBeforeStatement(grandParent, target);
    }
    if (parent.getTokenType() == IF_STATEMENT) {
      LighterASTNode condition = findExpressionChild(tree, parent);
      List<LighterASTNode> branches = getChildrenOfType(tree, parent, ElementType.JAVA_STATEMENT_BIT_SET);
      int index = branches.indexOf(statement);
      if (index == 0 && isNullCheck(condition, target, false) || index == 1 && isNullCheck(condition, target, true)) {
        return ReturnValue.NOT_NULL;
      }
      ReturnValue value = findValueInExpression(condition, target);
      if (value != null) {
        return value;
      }
      return findValueBeforeStatement(parent, target);
    }
    if (parent.getTokenType() == WHILE_STATEMENT) {
      LighterASTNode condition = findExpressionChild(tree, parent);
      if (isNullCheck(condition, target, false)) {
        return ReturnValue.NOT_NULL;
      }
      // Could be reassigned later in loop, do not analyze this now
      return ReturnValue.UNKNOWN;
    }
    if (parent.getTokenType() == SYNCHRONIZED_STATEMENT) {
      ReturnValue value = findValueInExpression(findExpressionChild(tree, parent), target);
      if (value != null) {
        return value;
      }
      return findValueBeforeStatement(parent, target);
    }
    return ReturnValue.UNKNOWN;
  }
@NotNull
  private ReturnValue findValueBeforeStatement(LighterASTNode statement, LighterASTNode target)