# Path: ejtp/identity/core.py
# class Identity(object):
#     def __init__(self, name, encryptor, location, **kwargs):
#         '''
#         >>> ident = Identity("joe", ['rotate', 8], None)
#         >>> ident.name
#         'joe'
#         '''
#         self._contents = {
#             'name': name,
#             'encryptor': encryptor,
#             'location': location,
#         }
#         self._contents.update(kwargs)
#         self._encryptor = None
# 
#     def __getitem__(self, i):
#         return self._contents[i]
# 
#     def __setitem__(self, i, v):
#         self._contents[i] = v
# 
#     def __delitem__(self, i):
#         del self._contents[i]
# 
#     def __eq__(self, other):
#         if not isinstance(other, Identity):
#             return False
#         return self.serialize() == other.serialize()
# 
#     @property
#     def key(self):
#         return str_address(self.location)
# 
#     def ref(self, cache):
#         return IdentRef(self.key, cache)
# 
#     # Encryptor shortcuts
# 
#     def encrypt(self, plaintext):
#         return self.encryptor.encrypt(plaintext)
# 
#     def decrypt(self, ciphertext):
#         return self.encryptor.decrypt(ciphertext)
# 
#     def sign(self, plaintext):
#         return self.encryptor.sign(plaintext)
# 
#     def verify_signature(self, signature, plaintext):
#         return self.encryptor.sig_verify(plaintext, signature)
# 
#     def public(self):
#         '''
#         Return a copy of this Identity with only the public component of
#         its encryptor object.
#         '''
#         public_proto = self.encryptor.public()
#         return Identity(self.name, public_proto, self.location)
# 
#     def is_public(self):
#         return self.encryptor.is_public()
# 
#     def can_encrypt(self):
#         return self.encryptor.can_encrypt()
# 
#     # Inner property and serialization stuff
# 
#     def serialize(self):
#         '''
#         Serialize Identity object to dict.
#         '''
#         self['encryptor'] = self.encryptor.proto()
#         return self._contents
# 
#     def clone(self):
#         '''
#         Create new unique copy in memory.
#         '''
#         return deserialize(self.serialize())
# 
#     @property
#     def name(self):
#         return self['name']
# 
#     @name.setter
#     def name(self, v):
#         self['name'] = v
# 
#     @property
#     def location(self):
#         return self['location']
# 
#     @location.setter
#     def location(self, v):
#         self['location'] = v
# 
#     @property
#     def encryptor(self):
#         if not self._encryptor:
#             self._encryptor = ejtp.crypto.make(self['encryptor'])
#         return self._encryptor
# 
#     @encryptor.setter
#     def encryptor(self, new_encryptor):
#         self._encryptor = ejtp.crypto.make(new_encryptor)
#         self['encryptor'] = self.encryptor.proto()
# 
# def deserialize(ident_dict):
#     '''
#     Deserialize a dict into an Identity.
#     '''
#     for req in ('name', 'location', 'encryptor'):
#         if not req in ident_dict:
#             raise ValueError("Missing ident property: %r" % req)
# 
#     name      = ident_dict['name']
#     location  = ident_dict['location']
#     encryptor = ident_dict['encryptor']
# 
#     cleaned = {}
#     cleaned.update(ident_dict)
#     del cleaned['name'], cleaned['location'], cleaned['encryptor']
# 
#     return Identity(name, encryptor, location, **cleaned)
# 
# Path: ejtp/identity/ref.py
# class IdentRef(object):
#     '''
#     Store a hashable reference to an Identity.
# 
#     This works like a glorified (key, cache) tuple, basically.
#     '''
#     def __init__(self, key, cache):
#         self.key   = String(key)
#         self.cache = cache
# 
#     def __eq__(self, other):
#         return (self.key == other.key) and (self.cache == other.cache)
# 
#     def __hash__(self):
#         return hash(self.key.export()) ^ hash(self.cache)
# 
#     def deref(self):
#         return self.cache[self.key]


import json
from persei import String, StringDecorator, JSONBytesEncoder
from ejtp.address import *
from ejtp.identity.core import Identity, deserialize
from ejtp.identity.ref  import IdentRef
    def __delitem__(self, location):
        location = str_address(location)
        del self.cache[location]

    def update_ident(self, ident):
        self[str_address(ident.location)] = ident

    def update_idents(self, idents):
        for ident in idents:
            self.update_ident(ident)

    def filter_by_name(self, name):
        '''
        Return a new cache of every ident matching the given name.
        '''
        return [x for x in self.all() if x.name == name]

    def find_by_name(self, name):
        for ident in self.cache.values():
            if ident.name == name:
                return ident
        raise KeyError(name)

    def find_by_location(self, location):
        return self.cache[str_address(location)]

    def all(self):
        return self.cache.values()

    def ref(self, ident):

# Path: ejtp/identity/core.py
# class Identity(object):
#     def __init__(self, name, encryptor, location, **kwargs):
#         '''
#         >>> ident = Identity("joe", ['rotate', 8], None)
#         >>> ident.name
#         'joe'
#         '''
#         self._contents = {
#             'name': name,
#             'encryptor': encryptor,
#             'location': location,
#         }
#         self._contents.update(kwargs)
#         self._encryptor = None
# 
#     def __getitem__(self, i):
#         return self._contents[i]
# 
#     def __setitem__(self, i, v):
#         self._contents[i] = v
# 
#     def __delitem__(self, i):
#         del self._contents[i]
# 
#     def __eq__(self, other):
#         if not isinstance(other, Identity):
#             return False
#         return self.serialize() == other.serialize()
# 
#     @property
#     def key(self):
#         return str_address(self.location)
# 
#     def ref(self, cache):
#         return IdentRef(self.key, cache)
# 
#     # Encryptor shortcuts
# 
#     def encrypt(self, plaintext):
#         return self.encryptor.encrypt(plaintext)
# 
#     def decrypt(self, ciphertext):
#         return self.encryptor.decrypt(ciphertext)
# 
#     def sign(self, plaintext):
#         return self.encryptor.sign(plaintext)
# 
#     def verify_signature(self, signature, plaintext):
#         return self.encryptor.sig_verify(plaintext, signature)
# 
#     def public(self):
#         '''
#         Return a copy of this Identity with only the public component of
#         its encryptor object.
#         '''
#         public_proto = self.encryptor.public()
#         return Identity(self.name, public_proto, self.location)
# 
#     def is_public(self):
#         return self.encryptor.is_public()
# 
#     def can_encrypt(self):
#         return self.encryptor.can_encrypt()
# 
#     # Inner property and serialization stuff
# 
#     def serialize(self):
#         '''
#         Serialize Identity object to dict.
#         '''
#         self['encryptor'] = self.encryptor.proto()
#         return self._contents
# 
#     def clone(self):
#         '''
#         Create new unique copy in memory.
#         '''
#         return deserialize(self.serialize())
# 
#     @property
#     def name(self):
#         return self['name']
# 
#     @name.setter
#     def name(self, v):
#         self['name'] = v
# 
#     @property
#     def location(self):
#         return self['location']
# 
#     @location.setter
#     def location(self, v):
#         self['location'] = v
# 
#     @property
#     def encryptor(self):
#         if not self._encryptor:
#             self._encryptor = ejtp.crypto.make(self['encryptor'])
#         return self._encryptor
# 
#     @encryptor.setter
#     def encryptor(self, new_encryptor):
#         self._encryptor = ejtp.crypto.make(new_encryptor)
#         self['encryptor'] = self.encryptor.proto()
# 
# def deserialize(ident_dict):
#     '''
#     Deserialize a dict into an Identity.
#     '''
#     for req in ('name', 'location', 'encryptor'):
#         if not req in ident_dict:
#             raise ValueError("Missing ident property: %r" % req)
# 
#     name      = ident_dict['name']
#     location  = ident_dict['location']
#     encryptor = ident_dict['encryptor']
# 
#     cleaned = {}
#     cleaned.update(ident_dict)
#     del cleaned['name'], cleaned['location'], cleaned['encryptor']
# 
#     return Identity(name, encryptor, location, **cleaned)
# 
# Path: ejtp/identity/ref.py
# class IdentRef(object):
#     '''
#     Store a hashable reference to an Identity.
# 
#     This works like a glorified (key, cache) tuple, basically.
#     '''
#     def __init__(self, key, cache):
#         self.key   = String(key)
#         self.cache = cache
# 
#     def __eq__(self, other):
#         return (self.key == other.key) and (self.cache == other.cache)
# 
#     def __hash__(self):
#         return hash(self.key.export()) ^ hash(self.cache)
# 
#     def deref(self):
#         return self.cache[self.key]


# Path: ejtp/identity/cache.py
import json
from persei import String, StringDecorator, JSONBytesEncoder
from ejtp.address import *
from ejtp.identity.core import Identity, deserialize
from ejtp.identity.ref  import IdentRef

    def __delitem__(self, location):
        location = str_address(location)
        del self.cache[location]

    def update_ident(self, ident):
        self[str_address(ident.location)] = ident

    def update_idents(self, idents):
        for ident in idents:
            self.update_ident(ident)

    def filter_by_name(self, name):
        '''
        Return a new cache of every ident matching the given name.
        '''
        return [x for x in self.all() if x.name == name]

    def find_by_name(self, name):
        for ident in self.cache.values():
            if ident.name == name:
                return ident
        raise KeyError(name)

    def find_by_location(self, location):
        return self.cache[str_address(location)]

    def all(self):
        return self.cache.values()

    def ref(self, ident):

        if isinstance(ident, Identity):