Accepts keys of SQL items available, sorts them and adds additional dependencies.
        Uses graph of `sql_state` nodes to build `keys` and `resolve_keys` into sequence that
        starts with leaves (items that have not dependents) and ends with roots.

        Changes `resolve_keys` argument as dependencies are added to the result.

        Args:
            keys (list): List of migration keys, that are one of create/delete operations, and
                dont require respective reverse operations.
            resolve_keys (list): List of migration keys, that are changing existing items,
                and may require respective reverse operations.
            sql_sate (graph.SQLStateGraph): State of SQL items.
        Returns:
            (list) Sorted sequence of migration keys, enriched with dependencies.

def assemble_changes(self, keys, resolve_keys, sql_state):
        """
        Accepts keys of SQL items available, sorts them and adds additional dependencies.
        Uses graph of `sql_state` nodes to build `keys` and `resolve_keys` into sequence that
        starts with leaves (items that have not dependents) and ends with roots.

        Changes `resolve_keys` argument as dependencies are added to the result.

        Args:
            keys (list): List of migration keys, that are one of create/delete operations, and
                dont require respective reverse operations.
            resolve_keys (list): List of migration keys, that are changing existing items,
                and may require respective reverse operations.
            sql_sate (graph.SQLStateGraph): State of SQL items.
        Returns:
            (list) Sorted sequence of migration keys, enriched with dependencies.
        """
        result_keys = []
        all_keys = keys | resolve_keys
        for key in all_keys:
            node = sql_state.node_map[key]
            sql_item = sql_state.nodes[key]
            ancs = node.ancestors()[:-1]
            ancs.reverse()
            pos = next((i for i, k in enumerate(result_keys) if k in ancs), len(result_keys))
            result_keys.insert(pos, key)

            if key in resolve_keys and not sql_item.replace:
                # ancestors() and descendants() include key itself, need to cut it out.
                descs = reversed(node.descendants()[:-1])
                for desc in descs:
                    if desc not in all_keys and desc not in result_keys:
                        result_keys.insert(pos, desc)
                        # these items added may also need reverse operations.
                        resolve_keys.add(desc)
        return result_keys