Return a macaroon obtained from the given dictionary as
        deserialized from JSON.
        @param json_dict The deserialized JSON object.

def from_dict(cls, json_dict):
        '''Return a macaroon obtained from the given dictionary as
        deserialized from JSON.
        @param json_dict The deserialized JSON object.
        '''
        json_macaroon = json_dict.get('m')
        if json_macaroon is None:
            # Try the v1 format if we don't have a macaroon field.
            m = pymacaroons.Macaroon.deserialize(
                json.dumps(json_dict), json_serializer.JsonSerializer())
            macaroon = Macaroon(root_key=None, id=None,
                                namespace=legacy_namespace(),
                                version=_bakery_version(m.version))
            macaroon._macaroon = m
            return macaroon

        version = json_dict.get('v', None)
        if version is None:
            raise ValueError('no version specified')
        if (version < VERSION_3 or
                version > LATEST_VERSION):
            raise ValueError('unknown bakery version {}'.format(version))
        m = pymacaroons.Macaroon.deserialize(json.dumps(json_macaroon),
                                             json_serializer.JsonSerializer())
        if m.version != macaroon_version(version):
            raise ValueError(
                'underlying macaroon has inconsistent version; '
                'got {} want {}'.format(m.version, macaroon_version(version)))
        namespace = checkers.deserialize_namespace(json_dict.get('ns'))
        cdata = json_dict.get('cdata', {})
        caveat_data = {}
        for id64 in cdata:
            id = b64decode(id64)
            data = b64decode(cdata[id64])
            caveat_data[id] = data
        macaroon = Macaroon(root_key=None, id=None,
                            namespace=namespace,
                            version=version)
        macaroon._caveat_data = caveat_data
        macaroon._macaroon = m
        return macaroon