class FirstMatchChain extends BooleanExpr {

  @Override
  public Result evaluate(Environment environment) {
    /* TODO
    It is unclear what result's value for _return means here, and it doesn't currently have any
    impact in any context where FirstMatchChain is used. For now, just set it to false.
     */
    for (BooleanExpr subroutine : _subroutines) {
      Result subroutineResult = subroutine.evaluate(environment);
      if (subroutineResult.getExit()) {
        // Reached an exit/terminal action. Return regardless of boolean value
        return subroutineResult;
      } else if (!subroutineResult.getFallThrough()) {
        // Found first match, short-circuit here
        return subroutineResult.toBuilder().setReturn(false).build();
      }
    }
    String defaultPolicy = environment.getDefaultPolicy();
    if (defaultPolicy != null) {
      CallExpr callDefaultPolicy = new CallExpr(environment.getDefaultPolicy());
      Result defaultPolicyResult = callDefaultPolicy.evaluate(environment);
      return defaultPolicyResult.toBuilder().setReturn(false).build();
    } else {
      throw new BatfishException("Default policy is not set");
    }
  }

  public  FirstMatchChain(List<BooleanExpr> subroutines);

}