'Given a set of targets, return a list of (Migration instance, backwards?).'

def migration_plan(self, targets, clean_start=False):

    plan = []
    if clean_start:
        applied = set()
    else:
        applied = set(self.loader.applied_migrations)
    for target in targets:
        if (target[1] is None):
            for root in self.loader.graph.root_nodes():
                if (root[0] == target[0]):
                    for migration in self.loader.graph.backwards_plan(root):
                        if (migration in applied):
                            plan.append((self.loader.graph.nodes[migration], True))
                            applied.remove(migration)
        elif (target in applied):
            next_in_app = sorted((n for n in self.loader.graph.node_map[target].children if (n[0] == target[0])))
            for node in next_in_app:
                for migration in self.loader.graph.backwards_plan(node):
                    if (migration in applied):
                        plan.append((self.loader.graph.nodes[migration], True))
                        applied.remove(migration)
        else:
            for migration in self.loader.graph.forwards_plan(target):
                if (migration not in applied):
                    plan.append((self.loader.graph.nodes[migration], False))
                    applied.add(migration)
    return plan
