def flatten_comments(comments, root_level=0):
        """
        Flatten a PRAW comment tree while preserving the nested level of each
        comment via the `nested_level` attribute.

        There are a couple of different ways that the input comment list can be
        organized depending on its source:

            1. Comments that are returned from the get_submission() api call.
               In this case, the comments list will contain only top level
               comments and replies will be attached to those comments via
               the `comment.replies` property.

            2. Comments that are returned from the comments() method on a
               MoreComments object. In this case, the api returns all of the
               comments and replies as a flat list. We need to sort out which
               ones are replies to other comments by looking at the parent_id
               parameter and checking if the id matches another comment.

        In addition, there is a bug in praw where a MoreComments object that is
        also a reply will be added below the comment as a sibling instead of
        a child. So it is especially important that this method is robust and
        double-checks all of the parent_id's of the comments.

        Reference:
            https://github.com/praw-dev/praw/issues/391

        """

        stack = comments[:]
        for item in stack:
            item.nested_level = root_level

        retval, parent_candidates = [], {}
        while stack:
            item = stack.pop(0)

            # The MoreComments item count should never be zero, discard it if
            # it is. Need to look into this further.
            if isinstance(item, praw.objects.MoreComments) and item.count == 0:
                continue

            if item.parent_id:
                # Search the list of previous comments for a possible parent
                # The match is based off of the parent_id parameter E.g.
                #   parent.id = c0tprcm
                #   child.parent_id = t1_c0tprcm
                parent = parent_candidates.get(item.parent_id[3:])
                if parent:
                    item.nested_level = parent.nested_level + 1

            # Add all of the attached replies to the front of the stack to be
            # parsed separately
            if hasattr(item, 'replies'):
                for n in item.replies:
                    n.nested_level = item.nested_level + 1
                stack[0:0] = item.replies

            # The comment is now a potential parent for the items that are
            # remaining on the stack.
            parent_candidates[item.id] = item

            retval.append(item)
        return retval