Snapshot current **hierarchy** and cache it into a new poco instance. This new poco instance is a copy from
        current poco instance (``self``). The hierarchy of the new poco instance is fixed and immutable. It will be
        super fast when calling ``dump`` function from frozen poco. See the example below.
        
        Examples:
            ::

                poco = Poco(...)
                frozen_poco = poco.freeze()
                hierarchy_dict = frozen_poco.agent.hierarchy.dump()  # will return the already cached hierarchy data
                

        Returns:
            :py:class:`Poco <poco.pocofw.Poco>`: new poco instance copy from current poco instance (``self``)

def freeze(this):
        """
        Snapshot current **hierarchy** and cache it into a new poco instance. This new poco instance is a copy from
        current poco instance (``self``). The hierarchy of the new poco instance is fixed and immutable. It will be
        super fast when calling ``dump`` function from frozen poco. See the example below.
        
        Examples:
            ::

                poco = Poco(...)
                frozen_poco = poco.freeze()
                hierarchy_dict = frozen_poco.agent.hierarchy.dump()  # will return the already cached hierarchy data
                

        Returns:
            :py:class:`Poco <poco.pocofw.Poco>`: new poco instance copy from current poco instance (``self``)
        """

        class FrozenPoco(Poco):
            def __init__(self, **kwargs):
                hierarchy_dict = this.agent.hierarchy.dump()
                hierarchy = create_immutable_hierarchy(hierarchy_dict)
                agent_ = PocoAgent(hierarchy, this.agent.input, this.agent.screen)
                kwargs['action_interval'] = 0.01
                kwargs['pre_action_wait_for_appearance'] = 0
                super(FrozenPoco, self).__init__(agent_, **kwargs)
                self.this = this

            def __enter__(self):
                return self

            def __exit__(self, exc_type, exc_val, exc_tb):
                pass

            def __getattr__(self, item):
                return getattr(self.this, item)

        return FrozenPoco()