diff --git a/IPython/external/jsonschema/VERSION b/IPython/external/jsonschema/VERSION
new file mode 100644
index 0000000..8b610fd
--- /dev/null
+++ b/IPython/external/jsonschema/VERSION
@@ -0,0 +1,3 @@
+_jsonschema from commit : 
+3ddd80543bd6da56eeea84b2f364febaeadf31b9
+
diff --git a/IPython/external/jsonschema/_jsonschema.py b/IPython/external/jsonschema/_jsonschema.py
index c7d662b..bb5a97c 100755
--- a/IPython/external/jsonschema/_jsonschema.py
+++ b/IPython/external/jsonschema/_jsonschema.py
@@ -1,12 +1,11 @@
 """
 An implementation of JSON Schema for Python
 
-The main functionality is provided by the :class:`Validator` class, with the
-:function:`validate` function being the most common way to quickly create a
-:class:`Validator` object and validate an instance with a given schema.
+The main functionality is provided by the validator classes for each of the
+supported JSON Schema versions.
 
-The :class:`Validator` class generally attempts to be as strict as possible
-under the JSON Schema specification. See its docstring for details.
+Most commonly, the :function:`validate` function is the quickest way to simply
+validate a given instance under a schema, and will create a validator for you.
 
 """
 
@@ -20,131 +19,33 @@ import sys
 import warnings
 
 
+__version__ = "0.7"
+
+FLOAT_TOLERANCE = 10 ** -15
 PY3 = sys.version_info[0] >= 3
 
 if PY3:
     basestring = unicode = str
     iteritems = operator.methodcaller("items")
+    from urllib.parse import unquote
 else:
     from itertools import izip as zip
     iteritems = operator.methodcaller("iteritems")
+    from urllib import unquote
 
 
-def _uniq(container):
+class UnknownType(Exception):
     """
-    Check if all of a container's elements are unique.
-
-    Successively tries first to rely that the elements are hashable, then
-    falls back on them being sortable, and finally falls back on brute
-    force.
+    An unknown type was given.
 
     """
 
-    try:
-        return len(set(container)) == len(container)
-    except TypeError:
-        try:
-            sort = sorted(container)
-            sliced = itertools.islice(container, 1, None)
-            for i, j in zip(container, sliced):
-                if i == j:
-                    return False
-        except (NotImplementedError, TypeError):
-            seen = []
-            for e in container:
-                if e in seen:
-                    return False
-                seen.append(e)
-    return True
-
-
-__version__ = "0.5"
-
-
-DRAFT_3 = {
-    "$schema" : "http://json-schema.org/draft-03/schema#",
-    "id" : "http://json-schema.org/draft-03/schema#",
-    "type" : "object",
 
-    "properties" : {
-        "type" : {
-            "type" : ["string", "array"],
-            "items" : {"type" : ["string", {"$ref" : "#"}]},
-            "uniqueItems" : True,
-            "default" : "any"
-        },
-        "properties" : {
-            "type" : "object",
-            "additionalProperties" : {"$ref" : "#", "type": "object"},
-            "default" : {}
-        },
-        "patternProperties" : {
-            "type" : "object",
-            "additionalProperties" : {"$ref" : "#"},
-            "default" : {}
-        },
-        "additionalProperties" : {
-            "type" : [{"$ref" : "#"}, "boolean"], "default" : {}
-        },
-        "items" : {
-            "type" : [{"$ref" : "#"}, "array"],
-            "items" : {"$ref" : "#"},
-            "default" : {}
-        },
-        "additionalItems" : {
-            "type" : [{"$ref" : "#"}, "boolean"], "default" : {}
-        },
-        "required" : {"type" : "boolean", "default" : False},
-        "dependencies" : {
-            "type" : ["string", "array", "object"],
-            "additionalProperties" : {
-                "type" : ["string", "array", {"$ref" : "#"}],
-                "items" : {"type" : "string"}
-            },
-            "default" : {}
-        },
-        "minimum" : {"type" : "number"},
-        "maximum" : {"type" : "number"},
-        "exclusiveMinimum" : {"type" : "boolean", "default" : False},
-        "exclusiveMaximum" : {"type" : "boolean", "default" : False},
-        "minItems" : {"type" : "integer", "minimum" : 0, "default" : 0},
-        "maxItems" : {"type" : "integer", "minimum" : 0},
-        "uniqueItems" : {"type" : "boolean", "default" : False},
-        "pattern" : {"type" : "string", "format" : "regex"},
-        "minLength" : {"type" : "integer", "minimum" : 0, "default" : 0},
-        "maxLength" : {"type" : "integer"},
-        "enum" : {"type" : "array", "minItems" : 1, "uniqueItems" : True},
-        "default" : {"type" : "any"},
-        "title" : {"type" : "string"},
-        "description" : {"type" : "string"},
-        "format" : {"type" : "string"},
-        "maxDecimal" : {"type" : "number", "minimum" : 0},
-        "divisibleBy" : {
-            "type" : "number",
-            "minimum" : 0,
-            "exclusiveMinimum" : True,
-            "default" : 1
-        },
-        "disallow" : {
-            "type" : ["string", "array"],
-            "items" : {"type" : ["string", {"$ref" : "#"}]},
-            "uniqueItems" : True
-        },
-        "extends" : {
-            "type" : [{"$ref" : "#"}, "array"],
-            "items" : {"$ref" : "#"},
-            "default" : {}
-        },
-        "id" : {"type" : "string", "format" : "uri"},
-        "$ref" : {"type" : "string", "format" : "uri"},
-        "$schema" : {"type" : "string", "format" : "uri"},
-    },
-    "dependencies" : {
-        "exclusiveMinimum" : "minimum", "exclusiveMaximum" : "maximum"
-    },
-}
+class InvalidRef(Exception):
+    """
+    An invalid reference was given.
 
-EPSILON = 10 ** -15
+    """
 
 
 class SchemaError(Exception):
@@ -188,9 +89,9 @@ class ValidationError(Exception):
         self.path = []
 
 
-class Validator(object):
+class Draft3Validator(object):
     """
-    A JSON Schema validator.
+    A validator for JSON Schema draft 3.
 
     """
 
@@ -199,23 +100,12 @@ class Validator(object):
         "number" : (int, float), "object" : dict, "string" : basestring,
     }
 
-    def __init__(
-        self, version=DRAFT_3, unknown_type="skip",
-        unknown_property="skip", types=(),
-    ):
+    def __init__(self, schema, types=()):
         """
-        Initialize a Validator.
-
-        ``version`` specifies which version of the JSON Schema specification to
-        validate with. Currently only draft-03 is supported (and is the
-        default).
+        Initialize a validator.
 
-        ``unknown_type`` and ``unknown_property`` control what to do when an
-        unknown type (resp. property) is encountered. By default, the
-        metaschema is respected (which e.g. for draft 3 allows a schema to have
-        additional properties), but if for some reason you want to modify this
-        behavior, you can do so without needing to modify the metaschema by
-        passing ``"error"`` or ``"warn"`` to these arguments.
+        ``schema`` should be a *valid* JSON Schema object already converted to
+        a native Python object (typically a dict via ``json.load``).
 
         ``types`` is a mapping (or iterable of 2-tuples) containing additional
         types or alternate types to verify via the 'type' property. For
@@ -223,100 +113,76 @@ class Validator(object):
         ``int`` and ``float``.  To override this behavior (e.g. for also
         allowing ``decimal.Decimal``), pass ``types={"number" : (int, float,
         decimal.Decimal)} *including* the default types if so desired, which
-        are fairly obvious but can be accessed via ``Validator.DEFAULT_TYPES``
-        if necessary.
+        are fairly obvious but can be accessed via the ``DEFAULT_TYPES``
+        attribute on this class if necessary.
 
         """
 
-        self._unknown_type = unknown_type
-        self._unknown_property = unknown_property
-        self._version = version
-
         self._types = dict(self.DEFAULT_TYPES)
         self._types.update(types)
         self._types["any"] = tuple(self._types.values())
 
+        self.schema = schema
+
     def is_type(self, instance, type):
         """
-        Check if an ``instance`` is of the provided ``type``.
+        Check if an ``instance`` is of the provided (JSON Schema) ``type``.
 
         """
 
-        py_type = self._types.get(type)
-
-        if py_type is None:
-            return self.schema_error(
-                self._unknown_type, "%r is not a known type" % (type,)
-            )
+        if type not in self._types:
+            raise UnknownType(type)
+        type = self._types[type]
 
-        # the only thing we're careful about here is evading bool inheriting
-        # from int, so let's be even dirtier than usual
+        # bool inherits from int, so ensure bools aren't reported as integers
+        if isinstance(instance, bool):
+            type = _flatten(type)
+            if int in type and bool not in type:
+                return False
+        return isinstance(instance, type)
 
-        elif (
-            # it's not a bool, so no worries
-            not isinstance(instance, bool) or
+    def is_valid(self, instance, _schema=None):
+        """
+        Check if the ``instance`` is valid under the current schema.
 
-            # it is a bool, but we're checking for a bool, so no worries
-            (
-                py_type is bool or
-                isinstance(py_type, tuple) and bool in py_type
-            )
+        Returns a bool indicating whether validation succeeded.
 
-        ):
-            return isinstance(instance, py_type)
+        """
 
-    def schema_error(self, level, msg):
-        if level == "skip":
-            return
-        elif level == "warn":
-            warnings.warn(msg)
-        else:
-            raise SchemaError(msg)
+        error = next(self.iter_errors(instance, _schema), None)
+        return error is None
 
-    def is_valid(self, instance, schema, meta_validate=True):
+    @classmethod
+    def check_schema(cls, schema):
         """
-        Check if the ``instance`` is valid under the ``schema``.
-
-        Returns a bool indicating whether validation succeeded.
+        Validate a ``schema`` against the meta-schema to see if it is valid.
 
         """
 
-        error = next(self.iter_errors(instance, schema, meta_validate), None)
-        return error is None
+        for error in cls(cls.META_SCHEMA).iter_errors(schema):
+            s = SchemaError(error.message)
+            s.path = error.path
+            s.validator = error.validator
+            # I think we're safer raising these always, not yielding them
+            raise s
 
-    def iter_errors(self, instance, schema, meta_validate=True):
+    def iter_errors(self, instance, _schema=None):
         """
         Lazily yield each of the errors in the given ``instance``.
 
-        If you are unsure whether your schema itself is valid,
-        ``meta_validate`` will first validate that the schema is valid before
-        attempting to validate the instance. ``meta_validate`` is ``True`` by
-        default, since setting it to ``False`` can lead to confusing error
-        messages with an invalid schema. If you're sure your schema is in fact
-        valid, or don't care, feel free to set this to ``False``. The meta
-        validation will be done using the appropriate ``version``.
-
         """
 
-        if meta_validate:
-            for error in self.iter_errors(
-                schema, self._version, meta_validate=False
-            ):
-                s = SchemaError(error.message)
-                s.path = error.path
-                s.validator = error.validator
-                # I think we're safer raising these always, not yielding them
-                raise s
-
-        for k, v in iteritems(schema):
+        if _schema is None:
+            _schema = self.schema
+
+        for k, v in iteritems(_schema):
             validator = getattr(self, "validate_%s" % (k.lstrip("$"),), None)
 
             if validator is None:
-                errors = self.unknown_property(k, instance, schema)
-            else:
-                errors = validator(v, instance, schema)
+                continue
 
-            for error in errors or ():
+            errors = validator(v, instance, _schema) or ()
+            for error in errors:
                 # if the validator hasn't already been set (due to recursion)
                 # make sure to set it
                 error.validator = error.validator or k
@@ -331,12 +197,6 @@ class Validator(object):
         for error in self.iter_errors(*args, **kwargs):
             raise error
 
-    def unknown_property(self, property, instance, schema):
-        self.schema_error(
-            self._unknown_property,
-            "%r is not a known schema property" % (property,)
-        )
-
     def validate_type(self, types, instance, schema):
         types = _list(types)
 
@@ -357,9 +217,7 @@ class Validator(object):
             )):
                 return
         else:
-            yield ValidationError(
-                "%r is not of type %r" % (instance, _delist(types))
-            )
+            yield ValidationError(_types_msg(instance, types))
 
     def validate_properties(self, properties, instance, schema):
         if not self.is_type(instance, "object"):
@@ -367,22 +225,7 @@ class Validator(object):
 
         for property, subschema in iteritems(properties):
             if property in instance:
-                dependencies = _list(subschema.get("dependencies", []))
-                if self.is_type(dependencies, "object"):
-                    for error in self.iter_errors(
-                        instance, dependencies, meta_validate=False
-                    ):
-                        yield error
-                else:
-                    for dependency in dependencies:
-                        if dependency not in instance:
-                            yield ValidationError(
-                            "%r is a dependency of %r" % (dependency, property)
-                            )
-
-                for error in self.iter_errors(
-                    instance[property], subschema, meta_validate=False
-                ):
+                for error in self.iter_errors(instance[property], subschema):
                     error.path.append(property)
                     yield error
             elif subschema.get("required", False):
@@ -397,59 +240,71 @@ class Validator(object):
         for pattern, subschema in iteritems(patternProperties):
             for k, v in iteritems(instance):
                 if re.match(pattern, k):
-                    for error in self.iter_errors(
-                        v, subschema, meta_validate=False
-                    ):
+                    for error in self.iter_errors(v, subschema):
                         yield error
 
     def validate_additionalProperties(self, aP, instance, schema):
         if not self.is_type(instance, "object"):
             return
 
-        # no viewkeys in <2.7, and pypy seems to fail on vk - vk anyhow, so...
-        extras = set(instance) - set(schema.get("properties", {}))
+        extras = set(_find_additional_properties(instance, schema))
 
         if self.is_type(aP, "object"):
             for extra in extras:
-                for error in self.iter_errors(
-                    instance[extra], aP, meta_validate=False
-                ):
+                for error in self.iter_errors(instance[extra], aP):
                     yield error
         elif not aP and extras:
             error = "Additional properties are not allowed (%s %s unexpected)"
             yield ValidationError(error % _extras_msg(extras))
 
+    def validate_dependencies(self, dependencies, instance, schema):
+        if not self.is_type(instance, "object"):
+            return
+
+        for property, dependency in iteritems(dependencies):
+            if property not in instance:
+                continue
+
+            if self.is_type(dependency, "object"):
+                for error in self.iter_errors(instance, dependency):
+                    yield error
+            else:
+                dependencies = _list(dependency)
+                for dependency in dependencies:
+                    if dependency not in instance:
+                        yield ValidationError(
+                            "%r is a dependency of %r" % (dependency, property)
+                        )
+
     def validate_items(self, items, instance, schema):
         if not self.is_type(instance, "array"):
             return
 
         if self.is_type(items, "object"):
             for index, item in enumerate(instance):
-                for error in self.iter_errors(
-                    item, items, meta_validate=False
-                ):
+                for error in self.iter_errors(item, items):
                     error.path.append(index)
                     yield error
         else:
             for (index, item), subschema in zip(enumerate(instance), items):
-                for error in self.iter_errors(
-                    item, subschema, meta_validate=False
-                ):
+                for error in self.iter_errors(item, subschema):
                     error.path.append(index)
                     yield error
 
     def validate_additionalItems(self, aI, instance, schema):
         if not self.is_type(instance, "array"):
             return
+        if not self.is_type(schema.get("items"), "array"):
+            return
 
         if self.is_type(aI, "object"):
             for item in instance[len(schema):]:
-                for error in self.iter_errors(item, aI, meta_validate=False):
+                for error in self.iter_errors(item, aI):
                     yield error
         elif not aI and len(instance) > len(schema.get("items", [])):
             error = "Additional items are not allowed (%s %s unexpected)"
             yield ValidationError(
-                error % _extras_msg(instance[len(schema) - 1:])
+                error % _extras_msg(instance[len(schema.get("items", [])):])
             )
 
     def validate_minimum(self, minimum, instance, schema):
@@ -520,7 +375,7 @@ class Validator(object):
 
         if isinstance(dB, float):
             mod = instance % dB
-            failed = (mod > EPSILON) and (dB - mod) > EPSILON
+            failed = (mod > FLOAT_TOLERANCE) and (dB - mod) > FLOAT_TOLERANCE
         else:
             failed = instance % dB
 
@@ -538,20 +393,119 @@ class Validator(object):
         if self.is_type(extends, "object"):
             extends = [extends]
         for subschema in extends:
-            for error in self.iter_errors(
-                instance, subschema, meta_validate=False
-            ):
+            for error in self.iter_errors(instance, subschema):
                 yield error
 
+    def validate_ref(self, ref, instance, schema):
+        if ref != "#" and not ref.startswith("#/"):
+            warnings.warn("jsonschema only supports json-pointer $refs")
+            return
+
+        resolved = resolve_json_pointer(self.schema, ref)
+        for error in self.iter_errors(instance, resolved):
+            yield error
+
+
+Draft3Validator.META_SCHEMA = {
+    "$schema" : "http://json-schema.org/draft-03/schema#",
+    "id" : "http://json-schema.org/draft-03/schema#",
+    "type" : "object",
+
+    "properties" : {
+        "type" : {
+            "type" : ["string", "array"],
+            "items" : {"type" : ["string", {"$ref" : "#"}]},
+            "uniqueItems" : True,
+            "default" : "any"
+        },
+        "properties" : {
+            "type" : "object",
+            "additionalProperties" : {"$ref" : "#", "type": "object"},
+            "default" : {}
+        },
+        "patternProperties" : {
+            "type" : "object",
+            "additionalProperties" : {"$ref" : "#"},
+            "default" : {}
+        },
+        "additionalProperties" : {
+            "type" : [{"$ref" : "#"}, "boolean"], "default" : {}
+        },
+        "items" : {
+            "type" : [{"$ref" : "#"}, "array"],
+            "items" : {"$ref" : "#"},
+            "default" : {}
+        },
+        "additionalItems" : {
+            "type" : [{"$ref" : "#"}, "boolean"], "default" : {}
+        },
+        "required" : {"type" : "boolean", "default" : False},
+        "dependencies" : {
+            "type" : ["string", "array", "object"],
+            "additionalProperties" : {
+                "type" : ["string", "array", {"$ref" : "#"}],
+                "items" : {"type" : "string"}
+            },
+            "default" : {}
+        },
+        "minimum" : {"type" : "number"},
+        "maximum" : {"type" : "number"},
+        "exclusiveMinimum" : {"type" : "boolean", "default" : False},
+        "exclusiveMaximum" : {"type" : "boolean", "default" : False},
+        "minItems" : {"type" : "integer", "minimum" : 0, "default" : 0},
+        "maxItems" : {"type" : "integer", "minimum" : 0},
+        "uniqueItems" : {"type" : "boolean", "default" : False},
+        "pattern" : {"type" : "string", "format" : "regex"},
+        "minLength" : {"type" : "integer", "minimum" : 0, "default" : 0},
+        "maxLength" : {"type" : "integer"},
+        "enum" : {"type" : "array", "minItems" : 1, "uniqueItems" : True},
+        "default" : {"type" : "any"},
+        "title" : {"type" : "string"},
+        "description" : {"type" : "string"},
+        "format" : {"type" : "string"},
+        "maxDecimal" : {"type" : "number", "minimum" : 0},
+        "divisibleBy" : {
+            "type" : "number",
+            "minimum" : 0,
+            "exclusiveMinimum" : True,
+            "default" : 1
+        },
+        "disallow" : {
+            "type" : ["string", "array"],
+            "items" : {"type" : ["string", {"$ref" : "#"}]},
+            "uniqueItems" : True
+        },
+        "extends" : {
+            "type" : [{"$ref" : "#"}, "array"],
+            "items" : {"$ref" : "#"},
+            "default" : {}
+        },
+        "id" : {"type" : "string", "format" : "uri"},
+        "$ref" : {"type" : "string", "format" : "uri"},
+        "$schema" : {"type" : "string", "format" : "uri"},
+    },
+    "dependencies" : {
+        "exclusiveMinimum" : "minimum", "exclusiveMaximum" : "maximum"
+    },
+}
+
 
-for no_op in [                                  # handled in:
-    "dependencies", "required",                 # properties
-    "exclusiveMinimum", "exclusiveMaximum",     # min*/max*
-    "default", "description", "format", "id",   # no validation needed
-    "links", "name", "title",
-    "ref", "schema",                            # not yet supported
-]:
-    setattr(Validator, "validate_" + no_op, lambda *args, **kwargs : None)
+class Validator(Draft3Validator):
+    """
+    Deprecated: Use :class:`Draft3Validator` instead.
+
+    """
+
+    def __init__(
+        self, version=None, unknown_type="skip", unknown_property="skip",
+        *args, **kwargs
+    ):
+        super(Validator, self).__init__({}, *args, **kwargs)
+        warnings.warn(
+            "Validator is deprecated and will be removed. "
+            "Use Draft3Validator instead.",
+            DeprecationWarning, stacklevel=2,
+        )
 
 
 class ErrorTree(object):
@@ -590,6 +544,51 @@ class ErrorTree(object):
         return "<%s (%s errors)>" % (self.__class__.__name__, len(self))
 
 
+def resolve_json_pointer(schema, ref):
+    """
+    Resolve a local reference ``ref`` within the given root ``schema``.
+
+    ``ref`` should be a local ref whose ``#`` is still present.
+
+    """
+
+    if ref == "#":
+        return schema
+
+    parts = ref.lstrip("#/").split("/")
+
+    parts = map(unquote, parts)
+    parts = [part.replace('~1', '/').replace('~0', '~') for part in parts]
+
+    try:
+        for part in parts:
+            schema = schema[part]
+    except KeyError:
+        raise InvalidRef("Unresolvable json-pointer %r" % ref)
+    else:
+        return schema
+
+
+def _find_additional_properties(instance, schema):
+    """
+    Return the set of additional properties for the given ``instance``.
+
+    Weeds out properties that should have been validated by ``properties`` and
+    / or ``patternProperties``.
+
+    Assumes ``instance`` is dict-like already.
+
+    """
+
+    properties = schema.get("properties", {})
+    patterns = "|".join(schema.get("patternProperties", {}))
+    for property in instance:
+        if property not in properties:
+            if patterns and re.search(patterns, property):
+                continue
+            yield property
+
+
 def _extras_msg(extras):
     """
     Create an error message for extra items or properties.
@@ -603,6 +602,49 @@ def _extras_msg(extras):
     return ", ".join(repr(extra) for extra in extras), verb
 
 
+def _types_msg(instance, types):
+    """
+    Create an error message for a failure to match the given types.
+
+    If the ``instance`` is an object and contains a ``name`` property, it will
+    be considered to be a description of that object and used as its type.
+
+    Otherwise the message is simply the reprs of the given ``types``.
+
+    """
+
+    reprs = []
+    for type in types:
+        try:
+            reprs.append(repr(type["name"]))
+        except Exception:
+            reprs.append(repr(type))
+    return "%r is not of type %s" % (instance, ", ".join(reprs))
+
+
+def _flatten(suitable_for_isinstance):
+    """
+    isinstance() can accept a bunch of really annoying different types:
+        * a single type
+        * a tuple of types
+        * an arbitrary nested tree of tuples
+
+    Return a flattened tuple of the given argument.
+
+    """
+
+    types = set()
+
+    if not isinstance(suitable_for_isinstance, tuple):
+        suitable_for_isinstance = (suitable_for_isinstance,)
+    for thing in suitable_for_isinstance:
+        if isinstance(thing, tuple):
+            types.update(_flatten(thing))
+        else:
+            types.add(thing)
+    return tuple(types)
+
+
 def _list(thing):
     """
     Wrap ``thing`` in a list if it's a single str.
@@ -633,21 +675,60 @@ def _delist(thing):
     return thing
 
 
-def validate(
-    instance, schema, meta_validate=True, cls=Validator, *args, **kwargs
-):
+def _uniq(container):
+    """
+    Check if all of a container's elements are unique.
+
+    Successively tries first to rely that the elements are hashable, then
+    falls back on them being sortable, and finally falls back on brute
+    force.
+
+    """
+
+    try:
+        return len(set(container)) == len(container)
+    except TypeError:
+        try:
+            sort = sorted(container)
+            sliced = itertools.islice(container, 1, None)
+            for i, j in zip(container, sliced):
+                if i == j:
+                    return False
+        except (NotImplementedError, TypeError):
+            seen = []
+            for e in container:
+                if e in seen:
+                    return False
+                seen.append(e)
+    return True
+
+
+def validate(instance, schema, cls=Draft3Validator, *args, **kwargs):
     """
     Validate an ``instance`` under the given ``schema``.
 
-    By default, the :class:`Validator` class from this module is used to
-    perform the validation. To use another validator, pass it into the ``cls``
-    argument.
+    First verifies that the provided schema is itself valid, since not doing so
+    can lead to less obvious failures when validating. If you know it is or
+    don't care, use ``YourValidator(schema).validate(instance)`` directly
+    instead (e.g. ``Draft3Validator``).
 
-    Any other provided positional and keyword arguments will be provided to the
-    ``cls``. See the :class:`Validator` class' docstring for details on the
-    arguments it accepts.
+    ``cls`` is a validator class that will be used to validate the instance.
+    By default this is a draft 3 validator.  Any other provided positional and
+    keyword arguments will be provided to this class when constructing a
+    validator.
 
     """
 
-    validator = cls(*args, **kwargs)
-    validator.validate(instance, schema, meta_validate=meta_validate)
+
+    meta_validate = kwargs.pop("meta_validate", None)
+
+    if meta_validate is not None:
+        warnings.warn(
+            "meta_validate is deprecated and will be removed. If you do not "
+            "want to validate a schema, use Draft3Validator.validate instead.",
+            DeprecationWarning, stacklevel=2,
+        )
+
+    if meta_validate is not False:  # yes this is needed since True was default
+        cls.check_schema(schema)
+    cls(schema, *args, **kwargs).validate(instance)
diff --git a/IPython/nbformat/v3/validator.py b/IPython/nbformat/v3/validator.py
index 06eac96..0073b0b 100755
--- a/IPython/nbformat/v3/validator.py
+++ b/IPython/nbformat/v3/validator.py
@@ -1,19 +1,19 @@
 #!/usr/bin/env python
 # -*- coding: utf8 -*-
 
-from IPython.external.jsonschema import  Validator, validate, ValidationError
+from IPython.external.jsonschema import  Draft3Validator, validate, ValidationError
 import IPython.external.jsonpointer as jsonpointer
 import argparse
 import traceback
 import json
 
-v = Validator();
 def nbvalidate(nbjson, schema='v3.withref.json', key=None,verbose=True):
     v3schema = resolve_ref(json.load(open(schema,'r')))
     if key :
         v3schema = jsonpointer.resolve_pointer(v3schema,key)
     errors = 0
-    for error in v.iter_errors(nbjson, v3schema):
+    v = Draft3Validator(v3schema);
+    for error in v.iter_errors(nbjson):
         errors = errors + 1
         if verbose:
             print(error)