// Path: jmespath-core/src/main/java/io/burt/jmespath/RuntimeConfiguration.java
// public class RuntimeConfiguration {
//   private final FunctionRegistry functionRegistry;
//   private final boolean silentTypeErrors;
// 
//   private RuntimeConfiguration(Builder builder) {
//     this.functionRegistry = builder.functionRegistry;
//     this.silentTypeErrors = builder.silentTypeErrors;
//   }
// 
//   public FunctionRegistry functionRegistry() {
//     return functionRegistry;
//   }
// 
//   public boolean silentTypeErrors() {
//     return silentTypeErrors;
//   }
// 
//   public static Builder builder() {
//     return new Builder();
//   }
// 
//   public static RuntimeConfiguration defaultConfiguration() {
//     return builder().build();
//   }
// 
//   public static class Builder {
//     protected FunctionRegistry functionRegistry;
//     protected boolean silentTypeErrors;
// 
//     public Builder() {
//       this.functionRegistry = FunctionRegistry.defaultRegistry();
//     }
// 
//     public RuntimeConfiguration build() {
//       return new RuntimeConfiguration(this);
//     }
// 
//     public Builder withFunctionRegistry(FunctionRegistry functionRegistry) {
//       this.functionRegistry = functionRegistry;
//       return this;
//     }
// 
//     public Builder withSilentTypeErrors(boolean silentTypeErrors) {
//       this.silentTypeErrors = silentTypeErrors;
//       return this;
//     }
//   }
// }
// 
// Path: jmespath-core/src/main/java/io/burt/jmespath/parser/ParseException.java
// @SuppressWarnings("serial")
// public class ParseException extends JmesPathException implements Iterable<ParseError> {
//   private final Iterable<ParseError> errors;
// 
//   public ParseException(String query, Iterable<ParseError> errors) {
//     super(String.format("Unable to compile expression \"%s\": %s", query, joinMessages(errors)));
//     this.errors = errors;
//   }
// 
//   private static String joinMessages(Iterable<ParseError> errors) {
//     StringBuilder s = new StringBuilder();
//     for (ParseError e : errors) {
//       s.append(String.format("%s at position %d, ", e.message(), e.position()));
//     }
//     s.setLength(s.length() - 2);
//     return s.toString();
//   }
// 
//   @Override
//   public Iterator<ParseError> iterator() { return errors.iterator(); }
// }
// 
// Path: jmespath-core/src/main/java/io/burt/jmespath/function/ArgumentTypeException.java
// @SuppressWarnings("serial")
// public class ArgumentTypeException extends FunctionCallException {
//   public ArgumentTypeException(Function function, String expectedType, String actualType) {
//     this(function, expectedType, actualType, null);
//   }
// 
//   public ArgumentTypeException(Function function, String expectedType, String actualType, Throwable cause) {
//     super(String.format("Invalid argument type calling \"%s\": expected %s but was %s", function.name(), expectedType, actualType), cause);
//   }
// }


import org.junit.Before;
import org.junit.Test;
import org.hamcrest.Matcher;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import java.util.Collection;
import java.util.Collections;
import io.burt.jmespath.RuntimeConfiguration;
import io.burt.jmespath.parser.ParseException;
import io.burt.jmespath.function.ArgumentTypeException;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.both;
import static org.hamcrest.Matchers.containsString;

  @Test
  public void anEmptyObjectIsNotTruthy() {
    T result = search("!@", parse("{}"));
    assertThat(result, is(jsonBoolean(true)));
  }

  @Test
  public void callFunction() {
    T result = search("type(@)", parse("{}"));
    assertThat(result, is(jsonString("object")));
  }

  @Test
  public void callFunctionWithExpressionReference() {
    T result = search("map(&userIdentity.userName, Records)", cloudtrail);
    assertThat(result, is(jsonArrayOfStrings("Alice", "Bob", "Alice")));
  }

  @Test
  public void callVariadicFunction() {
    T result = search("not_null(Records[0].requestParameters.keyName, Records[1].requestParameters.keyName, Records[2].requestParameters.keyName)", cloudtrail);
    assertThat(result, is(jsonString("mykeypair")));
  }

  @Test
  public void callingNonExistentFunctionThrowsParseException() {
    try {
      search("bork()", parse("{}"));
      fail("Expected ParseException to have been thrown");
// Path: jmespath-core/src/main/java/io/burt/jmespath/RuntimeConfiguration.java
// public class RuntimeConfiguration {
//   private final FunctionRegistry functionRegistry;
//   private final boolean silentTypeErrors;
// 
//   private RuntimeConfiguration(Builder builder) {
//     this.functionRegistry = builder.functionRegistry;
//     this.silentTypeErrors = builder.silentTypeErrors;
//   }
// 
//   public FunctionRegistry functionRegistry() {
//     return functionRegistry;
//   }
// 
//   public boolean silentTypeErrors() {
//     return silentTypeErrors;
//   }
// 
//   public static Builder builder() {
//     return new Builder();
//   }
// 
//   public static RuntimeConfiguration defaultConfiguration() {
//     return builder().build();
//   }
// 
//   public static class Builder {
//     protected FunctionRegistry functionRegistry;
//     protected boolean silentTypeErrors;
// 
//     public Builder() {
//       this.functionRegistry = FunctionRegistry.defaultRegistry();
//     }
// 
//     public RuntimeConfiguration build() {
//       return new RuntimeConfiguration(this);
//     }
// 
//     public Builder withFunctionRegistry(FunctionRegistry functionRegistry) {
//       this.functionRegistry = functionRegistry;
//       return this;
//     }
// 
//     public Builder withSilentTypeErrors(boolean silentTypeErrors) {
//       this.silentTypeErrors = silentTypeErrors;
//       return this;
//     }
//   }
// }
// 
// Path: jmespath-core/src/main/java/io/burt/jmespath/parser/ParseException.java
// @SuppressWarnings("serial")
// public class ParseException extends JmesPathException implements Iterable<ParseError> {
//   private final Iterable<ParseError> errors;
// 
//   public ParseException(String query, Iterable<ParseError> errors) {
//     super(String.format("Unable to compile expression \"%s\": %s", query, joinMessages(errors)));
//     this.errors = errors;
//   }
// 
//   private static String joinMessages(Iterable<ParseError> errors) {
//     StringBuilder s = new StringBuilder();
//     for (ParseError e : errors) {
//       s.append(String.format("%s at position %d, ", e.message(), e.position()));
//     }
//     s.setLength(s.length() - 2);
//     return s.toString();
//   }
// 
//   @Override
//   public Iterator<ParseError> iterator() { return errors.iterator(); }
// }
// 
// Path: jmespath-core/src/main/java/io/burt/jmespath/function/ArgumentTypeException.java
// @SuppressWarnings("serial")
// public class ArgumentTypeException extends FunctionCallException {
//   public ArgumentTypeException(Function function, String expectedType, String actualType) {
//     this(function, expectedType, actualType, null);
//   }
// 
//   public ArgumentTypeException(Function function, String expectedType, String actualType, Throwable cause) {
//     super(String.format("Invalid argument type calling \"%s\": expected %s but was %s", function.name(), expectedType, actualType), cause);
//   }
// }


// Path: jmespath-core/src/test/java/io/burt/jmespath/JmesPathRuntimeTest.java
import org.junit.Before;
import org.junit.Test;
import org.hamcrest.Matcher;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import java.util.Collection;
import java.util.Collections;
import io.burt.jmespath.RuntimeConfiguration;
import io.burt.jmespath.parser.ParseException;
import io.burt.jmespath.function.ArgumentTypeException;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.both;
import static org.hamcrest.Matchers.containsString;


  @Test
  public void anEmptyObjectIsNotTruthy() {
    T result = search("!@", parse("{}"));
    assertThat(result, is(jsonBoolean(true)));
  }

  @Test
  public void callFunction() {
    T result = search("type(@)", parse("{}"));
    assertThat(result, is(jsonString("object")));
  }

  @Test
  public void callFunctionWithExpressionReference() {
    T result = search("map(&userIdentity.userName, Records)", cloudtrail);
    assertThat(result, is(jsonArrayOfStrings("Alice", "Bob", "Alice")));
  }

  @Test
  public void callVariadicFunction() {
    T result = search("not_null(Records[0].requestParameters.keyName, Records[1].requestParameters.keyName, Records[2].requestParameters.keyName)", cloudtrail);
    assertThat(result, is(jsonString("mykeypair")));
  }

  @Test
  public void callingNonExistentFunctionThrowsParseException() {
    try {
      search("bork()", parse("{}"));
      fail("Expected ParseException to have been thrown");
    } catch (ParseException pe) {