public static @Nullable("When result is too big or contracts are erroneous") List<StandardMethodContract>
  toNonIntersectingStandardContracts(List<StandardMethodContract> contracts) {
    if (contracts.isEmpty()) return contracts;
    int paramCount = contracts.get(0).getParameterCount();
    List<StandardMethodContract> result = new ArrayList<>();
    List<StandardMethodContract> leftovers = Collections.singletonList(trivialContract(paramCount, ContractReturnValue.returnAny()));
    for (StandardMethodContract contract : contracts) {
      if (contract.getParameterCount() != paramCount) return null;
      StreamEx.of(leftovers).map(c -> c.intersect(contract)).nonNull().into(result);
      if (result.size() >= StandardDataFlowInterpreter.DEFAULT_MAX_STATES_PER_BRANCH) return null;
      leftovers = StreamEx.of(leftovers).flatMap(c -> c.excludeContract(contract)).toList();
      if (leftovers.isEmpty()) break;
    }
    return result;
  }
public static @Nullable("When result is too big or contracts are erroneous") List<StandardMethodContract>
  toNonIntersectingStandardContracts(List<StandardMethodContract> contracts)