Apply permissions in this set to the provided data, effectively
        removing all keys from it are not permissioned to be viewed

        Arguments:

        data -- dict of data

        Returns:

        Cleaned data

def apply(self, data, path=None):
        """
        Apply permissions in this set to the provided data, effectively
        removing all keys from it are not permissioned to be viewed

        Arguments:

        data -- dict of data

        Returns:

        Cleaned data
        """

        if path is None:
            path = []

        if not isinstance(data, dict):
            return data

        def _enumerate(value):
            if isinstance(value, list):
                for k, v in enumerate(value):
                    yield k, v
            elif isinstance(value, dict):
                for k, v in value.items():
                    yield k, v

        def _set(container, key, value):
            if isinstance(container, list):
                container.append(value)
            else:
                container[key] = value

        def _apply(ramap, value, status=False, wc=False, path=[]):


            if not isinstance(value, dict) and not isinstance(value, list):
                if status:
                    return value
                else:
                    return None

            if not wc:
                status = ramap.get("__", status)

            handler = None
            key_handler = None
            if path and self.handlers:
                namespace = Namespace(path)
                for _handler in self.handlers.values():
                    if namespace.match(_handler.get("namespace").keys, partial=False):
                        handler = _handler
                        key_handler = handler.get("key")
                        break

            if isinstance(value, list):
                if not key_handler:
                    key_handler = list_key_handler
                rv = []
            else:
                rv = {}

            for k, v in _enumerate(value):
                if key_handler:
                    k = key_handler(v, k)
                k = str(k)
                if isinstance(v, dict) or isinstance(v, list):
                    if k in ramap:
                        r = _apply(ramap[k], v, status=status, path=path+[k])
                        if r:
                            _set(rv, k, r)
                    elif "*" in ramap:
                        r = _apply(ramap["*"], v, status=status, wc=True, path=path+[k])
                        if r:
                            _set(rv, k, r)
                    elif status:
                        _set(rv, k, v)
                else:
                    if k in ramap:
                        if ramap[k].get("__", True):
                            _set(rv, k, v)
                    elif "*" in ramap and ramap["*"].get("__", True):
                        _set(rv, k, v)
                    elif status:
                        _set(rv, k, v)

            return rv

        # loop through all the handlers that specify the `explicit` arguments
        # and temprorarily add deny rules for those to the targeted permissionset
        tmpns = {}
        for ns, handler in self.handlers.items():
            if handler.get("explicit"):
                p = self.pset.get_permissions(ns)
                if p & const.PERM_READ:
                    exists = False
                    for _ns in self.pset.namespaces:
                        if Namespace(_ns).match(Namespace(ns).keys, partial=False):
                            exists = True
                            break
                    if exists:
                        continue
                    tmpns[ns] = p
                    self.pset[ns] = const.PERM_DENY


        # apply permissions
        rv = _apply(self.pset.read_access_map, data)

        # remove temporarily added deny rules
        for ns, p in tmpns.items():
            if p is None:
                del self.pset[ns]
            else:
                self.pset[ns] = p

        return rv