diff --git a/json-path-assert/README.md b/json-path-assert/README.md
new file mode 100644
index 00000000..8847deb4
--- /dev/null
+++ b/json-path-assert/README.md
@@ -0,0 +1,82 @@
+json-path-assert
+================
+
+A library with [hamcrest-matchers](http://hamcrest.org/JavaHamcrest/) for JsonPath.
+
+# Getting started
+
+This library is available at the Central Maven Repository. Maven users add this to your POM.
+
+```xml
+
+ com.jayway.jsonpath
+ json-path-assert
+ 2.1.0
+
+```
+
+# Usage guide
+
+Statically import the library entry point:
+
+ import static com.jayway.jsonpath.matchers.JsonPathMatchers.*;
+
+NOTE: The actual evaluation of JsonPath will depend on the current configuration:
+
+ Configuration.setDefaults(...);
+
+The matchers can be used to inspect different representations of JSON:
+
+ // As a String...
+ String json = ...;
+
+ // or a file...
+ File json = ...;
+
+ // or an already parsed json object...
+ Object json = Configuration.defaultConfiguration().jsonProvider().parse(content);
+
+Usage examples:
+
+ // Verify validity of JSON
+ assertThat(json, isJson());
+
+ // Verify existence (or non-existence) of JSON path
+ assertThat(json, hasJsonPath("$.message"));
+ assertThat(json, hasNoJsonPath("$.message"));
+
+ // Verify evaluation of JSON path
+ assertThat(json, hasJsonPath("$.message", equalTo("Hi there")));
+ assertThat(json, hasJsonPath("$.quantity", equalTo(5)));
+ assertThat(json, hasJsonPath("$.price", equalTo(34.56)));
+ assertThat(json, hasJsonPath("$.store.book[*].author", hasSize(4)));
+ assertThat(json, hasJsonPath("$.store.book[*].author", hasItem("Evelyn Waugh")));
+
+Combine matchers for greater expressiveness
+
+ // This will separate the JSON parsing from the path evaluation
+ assertThat(json, isJson(withoutJsonPath("...")));
+ assertThat(json, isJson(withJsonPath("...", equalTo(3))));
+
+ // Combine several JSON path evaluations into a single statement
+ // (This will parse the JSON only once)
+ assertThat(json, isJson(allOf(
+ withJsonPath("$.store.name", equalTo("Little Shop")),
+ withoutJsonPath("$.expensive"),
+ withJsonPath("$..title", hasSize(4)))));
+
+Match on pre-compiled complex JSON path expressions
+
+ Filter cheapFictionFilter = filter(
+ where("category").is("fiction").and("price").lte(10D));
+ JsonPath cheapFiction = JsonPath.compile("$.store.book[?]", cheapFictionFilter);
+ String json = ...;
+ assertThat(json, isJson(withJsonPath(cheapFiction)));
+
+Use typed matchers for specific JSON representations, if needed
+
+ String json = ...
+ assertThat(json, isJsonString(withJsonPath("$..author")));
+
+ File json = ...
+ assertThat(json, isJsonFile(withJsonPath("$..author")));
diff --git a/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/IsJson.java b/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/IsJson.java
new file mode 100644
index 00000000..c46eb07c
--- /dev/null
+++ b/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/IsJson.java
@@ -0,0 +1,65 @@
+package com.jayway.jsonpath.matchers;
+
+import com.jayway.jsonpath.JsonPath;
+import com.jayway.jsonpath.JsonPathException;
+import com.jayway.jsonpath.ReadContext;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+import java.io.File;
+import java.io.IOException;
+
+public class IsJson extends TypeSafeMatcher {
+ private final Matcher super ReadContext> jsonMatcher;
+
+ public IsJson(Matcher super ReadContext> jsonMatcher) {
+ this.jsonMatcher = jsonMatcher;
+ }
+
+ @Override
+ protected boolean matchesSafely(T json) {
+ try {
+ ReadContext context = parse(json);
+ return jsonMatcher.matches(context);
+ } catch (JsonPathException e) {
+ return false;
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ public void describeTo(Description description) {
+ description.appendText("is json ").appendDescriptionOf(jsonMatcher);
+ }
+
+ @Override
+ protected void describeMismatchSafely(T json, Description mismatchDescription) {
+ try {
+ ReadContext context = parse(json);
+ jsonMatcher.describeMismatch(context, mismatchDescription);
+ } catch (JsonPathException e) {
+ buildMismatchDescription(json, mismatchDescription, e);
+ } catch (IOException e) {
+ buildMismatchDescription(json, mismatchDescription, e);
+ }
+ }
+
+ private static void buildMismatchDescription(Object json, Description mismatchDescription, Exception e) {
+ mismatchDescription
+ .appendText("was ")
+ .appendValue(json)
+ .appendText(" which failed with ")
+ .appendValue(e.getMessage());
+ }
+
+ private static ReadContext parse(Object object) throws IOException {
+ if (object instanceof String) {
+ return JsonPath.parse((String) object);
+ } else if (object instanceof File) {
+ return JsonPath.parse((File) object);
+ } else {
+ return JsonPath.parse(object);
+ }
+ }
+}
diff --git a/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java b/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java
new file mode 100644
index 00000000..c89c42cc
--- /dev/null
+++ b/json-path-assert/src/main/java/com/jayway/jsonpath/matchers/JsonPathMatchers.java
@@ -0,0 +1,73 @@
+package com.jayway.jsonpath.matchers;
+
+import com.jayway.jsonpath.JsonPath;
+import com.jayway.jsonpath.Predicate;
+import com.jayway.jsonpath.ReadContext;
+import org.hamcrest.Matcher;
+
+import java.io.File;
+
+import static org.hamcrest.Matchers.*;
+
+public class JsonPathMatchers {
+
+ private JsonPathMatchers() {
+ throw new AssertionError("prevent instantiation");
+ }
+
+ public static Matcher super Object> hasJsonPath(String jsonPath) {
+ return describedAs("has json path %0",
+ hasJsonPath(jsonPath, not(anyOf(nullValue(), empty()))),
+ jsonPath);
+ }
+
+ public static Matcher super Object> hasJsonPath(final String jsonPath, final Matcher resultMatcher) {
+ return isJson(withJsonPath(jsonPath, resultMatcher));
+ }
+
+ public static Matcher super Object> hasNoJsonPath(String jsonPath) {
+ return isJson(withoutJsonPath(jsonPath));
+ }
+
+ public static Matcher