private void buildContainer()

in src/main/java/org/apache/commons/net/nntp/Threader.java [46:139]


    private void buildContainer(final Threadable threadable, final HashMap<String, NntpThreadContainer> idTable) {
        String id = threadable.messageThreadId();
        NntpThreadContainer container = idTable.get(id);
        int bogusIdCount = 0;

        // A NntpThreadContainer exists for this id already. This should be a forward reference, but may
        // be a duplicate id, in which case we will need to generate a bogus placeholder id
        if (container != null) {
            if (container.threadable != null) { // oops! duplicate ids...
                bogusIdCount++; // Avoid dead local store warning
                id = "<Bogus-id:" + bogusIdCount + ">";
                container = null;
            } else {
                // The container just contained a forward reference to this message, so let's
                // fill in the threadable field of the container with this message
                container.threadable = threadable;
            }
        }

        // No container exists for that message Id. Create one and insert it into the hash table.
        if (container == null) {
            container = new NntpThreadContainer();
            container.threadable = threadable;
            idTable.put(id, container);
        }

        // Iterate through all the references and create ThreadContainers for any references that
        // don't have them.
        NntpThreadContainer parentRef = null;
        {
            final String[] references = threadable.messageThreadReferences();
            for (final String refString : references) {
                NntpThreadContainer ref = idTable.get(refString);

                // if this id doesn't have a container, create one
                if (ref == null) {
                    ref = new NntpThreadContainer();
                    idTable.put(refString, ref);
                }

                // Link references together in the order they appear in the References: header,
                // IF they don't have a parent already &&
                // IF it will not cause a circular reference
                if (parentRef != null && ref.parent == null && parentRef != ref && !ref.findChild(parentRef)) {
                    // Link ref into the parent's child list
                    ref.parent = parentRef;
                    ref.next = parentRef.child;
                    parentRef.child = ref;
                }
                parentRef = ref;
            }
        }

        // parentRef is now set to the container of the last element in the references field. make that
        // be the parent of this container, unless doing so causes a circular reference
        if (parentRef != null && (parentRef == container || container.findChild(parentRef))) {
            parentRef = null;
        }

        // if it has a parent already, it's because we saw this message in a References: field, and presumed
        // a parent based on the other entries in that field. Now that we have the actual message, we can
        // throw away the old parent and use this new one
        if (container.parent != null) {
            NntpThreadContainer rest;
            NntpThreadContainer prev;

            for (prev = null, rest = container.parent.child; rest != null; prev = rest, rest = rest.next) {
                if (rest == container) {
                    break;
                }
            }

            if (rest == null) {
                throw new IllegalStateException("Didnt find " + container + " in parent " + container.parent);
            }

            // Unlink this container from the parent's child list
            if (prev == null) {
                container.parent.child = container.next;
            } else {
                prev.next = container.next;
            }

            container.next = null;
            container.parent = null;
        }

        // If we have a parent, link container into the parents child list
        if (parentRef != null) {
            container.parent = parentRef;
            container.next = parentRef.child;
            parentRef.child = container;
        }
    }