def run(self):
        ''' run all patterns in the playbook '''
        plays = []
        matched_tags_all = set()
        unmatched_tags_all = set()

        # loop through all patterns and run them
        self.callbacks.on_start()
        for (play_ds, play_basedir) in zip(self.playbook, self.play_basedirs):
            play = Play(self, play_ds, play_basedir)
            matched_tags, unmatched_tags = play.compare_tags(self.only_tags)
            matched_tags_all = matched_tags_all | matched_tags
            unmatched_tags_all = unmatched_tags_all | unmatched_tags

            # if we have matched_tags, the play must be run.
            # if the play contains no tasks, assume we just want to gather facts
            if (len(matched_tags) > 0 or len(play.tasks()) == 0):
                plays.append(play)

        # if the playbook is invoked with --tags that don't exist at all in the playbooks
        # then we need to raise an error so that the user can correct the arguments.
        unknown_tags = set(self.only_tags) - (matched_tags_all | unmatched_tags_all)
        unknown_tags.discard('all')

        if len(unknown_tags) > 0:
            unmatched_tags_all.discard('all')
            msg = 'tag(s) not found in playbook: %s.  possible values: %s'
            unknown = ','.join(sorted(unknown_tags))
            unmatched = ','.join(sorted(unmatched_tags_all))
            raise errors.AnsibleError(msg % (unknown, unmatched))

        for play in plays:
            if not self._run_play(play):
                break

        # summarize the results
        results = {}
        for host in self.stats.processed.keys():
            results[host] = self.stats.summarize(host)
        return results
run all patterns in the playbook