do_linkup(struct module *mp, struct node *np)
{
    struct module_import *mip;
    struct node    *onp, *oldp, *newp;
    struct tree    *tp;
    int             i, more;
    /*
     * All modules implicitly import
     *   the roots of the tree
     */
    if (snmp_get_do_debugging() > 1)
        dump_module_list();
    DEBUGMSGTL(("parse-mibs", "Processing IMPORTS for module %d %s\n",
                mp->modid, mp->name));
    if (mp->no_imports == 0) {
        mp->no_imports = NUMBER_OF_ROOT_NODES;
        mp->imports = root_imports;
    }

    /*
     * Build the tree
     */
    init_node_hash(np);
    for (i = 0, mip = mp->imports; i < mp->no_imports; ++i, ++mip) {
        char            modbuf[256];
        DEBUGMSGTL(("parse-mibs", "  Processing import: %s\n",
                    mip->label));
        if (get_tc_index(mip->label, mip->modid) != -1)
            continue;
        tp = find_tree_node(mip->label, mip->modid);
        if (!tp) {
	    if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_MIB_ERRORS))
                snmp_log(LOG_WARNING,
                         "Did not find '%s' in module %s (%s)\n",
                         mip->label, module_name(mip->modid, modbuf),
                         File);
            continue;
        }
        do_subtree(tp, &np);
    }

    /*
     * If any nodes left over,
     *   check that they're not the result of a "fully qualified"
     *   name, and then add them to the list of orphans
     */

    if (!np)
        return;
    for (tp = tree_head; tp; tp = tp->next_peer)
        do_subtree(tp, &np);
    if (!np)
        return;

    /*
     * quietly move all internal references to the orphan list 
     */
    oldp = orphan_nodes;
    do {
        for (i = 0; i < NHASHSIZE; i++)
            for (onp = nbuckets[i]; onp; onp = onp->next) {
                struct node    *op = NULL;
                int             hash = NBUCKET(name_hash(onp->label));
                np = nbuckets[hash];
                while (np) {
                    if (label_compare(onp->label, np->parent)) {
                        op = np;
                        np = np->next;
                    } else {
                        if (op)
                            op->next = np->next;
                        else
                            nbuckets[hash] = np->next;
			DEBUGMSGTL(("parse-mibs", "Moving %s to orphanage", np->label));
                        np->next = orphan_nodes;
                        orphan_nodes = np;
                        op = NULL;
                        np = nbuckets[hash];
                    }
                }
            }
        newp = orphan_nodes;
        more = 0;
        for (onp = orphan_nodes; onp != oldp; onp = onp->next) {
            struct node    *op = NULL;
            int             hash = NBUCKET(name_hash(onp->label));
            np = nbuckets[hash];
            while (np) {
                if (label_compare(onp->label, np->parent)) {
                    op = np;
                    np = np->next;
                } else {
                    if (op)
                        op->next = np->next;
                    else
                        nbuckets[hash] = np->next;
                    np->next = orphan_nodes;
                    orphan_nodes = np;
                    op = NULL;
                    np = nbuckets[hash];
                    more = 1;
                }
            }
        }
        oldp = newp;
    } while (more);

    /*
     * complain about left over nodes 
     */
    for (np = orphan_nodes; np && np->next; np = np->next);     /* find the end of the orphan list */
    for (i = 0; i < NHASHSIZE; i++)
        if (nbuckets[i]) {
            if (orphan_nodes)
                onp = np->next = nbuckets[i];
            else
                onp = orphan_nodes = nbuckets[i];
            nbuckets[i] = NULL;
            while (onp) {
                snmp_log(LOG_WARNING,
                         "Unlinked OID in %s: %s ::= { %s %ld }\n",
                         (mp->name ? mp->name : "<no module>"),
                         (onp->label ? onp->label : "<no label>"),
                         (onp->parent ? onp->parent : "<no parent>"),
                         onp->subid);
		 snmp_log(LOG_WARNING,
			  "Undefined identifier: %s near line %d of %s\n",
			  (onp->parent ? onp->parent : "<no parent>"),
			  onp->lineno, onp->filename);
                np = onp;
                onp = onp->next;
            }
        }
    return;
}