Calculate the coverage of a file.

def coverage(self):
        """Calculate the coverage of a file."""
        items_unk = collections.Counter()
        items_ok = collections.Counter()

        def _go_deep(obj):
            """Recursive function to find internal attributes."""
            if type(obj).__name__ in ('UnknownObject', 'UnknownAction'):
                # blatantly unknown
                items_unk[obj.name] += 1
            elif obj.name in ('DefineMorphShape2', 'ClipActions'):
                # these are incomplete, see FIXMEs in the code above
                items_unk[obj.name] += 1
            else:
                # fully parsed
                items_ok[obj.name] += 1

            for name in obj._attribs:
                attr = getattr(obj, name)
                if isinstance(attr, SWFObject):
                    _go_deep(attr)

        for tag in self.tags:
            _go_deep(tag)

        full_count = sum(items_ok.values()) + sum(items_unk.values())
        coverage = 100 * sum(items_ok.values()) / full_count
        print("Coverage is {:.1f}% of {} total items".format(coverage,
                                                             full_count))
        print("Most common parsed objects:")
        for k, v in items_ok.most_common(3):
            print("{:5d} {}".format(v, k))
        if items_unk:
            print("Most common Unknown objects")
            for k, v in items_unk.most_common(3):
                print("{:5d} {}".format(v, k))