// Path: core/src/main/java/au/com/sensis/stubby/utils/EqualsUtils.java
// public class EqualsUtils {
//     
//     public static boolean safeEquals(Object a, Object b) {
//         return (a == null && b == null) || (a != null && a.equals(b));
//     }
//     
// }
// 
// Path: core/src/main/java/au/com/sensis/stubby/utils/JsonUtils.java
// public class JsonUtils {
//     
//     public static ObjectMapper mapper() {
//         return new ObjectMapper();
//     }
//     
//     public static ObjectMapper defaultMapper() {
//         ObjectMapper result = mapper();
//         result.enable(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES);
//         result.enable(DeserializationConfig.Feature.USE_BIG_DECIMAL_FOR_FLOATS); // for 'exact' floating-point matches
//         result.setSerializationInclusion(Inclusion.NON_NULL);
//         return result;
//     }
//     
//     public static ObjectWriter prettyWriter() {
//         return defaultMapper().writerWithDefaultPrettyPrinter();
//     }
//     
//     public static String prettyPrint(Object value) {
//         try {
//             return prettyWriter().writeValueAsString(value); 
//         } catch (IOException e) {
//             throw new RuntimeException("Error serializing JSON", e);
//         }
//     }
// 
//     public static String serialize(Object object) {
//         try {
//             return defaultMapper().writeValueAsString(object);
//         } catch (IOException e) {
//             throw new RuntimeException("Error serializing JSON", e);
//         }
//     }
//     
//     public static void serialize(OutputStream stream, Object object) {
//         try {
//             defaultMapper().writeValue(stream, object);
//         } catch (IOException e) {
//             throw new RuntimeException("Error serializing JSON", e);
//         }
//     }
// 
//     public static <T> T deserialize(String json, Class<T> type) {
//         try {
//             return defaultMapper().readValue(json, type);
//         } catch (IOException e) {
//             throw new RuntimeException("Error deserializing JSON", e);
//         }
//     }
//     
//     public static <T> T deserialize(InputStream stream, Class<T> type) {
//         try {
//             return defaultMapper().readValue(stream, type);
//         } catch (IOException e) {
//             throw new RuntimeException("Error deserializing JSON", e);
//         }
//     }
//     
// }


import java.util.regex.Pattern;
import org.apache.commons.lang.builder.EqualsBuilder;
import au.com.sensis.stubby.utils.EqualsUtils;
import au.com.sensis.stubby.utils.JsonUtils;
            }
        case MATCH:
            switch (fieldType) {
            case PATH:
                return 5; // path is most important in the match
            default:
                return 2;
            }
        default:
            throw new RuntimeException(); // impossible
        }
    }

    @Override
    public String toString() {
        return JsonUtils.serialize(this);
    }

    @Override
    public boolean equals(Object object) { // only used in tests
        if (object instanceof MatchField) {
            MatchField other = (MatchField) object;
            if (!fieldName.equals(other.fieldName)
                    || !fieldType.equals(other.fieldType)
                    || !matchType.equals(other.matchType)) {
                return false;
            }
            if (!EqualsUtils.safeEquals(message, other.message)) {
                return false;
            }
// Path: core/src/main/java/au/com/sensis/stubby/utils/EqualsUtils.java
// public class EqualsUtils {
//     
//     public static boolean safeEquals(Object a, Object b) {
//         return (a == null && b == null) || (a != null && a.equals(b));
//     }
//     
// }
// 
// Path: core/src/main/java/au/com/sensis/stubby/utils/JsonUtils.java
// public class JsonUtils {
//     
//     public static ObjectMapper mapper() {
//         return new ObjectMapper();
//     }
//     
//     public static ObjectMapper defaultMapper() {
//         ObjectMapper result = mapper();
//         result.enable(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES);
//         result.enable(DeserializationConfig.Feature.USE_BIG_DECIMAL_FOR_FLOATS); // for 'exact' floating-point matches
//         result.setSerializationInclusion(Inclusion.NON_NULL);
//         return result;
//     }
//     
//     public static ObjectWriter prettyWriter() {
//         return defaultMapper().writerWithDefaultPrettyPrinter();
//     }
//     
//     public static String prettyPrint(Object value) {
//         try {
//             return prettyWriter().writeValueAsString(value); 
//         } catch (IOException e) {
//             throw new RuntimeException("Error serializing JSON", e);
//         }
//     }
// 
//     public static String serialize(Object object) {
//         try {
//             return defaultMapper().writeValueAsString(object);
//         } catch (IOException e) {
//             throw new RuntimeException("Error serializing JSON", e);
//         }
//     }
//     
//     public static void serialize(OutputStream stream, Object object) {
//         try {
//             defaultMapper().writeValue(stream, object);
//         } catch (IOException e) {
//             throw new RuntimeException("Error serializing JSON", e);
//         }
//     }
// 
//     public static <T> T deserialize(String json, Class<T> type) {
//         try {
//             return defaultMapper().readValue(json, type);
//         } catch (IOException e) {
//             throw new RuntimeException("Error deserializing JSON", e);
//         }
//     }
//     
//     public static <T> T deserialize(InputStream stream, Class<T> type) {
//         try {
//             return defaultMapper().readValue(stream, type);
//         } catch (IOException e) {
//             throw new RuntimeException("Error deserializing JSON", e);
//         }
//     }
//     
// }


// Path: core/src/main/java/au/com/sensis/stubby/service/model/MatchField.java
import java.util.regex.Pattern;
import org.apache.commons.lang.builder.EqualsBuilder;
import au.com.sensis.stubby.utils.EqualsUtils;
import au.com.sensis.stubby.utils.JsonUtils;

            }
        case MATCH:
            switch (fieldType) {
            case PATH:
                return 5; // path is most important in the match
            default:
                return 2;
            }
        default:
            throw new RuntimeException(); // impossible
        }
    }

    @Override
    public String toString() {
        return JsonUtils.serialize(this);
    }

    @Override
    public boolean equals(Object object) { // only used in tests
        if (object instanceof MatchField) {
            MatchField other = (MatchField) object;
            if (!fieldName.equals(other.fieldName)
                    || !fieldType.equals(other.fieldType)
                    || !matchType.equals(other.matchType)) {
                return false;
            }
            if (!EqualsUtils.safeEquals(message, other.message)) {
                return false;
            }
            if (!EqualsUtils.safeEquals(normalise(expectedValue), normalise(other.expectedValue))) {