def __init__(self, functions, tensors, updater):
        self._functions = functions
        self._tensors = tensors

        # Force evaluation to happen at with the default feed_dict
        functions["dummy"] = DummyFunc()

        self.updater = updater

        self.functions = defaultdict(list)
        self.feed_dicts = {}
        fetch_keys = defaultdict(set)

        for name, func in functions.items():
            if hasattr(func, 'get_feed_dict'):
                feed_dict = func.get_feed_dict(updater)
            else:
                feed_dict = {}

            fd_key = {str(k): str(v) for k, v in feed_dict.items()}
            fd_key = json.dumps(fd_key, default=str, indent=4, sort_keys=True)

            self.functions[fd_key].append((name, func))
            self.feed_dicts[fd_key] = feed_dict

            # store for the function

            keys_accessed = func.keys_accessed

            if isinstance(keys_accessed, str):
                keys_accessed = keys_accessed.split()

            for key in keys_accessed:
                fetch_keys[fd_key].add(key)

        self.fetches = {}

        for fd_key, _fetch_keys in fetch_keys.items():
            fetches = self.fetches[fd_key] = {}

            for key in _fetch_keys:
                dst = fetches
                src = tensors
                subkeys = key.split(":")

                for i, _key in enumerate(subkeys):
                    if i == len(subkeys)-1:
                        dst[_key] = src[_key]
                    else:
                        if _key not in dst:
                            dst[_key] = dict()
                        dst = dst[_key]
                        src = src[_key]