/*
 * testnode.cpp --
 *
 * Tests of the e4_Node class.
 *
 * Copyright (c) 2000-2003, JYL Software Inc.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE, EVEN IF
 * JYL SOFTWARE INC. IS MADE AWARE OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#ifndef	_WIN32
#include <unistd.h>
#endif
#include "test.h"

#define TN_VERTEXLIMIT	256

static int
test_node1()
{
    e4_Node n, n1;
    int i = 0, rank = 0;

    /*
     * Test that we can get the root node from an e4_StorageImpl. Test that
     * other nodes within the storage are not the root node.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test nod1 failed (step 0)\n");
	    return 1;
	}

	if (!s.IsValid()) {
	    fprintf(stderr, "test node1 failed (step 1)\n");
	    return 1;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test node1 failed (step 2)\n");
	    return 1;
	}
	for (i = 0; i < 10; i++) {
	    if (!n.AddNode("n1", E4_IOLAST, rank, n1) || !n1.IsValid() ||
		n1.IsRoot() || (n == n1) || (n1 == n)) {
		fprintf(stderr, "test node1 failed (step 3.%d)\n", i);
		return 1;
	    }
	}
	if (n.VertexCount() != 10) {
	    fprintf(stderr, "test node1 failed (step 4)\n");
	    return 1;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node1 failed (step 5)\n");
	    return 1;
	}
    }
    if (n.IsValid()) {
	fprintf(stderr, "test node1 failed (step 4)\n");
	return 1;
    }

    return 0;
}

static int
test_node4()
{
    e4_Node n;
    int rank = 0, i = 0;

    /*
     * Test e4_Node::VertexCount() under various circumstances.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node4 failed (step 0)\n");
	    return 4;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node4 failed (step 1)\n");
	    return 4;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test node4 failed (step 2)\n");
	    return 4;
	}
	if (n.VertexCount() != 0) {
	    fprintf(stderr, "test node4 failed (step 3)\n");
	    return 4;
	}
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    if (!n.AddVertex("f", E4_IOLAST, rank, (int) 34)) {
		fprintf(stderr, "test node4 failed (step 4.%d.1)\n", i+1);
		return 4;
	    }
	    if (n.VertexCount() != i + 1) {
		fprintf(stderr, "test node4 failed (step 4.%d.2)\n", i+1);
		return 4;
	    }
	}
	s.Commit();
    }
    if (n.IsValid()) {
	fprintf(stderr, "test node4 failed (step 5)\n");
	return 4;
    }
    {
        e4_Storage s("foo.db", E4_METAKIT);

	if (!s.IsValid()) {
	    fprintf(stderr, "test node4 failed (step 6)\n");
	    return 4;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test node4 failed (step 7)\n");
	    return 4;
	}
	if (n.VertexCount() != TN_VERTEXLIMIT) {
	    fprintf(stderr, "test node4 failed (step 8)\n");
	    return 4;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node4 failed (step 9)\n");
	    return 4;
	}
    }
    if (n.IsValid()) {
	fprintf(stderr, "test node4 failed (step 10)\n");
	return 4;
    }
    if (n.VertexCount() == TN_VERTEXLIMIT) {
	fprintf(stderr, "test node4 failed (step 11)\n");
	return 4;
    }

    return 0;
}


static int
test_node5()
{
    e4_Node n1, n2, n3;
    int rank = 0;

    /*
     * Test the e4_Node::SetNthNode and e4_Node::GetParent APIs.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node5 failed (step 0)\n");
	    return 5;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node5 failed (step 1)\n");
	    return 5;
	}
	if (!s.GetRootNode(n1) || !n1.IsValid() || !n1.IsRoot()) {
	    fprintf(stderr, "test node5 failed (step 2)\n");
	    return 5;
	}
	if (!n1.AddVertex("f", E4_IOLAST, rank, (int) 33)) {
	    fprintf(stderr, "test node5 failed (step 3)\n");
	    return 5;
	}
	if (n1.VertexCount() != 1) {
	    fprintf(stderr, "test node5 failed (step 4)\n");
	    return 5;
	}
	if (!n1.SetNthNode("f", 1, n2)) {
	    fprintf(stderr, "test node5 failed (step 5)\n");
	    return 5;
	}
	if (!n2.IsValid()) {
	    fprintf(stderr, "test node5 failed (step 6)\n");
	    return 5;
	}
	if (n2.VertexCount() != 0) {
	    fprintf(stderr, "test node5 failed (step 7)\n");
	    return 5;
	}
	if (n1.VertexCount() != 1) {
	    fprintf(stderr, "test node5 failed (step 8)\n");
	    return 5;
	}
	if (!n2.GetParent(n3)) {
	    fprintf(stderr, "test node5 failed (step 9)\n");
	    return 5;
	}
	if (!n3.IsValid()) {
	    fprintf(stderr, "test node5 failed (step 10)\n");
	    return 5;
	}
	if (n3 != n1) {
	    fprintf(stderr, "test node5 failed (step 11)\n");
	    return 5;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node5 failed (step 12)\n");
	    return 5;
	}
    }
    if (n1.IsValid() || n2.IsValid() || n3.IsValid()) {
	fprintf(stderr, "test node5 failed (step 13)\n");
	return 5;
    }
    if (n2.GetParent(n3)) {
	fprintf(stderr, "test node5 failed (step 14)\n");
	return 5;
    }

    return 0;
}

static int
test_node6()
{
    e4_Node n1, n2, n3;
    int rank = 0;

    /*
     * Test the e4_Node::SetNthNode API.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node6 failed (step 0)\n");
	    return 6;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node6 failed (step 1)\n");
	    return 6;
	}
	if (!s.GetRootNode(n1) || !n1.IsValid() || !n1.IsRoot()) {
	    fprintf(stderr, "test node6 failed (step 2)\n");
	    return 6;
	}
	if (!n1.AddVertex("f", E4_IOLAST, rank, (int) 33)) {
	    fprintf(stderr, "test node6 failed (step 3)\n");
	    return 6;
	}
	if (n1.VertexCount() != 1) {
	    fprintf(stderr, "test node6 failed (step 4)\n");
	    return 6;
	}
	if (!n1.SetNthNode("f", 1, n2)) {
	    fprintf(stderr, "test node6 failed (step 5)\n");
	    return 6;
	}
	if (!n2.IsValid()) {
	    fprintf(stderr, "test node6 failed (step 6)\n");
	    return 6;
	}
	if (n2.VertexCount() != 0) {
	    fprintf(stderr, "test node6 failed (step 7)\n");
	    return 6;
	}
	if (n1.VertexCount() != 1) {
	    fprintf(stderr, "test node6 failed (step 8)\n");
	    return 6;
	}
	if (!n2.AddVertex("f", E4_IOLAST, rank, (int) 33)) {
	    fprintf(stderr, "test node6 failed (step 9)\n");
	    return 6;
	}
	if (n2.VertexCount() != 1) {
	    fprintf(stderr, "test node6 failed (step 10)\n");
	    return 6;
	}
	if (!n2.SetNthNode("f", 1, n3)) {
	    fprintf(stderr, "test node6 failed (step 11)\n");
	    return 6;
	}
	if (!n3.IsValid()) {
	    fprintf(stderr, "test node6 failed (step 12)\n");
	    return 6;
	}
	if (n3.VertexCount() != 0) {
	    fprintf(stderr, "test node6 failed (step 13)\n");
	    return 6;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node6 failed (step 14)\n");
	    return 6;
	}
    }
    if (n1.IsValid() || n2.IsValid() || n3.IsValid()) {
	fprintf(stderr, "test node6 failed (step 14)\n");
	return 6;
    }

    return 0;
}

static int
test_node7()
{
    e4_Node n1, n2, n3;
    e4_Vertex v1, v2, v3;
    int rank = 0;

    /*
     * Test e4_Node::SetNode.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node7 failed (step 0)\n");
	    return 7;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node7 failed (step 1)\n");
	    return 7;
	}
	if (!s.GetRootNode(n1) || !n1.IsValid() || !n1.IsRoot()) {
	    fprintf(stderr, "test node7 failed (step 2)\n");
	    return 7;
	}
	if (!n1.AddVertex("f1", E4_IOFIRST, rank, 0)) {
	    fprintf(stderr, "test node7 failed (step 3)\n");
	    return 7;
	}
	if (!n1.SetNode("f1", n2)) {
	    fprintf(stderr, "test node7 failed (step 4)\n");
	    return 7;
	}
	if (!n2.IsValid()) {
	    fprintf(stderr, "test node7 failed (step 5)\n");
	    return 7;
	}
	if (!n2.GetParent(n3)) {
	    fprintf(stderr, "test node7 failed (step 6)\n");
	    return 7;
	}
	if (!n3.IsValid()) {
	    fprintf(stderr, "test node7 failed (step 7)\n");
	    return 7;
	}
	if (n3 != n1) {
	    fprintf(stderr, "test node7 failed (step 8)\n");
	    return 7;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node7 failed (step 9)\n");
	    return 7;
	}
    }
    if (n1.IsValid() || n2.IsValid() || n3.IsValid()) {
	fprintf(stderr, "test node7 failed (step 10)\n");
	return 7;
    }
    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node7 failed (step 11.0)\n");
	    return 7;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node7 failed (step 11)\n");
	    return 7;
	}
	if (!s.GetRootNode(n1) || !n1.IsValid() || !n1.IsRoot()) {
	    fprintf(stderr, "test node7 failed (step 12)\n");
	    return 7;
	}
	if ((!n1.AddNodeRef("f1", E4_IOFIRST, rank, n2, v2)) ||
	    (!n2.IsValid()) || (!v2.IsValid())) {
	    fprintf(stderr, "test node7 failed (step 13)\n");
	    return 7;
	}
	if (!n2.GetParent(n3)) {
	    fprintf(stderr, "test node7 failed (step 14)\n");
	    return 7;
	}
	if (!n3.IsValid()) {
	    fprintf(stderr, "test node7 failed (step 15)\n");
	    return 7;
	}
	if (n3 != n1) {
	    fprintf(stderr, "test node7 failed (step 16)\n");
	    return 7;
	}
	if ((!v2.GetNode(n3)) || (!n3.IsValid()) || (n3 != n1)) {
	    fprintf(stderr, "test node7 failed (step 17)\n");
	    return 7;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node7 failed (step 18)\n");
	    return 7;
	}
    }
    if (n1.IsValid() || n2.IsValid() || n3.IsValid() || v2.IsValid()) {
	fprintf(stderr, "test node7 failed (step 19)\n");
	return 7;
    }


    return 0;
}

static int
test_node8()
{
    e4_Node n1, n2;
    e4_Node subnodes[TN_VERTEXLIMIT];
    int i = 0, rank = 0;
    char buf[32];

    /*
     * Test e4_Node::AddNode.
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node8 failed (step 0)\n");
	    return 8;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node8 failed (step 1)\n");
	    return 8;
	}
	if (!s.GetRootNode(n1) || !n1.IsValid() || !n1.IsRoot()) {
	    fprintf(stderr, "test node8 failed (step 2)\n");
	    return 8;
	}
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "n%d", i);
	    if (!n1.AddNode(buf, E4_IOLAST, rank, subnodes[i])) {
	        fprintf(stderr, "test node8 failed (step 3.1.%d)\n", i);
		return 8;
	    }
	    if (!subnodes[i].IsValid()) {
		fprintf(stderr, "test node8 failed (step 3.2.%d)\n", i);
		return 8;
	    }
	    if (rank != i + 1) {
		fprintf(stderr, "test node8 failed (step 3.3.%d)\n", i);
		return 8;
	    }
	    if (n1.VertexCount() != i + 1) {
		fprintf(stderr, "test node8 failed (step 3.4.%d)\n", i);
		return 8;
	    }
	    if (subnodes[i].VertexCount() != 0) {
	        fprintf(stderr, "test node8 failed (step 3.5.%d)\n", i);
		return 8;
	    }
	    if (!subnodes[i].GetParent(n2)) {
		fprintf(stderr, "test node8 failed (step 3.6.%d)\n", i);
		return 8;
	    }
	    if (!n2.IsValid()) {
		fprintf(stderr, "test node8 failed (step 3.7.%d)\n", i);
		return 8;
	    }
	    if (n1 != n2) {
		fprintf(stderr, "test node8 failed (step 3.8.%d)\n", i);
		return 8;
	    }
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node8 failed (step 4)\n");
	    return 8;
	}
    }
    if (n1.IsValid() || n2.IsValid()) {
	fprintf(stderr, "test node8 failed (step 5)\n");
	return 8;
    }

    return 0;
}

static int
test_node9()
{
    e4_Node n1, n2, n3, n4;
    int i = 0, rank = 0;
    char buf[32];

    /*
     * Test e4_Node::SetNodeByRank, e4_Node::GetVertexByRank,
     * e4_Node::GetParent.
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node9 failed (step 0)\n");
            return 9;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node9 failed (step 1)\n");
            return 9;
        }
	if (!s.GetRootNode(n1) || !n1.IsValid() || !n1.IsRoot()) {
            fprintf(stderr, "test node9 failed (step 2)\n");
            return 9;
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
            sprintf(buf, "f%d", i);
            if (!n1.AddVertex(buf, E4_IOLAST, rank, i)) {
                fprintf(stderr, "test node9 failed (step 3.1.%d)\n", i);
                return 9;
            }
            if (rank != i + 1) {
                fprintf(stderr, "test node9 failed (step 3.2.%d)\n", i);
                return 9;
            }
            if (n1.VertexCount() != i + 1) {
                fprintf(stderr, "test node9 failed (step 3.3.%d)\n", i);
                return 9;
            }
        }
        if (!n1.SetNodeByRank(22, n2)) {
            fprintf(stderr, "test node9 failed (step 4)\n");
            return 9;
        }
        if (!n2.IsValid()) {
            fprintf(stderr, "test node9 failed (step 5)\n");
            return 9;
        }
        if (n1.VertexCount() != TN_VERTEXLIMIT) {
            fprintf(stderr, "test node9 failed (step 6)\n");
            return 9;
        }
        if (!n2.GetParent(n3)) {
            fprintf(stderr, "test node9 failed (step 7)\n");
            return 9;
        }
        if (!n3.IsValid()) {
            fprintf(stderr, "test node9 failed (step 8)\n");
            return 9;
        }
        if (n1 != n3) {
            fprintf(stderr, "test node9 failed (step 9)\n");
            return 9;
        }
        if (!n1.GetVertexByRank(22, n4)) {
            fprintf(stderr, "test node9 failed (step 10)\n");
            return 9;
        }
        if (!n4.IsValid()) {
            fprintf(stderr, "test node9 failed (step 11)\n");
            return 9;
        }
        if (n4 != n2) {
            fprintf(stderr, "test node9 failed (step 12)\n");
            return 9;
        }
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node9 failed (step 13)\n");
	    return 9;
	}
    }
    if (n1.IsValid() || n2.IsValid() || n3.IsValid() || n4.IsValid()) {
        fprintf(stderr, "test node9 failed (step 14)\n");
        return 9;
    }

    return 0;
}

static int
test_node10()
{
    e4_Node n1;
    int i = 0, j = 0, rank = 0;
    e4_Value v;

    /*
     * Test e4_Node::SetNthVertex, e4_Node::GetNthVertex with e4_Value 
     * argument, and e4_Node::VertexTypeByRank.
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node10 failed (step 0)\n");
            return 10;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node10 failed (step 1)\n");
            return 10;
        }
	if (!s.GetRootNode(n1) || !n1.IsValid() || !n1.IsRoot()) {
            fprintf(stderr, "test node10 failed (step 2)\n");
            return 10;
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
            if (!n1.AddVertex("f1", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test node10 failed (step 3.1.%d)\n", i);
                return 10;
            }
            if (n1.VertexCount() != i + 1) {
                fprintf(stderr, "test node10 failed (step 3.2.%d)\n", i);
                return 10;
            }
            if (rank != i + 1) {
                fprintf(stderr, "test node10 failed (step 3.3.%d)\n", i);
                return 10;
            }
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
            j = i % (int) E4_VTLASTVERTEXTYPE;
            switch ((e4_VertexType) j) {
            case E4_VTNODE:
            case E4_VTINT:
                if (!n1.SetNthVertex("f1", i + 1, i)) {
                    fprintf(stderr, "test node10 failed (step 4.1.%d)\n", i);
                    return 10;
                }
                if (n1.VertexTypeByRank(i + 1) != E4_VTINT) {
                    fprintf(stderr, "test node10 failed (step 4.2.%d)\n", i);
                    return 10;
                }
                if (!n1.GetNthVertex("f1", i + 1, v)) {
                    fprintf(stderr, "test node10 failed (step 4.3.%d)\n", i);
                    return 10;
                }
                if (v.vertexType != E4_VTINT) {
                    fprintf(stderr, "test node10 failed (step 4.4.%d)\n", i);
                    return 10;
                }
                if (v.u.i != i) {
                    fprintf(stderr, "test node10 failed (step 4.5.%d, %d)\n", 
			    i, v.u.i);
                    return 10;
                }
                break;
            case E4_VTDOUBLE:
                if (!n1.SetNthVertex("f1", i + 1, (double) 3.145678)) {
                    fprintf(stderr, "test node10 failed (step 4.1.%d)\n", i);
                    return 10;
                }
                if (n1.VertexTypeByRank(i + 1) != E4_VTDOUBLE) {
                    fprintf(stderr, "test node10 failed (step 4.2.%d)\n", i);
                    return 10;
                }
                if (!n1.GetNthVertex("f1", i + 1, v)) {
                    fprintf(stderr, "test node10 failed (step 4.3.%d)\n", i);
                    return 10;
                }
                if (v.vertexType != E4_VTDOUBLE) {
                    fprintf(stderr, "test node10 failed (step 4.4.%d)\n", i);
                    return 10;
                }
                break;
            case E4_VTSTRING:
                if (!n1.SetNthVertex("f1", i + 1, "hello there")) {
                    fprintf(stderr, "test node10 failed (step 4.1.%d)\n", i);
                    return 10;
                }
                if (n1.VertexTypeByRank(i + 1) != E4_VTSTRING) {
                    fprintf(stderr, "test node10 failed (step 4.2.%d)\n", i);
                    return 10;
                }
                if (!n1.GetNthVertex("f1", i + 1, v)) {
                    fprintf(stderr, "test node10 failed (step 4.3.%d)\n", i);
                    return 10;
                }
                if (v.vertexType != E4_VTSTRING) {
                    fprintf(stderr, "test node10 failed (step 4.4.%d)\n", i);
                    return 10;
                }
                if (strcmp(v.u.s, "hello there") != 0) {
                    fprintf(stderr, "test node10 failed (step 4.5.%d, %s)\n", 
			    i, v.u.s);
                    return 10;
                }
                break;
            case E4_VTBINARY:
                if (!n1.SetNthVertex("f1", i + 1, (const void *) "hello there",
                                    12)) {
                    fprintf(stderr, "test node10 failed (step 4.1.%d)\n", i);
                    return 10;
                }
                if (n1.VertexTypeByRank(i + 1) != E4_VTBINARY) {
                    fprintf(stderr, "test node10 failed (step 4.2.%d)\n", i);
                    return 10;
                }
                if (!n1.GetNthVertex("f1", i + 1, v)) {
                    fprintf(stderr, "test node10 failed (step 4.3.%d)\n", i);
                    return 10;
                }
                if (v.vertexType != E4_VTBINARY) {
                    fprintf(stderr, "test node10 failed (step 4.4.%d)\n", i);
                    return 10;
                }
                if (strcmp((const char *) v.u.b.bytes, "hello there") != 0) {
                    fprintf(stderr, "test node10 failed (step 4.5.%d)\n", i);
                    return 10;
                }
                if (v.u.b.nbytes != 12) {
                    fprintf(stderr, "test node10 failed (step 4.6.%d)\n", i);
                    return 10;
                }
                break;
            default:
                fprintf(stderr, "test node10 failed (step 4.%d)\n", i);
                return 10;
            }
        }
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node10 failed (step 5)\n");
	    return 10;
	}
    }

    return 0;
}

static int
test_node11()
{
    e4_Node n;
    int i = 0, j = 0, k = 0, rank = 0, nbytes = 0;
    double f = 0.0;
    const char *ss;
    const void *v;

    /*
     * Test e4_Node::SetNthVertex, e4_Node::GetNthVertex 
     * with various types, and e4_Node::VertexTypeByRank.
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node11 failed (step 0)\n");
            return 11;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node11 failed (step 1)\n");
            return 11;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node11 failed (step 2)\n");
            return 11;
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
            if (!n.AddVertex("f1", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test node11 failed (step 3.1.%d)\n", i);
                return 11;
            }
            if (n.VertexCount() != i + 1) {
                fprintf(stderr, "test node11 failed (step 3.2.%d)\n", i);
                return 11;
            }
            if (rank != i + 1) {
                fprintf(stderr, "test node11 failed (step 3.3.%d)\n", i);
                return 11;
            }
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
            j = i % (int) E4_VTLASTVERTEXTYPE;
            switch ((e4_VertexType) j) {
            case E4_VTNODE:
            case E4_VTINT:
                if (!n.SetNthVertex("f1", i + 1, i)) {
                    fprintf(stderr, "test node11 failed (step 4.1.%d)\n", i);
                    return 11;
                }
                if (n.VertexTypeByRank(i + 1) != E4_VTINT) {
                    fprintf(stderr, "test node11 failed (step 4.2.%d)\n", i);
                    return 11;
                }
                if (!n.GetNthVertex("f1", i + 1, k)) {
                    fprintf(stderr, "test node11 failed (step 4.3.%d)\n", i);
                    return 11;
                }
                if (k != i) {
                    fprintf(stderr, "test node11 failed (step 4.4.%d)\n", i);
                    return 11;
                }
                break;
            case E4_VTDOUBLE:
                if (!n.SetNthVertex("f1", i + 1, (double) 3.145678)) {
                    fprintf(stderr, "test node11 failed (step 4.1.%d)\n", i);
                    return 11;
                }
                if (n.VertexTypeByRank(i + 1) != E4_VTDOUBLE) {
                    fprintf(stderr, "test node11 failed (step 4.2.%d)\n", i);
                    return 11;
                }
                if (!n.GetNthVertex("f1", i + 1, f)) {
                    fprintf(stderr, "test node11 failed (step 4.3.%d)\n", i);
                    return 11;
                }
                break;
            case E4_VTSTRING:
                if (!n.SetNthVertex("f1", i + 1, "hello there")) {
                    fprintf(stderr, "test node11 failed (step 4.1.%d)\n", i);
                    return 11;
                }
                if (n.VertexTypeByRank(i + 1) != E4_VTSTRING) {
                    fprintf(stderr, "test node11 failed (step 4.2.%d)\n", i);
                    return 11;
                }
                if (!n.GetNthVertex("f1", i + 1, ss)) {
                    fprintf(stderr, "test node11 failed (step 4.3.%d)\n", i);
                    return 11;
                }
                if (strcmp("hello there", ss) != 0) {
                    fprintf(stderr, "test node11 failed (step 4.4.%d)\n", i);
                    return 11;
                }
                break;
            case E4_VTBINARY:
                if (!n.SetNthVertex("f1", i + 1, (const void *) "hello there",
                                   12)) {
                    fprintf(stderr, "test node11 failed (step 4.1.%d)\n", i);
                    return 11;
                }
                if (n.VertexTypeByRank(i + 1) != E4_VTBINARY) {
                    fprintf(stderr, "test node11 failed (step 4.2.%d)\n", i);
                    return 11;
                }
                if (!n.GetNthVertex("f1", i + 1, v, nbytes)) {
                    fprintf(stderr, "test node11 failed (step 4.3.%d)\n", i);
                    return 11;
                }
                if (strcmp((const char *) v, "hello there") != 0) {
                    fprintf(stderr, "test node11 failed (step 4.4.%d)\n", i);
                    return 11;
                }
                if (nbytes != 12) {
                    fprintf(stderr, "test node11 failed (step 4.5.%d)\n", i);
                    return 11;
                }
                break;
            default:
                fprintf(stderr, "test node11 failed (step 4.%d)\n", i);
                return 11;
            }
        }
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node11 failed (step 5)\n");
	    return 11;
	}
    }

    return 0;
}

static int
test_node12()
{
    e4_Node n;
    int i = 0, j = 0, k = 0, rank = 0, nbytes = 0;
    double f = 0.0;
    const char *ss;
    const void *v;
    char nb[32];

    /*
     * Test e4_Node::SetVertex, e4_Node::GetVertexByRank with 
     * various types, and e4_Node::VertexTypeByRank.
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node12 failed (step 0)\n");
            return 12;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node12 failed (step 1)\n");
            return 12;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test node12 failed (step 2)\n");
	    return 12;
	}
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
            sprintf(nb, "f%d", i);
            if (!n.AddVertex(nb, E4_IOLAST, rank, i)) {
                fprintf(stderr, "test node12 failed (step 3.1.%d)\n", i);
                return 12;
            }
            if (n.VertexCount() != i + 1) {
                fprintf(stderr, "test node12 failed (step 3.2.%d)\n", i);
                return 12;
            }
            if (rank != i + 1) {
                fprintf(stderr, "test node12 failed (step 3.3.%d)\n", i);
                return 12;
            }
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
            sprintf(nb, "f%d", i);
            j = i % (int) E4_VTLASTVERTEXTYPE;
            switch ((e4_VertexType) j) {
            case E4_VTNODE:
            case E4_VTINT:
                if (!n.SetVertex(nb, i)) {
                    fprintf(stderr, "test node12 failed (step 4.1.%d)\n", i);
                    return 12;
                }
                if (n.VertexTypeByRank(i + 1) != E4_VTINT) {
                    fprintf(stderr, "test node12 failed (step 4.2.%d)\n", i);
                    return 12;
                }
                if (!n.GetVertexByRank(i + 1, k)) {
                    fprintf(stderr, "test node12 failed (step 4.3.%d)\n", i);
                    return 12;
                }
                if (k != i) {
                    fprintf(stderr, "test node12 failed (step 4.4.%d)\n", i);
                    return 12;
                }
                break;
            case E4_VTDOUBLE:
                if (!n.SetVertex(nb, (double) 3.145678)) {
                    fprintf(stderr, "test node12 failed (step 4.1.%d)\n", i);
                    return 12;
                }
                if (n.VertexTypeByRank(i + 1) != E4_VTDOUBLE) {
                    fprintf(stderr, "test node12 failed (step 4.2.%d)\n", i);
                    return 12;
                }
                if (!n.GetVertexByRank(i + 1, f)) {
                    fprintf(stderr, "test node12 failed (step 4.3.%d)\n", i);
                    return 12;
                }
                break;
            case E4_VTSTRING:
                if (!n.SetVertex(nb, "hello there")) {
                    fprintf(stderr, "test node12 failed (step 4.1.%d)\n", i);
                    return 12;
                }
                if (n.VertexTypeByRank(i + 1) != E4_VTSTRING) {
                    fprintf(stderr, "test node12 failed (step 4.2.%d)\n", i);
                    return 12;
                }
                if (!n.GetVertexByRank(i + 1, ss)) {
                    fprintf(stderr, "test node12 failed (step 4.3.%d)\n", i);
                    return 12;
                }
                if (strcmp("hello there", ss) != 0) {
                    fprintf(stderr, "test node12 failed (step 4.4.%d)\n", i);
                    return 12;
                }
                break;
            case E4_VTBINARY:
                if (!n.SetVertex(nb, (const void *) "hello there", 12)) {
                    fprintf(stderr, "test node12 failed (step 4.1.%d)\n", i);
                    return 12;
                }
                if (n.VertexTypeByRank(i + 1) != E4_VTBINARY) {
                    fprintf(stderr, "test node12 failed (step 4.2.%d)\n", i);
                    return 12;
                }
                if (!n.GetVertexByRank(i + 1, v, nbytes)) {
                    fprintf(stderr, "test node12 failed (step 4.3.%d)\n", i);
                    return 12;
                }
                if (strcmp((const char *) v, "hello there") != 0) {
                    fprintf(stderr, "test node12 failed (step 4.4.%d)\n", i);
                    return 12;
                }
                if (nbytes != 12) {
                    fprintf(stderr, "test node12 failed (step 4.5.%d)\n", i);
                    return 12;
                }
                break;
            default:
                fprintf(stderr, "test node12 failed (step 4.%d)\n", i);
                return 12;
            }
        }
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node12 failed (step 5)\n");
	    return 12;
	}
    }

    return 0;
}

static int
test_node13()
{
    e4_Node n;
    int i = 0, j = 0, rank = 0;
    e4_Value v;
    char nb[32];

    /*
     * Test e4_Node::SetVertex, e4_Node::GetVertexByRank with e4_Value
     * and e4;
     */

    {
        e4_Storage s;

        if (!clean_storage("foo.db", s) || !s.IsValid()) {
            fprintf(stderr, "test node13 failed (step 0)\n");
            return 13;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node13 failed (step 1)\n");
            return 13;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node13 failed (step 2)\n");
            return 13;
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
            sprintf(nb, "f%d", i);
            if (!n.AddVertex(nb, E4_IOLAST, rank, i)) {
                fprintf(stderr, "test node13 failed (step 3.1.%d)\n", i);
                return 13;
            }
            if (n.VertexCount() != i + 1) {
                fprintf(stderr, "test node13 failed (step 3.2.%d)\n", i);
                return 13;
            }
            if (rank != i + 1) {
                fprintf(stderr, "test node13 failed (step 3.3.%d)\n", i);
                return 13;
            }
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
            sprintf(nb, "f%d", i);
            j = i % (int) E4_VTLASTVERTEXTYPE;
            switch ((e4_VertexType) j) {
            case E4_VTNODE:
            case E4_VTINT:
                if (!n.SetVertex(nb, i)) {
                    fprintf(stderr, "test node13 failed (step 4.1.%d)\n", i);
                    return 13;
                }
                if (n.VertexTypeByRank(i + 1) != E4_VTINT) {
                    fprintf(stderr, "test node13 failed (step 4.2.%d)\n", i);
                    return 13;
                }
                if (!n.GetVertexByRank(i + 1, v)) {
                    fprintf(stderr, "test node13 failed (step 4.3.%d)\n", i);
                    return 13;
                }
                if (v.vertexType != E4_VTINT) {
                    fprintf(stderr, "test node13 failed (step 4.4.%d)\n", i);
                    return 13;
                }
                if (v.u.i != i) {
                    fprintf(stderr, "test node13 failed (step 4.5.%d)\n", i);
                    return 13;
                }
                break;
            case E4_VTDOUBLE:
                if (!n.SetVertex(nb, (double) 3.145678)) {
                    fprintf(stderr, "test node13 failed (step 4.1.%d)\n", i);
                    return 13;
                }
                if (n.VertexTypeByRank(i + 1) != E4_VTDOUBLE) {
                    fprintf(stderr, "test node13 failed (step 4.2.%d)\n", i);
		return 13;
                }
                if (!n.GetVertexByRank(i + 1, v)) {
                    fprintf(stderr, "test node13 failed (step 4.3.%d)\n", i);
                    return 13;
                }
                if (v.vertexType != E4_VTDOUBLE) {
                    fprintf(stderr, "test node13 failed (step 4.5.%d)\n", i);
                    return 13;
                }
                break;
            case E4_VTSTRING:
                if (!n.SetVertex(nb, "hello there")) {
                    fprintf(stderr, "test node13 failed (step 4.1.%d)\n", i);
                    return 13;
                }
                if (n.VertexTypeByRank(i + 1) != E4_VTSTRING) {
                    fprintf(stderr, "test node13 failed (step 4.2.%d)\n", i);
                    return 13;
                }
                if (!n.GetVertexByRank(i + 1, v)) {
                    fprintf(stderr, "test node13 failed (step 4.3.%d)\n", i);
                    return 13;
                }
                if (v.vertexType != E4_VTSTRING) {
                    fprintf(stderr, "test node13 failed (step 4.4.%d)\n", i);
                    return 13;
                }
                if (strcmp("hello there", v.u.s) != 0) {
                    fprintf(stderr, "test node13 failed (step 4.5.%d)\n", i);
                    return 13;
                }
                break;
            case E4_VTBINARY:
                if (!n.SetVertex(nb, (const void *) "hello there", 12)) {
                    fprintf(stderr, "test node13 failed (step 4.1.%d)\n", i);
                    return 13;
                }
                if (n.VertexTypeByRank(i + 1) != E4_VTBINARY) {
                    fprintf(stderr, "test node13 failed (step 4.2.%d)\n", i);
                    return 13;
                }
                if (!n.GetVertexByRank(i + 1, v)) {
                    fprintf(stderr, "test node13 failed (step 4.3.%d)\n", i);
                    return 13;
                }
                if (v.vertexType != E4_VTBINARY) {
                    fprintf(stderr, "test node13 failed (step 4.4.%d)\n", i);
                    return 13;
                }
                if (v.u.b.nbytes != 12) {
                    fprintf(stderr, "test node13 failed (step 4.5.%d)\n", i);
                    return 13;
                }
                if (strcmp((const char *) v.u.b.bytes, "hello there") != 0) {
                    fprintf(stderr, "test node13 failed (step 4.6.%d)\n", i);
                    return 13;
                }
                break;
            default:
                fprintf(stderr, "test node13 failed (step 4.%d)\n", i);
                return 13;
            }
        }
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node13 failed (step 5)\n");
	    return 13;
	}
    }

    return 0;
}

static int
test_node14()
{
    e4_Node n;
    int i = 0, j = 0, k = 0, rank = 0, nbytes = 0;
    double f = 0.0;
    const char *ss;
    const void *bytes;

    /*
     * Test e4_Node::SetVertexByRank, e4_Node::GetNthVertex
     * and e4;
     */

    {
        e4_Storage s;

        if (!clean_storage("foo.db", s) || !s.IsValid()) {
            fprintf(stderr, "test node14 failed (step 0)\n");
            return 14;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node14 failed (step 1)\n");
            return 14;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node14 failed (step 2)\n");
            return 14;
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
            if (!n.AddVertex("f1", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test node14 failed (step 3.1.%d)\n", i);
                return 14;
            }
            if (n.VertexCount() != i + 1) {
                fprintf(stderr, "test node14 failed (step 3.2.%d)\n", i);
                return 14;
            }
            if (rank != i + 1) {
                fprintf(stderr, "test node14 failed (step 3.3.%d)\n", i);
                return 14;
            }
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
            j = i % (int) E4_VTLASTVERTEXTYPE;
            switch ((e4_VertexType) j) {
            case E4_VTNODE:
            case E4_VTINT:
                if (!n.SetVertexByRank(i + 1, i)) {
                    fprintf(stderr, "test node14 failed (step 4.1.%d)\n", i);
                    return 14;
                }
                if (n.VertexTypeByRank(i + 1) != E4_VTINT) {
                    fprintf(stderr, "test node14 failed (step 4.2.%d)\n", i);
                    return 14;
                }
                if (!n.GetNthVertex("f1", i + 1, k)) {
                    fprintf(stderr, "test node14 failed (step 4.3.%d)\n", i);
                    return 14;
                }
                if (k != i) {
                    fprintf(stderr, "test node14 failed (step 4.4.%d)\n", i);
                    return 14;
                }
                break;
            case E4_VTDOUBLE:
                if (!n.SetVertexByRank(i + 1, (double) 3.14567)) {
                    fprintf(stderr, "test node14 failed (step 4.1.%d)\n", i);
                    return 14;
                }
                if (n.VertexTypeByRank(i + 1) != E4_VTDOUBLE) {
                    fprintf(stderr, "test node14 failed (step 4.2.%d)\n", i);
                    return 14;
                }
                if (!n.GetNthVertex("f1", i + 1, f)) {
                    fprintf(stderr, "test node14 failed (step 4.3.%d)\n", i);
                    return 14;
                }
                break;
            case E4_VTSTRING:
                if (!n.SetVertexByRank(i + 1, "hello there")) {
                    fprintf(stderr, "test node14 failed (step 4.1.%d)\n", i);
                    return 14;
                }
                if (n.VertexTypeByRank(i + 1) != E4_VTSTRING) {
                    fprintf(stderr, "test node14 failed (step 4.2.%d)\n", i);
                    return 14;
                }
                if (!n.GetNthVertex("f1", i + 1, ss)) {
                    fprintf(stderr, "test node14 failed (step 4.3.%d)\n", i);
                    return 14;
                }
                if (strcmp(ss, "hello there") != 0) {
                    fprintf(stderr, "test node14 failed (step 4.4.%d)\n", i);
                    return 14;
                }
                break;
            case E4_VTBINARY:
                if (!n.SetVertexByRank(i + 1, (const void *) "hello there",
                                      12)) {
                    fprintf(stderr, "test node14 failed (step 4.1.%d)\n", i);
                    return 14;
                }
                if (n.VertexTypeByRank(i + 1) != E4_VTBINARY) {
                    fprintf(stderr, "test node14 failed (step 4.2.%d)\n", i);
                    return 14;
                }
                if (!n.GetNthVertex("f1", i + 1, bytes, nbytes)) {
                    fprintf(stderr, "test node14 failed (step 4.3.%d)\n", i);
                    return 14;
                }
                if (strcmp((const char *) bytes, "hello there") != 0) {
                    fprintf(stderr, "test node14 failed (step 4.4.%d)\n", i);
                    return 14;
                }
                if (nbytes != 12) {
                    fprintf(stderr, "test node14 failed (step 4.5.%d)\n", i);
                    return 14;
                }
                break;
            default:
                fprintf(stderr, "test node14 failed (step 4.%d)\n", i);
                return 14;
            }
        }
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node14 failed (step 5)\n");
	    return 14;
	}
    }

    return 0;
}

static int
test_node15()
{
    e4_Node n;
    int i = 0, j = 0, k = 0, rank = 0, nbytes = 0;
    double f = 0.0;
    const char *ss;
    const void *bytes;

    /*
     * Testing e4_Node::AddVertex.
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node15 failed (step 0)\n");
            return 15;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node15 failed (step 1)\n");
            return 15;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node15 failed (step 2)\n");
            return 15;
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
            j = i % (int) E4_VTLASTVERTEXTYPE;
            switch ((e4_VertexType) j) {
            case E4_VTNODE:
            case E4_VTINT:
                if (!n.AddVertex("f1", E4_IOLAST, rank, i)) {
                    fprintf(stderr, "test node15 failed (step 3.1.%d)\n", i);
                    return 15;
                }
                if (!n.GetVertexByRank(rank, k)) {
                    fprintf(stderr, "test node15 failed (step 3.2.%d)\n", i);
                    return 15;
                }
                if (k != i) {
                    fprintf(stderr, "test node15 failed (step 3.3.%d)\n", i);
                    return 15;
                }
                break;
            case E4_VTDOUBLE:
                if (!n.AddVertex("f1", E4_IOLAST, rank, (double) 3.145678)) {
                    fprintf(stderr, "test node15 failed (step 3.1.%d)\n", i);
                    return 15;
                }
                if (!n.GetVertexByRank(rank, f)) {
                    fprintf(stderr, "test node15 failed (step 3.2.%d)\n", i);
                    return 15;
                }
                break;
            case E4_VTSTRING:
                if (!n.AddVertex("f1", E4_IOLAST, rank, "hello there")) {
                    fprintf(stderr, "test node15 failed (step 3.1.%d)\n", i);
                    return 15;
                }
                if (!n.GetVertexByRank(rank, ss)) {
                    fprintf(stderr, "test node15 failed (step 3.2.%d)\n", i);
                    return 15;
                }
                if (strcmp(ss, "hello there") != 0) {
                    fprintf(stderr, "test node15 failed (step 3.3.%d)\n", i);
                    return 15;
                }
                break;
            case E4_VTBINARY:
                if (!n.AddVertex("f1", E4_IOLAST, rank,
                                (const void *) "hello there", 12)) {
                    fprintf(stderr, "test node15 failed (step 3.1.%d)\n", i);
                    return 15;
                }
                if (!n.GetVertexByRank(rank, bytes, nbytes)) {
                    fprintf(stderr, "test node15 failed (step 3.2.%d)\n", i);
                    return 15;
                }
                if (strcmp((const char *) bytes, "hello there") != 0) {
                    fprintf(stderr, "test node15 failed (step 3.3.%d)\n", i);
                    return 15;
                }
                if (nbytes != 12) {
                    fprintf(stderr, "test node15 failed (step 3.4.%d)\n", i);
                    return 15;
                }
                break;
            }
        }
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node15 failed (step 4)\n");
	    return 15;
	}
    }

    return 0;
}

static int
test_node16()
{
    e4_Node n;
    e4_Vertex f;
    int i = 0, j = 0, rank = 0;

    /*
     * Test e4_Node::AddVertexRef.
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node16 failed (step 0)\n");
            return 16;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node16 failed (step 1)\n");
            return 16;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node16 failed (step 2)\n");
            return 16;
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
            j = i % (int) E4_VTLASTVERTEXTYPE;
            switch ((e4_VertexType) j) {
            case E4_VTNODE:
            case E4_VTINT:
                if (!n.AddVertexRef("f1", E4_IOLAST, rank, i, f)) {
                    fprintf(stderr, "test node16 failed (step 3.1.%d)\n", i);
                    return 16;
                }
                if (!f.IsValid()) {
                    fprintf(stderr, "test node16 failed (step 3.2.%d)\n", i);
                    return 16;
                }
                if (rank != i + 1) {
                    fprintf(stderr, "test node16 failed (step 3.3.%d)\n", i);
                    return 16;
                }
                if (n.VertexCount() != i + 1) {
                    fprintf(stderr, "test node16 failed (step 3.4.%d)\n", i);
                    return 16;
                }
                break;
            case E4_VTDOUBLE:
                if (!n.AddVertexRef("f1", E4_IOLAST, rank, (double) 3.16, f)) {
                    fprintf(stderr, "test node16 failed (step 3.1.%d)\n", i);
                    return 16;
                }
                if (!f.IsValid()) {
                    fprintf(stderr, "test node16 failed (step 3.2.%d)\n", i);
                    return 16;
                }
                if (rank != i + 1) {
                    fprintf(stderr, "test node16 failed (step 3.3.%d)\n", i);
                    return 16;
                }
                if (n.VertexCount() != i + 1) {
                    fprintf(stderr, "test node16 failed (step 3.4.%d)\n", i);
                    return 16;
                }
                break;
            case E4_VTSTRING:
                if (!n.AddVertexRef("f1", E4_IOLAST, rank, "hello there", f)) {
                    fprintf(stderr, "test node16 failed (step 3.1.%d)\n", i);
                    return 16;
                }
                if (!f.IsValid()) {
                    fprintf(stderr, "test node16 failed (step 3.2.%d)\n", i);
                    return 16;
                }
                if (rank != i + 1) {
                    fprintf(stderr, "test node16 failed (step 3.3.%d)\n", i);
                    return 16;
                }
                if (n.VertexCount() != i + 1) {
                    fprintf(stderr, "test node16 failed (step 3.4.%d)\n", i);
                    return 16;
                }
                break;
            case E4_VTBINARY:
                if (!n.AddVertexRef("f1", E4_IOLAST, rank,
                                   (const void *) "hello there", 12, f)) {
                    fprintf(stderr, "test node16 failed (step 3.1.%d)\n", i);
                    return 16;
                }
                if (!f.IsValid()) {
                    fprintf(stderr, "test node16 failed (step 3.2.%d)\n", i);
                    return 16;
                }
                if (rank != i + 1) {
                    fprintf(stderr, "test node16 failed (step 3.3.%d)\n", i);
                    return 16;
                }
                if (n.VertexCount() != i + 1) {
                    fprintf(stderr, "test node16 failed (step 3.4.%d)\n", i);
                    return 16;
                }
                break;
            default:
                fprintf(stderr, "test node16 failed (step 3.%d)\n", i);
                return 16;
            }
        }
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node16 failed (step 4)\n");
	    return 16;
	}
    }

    return 0;
}

static int
test_node17()
{
    e4_Node n1, n2, n3;
    e4_Vertex f;
    int rank = 0;

    /*
     * Testing e4_Node::AddNodeRef.
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node17 failed (step 0)\n");
            return 17;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node17 failed (step 1)\n");
            return 17;
        }
	if (!s.GetRootNode(n1) || !n1.IsValid() || !n1.IsRoot()) {
            fprintf(stderr, "test node17 failed (step 2)\n");
            return 17;
        }
        if (!n1.AddNodeRef("f1", E4_IOFIRST, rank, n2, f)) {
            fprintf(stderr, "test node17 failed (step 3)\n");
            return 17;
        }
        if (!n2.IsValid()) {
            fprintf(stderr, "test node17 failed (step 4)\n");
            return 17;
        }
        if (!n2.GetParent(n3)) {
            fprintf(stderr, "test node17 failed (step 5)\n");
            return 17;
        }
        if (!n3.IsValid()) {
            fprintf(stderr, "test node17 failed (step 6)\n");
            return 17;
        }
        if (n1 != n3) {
            fprintf(stderr, "test node17 failed (step 7)\n");
            return 17;
        }
        if (!f.IsValid()) {
            fprintf(stderr, "test node17 failed (step 8)\n");
            return 17;
        }
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node17 failed (step 9)\n");
	    return 17;
	}
    }

    return 0;
}
    
static int
test_node18()
{
    e4_Node n;
    int i = 0, j = 0, rank = 0;
    char buf[32];

    /*
     * Testing e4_Node::GetVertex().
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node18 failed (step 0)\n");
	    return 18;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node18 failed (step 1)\n");
	    return 18;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test node18 failed (step 2)\n");
	    return 18;
	}
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!n.AddVertex(buf, E4_IOLAST, rank, i + 1)) {
		fprintf(stderr, "test node18 failed (step 3.1.%d)\n", i);
		return 18;
	    }
	    if (rank != i + 1) {
		fprintf(stderr, "test node18 failed (step 3.2.%d)\n", i);
		return 18;
	    }
	    if (n.VertexCount() != i + 1) {
		fprintf(stderr, "test node18 failed (step 3.3.%d)\n", i);
		return 18;
	    }
	}
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!n.GetVertex(buf, j)) {
		fprintf(stderr, "test node18 failed (step 4.1.%d)\n", i);
		return 18;
	    }
	    if (j != i + 1) {
		fprintf(stderr, "test node18 failed (step 4.2.%d)\n", i);
		return 18;
	    }
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node18 failed (step 5)\n");
	    return 18;
	}
    }

    return 0;
}
    
static int
test_node19()
{
    e4_Node n;
    int i = 0, j = 0, rank = 0;
    char buf[32];

    /*
     * Testing e4_Node::DetachVertex().
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node19 failed (step 0)\n");
	    return 19;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node19 failed (step 1)\n");
	    return 19;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test node19 failed (step 2)\n");
	    return 19;
	}
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!n.AddVertex(buf, E4_IOLAST, rank, i + 1)) {
		fprintf(stderr, "test node19 failed (step 3.1.%d)\n", i);
		return 19;
	    }
	    if (rank != i + 1) {
		fprintf(stderr, "test node19 failed (step 3.2.%d)\n", i);
		return 19;
	    }
	    if (n.VertexCount() != i + 1) {
		fprintf(stderr, "test node19 failed (step 3.3.%d)\n", i);
		return 19;
	    }
	}
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!n.GetVertex(buf, j)) {
		fprintf(stderr, "test node19 failed (step 4.1.%d)\n", i);
		return 19;
	    }
	    if (j != i + 1) {
		fprintf(stderr, "test node19 failed (step 4.2.%d)\n", i);
		return 19;
	    }
	}
	for (i = TN_VERTEXLIMIT; i > 0; i--) {
	    sprintf(buf, "f%d", i);
	    if (!n.DetachVertex(buf)) {
		fprintf(stderr, "test node19 failed (step 5.1.%d)\n", i);
		return 19;
	    }
	    if (n.GetVertex(buf, j)) {
		fprintf(stderr, "test node19 failed (step 5.2.%d), %d %d %s\n",
			i, j, n.VertexCount(), buf);
		return 19;
	    }
	    if (n.VertexCount() != i - 1) {
	        fprintf(stderr, "test node19 failed (step 5.3.%d) %d\n", 
			i, n.VertexCount());
		return 19;
	    }
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node19 failed (step 6)\n");
	    return 19;
	}
    }

    return 0;
}
    
static int
test_node20()
{
    e4_Node n;
    int i = 0, j = 0, rank = 0;
    char buf[32];

    /*
     * Testing e4_Node::DetachVertexByRank().
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node20 failed (step 0)\n");
	    return 20;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node20 failed (step 1)\n");
	    return 20;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test node20 failed (step 2)\n");
	    return 20;
	}
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!n.AddVertex(buf, E4_IOLAST, rank, i + 1)) {
		fprintf(stderr, "test node20 failed (step 3.1.%d)\n", i);
		return 20;
	    }
	    if (rank != i + 1) {
		fprintf(stderr, "test node20 failed (step 3.2.%d)\n", i);
		return 20;
	    }
	    if (n.VertexCount() != i + 1) {
		fprintf(stderr, "test node20 failed (step 3.3.%d)\n", i);
		return 20;
	    }
	}
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!n.GetVertex(buf, j)) {
		fprintf(stderr, "test node20 failed (step 4.1.%d)\n", i);
		return 20;
	    }
	    if (j != i + 1) {
		fprintf(stderr, "test node20 failed (step 4.2.%d)\n", i);
		return 20;
	    }
	}
	for (i = TN_VERTEXLIMIT; i > 0; i--) {
	    sprintf(buf, "f%d", i);
	    if (!n.DetachVertexByRank(i)) {
		fprintf(stderr, "test node20 failed (step 5.1.%d)\n", i);
		return 20;
	    }
	    if (n.GetVertex(buf, j)) {
		fprintf(stderr, "test node20 failed (step 5.2.%d), %d, %d\n", 
			i, j, n.VertexCount());
		return 20;
	    }
	    if (n.VertexCount() != i - 1) {
	        fprintf(stderr, "test node20 failed (step 5.3.%d)\n", i);
		return 20;
	    }
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node20 failed (step 6)\n");
	    return 20;
	}
    }

    return 0;
}
    
static int
test_node21()
{
    e4_Node n;
    e4_Vertex f;
    int i = 0, j = 0, rank = 0;
    char buf[32];
    char *ss = NULL;

    /*
     * Testing e4_Node::GetVertexRef().
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node21 failed (step 0)\n");
	    return 21;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node21 failed (step 1)\n");
	    return 21;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test node21 failed (step 2)\n");
	    return 21;
	}
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!n.AddVertex(buf, E4_IOLAST, rank, i + 1)) {
		fprintf(stderr, "test node21 failed (step 3.1.%d)\n", i);
		return 21;
	    }
	    if (rank != i + 1) {
		fprintf(stderr, "test node21 failed (step 3.2.%d)\n", i);
		return 21;
	    }
	    if (n.VertexCount() != i + 1) {
		fprintf(stderr, "test node21 failed (step 3.3.%d)\n", i);
		return 21;
	    }
	}
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!n.GetVertex(buf, j)) {
		fprintf(stderr, "test node21 failed (step 4.1.%d)\n", i);
		return 21;
	    }
	    if (j != i + 1) {
		fprintf(stderr, "test node21 failed (step 4.2.%d)\n", i);
		return 21;
	    }
	}
	for (i = TN_VERTEXLIMIT; i > 0; i--) {
	    sprintf(buf, "f%d", i);
	    if (!n.GetVertexRef(buf, f)) {
		fprintf(stderr, "test node21 failed (step 5.1.%d)\n", i);
		return 21;
	    }
	    if (!f.IsValid()) {
		fprintf(stderr, "test node21 failed (step 5.2.%d)\n", i);
		return 21;
	    }
	    ss = (char *) f.Name();
	    if (ss == NULL) {
		fprintf(stderr, "test node21 failed (step 5.3.%d)\n", i);
		return 21;
	    }
	    if (strcmp(buf, ss) != 0) {
		fprintf(stderr, "test node21 failed (step 5.4.%d, %s %s)\n",
			i, buf, ss);
		return 21;
	    }
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node21 failed (step 6)\n");
	    return 21;
	}
    }

    return 0;
}

static int
test_node22()
{
    e4_Node n;
    int i = 0, j = 0, rank = 0;

    /*
     * Test e4_Node::VertexType.
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node22 failed (step 0)\n");
            return 22;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node22 failed (step 1)\n");
            return 22;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node22 failed (step 2)\n");
            return 22;
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
            j = i % (int) E4_VTLASTVERTEXTYPE;
            switch ((e4_VertexType) j) {
            case E4_VTNODE:
            case E4_VTINT:
                if (!n.AddVertex("f1", E4_IOLAST, rank, i)) {
                    fprintf(stderr, "test node22 failed (step 3.1.%d)\n", i);
                    return 22;
                }
                if (rank != i + 1) {
                    fprintf(stderr, "test node22 failed (step 3.2.%d)\n", i);
                    return 22;
                }
                if (n.VertexCount() != i + 1) {
                    fprintf(stderr, "test node22 failed (step 3.3.%d)\n", i);
                    return 22;
                }
                break;
            case E4_VTDOUBLE:
                if (!n.AddVertex("f1", E4_IOLAST, rank, (double) 3.22)) {
                    fprintf(stderr, "test node22 failed (step 3.1.%d)\n", i);
                    return 22;
                }
                if (rank != i + 1) {
                    fprintf(stderr, "test node22 failed (step 3.2.%d)\n", i);
                    return 22;
                }
                if (n.VertexCount() != i + 1) {
                    fprintf(stderr, "test node22 failed (step 3.3.%d)\n", i);
                    return 22;
                }
                break;
            case E4_VTSTRING:
                if (!n.AddVertex("f1", E4_IOLAST, rank, "hello there")) {
                    fprintf(stderr, "test node22 failed (step 3.1.%d)\n", i);
                    return 22;
                }
                if (rank != i + 1) {
                    fprintf(stderr, "test node22 failed (step 3.2.%d)\n", i);
                    return 22;
                }
                if (n.VertexCount() != i + 1) {
                    fprintf(stderr, "test node22 failed (step 3.3.%d)\n", i);
                    return 22;
                }
                break;
            case E4_VTBINARY:
                if (!n.AddVertex("f1", E4_IOLAST, rank,
				(const void *) "hello there", 12)) {
                    fprintf(stderr, "test node22 failed (step 3.1.%d)\n", i);
                    return 22;
                }
                if (rank != i + 1) {
                    fprintf(stderr, "test node22 failed (step 3.2.%d)\n", i);
                    return 22;
                }
                if (n.VertexCount() != i + 1) {
                    fprintf(stderr, "test node22 failed (step 3.3.%d)\n", i);
                    return 22;
                }
                break;
            default:
                fprintf(stderr, "test node22 failed (step 3.%d)\n", i);
                return 22;
            }
        }
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
            j = i % (int) E4_VTLASTVERTEXTYPE;
	    if ((e4_VertexType) j == E4_VTNODE) {
		j = (int) E4_VTINT;
	    }
	    if ((e4_VertexType) j != n.VertexType("f1", i + 1)) {
	        fprintf(stderr, "test node22 failed (step 4.%d)\n", i);
		return 22;
	    }
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node22 failed (step 5)\n");
	    return 22;
	}
    }

    return 0;
}

static int
test_node23()
{
    e4_Node n;
    int i = 0, j = 0, rank = 0;

    /*
     * Test e4_Node::VertexTypeByRank.
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node23 failed (step 0)\n");
            return 23;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node23 failed (step 1)\n");
            return 23;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node23 failed (step 2)\n");
            return 23;
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
            j = i % (int) E4_VTLASTVERTEXTYPE;
            switch ((e4_VertexType) j) {
            case E4_VTNODE:
            case E4_VTINT:
                if (!n.AddVertex("f1", E4_IOLAST, rank, i)) {
                    fprintf(stderr, "test node23 failed (step 3.1.%d)\n", i);
                    return 23;
                }
                if (rank != i + 1) {
                    fprintf(stderr, "test node23 failed (step 3.2.%d)\n", i);
                    return 23;
                }
                if (n.VertexCount() != i + 1) {
                    fprintf(stderr, "test node23 failed (step 3.3.%d)\n", i);
                    return 23;
                }
                break;
            case E4_VTDOUBLE:
                if (!n.AddVertex("f1", E4_IOLAST, rank, (double) 3.23)) {
                    fprintf(stderr, "test node23 failed (step 3.1.%d)\n", i);
                    return 23;
                }
                if (rank != i + 1) {
                    fprintf(stderr, "test node23 failed (step 3.2.%d)\n", i);
                    return 23;
                }
                if (n.VertexCount() != i + 1) {
                    fprintf(stderr, "test node23 failed (step 3.3.%d)\n", i);
                    return 23;
                }
                break;
            case E4_VTSTRING:
                if (!n.AddVertex("f1", E4_IOLAST, rank, "hello there")) {
                    fprintf(stderr, "test node23 failed (step 3.1.%d)\n", i);
                    return 23;
                }
                if (rank != i + 1) {
                    fprintf(stderr, "test node23 failed (step 3.2.%d)\n", i);
                    return 23;
                }
                if (n.VertexCount() != i + 1) {
                    fprintf(stderr, "test node23 failed (step 3.3.%d)\n", i);
                    return 23;
                }
                break;
            case E4_VTBINARY:
                if (!n.AddVertex("f1", E4_IOLAST, rank,
				(const void *) "hello there", 12)) {
                    fprintf(stderr, "test node23 failed (step 3.1.%d)\n", i);
                    return 23;
                }
                if (rank != i + 1) {
                    fprintf(stderr, "test node23 failed (step 3.2.%d)\n", i);
                    return 23;
                }
                if (n.VertexCount() != i + 1) {
                    fprintf(stderr, "test node23 failed (step 3.3.%d)\n", i);
                    return 23;
                }
                break;
            default:
                fprintf(stderr, "test node23 failed (step 3.%d)\n", i);
                return 23;
            }
        }
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
            j = i % (int) E4_VTLASTVERTEXTYPE;
	    if ((e4_VertexType) j == E4_VTNODE) {
		j = (int) E4_VTINT;
	    }
	    if ((e4_VertexType) j != n.VertexTypeByRank(i + 1)) {
	        fprintf(stderr, "test node23 failed (step 4.%d)\n", i);
		return 23;
	    }
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node23 failed (step 5)\n");
	    return 23;
	}
    }

    return 0;
}

static int
test_node24()
{
    e4_Node n;
    int i = 0, rank = 0;
    char buf[32];
    const char *ss;

    /*
     * Test e4_Node::VertexName().
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node24 failed (step 0)\n");
            return 24;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node24 failed (step 1)\n");
            return 24;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node24 failed (step 2)\n");
            return 24;
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!n.AddVertex(buf, E4_IOLAST, rank, i)) {
		fprintf(stderr, "test node24 failed (step 3.1.%d)\n", i);
		return 24;
	    }
	    if (rank != i + 1) {
	        fprintf(stderr, "test node24 failed (step 3.2.%d)\n", i);
		return 24;
	    }
	    if (n.VertexCount() != i + 1) {
	        fprintf(stderr, "test node24 failed (step 3.3.%d)\n", i);
		return 24;
	    }
        }
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    ss = n.VertexName(i + 1);
	    if (ss == NULL) {
		fprintf(stderr, "test node24 failed (step 4.1.%d)\n", i);
		return 24;
	    }
	    if (strcmp(ss, buf) != 0) {
		fprintf(stderr, "test node24 failed (step 4.2.%d)\n", i);
		return 24;
	    }
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node24 failed (step 5)\n");
	    return 24;
	}
    }

    return 0;
}

static int
test_node25()
{
    e4_Node n;
    int i = 0, rank = 0;
    char buf[32];
    const char *ss;

    /*
     * Test e4_Node::RenameVertex().
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node25 failed (step 0)\n");
            return 25;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node25 failed (step 1)\n");
            return 25;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node25 failed (step 2)\n");
            return 25;
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!n.AddVertex(buf, E4_IOLAST, rank, i)) {
		fprintf(stderr, "test node25 failed (step 3.1.%d)\n", i);
		return 25;
	    }
	    if (rank != i + 1) {
	        fprintf(stderr, "test node25 failed (step 3.2.%d)\n", i);
		return 25;
	    }
	    if (n.VertexCount() != i + 1) {
	        fprintf(stderr, "test node25 failed (step 3.3.%d)\n", i);
		return 25;
	    }
        }
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    ss = n.VertexName(i + 1);
	    if (ss == NULL) {
		fprintf(stderr, "test node25 failed (step 4.1.%d)\n", i);
		return 25;
	    }
	    if (strcmp(ss, buf) != 0) {
		fprintf(stderr, "test node25 failed (step 4.2.%d)\n", i);
		return 25;
	    }
	}
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "g%d", i + 1);
	    if (!n.RenameVertex(i + 1, buf)) {
		fprintf(stderr, "test node25 failed (step 5.%d)\n", i);
		return 25;
	    }
	}
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "g%d", i + 1);
	    ss = n.VertexName(i + 1);
	    if (ss == NULL) {
		fprintf(stderr, "test node25 failed (step 6.1.%d)\n", i);
		return 25;
	    }
	    if (strcmp(ss, buf) != 0) {
		fprintf(stderr, "test node25 failed (step 6.2.%d)\n", i);
		return 25;
	    }
	}
    }
    if (n.IsValid()) {
	fprintf(stderr, "test node25 failed (step 7)\n");
	return 25;
    }
    {
        e4_Storage s("foo.db", E4_METAKIT);

        if (!s.IsValid()) {
            fprintf(stderr, "test node25 failed (step 8)\n");
            return 25;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node25 failed (step 9)\n");
            return 25;
        }
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "g%d", i + 1);
	    ss = n.VertexName(i + 1);
	    if (ss == NULL) {
		fprintf(stderr, "test node25 failed (step 10.1.%d)\n", i);
		return 25;
	    }
	    if (strcmp(ss, buf) != 0) {
		fprintf(stderr, "test node25 failed (step 10.2.%d)\n", i);
		return 25;
	    }
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node25 failed (step 11)\n");
	    return 25;
	}
    }

    return 0;
}

static int
test_node26()
{
    e4_Node n;
    int i = 0, rank = 0;
    char buf[32];

    /*
     * Test e4_Node::VertexRank().
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node26 failed (step 0)\n");
            return 26;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node26 failed (step 1)\n");
            return 26;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node26 failed (step 2)\n");
            return 26;
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!n.AddVertex(buf, E4_IOLAST, rank, i)) {
		fprintf(stderr, "test node26 failed (step 3.1.%d)\n", i);
		return 26;
	    }
	    if (rank != i + 1) {
	        fprintf(stderr, "test node26 failed (step 3.2.%d)\n", i);
		return 26;
	    }
	    if (n.VertexCount() != i + 1) {
	        fprintf(stderr, "test node26 failed (step 3.3.%d)\n", i);
		return 26;
	    }
        }
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    rank = n.VertexRank(buf);
	    if (rank == E4_VERTEXNOTFOUND) {
		fprintf(stderr, "test node26 failed (step 4.1.%d)\n", i);
		return 26;
	    }
	    if (rank != i + 1) {
		fprintf(stderr, "test node26 failed (step 4.2.%d)\n", i);
		return 26;
	    }
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node26 failed (step 5)\n");
	    return 26;
	}
    }

    return 0;
}

static int
test_node27()
{
    e4_Node n;
    int i = 0, rank = 0;
    char buf[32];

    /*
     * Test e4_Node::Exists().
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node27 failed (step 0)\n");
            return 27;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node27 failed (step 1)\n");
            return 27;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node27 failed (step 2)\n");
            return 27;
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!n.AddVertex(buf, E4_IOLAST, rank, i)) {
		fprintf(stderr, "test node27 failed (step 3.1.%d)\n", i);
		return 27;
	    }
	    if (rank != i + 1) {
	        fprintf(stderr, "test node27 failed (step 3.2.%d)\n", i);
		return 27;
	    }
	    if (n.VertexCount() != i + 1) {
	        fprintf(stderr, "test node27 failed (step 3.3.%d)\n", i);
		return 27;
	    }
        }
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!n.Exists(buf)) {
		fprintf(stderr, "test node27 failed (step 4.%d)\n", i);
		return 27;
	    }
	}
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "g%d", i + 1);
	    if (n.Exists(buf)) {
		fprintf(stderr, "test node27 failed (step 5.%d)\n", i);
		return 27;
	    }
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node27 failed (step 6)\n");
	    return 27;
	}
    }

    return 0;
}

static int
test_node29()
{
    e4_Node n, sn;
    int i = 0, rank = 0;
    char buf[32];

    /*
     * Test e4_Node::GetRankInParent(), e4_Node::IsRoot().
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node29 failed (step 0)\n");
            return 29;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node29 failed (step 1)\n");
            return 29;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node29 failed (step 2)\n");
            return 29;
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!n.AddVertex(buf, E4_IOLAST, rank, i)) {
		fprintf(stderr, "test node29 failed (step 3.1.%d)\n", i);
		return 29;
	    }
	    if (rank != i + 1) {
	        fprintf(stderr, "test node29 failed (step 3.2.%d)\n", i);
		return 29;
	    }
	    if (n.VertexCount() != i + 1) {
	        fprintf(stderr, "test node29 failed (step 3.3.%d)\n", i);
		return 29;
	    }
        }
	if (!n.SetNodeByRank(25, sn)) {
	    fprintf(stderr, "test node29 failed (step 4)\n");
	    return 29;
	}
	if (!sn.IsValid()) {
	    fprintf(stderr, "test node29 failed (step 5)\n");
	    return 29;
	}
	rank = sn.GetRankInParent();
	if (rank == E4_NODENOTFOUND) {
	    fprintf(stderr, "test node29 failed (step 6)\n");
	    return 29;
	}
	if (rank != 25) {
	    fprintf(stderr, "test node29 failed (step 7)\n");
	    return 29;
	}
	if (sn.IsRoot()) {
	    fprintf(stderr, "test node29 failed (step 8)\n");
	    return 29;
	}
	if (!n.IsRoot()) {
	    fprintf(stderr, "test node29 failed (step 9)\n");
	    return 29;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node29 failed (step 10)\n");
	    return 29;
	}
    }

    return 0;
}

static int
test_node30()
{
    e4_Node n, sn;
    int i = 0, rank = 0;
    char buf[32];
    const char *ss;

    /*
     * Test e4_Node::GetNameInParent().
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node30 failed (step 0)\n");
            return 30;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node30 failed (step 1)\n");
            return 30;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node30 failed (step 2)\n");
            return 30;
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!n.AddVertex(buf, E4_IOLAST, rank, i)) {
		fprintf(stderr, "test node30 failed (step 3.1.%d)\n", i);
		return 30;
	    }
	    if (rank != i + 1) {
	        fprintf(stderr, "test node30 failed (step 3.2.%d)\n", i);
		return 30;
	    }
	    if (n.VertexCount() != i + 1) {
	        fprintf(stderr, "test node30 failed (step 3.3.%d)\n", i);
		return 30;
	    }
        }
	if (!n.SetNodeByRank(25, sn)) {
	    fprintf(stderr, "test node30 failed (step 4)\n");
	    return 30;
	}
	if (!sn.IsValid()) {
	    fprintf(stderr, "test node30 failed (step 5)\n");
	    return 30;
	}
	ss = sn.GetNameInParent();
	if (ss == NULL) {
	    fprintf(stderr, "test node30 failed (step 6)\n");
	    return 30;
	}
	if (strcmp(ss, "f25") != 0) {
	    fprintf(stderr, "test node30 failed (step 7)\n");
	    return 30;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node30 failed (step 8)\n");
	    return 30;
	}
    }

    return 0;
}

static int
test_node31()
{
    e4_Node n, sn;
    int i = 0, rank = 0;
    char buf[32];

    /*
     * Test e4_Node::GetStorage().
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node31 failed (step 0)\n");
            return 31;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node31 failed (step 1)\n");
            return 31;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node31 failed (step 2)\n");
            return 31;
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!n.AddVertex(buf, E4_IOLAST, rank, i)) {
		fprintf(stderr, "test node31 failed (step 3.1.%d)\n", i);
		return 31;
	    }
	    if (rank != i + 1) {
	        fprintf(stderr, "test node31 failed (step 3.2.%d)\n", i);
		return 31;
	    }
	    if (n.VertexCount() != i + 1) {
	        fprintf(stderr, "test node31 failed (step 3.3.%d)\n", i);
		return 31;
	    }
        }
	if (!n.SetNodeByRank(25, sn)) {
	    fprintf(stderr, "test node31 failed (step 4)\n");
	    return 31;
	}
	if (!sn.IsValid()) {
	    fprintf(stderr, "test node31 failed (step 5)\n");
	    return 31;
	}

	e4_Storage s1;

	if (!n.GetStorage(s1)) {
	    fprintf(stderr, "test node31 failed (step 6)\n");
	    return 31;
	}
	if (!s1.IsValid()) {
	    fprintf(stderr, "test node31 failed (step 7)\n");
	    return 31;
	}
	if (s1 != s) {
	    fprintf(stderr, "test node31 failed (step 8)\n");
	    return 31;
	}
	if (!sn.GetStorage(s1)) {
	    fprintf(stderr, "test node31 failed (step 9)\n");
	    return 31;
	}
	if (!s1.IsValid()) {
	    fprintf(stderr, "test node31 failed (step 10)\n");
	    return 31;
	}
	if (s1 != s) {
	    fprintf(stderr, "test node31 failed (step 11)\n");
	    return 31;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node31 failed (step 12)\n");
	    return 31;
	}
    }

    return 0;
}

static int
test_node32()
{
    e4_Node n, sn;
    e4_NodeUniqueID nuid1, nuid2, tnuid;
    int i = 0, rank = 0;
    char buf[32];

    /*
     * Test e4_Node::GetUniqueID().
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node32 failed (step 0)\n");
            return 32;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node32 failed (step 1)\n");
            return 32;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node32 failed (step 2)\n");
            return 32;
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!n.AddVertex(buf, E4_IOLAST, rank, i)) {
		fprintf(stderr, "test node32 failed (step 3.1.%d)\n", i);
		return 32;
	    }
	    if (rank != i + 1) {
	        fprintf(stderr, "test node32 failed (step 3.2.%d)\n", i);
		return 32;
	    }
	    if (n.VertexCount() != i + 1) {
	        fprintf(stderr, "test node32 failed (step 3.3.%d)\n", i);
		return 32;
	    }
        }
	if (!n.SetNodeByRank(25, sn)) {
	    fprintf(stderr, "test node32 failed (step 4)\n");
	    return 32;
	}
	if (!sn.IsValid()) {
	    fprintf(stderr, "test node32 failed (step 5)\n");
	    return 32;
	}
	(void) n.GetUniqueID(nuid1);
	(void) sn.GetUniqueID(nuid2);
	if (nuid1 == nuid2) {
	    fprintf(stderr, "test node32 failed (step 6)\n");
	    return 32;
	}
    }
    if (n.IsValid() || sn.IsValid()) {
	fprintf(stderr, "test node32 failed (step 7)\n");
	return 32;
    }
    {
        e4_Storage s("foo.db", E4_METAKIT);

        if (!s.IsValid()) {
            fprintf(stderr, "test node32 failed (step 8)\n");
            return 32;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node32 failed (step 9)\n");
            return 32;
        }
	if (!n.GetVertexByRank(25, sn)) {
	    fprintf(stderr, "test node32 failed (step 10)\n");
	    return 32;
	}
	if (!sn.IsValid()) {
	    fprintf(stderr, "test node32 failed (step 11)\n");
	    return 32;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node32 failed (step 12)\n");
	    return 32;
	}
    }

    return 0;
}

static int
test_node33()
{
    e4_Node n, sn, pn;
    e4_Vertex v;
    int i = 0, rank = 0, oldState = 0, newState = 0;
    char buf[32];
    e4_Node ssns[TN_VERTEXLIMIT];

    /*
     * Testing e4_Node::Detach(), e4_Node::IsValid().
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node33 failed (step 0)\n");
            return 33;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node33 failed (step 1)\n");
            return 33;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node33 failed (step 2)\n");
            return 33;
        }
        for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!n.AddVertex(buf, E4_IOLAST, rank, i)) {
		fprintf(stderr, "test node33 failed (step 3.1.%d)\n", i);
		return 33;
	    }
	    if (rank != i + 1) {
	        fprintf(stderr, "test node33 failed (step 3.2.%d) %d\n", 
			i, rank);
		return 33;
	    }
	    if (n.VertexCount() != i + 1) {
	        fprintf(stderr, "test node33 failed (step 3.3.%d)\n", i);
		return 33;
	    }
        }
	if (!n.SetNodeByRank(11, sn)) {
	    fprintf(stderr, "test node33 failed (step 4)\n");
	    return 33;
	}
	if (!n.GetVertexRefByRank(11, v) || (!v.IsValid())) {
	    fprintf(stderr, "test node33 failed (step 5)\n");
	    return 33;
	}
	if (!sn.IsValid()) {
	    fprintf(stderr, "test node33 failed (step 6)\n");
	    return 33;
	}
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i + 1);
	    if (!sn.AddNode(buf, E4_IOLAST, rank, ssns[i])) {
		fprintf(stderr, "test node33 failed (step 7.1.%d)\n", i);
		return 33;
	    }
	    if (!ssns[i].IsValid()) {
		fprintf(stderr, "test node33 failed (step 7.2.%d)\n", i);
		return 33;
	    }
	    if (sn.VertexCount() != i + 1) {
		fprintf(stderr, "test node33 failed (step 7.3.%d)\n", i);
		return 33;
	    }
	    if (rank != i + 1) {
		fprintf(stderr, "test node33 failed (step 7.4.%d)\n", i);
		return 33;
	    }
	}
	if (!sn.Detach() || !sn.IsValid() || sn.GetParent(pn) ||
	    pn.IsValid() || !sn.IsDetached()) {
	    fprintf(stderr, "test node33 failed (step 8)\n");
	    return 33;
	}
	sn = invalidNode;
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    if (!ssns[i].IsValid()) {
		fprintf(stderr, "test node33 failed (step 9.%d)\n", i);
		return 33;
	    }
	}
	if (!v.IsValid() || (v.Type() != E4_VTNODE) || (!v.Get(sn))) {
	    fprintf(stderr, "test node33 failed (step 10)\n");
	    return 33;
	}
	if (!sn.IsValid() || !sn.IsDetached()) {
	    fprintf(stderr, "test node33 failed (step 11)\n");
	    return 33;
	}

	/*
	 * Lose the last reference to the just-detached vertex and to
	 * its node value.
	 */

	v = invalidVertex;
	sn = invalidNode;

	if (n.VertexCount() != TN_VERTEXLIMIT - 1) {
	    fprintf(stderr, "test node33 failed (step 12), %d %d\n",
		    n.VertexCount(), TN_VERTEXLIMIT - 1);
	    return 33;
	}
	oldState = s.GetState();
	newState = (oldState & (~(E4_AUTOGC)));
	(void) s.SetState(newState);
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    if (!ssns[i].IsDetached()) {
		fprintf(stderr, "test node33 failed (step 13.%d\n", i);
		return 33;
	    }
	    ssns[i] = invalidNode;
	}
	oldState = s.GetState();
	newState = (oldState | E4_AUTOGC);
	(void) s.SetState(newState);
	if (s.NeedsGC()) {
	    s.DoGC();
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node33 failed (step 14)\n");
	    return 33;
	}
    }

    return 0;
}

static int
test_node34()
{
    e4_Node n, sn, dn, hn, root;
    int i = 0, j = 0, rank = 0;
    char buf[32];

    /*
     * Testing e4_Node::Detach(), e4_Node::IsValid().
     */

    {
        e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node34 failed (step 0)\n");
            return 34;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node34 failed (step 1)\n");
            return 34;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node34 failed (step 2)\n");
            return 34;
        }
	root = n;
	for (j = 0; j < TN_VERTEXLIMIT; j++) {
	    if (j == 22) {
		hn = n;
	    }
	    if (j == 55) {
		dn = n;
	    }
	    for (i = 0; i < TN_VERTEXLIMIT; i++) {
		sprintf(buf, "f%d", i + 1);
		if (!n.AddVertex(buf, E4_IOLAST, rank, i)) {
		    fprintf(stderr, "test node34 failed (step 3.1.%d.%d)\n", 
			    j, i);
		    return 34;
		}
		if (rank != i + 1) {
		    fprintf(stderr, "test node34 failed (step 3.2.%d.%d)\n",
			    j, i);
		    return 34;
		}
		if (n.VertexCount() != i + 1) {
		    fprintf(stderr, "test node34 failed (step 3.3.%d.%d)\n", 
			    j, i);
		    return 34;
		}
	    }
	    if (!n.SetNodeByRank(11, sn)) {
		fprintf(stderr, "test node34 failed (step 4.%d)\n", j);
		return 34;
	    }
	    if (!sn.IsValid()) {
		fprintf(stderr, "test node34 failed (step 5.%d)\n", j);
		return 34;
	    }
	    n = sn;
	}
	if (!hn.IsValid()) {
	    fprintf(stderr, "test node34 failed (step 6)\n");
	    return 34;
	}
	if (!dn.IsValid()) {
	    fprintf(stderr, "test node34 failed (step 7)\n");
	    return 34;
	}
	if (!dn.Detach()) {
	    fprintf(stderr, "test node34 failed (step 8)\n");
	    return 34;
	}
	if (!hn.IsValid()) {
	    fprintf(stderr, "test node34 failed (step 9)\n");
	    return 34;
	}
	if (!hn.Detach()) {
	    fprintf(stderr, "test node34 failed (step 10)\n");
	    return 34;
	}
	if (!root.IsValid()) {
	    fprintf(stderr, "test node34 failed (step 11)\n");
	    return 34;
	}
	if (root.VertexCount() != TN_VERTEXLIMIT) {
	    fprintf(stderr, "test node34 failed (step 11)\n");
	    return 34;
	}
	hn = invalidNode;
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node34 failed (step 12)\n");
	    return 34;
	}
    }

    return 0;
}

static int
test_node35()
{
    e4_Node n;
    int i = 0, rank = 0;

    /*
     * Test e4_Node::Detach on the root of the storage.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node35 failed (step 0)\n");
            return 35;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node35 failed (step 1)\n");
            return 35;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node35 failed (step 2)\n");
            return 35;
        }
	for (i = 0; i < TN_VERTEXLIMIT; i++) {
	    if (!n.AddVertex("f1", E4_IOLAST, rank, i)) {
		fprintf(stderr, "test node35 failed (step 3.1.%d)\n", i);
		return 35;
	    }
	    if (rank != i + 1) {
		fprintf(stderr, "test node35 failed (step 3.2.%d)\n", i);
		return 35;
	    }
	    if (n.VertexCount() != i + 1) {
		fprintf(stderr, "test node35 failed (step 3.3.%d)\n", i);
		return 35;
	    }
	}
	if (!n.Detach()) {
	    fprintf(stderr, "test node35 failed (step 4)\n");
	    return 35;
	}
	if (!n.IsDetached() || !n.IsValid()) {
	    fprintf(stderr, "test node35 failed (step 5)\n");
	    return 35;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node35 failed (step 6)\n");
	    return 35;
	}
    }

    return 0;
}

static int
test_node37()
{
    e4_Node n, n1, n2, n3;
    e4_Vertex f;
    int i = 0, rank = 0;

    /*
     * Test e4_Node::MoveVertex to move a vertex between two nodes.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node37 failed (step 0)\n");
            return 37;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node37 failed (step 1)\n");
            return 37;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node37 failed (step 2)\n");
            return 37;
        }
	if ((!n.AddNode("n1", E4_IOLAST, rank, n1)) || (!n1.IsValid())) {
	    fprintf(stderr, "test node37 failed (step 3)\n");
	    return 37;
	}
	if ((!n.AddNode("n2", E4_IOLAST, rank, n2)) || (!n2.IsValid())) {
	    fprintf(stderr, "test node37 failed (step 4)\n");
	    return 37;
	}
	if ((n1.VertexCount() != 0) || (n2.VertexCount() != 0)) {
	    fprintf(stderr, "test node37 failed (step 5)\n");
	    return 37;
	}
	if ((!n1.AddVertexRef("f1", E4_IOLAST, rank, 37, f)) || 
	    (!f.IsValid())) {
	    fprintf(stderr, "test node37 failed (step 6)\n");
	    return 37;
	}
	for (i = 0; i < 32; i++) {
	    if (!n1.AddVertex("int", E4_IOLAST, rank, i)) {
		fprintf(stderr, "test node37 failed (step 7.%d)\n", i);
		return 37;
	    }
	}
	if (n1.VertexCount() != 33) {
	    fprintf(stderr, "test node37 failed (step 8)\n");
	    return 37;
	}
	for (i = 0; i < 32; i++) {
	    if (!n2.AddVertex("int", E4_IOLAST, rank, i)) {
		fprintf(stderr, "test node37 failed (step 9.%d)\n", i);
		return 37;
	    }
	}
	if (n2.VertexCount() != 32) {
	    fprintf(stderr, "test node37 failed (step 10)\n");
	    return 37;
	}
	if (f.Rank() != 1) {
	    fprintf(stderr, "test node37 failed (step 11)\n");
	    return 37;
	}
	if ((!f.GetNode(n3)) || (!n3.IsValid()) || (n3 != n1)) {
	    fprintf(stderr, "test node37 failed (step 12)\n");
	    return 37;
	}

	/*
	 * Move f from n1 to n2.
	 */

	if (!n2.MoveVertex(f, E4_IOLAST, rank)) {
	    fprintf(stderr, "test node37 failed (step 13)\n");
	    return 37;
	}
	if (n1.VertexCount() != 32) {
	    fprintf(stderr, "test node37 failed (step 14)\n");
	    return 37;
	}
	if (n2.VertexCount() != 33) {
	    fprintf(stderr, "test node37 failed (step 15)\n");
	    return 37;
	}
	if (!f.IsValid()) {
	    fprintf(stderr, "test node37 failed (step 16)\n");
	    return 37;
	}
	if (!f.GetNode(n3)) {
	    fprintf(stderr, "test node37 failed (step 17)\n");
	    return 37;
	}
	if (!n3.IsValid()) {
	    fprintf(stderr, "test node37 failed (step 18)\n");
	    return 37;
	}
	if (n3 != n2) {
	    fprintf(stderr, "test node37 failed (step 19)\n");
	    return 37;
	}
	if (n3 == n1) {
	    fprintf(stderr, "test node37 failed (step 20)\n");
	    return 37;
	}
	if (f.Rank() != 33) {
	    fprintf(stderr, "test node37 failed (step 21), %d\n", f.Rank());
	    return 37;
	}

	/*
	 * Move f from last rank in n2 to rank 17 in n2.
	 */

	rank = 17;
	if (!n2.MoveVertex(f, E4_IOAT, rank)) {
	    fprintf(stderr, "test node37 failed (step 22)\n");
	    return 37;
	}
	if ((n2.VertexCount() != 33) || (f.Rank() != 17) ||
	    (n1.VertexCount() != 32)) {
	    fprintf(stderr, "rank is %d expect 17\n", f.Rank());
	    fprintf(stderr, "test node37 failed (step 22)\n");
	    return 37;
	}
	if ((!f.GetNode(n3)) || (!n3.IsValid()) || (n3 != n2) ||
	    (n3 == n1)) {
	    fprintf(stderr, "test node37 failed (step 23)\n");
	    return 37;
	}

	/*
	 * Move f from rank 17 in n2 to rank 24 in n1.
	 */

	rank = 24;
	if (!n1.MoveVertex(f, E4_IOAT, rank)) {
	    fprintf(stderr, "test node37 failed (step 25)\n");
	    return 37;
	}
	if ((n1.VertexCount() != 33) || (f.Rank() != 24) ||
	    (n2.VertexCount() != 32)) {
	    fprintf(stderr, "test node37 failed (step 25)\n");
	    return 37;
	}
	if ((!f.GetNode(n3)) || (!n3.IsValid()) || (n3 != n1) ||
	    (n3 == n2)) {
	    fprintf(stderr, "test node37 failed (step 26)\n");
	    return 37;
	}

	/*
	 * Try to move f from rank 24 in n1 to rank 24 in n1.
	 */

	rank = 24;
	if (!n1.MoveVertex(f, E4_IOAT, rank)) {
	    fprintf(stderr, "test node37 failed (step 27)\n");
	    return 37;
	}
	if ((n1.VertexCount() != 33) || (f.Rank() != 24) ||
	    (n2.VertexCount() != 32)) {
	    fprintf(stderr, "test node37 failed (step 28)\n");
	    return 37;
	}
	if ((!f.GetNode(n3)) || (!n3.IsValid()) || (n3 != n1) ||
	    (n3 == n2)) {
	    fprintf(stderr, "test node37 failed (step 29)\n");
	    return 37;
	}

	/*
	 * Try to move a vertex to before itself.
	 */

	rank = 24;
	if (!n1.MoveVertex(f, E4_IOBEFORE, rank)) {
	    fprintf(stderr, "test node37 failed (step 30)\n");
	    return 37;
	}
	if ((n1.VertexCount() != 33) || (f.Rank() != 24) ||
	    (n2.VertexCount() != 32)) {
	    fprintf(stderr, "test node37 failed (step 31)\n");
	    return 37;
	}
	if ((!f.GetNode(n3)) || (!n3.IsValid()) || (n3 != n1) ||
	    (n3 == n2)) {
	    fprintf(stderr, "test node37 failed (step 32)\n");
	    return 37;
	}

	/*
	 * Try to move a vertex to after itself. It actually does the
	 * right thing and moves the vertex to after the next vertex,
	 * so that the vertex ends up with rank + 1.
	 */

	rank = 24;
	if (!n1.MoveVertex(f, E4_IOAFTER, rank)) {
	    fprintf(stderr, "test node37 failed (step 33)\n");
	    return 37;
	}
	if ((n1.VertexCount() != 33) || (f.Rank() != 25) ||
	    (n2.VertexCount() != 32)) {
	    fprintf(stderr, "test node37 failed (step 34)\n");
	    return 37;
	}
	if ((!f.GetNode(n3)) || (!n3.IsValid()) || (n3 != n1) ||
	    (n3 == n2)) {
	    fprintf(stderr, "test node37 failed (step 35)\n");
	    return 37;
	}

	s.Delete();
	if ((s.IsValid()) || (n1.IsValid()) || (n2.IsValid()) ||
	    (f.IsValid())) {
	    fprintf(stderr, "test node37 failed (step 36)\n");
	    return 37;
	}
    }

    return 0;
}

static int
test_node38()
{
    e4_Node n, n1, n2, n3;
    e4_Node no;
    e4_Vertex f;
    int rank = 0;

    /*
     * Test e4_Node::MoveVertex() with various illegal combinations.
     * All of these illegal attempts should be caught.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node38 failed (step 0)\n");
            return 38;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node38 failed (step 1)\n");
            return 38;
        }
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
            fprintf(stderr, "test node38 failed (step 2)\n");
            return 38;
        }
	if ((!n.AddNode("n1", E4_IOLAST, rank, n1)) || (!n1.IsValid())) {
	    fprintf(stderr, "test node38 failed (step 3)\n");
	    return 38;
	}
	if ((!n.AddNode("n2", E4_IOLAST, rank, n2)) || (!n2.IsValid())) {
	    fprintf(stderr, "test node38 failed (step 4)\n");
	    return 38;
	}
	if ((!n1.AddVertexRef("f", E4_IOLAST, rank, 27, f)) ||
	    (!f.IsValid())) {
	    fprintf(stderr, "test node38 failed (step 5)\n");
	    return 38;
	}
	if ((n1.VertexCount() != 1) || (f.Rank() != 1)) {
	    fprintf(stderr, "test node38 failed (step 6)\n");
	    return 38;
	}
	e4_Storage so("another.db", E4_METAKIT);

	if (!so.IsValid()) {
	    fprintf(stderr, "test node38 failed (step 7)\n");
	    return 38;
	}
	if (!so.GetRootNode(no) || !no.IsValid() || !no.IsRoot()) {
	    fprintf(stderr, "test node38 failed (step 8)\n");
	    return 38;
	}

	/*
	 * Attempt to move a vertex into another storage.
	 */

	if (no.MoveVertex(f, E4_IOLAST, rank)) {
	    fprintf(stderr, "test node38 failed (step 9)\n");
	    return 38;
	}
	if ((!f.IsValid()) || (!f.GetNode(n3)) || (!n3.IsValid()) ||
	    (n3 == no) || (n3 != n1) || (n1.VertexCount() != 1) ||
	    (f.Rank() != 1)) {
	    fprintf(stderr, "test node38 failed (step 10)\n");
	    return 38;
	}
	so.Delete();
	if (so.IsValid() || (no.IsValid())) {
	    fprintf(stderr, "test node38 failed (step 11)\n");
	    return 38;
	}

	/*
	 * Attempt to move a detached vertex between two nodes.
	 */

	n3 = invalidNode;
	if ((!f.Detach()) || (!f.IsValid()) || (f.GetNode(n3)) || 
	    (n3.IsValid())) {
	    fprintf(stderr, "test node38 failed (step 12)\n");
	    return 38;
	}
	if (!n2.MoveVertex(f, E4_IOLAST, rank)) {
	    fprintf(stderr, "test node38 failed (step 13)\n");
	    return 38;
	}

	/*
	 * Attempt to move a vertex to a detached node.
	 */

	if ((!n1.AddVertexRef("f", E4_IOLAST, rank, 27, f)) || 
	    (!f.IsValid()) || (!f.GetNode(n3)) || 
	    (!n3.IsValid()) || (n3 != n1) ||
	    (f.Rank() != 1) || (n1.VertexCount() != 1)) {
	    fprintf(stderr, "test node38 failed (step 14)\n");
	    return 38;
	}
	if ((!n2.Detach()) || (!n2.IsValid())) {
	    fprintf(stderr, "test node38 failed (step 15)\n");
	    return 38;
	}
	if ((!n2.MoveVertex(f, E4_IOLAST, rank)) || (!f.IsValid()) ||
	    (!f.GetNode(n3)) || (!n3.IsValid()) || (n3 != n2)) {
	    fprintf(stderr, "test node38 failed (step 16)\n");
	    return 38;
	}
	s.Delete();
	if ((s.IsValid()) || (n.IsValid()) || (n1.IsValid()) || 
	    (n2.IsValid()) || (n3.IsValid())) {
	    fprintf(stderr, "test node38 failed (step 19)\n");
	    return 38;
	}
    }

    return 0;
}

static int
test_node39()
{
    int rank = 0, i = 0;
    e4_Node r, n1, n2, n3, n4;

    /*
     * Test e4_Node::AddVertex with a node value, e4_Node::ParentCount
     * and e4_Node::OccurrenceCount.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node39 failed (step 0)\n");
            return 39;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node39 failed (step 1)\n");
            return 39;
        }
	if (!s.GetRootNode(r) || !r.IsValid() || !r.IsRoot()) {
            fprintf(stderr, "test node39 failed (step 2)\n");
            return 39;
        }
	if ((!r.AddNode("n1", E4_IOLAST, rank, n1)) || (!n1.IsValid())) {
	    fprintf(stderr, "test node39 failed (step 3)\n");
	    return 39;
	}
	if ((!r.AddNode("n2", E4_IOLAST, rank, n2)) || (!n2.IsValid())) {
	    fprintf(stderr, "test node39 failed (step 4)\n");
	    return 39;
	}
	if ((!n1.AddNode("n3", E4_IOLAST, rank, n3)) || (!n3.IsValid())) {
	    fprintf(stderr, "test node39 failed (step 5)\n");
	    return 39;
	}
	if (n3.ParentCount() != 1) {
	    fprintf(stderr, "test node39 failed (step 6)\n");
	    return 39;
	}
	if ((!n2.AddVertex("n3", E4_IOLAST, rank, n3)) || (!n3.IsValid()) ||
	    (n2.VertexCount() != 1) || (n3.ParentCount() != 2)) {
	    fprintf(stderr, "test node39 failed (step 7)\n");
	    return 39;
	}

	/*
	 * "n3" now occurs in both "n1" and "n2". Check that all is sane.
	 */

	if ((n3.OccurrenceCount(n1) != 1) ||
	    (n3.OccurrenceCount(n2) != 1) ||
	    (n3.OccurrenceCount(r) != 0) ||
	    (n3.OccurrenceCount() != 2) ||
	    (n3.ParentCount() != 2)) {
	    fprintf(stderr, "test node39 failed (step 8)\n");
	    return 39;
	}

	/*
	 * Add "n3" some more times to "n1" and "n2".
	 */

	for (i = 0; i < 32; i++) {
	    if ((i % 2) == 1) {
		if (!n1.AddVertex("n3", E4_IOLAST, rank, n3)) {
		    fprintf(stderr, "test node39 failed (step 9.1.%d)\n", i);
		    return 39;
		}
	    } else {
		if (!n2.AddVertex("n3", E4_IOLAST, rank, n3)) {
		    fprintf(stderr, "test node39 failed (step 9.2.%d)\n", i);
		    return 39;
		}
	    }
	    if (n3.ParentCount() != 2) {
		fprintf(stderr, "test node39 failed (step 9.3.%d)\n", i);
		return 39;
	    }
	}

	/*
	 * Ensure that things are still correct.
	 */

	if ((n3.OccurrenceCount() != 34) ||
	    (n3.OccurrenceCount(n1) != 17) ||
	    (n3.OccurrenceCount(n2) != 17)) {
	    fprintf(stderr, "test node39 failed (step 10)\n");
	    return 39;
	}

	/*
	 * Check parent ranks in "n3".
	 */

	if ((n3.ParentRank(n1) != 1) ||
	    (n3.ParentRank(n2) != 2) ||
	    (n3.ParentRank(r) != E4_NODENOTFOUND)) {
	    fprintf(stderr, "test node39 failed (step 11)\n");
	    return 39;
	}

	/*
	 * Attempt to retrieve individual parents.
	 */

	n4 = invalidNode;
	if ((!n3.GetParent(1, n4)) || (!n4.IsValid()) ||
	    (n4 != n1) || (n4 == n2)) {
	    fprintf(stderr, "test node39 failed (step 12)\n");
	    return 39;
	}

	n4 = invalidNode;
	if ((!n3.GetParent(2, n4)) || (!n4.IsValid()) ||
	    (n4 == n1) || (n4 != n2)) {
	    fprintf(stderr, "test node39 failed (step 13)\n");
	    return 39;
	}

	/*
	 * Detach "n1" and then lose the last reference. See if
	 * the parent count and occurrence count of "n3" are updated.
	 */

	if (!n1.Detach() || !n1.IsValid()) {
	    fprintf(stderr, "test node39 failed (step 14)\n");
	    return 39;
	}
	n1 = invalidNode;

	n4 = invalidNode;
	if ((!n3.IsValid()) || 
	    (n3.OccurrenceCount() != 17) ||
	    (n3.OccurrenceCount(n2) != 17) ||
	    (n1.IsValid()) ||
	    (n3.OccurrenceCount(n1) != E4_NODENOTFOUND) ||
	    (n3.ParentCount() != 1) ||
	    (!n3.GetParent(1, n4)) ||
	    (!n4.IsValid()) ||
	    (n4 != n2)) {
	    fprintf(stderr, "test node39 failed (step 15)\n");
	    return 39;
	}
	n4 = invalidNode;

	/*
	 * Detach "n2" and lose the last reference. See that "n3" becomes
	 * detached too.
	 */

	if (!n2.Detach() || !n2.IsValid() || !n2.IsDetached()) {
	    fprintf(stderr, "test node39 failed (step 16)\n");
	    return 39;
	}
	n2 = invalidNode;
	if (!n3.IsValid() || !n3.IsDetached() || (n3.OccurrenceCount() != 0)) {
	    fprintf(stderr, "test node39 failed (step 17)\n");
	    return 39;
	}

	/*
	 * Delete the storage.
	 */

	s.Delete();
	if ((s.IsValid()) || (r.IsValid()) ||
	    (n1.IsValid()) || (n2.IsValid()) || (n3.IsValid()) ||
	    (n4.IsValid())) {
	    fprintf(stderr, "test node39 failed (step 18)\n");
	    return 39;
	}
    }

    return 0;
}

static int
test_node40()
{
    e4_Node r, n1, n2, n3, n4, n5;
    e4_Vertex f1, f2;
    int rank = 0;

    /*
     * Test e4_Node::AddVertexRef() with a node value, e4_Node::ParentCount
     * and e4_Node::OccurrenceCount.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node40 failed (step 0)\n");
            return 40;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node40 failed (step 1)\n");
            return 40;
        }
	if (!s.GetRootNode(r) || !r.IsValid() || !r.IsRoot()) {
            fprintf(stderr, "test node40 failed (step 2)\n");
            return 40;
        }
	if ((!r.AddNode("n1", E4_IOLAST, rank, n1)) || (!n1.IsValid())) {
	    fprintf(stderr, "test node40 failed (step 3)\n");
	    return 40;
	}
	if ((!r.AddNode("n2", E4_IOLAST, rank, n2)) || (!n2.IsValid())) {
	    fprintf(stderr, "test node40 failed (step 4)\n");
	    return 40;
	}
	if ((!n1.AddNode("n3", E4_IOLAST, rank, n3)) || (!n3.IsValid())) {
	    fprintf(stderr, "test node40 failed (step 5)\n");
	    return 40;
	}
	if (n3.ParentCount() != 1) {
	    fprintf(stderr, "test node40 failed (step 6)\n");
	    return 40;
	}
	if ((!n2.AddVertex("n3", E4_IOLAST, rank, n3)) || (!n3.IsValid()) ||
	    (n2.VertexCount() != 1) || (n3.ParentCount() != 2)) {
	    fprintf(stderr, "test node40 failed (step 7)\n");
	    return 40;
	}

	/*
	 * Try e4_Node::AddVertexRef.
	 */

	if ((!n2.AddVertexRef("n3", E4_IOLAST, rank, n3, f2)) || 
	    (!f2.IsValid()) ||
	    (n2.VertexCount() != 2) || (n3.ParentCount() != 2) ||
	    (n3.OccurrenceCount() != 3) || (f2.Rank() != 2)) {
	    fprintf(stderr, "test node40 failed (step 8)\n");
	    return 40;
	}
	if ((!n1.AddVertexRef("n3", E4_IOLAST, rank, n3, f1)) ||
	    (!f1.IsValid()) ||
	    (n1.VertexCount() != 2) || (n3.ParentCount() != 2) ||
	    (n3.OccurrenceCount() != 4) || (f1.Rank() != 2)) {
	    fprintf(stderr, "test node40 failed (step 9)\n");
	    return 40;
	}
	if ((n3.OccurrenceCount(n1) != 2) || (n3.OccurrenceCount(n2) != 2)) {
	    fprintf(stderr, "test node40 failed (step 10)\n");
	    return 40;
	}

	/*
	 * OK, now make an "n4" child of "r" and move "f1" and "f2"
	 * to it. Avter the move of "f1", "n3" should have a new parent,
	 * "n4", and that should be the last parent in the list. After the
	 * move of "f2" to "n4", no parent changes should happen but the
	 * occurrence count of "n2" and "n4" in the parent list of "n3"
	 * should change.
	 */

	if ((!r.AddNode("n4", E4_IOLAST, rank, n4)) || (!n4.IsValid()) ||
	    (r.VertexCount() != 3) || (n4.VertexCount() != 0)) {
	    fprintf(stderr, "test node40 failed (step 11)\n");
	    return 40;
	}
	if ((!n4.MoveVertex(f1, E4_IOLAST, rank)) || (!f1.IsValid()) ||
	    (n4.VertexCount() != 1)) {
	    fprintf(stderr, "test node40 failed (step 12)\n");
	    return 40;
	}
	if (n3.ParentCount() != 3) {
	    fprintf(stderr, "test node40 failed (step 13)\n");
	    return 40;
	}
	if (n3.OccurrenceCount() != 4) {
	    fprintf(stderr, "test node40 failed (step 14), %d\n",
		    n3.OccurrenceCount());
	    return 40;
	}
	if (n3.OccurrenceCount(n4) != 1) {
	    fprintf(stderr, "test node40 failed (step 15)\n");
	    return 40;
	}
	if ((n3.ParentCount() != 3) || (n3.OccurrenceCount() != 4) ||
	    (n3.OccurrenceCount(n4) != 1) || (n3.OccurrenceCount(n1) != 1) ||
	    (!n3.GetParent(3, n5)) || (!n5.IsValid()) || (n4 != n5)) {
	    fprintf(stderr, "test node40 failed (step 16)\n");
	    return 40;
	}
	if ((!n4.MoveVertex(f2, E4_IOLAST, rank)) || (!f2.IsValid()) ||
	    (n4.VertexCount() != 2)) {
	    fprintf(stderr, "test node40 failed (step 17)\n");
	    return 40;
	}
	if ((n3.ParentCount() != 3) || (n3.OccurrenceCount() != 4) ||
	    (n3.OccurrenceCount(n4) != 2) || (n3.OccurrenceCount(n2) != 1) ||
	    (!n3.GetParent(1, n5)) || (!n5.IsValid()) || (n1 != n5)) {
	    fprintf(stderr, "test node40 failed (step 17)\n");
	    return 40;
	}

	s.Delete();
	if ((s.IsValid()) || (r.IsValid()) || 
	    (n1.IsValid()) || (n2.IsValid()) || (n3.IsValid()) ||
	    (f1.IsValid()) || (f2.IsValid()) || (n4.IsValid()) ||
	    (n5.IsValid())) {
	    fprintf(stderr, "test node40 failed (step 18)\n");
	    return 40;
	}
    }

    return 0;
}

static int
test_node43()
{
    e4_Node r, n;
    e4_NodeUniqueID nuid0, nuid1;
    int rank = 0, i = 0;

    /*
     * This test checks that storage space (as denoted by the unique
     * identifier assigned to a node) is properly being recycled. This
     * test is specific to the E4_METAKIT driver because it relies on
     * the unique ID recycling behavior of that driver.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
            fprintf(stderr, "test node43 failed (step 0)\n");
            return 43;
        }
        if (!s.IsValid()) {
            fprintf(stderr, "test node43 failed (step 1)\n");
            return 43;
        }
	if (!s.GetRootNode(r) || !r.IsValid() || !r.IsRoot()) {
            fprintf(stderr, "test node43 failed (step 2)\n");
            return 43;
        }
	if ((!r.AddNode("n", E4_IOLAST, rank, n)) || (!n.IsValid())) {
	    fprintf(stderr, "test node43 failed (step 3)\n");
	    return 43;
	}
	(void) n.GetUniqueID(nuid0);
	for (i = 0; i < 255; i++) {
	    if ((!n.Detach()) || (!n.IsValid())) {
		fprintf(stderr, "test node43 failed (step 4.1.%d)\n", i);
		return 43;
	    }
	    if ((!r.AddVertex("n", E4_IOLAST, rank, n)) || (!n.IsValid())) {
		fprintf(stderr, "test node43 failed (step 4.2.%d)\n", i);
		return 43;
	    }
	    if ((!n.GetUniqueID(nuid1)) || (nuid0 != nuid1)) {
		fprintf(stderr, "test node43 failed (step 4.3.%d)\n", i);
		return 43;
	    }
	}
	s.Delete();
	if ((s.IsValid()) || (r.IsValid()) || (n.IsValid())) {
	    fprintf(stderr, "test node43 failed (step 5)\n");
	    return 43;
	}
    }

    return 0;
}

static int
test_node44()
{
    e4_Node n1, n2, n3;
    int rank = 0;
    
    /*
     * Test SetVertex with a vertex whose value is a node.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node44 failed (step 0)\n");
	    return 44;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node44 failed (step 1)\n");
	    return 44;
	}
	if (!s.GetRootNode(n1) || !n1.IsValid() || !n1.IsRoot()) {
	    fprintf(stderr, "test node44 failed (step 2)\n");
	    return 44;
	}
	if (!s.CreateDetachedNode(n2) || !n2.IsValid() || n2.IsRoot()) {
	    fprintf(stderr, "test node44 failed (step 3)\n");
	    return 44;
	}
	if (!n1.AddNode("n3", E4_IOLAST, rank, n3) || !n3.IsValid()) {
	    fprintf(stderr, "test node44 failed (step 4)\n");
	    return 44;
	}
	if (!n2.AddVertex("n3", E4_IOLAST, rank, n3)) {
	    fprintf(stderr, "test node44 failed (step 5)\n");
	    return 44;
	}
	if ((n3.ParentCount() != 2) || (n1.VertexCount() != 1) ||
	    (n2.VertexCount() != 1) || (n3.VertexCount() != 0)) {
	    fprintf(stderr, "test node44 failed (step 6)\n");
	    return 44;
	}
	if (!n1.SetVertex("n3", 1)) {
	    fprintf(stderr, "test node44 failed (step 7)\n");
	    return 44;
	}
	if (n3.ParentCount() != 1) {
	    fprintf(stderr, "test node44 failed (step 8)\n");
	    return 44;
	}
	if (n1.VertexCount() != 1) {
	    fprintf(stderr, "test node44 failed (step 9)\n");
	    return 44;
	}
	if (n2.VertexCount() != 1) {
	    fprintf(stderr, "test node44 failed (step 10)\n");
	    return 44;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node44 failed (step 11)\n");
	    return 44;
	}
    }
    if (n1.IsValid() || n2.IsValid() || n3.IsValid()) {
	fprintf(stderr, "test node44 failed (step 12)\n");
	return 44;
    }

    return 0;
}

static int
test_node45()
{
    e4_Node n1, n2, n3;
    int rank = 0;
    
    /*
     * Test SetVertexByRank with a vertex whose value is a node.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node45 failed (step 1)\n");
	    return 45;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node45 failed (step 1)\n");
	    return 45;
	}
	if (!s.CreateDetachedNode(n1) || !n1.IsValid() || n1.IsRoot()) {
	    fprintf(stderr, "test node45 failed (step 2)\n");
	    return 45;
	}
	if (!s.CreateDetachedNode(n2) || !n2.IsValid() || n2.IsRoot()) {
	    fprintf(stderr, "test node45 failed (step 3)\n");
	    return 45;
	}
	if (!n1.AddNode("n3", E4_IOLAST, rank, n3) || !n3.IsValid()) {
	    fprintf(stderr, "test node45 failed (step 4)\n");
	    return 45;
	}
	if (!n2.AddVertex("n3", E4_IOLAST, rank, n3)) {
	    fprintf(stderr, "test node45 failed (step 5)\n");
	    return 45;
	}
	if ((n3.ParentCount() != 2) || (n1.VertexCount() != 1) ||
	    (n2.VertexCount() != 1) || (n3.VertexCount() != 0)) {
	    fprintf(stderr, "test node45 failed (step 6)\n");
	    return 45;
	}
	if (!n1.SetVertexByRank(1, 1)) {
	    fprintf(stderr, "test node45 failed (step 7)\n");
	    return 45;
	}
	if (n3.ParentCount() != 1) {
	    fprintf(stderr, "test node45 failed (step 8)\n");
	    return 45;
	}
	if (n1.VertexCount() != 1) {
	    fprintf(stderr, "test node45 failed (step 9)\n");
	    return 45;
	}
	if (n2.VertexCount() != 1) {
	    fprintf(stderr, "test node45 failed (step 10)\n");
	    return 45;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test node45 failed (step 11)\n");
	    return 45;
	}
    }
    if (n1.IsValid() || n2.IsValid() || n3.IsValid()) {
	fprintf(stderr, "test node45 failed (step 12)\n");
	return 45;
    }

    return 0;
}

static int
test_node46()
{
    e4_Node n1, n2, n3;
    int rank = 0;
    e4_Vertex v1, v2;

    /*
     * Test that when executing e4_Node::Detach() any vertices that
     * have the node as their value also become detached (or are
     * recycled if the user program does not hold a reference).
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node46 failed (step 0)\n");
	    return 46;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node46 failed (step 1)\n");
	    return 46;
	}
	if (!s.CreateDetachedNode(n1) || !n1.IsValid() || n1.IsRoot()) {
	    fprintf(stderr, "test node46 failed (step 2)\n");
	    return 46;
	}
	if (!n1.AddNodeRef("foo", E4_IOLAST, rank, n2, v1) ||
	    !v1.IsValid() || !n2.IsValid()) {
	    fprintf(stderr, "test node46 failed (step 3)\n");
	    return 46;
	}
	if (!n1.AddVertex("foo", E4_IOLAST, rank, n2)) {
	    fprintf(stderr, "test node46 failed (step 4)\n");
	    return 46;
	}
	if (!n1.AddVertexRef("foo", E4_IOLAST, rank, n2, v2) ||
	    !v2.IsValid()) {
	    fprintf(stderr, "test node46 failed (step 5)\n");
	    return 46;
	}
	if (n1.VertexCount() != 3) {
	    fprintf(stderr, "test node46 failed (step 6)\n");
	    return 46;
	}
	if (!n2.Detach() || !n2.IsValid() || !n2.IsDetached() ||
	    !v1.IsValid() || !v1.IsDetached() ||
	    !v2.IsValid() || !v2.IsDetached() ||
	    (n1.VertexCount() != 0)) {
	    fprintf(stderr, "test node46 failed (step 7)\n");
	    return 46;
	}
	if (!v1.Get(n3) || !n3.IsValid() || (n3 != n2)) {
	    fprintf(stderr, "test node46 failed (step 8)\n");
	    return 46;
	}
	if (!v2.Get(n3) || !n3.IsValid() || (n3 != n2)) {
	    fprintf(stderr, "test node46 failed (step 9)\n");
	    return 46;
	}

	v1 = invalidVertex;
	if (!v2.IsValid() || !v2.IsDetached() || !n2.IsValid() ||
	    !n2.IsDetached()) {
	    fprintf(stderr, "test node46 failed (step 10)\n");
	    return 46;
	}
	v2 = invalidVertex;
	if (!n2.IsValid() || !n2.IsDetached()) {
	    fprintf(stderr, "test node46 failed (step 11)\n");
	    return 46;
	}

	s.Delete();

	if (s.IsValid() ||
	    n1.IsValid() || n2.IsValid() || n3.IsValid() ||
	    v1.IsValid() || v2.IsValid()) {
	    fprintf(stderr, "test node46 failed (step 12)\n");
	    return 46;
	}
    }

    return 0;
}

static int
test_node47()
{
    e4_Node r;
    int rud = 0;

    /*
     * Test that user data is saved in the persistent storage.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node47 failed (step 0)\n");
	    return 47;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node47 failed (step 1)\n");
	    return 47;
	}
	if (!s.GetRootNode(r) || !r.IsValid() || !r.IsRoot()) {
	    fprintf(stderr, "test node47 failed (step 2)\n");
	    return 47;
	}
	if (!s.IsStable() || !s.Commit() || !s.IsStable()) {
	    fprintf(stderr, "test node47 failed (step 2.1)\n");
	    return 47;
	}
	if (!r.GetUserData(rud) || (rud != 0)) {
	    fprintf(stderr, "test node47 failed (step 3.0)\n");
	    return 47;
	}
	if (!s.IsStable()) {
	    fprintf(stderr, "test node47 failed (step 3.1)\n");
	    return 47;
	}

	if (!r.SetUserData(101) || !r.GetUserData(rud) || (rud != 101)) {
	    fprintf(stderr, "test node47 failed (step 4.0)\n");
	    return 47;
	}
	if (s.IsStable()) {
	    fprintf(stderr, "test node47 failed (step 4.1)\n");
	    return 47;
	}

	/*
	 * By going out of scope, the storage will get committed and closed.
	 */
    }

    {
	e4_Storage s("foo.db", E4_METAKIT);

	if (!s.IsValid()) {
	    fprintf(stderr, "test node47 failed (step 5)\n");
	    return 47;
	}
	if (!s.GetRootNode(r) || !r.IsValid() || !r.IsRoot()) {
	    fprintf(stderr, "test node47 failed (step 6)\n");
	    return 47;
	}
	if (!r.GetUserData(rud) || (rud != 101)) {
	    fprintf(stderr, "test node47 failed (step 7.0)\n");
	    return 47;
	}
	if (!s.IsStable()) {
	    fprintf(stderr, "test node47 failed (step 7.1)\n");
	    return 47;
	}

	s.Delete();
    }

    return 0;
}      

static int
test_node48()
{
    e4_Node n1, n2, n3, nt, n2h, n3h;
    int rank = 0;

    /*
     * Test inserting with E4_IOAT and detached nodes.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node48 failed (step 0)\n");
	    return 48;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node48 failed (step 1)\n");
	    return 48;
	}
	if (!s.CreateDetachedNode(n1) || !n1.IsValid() || n1.IsRoot() ||
	    !n1.IsDetached()) {
	    fprintf(stderr, "test node48 failed (step 2)\n");
	    return 48;
	}
	if (!s.CreateDetachedNode(n2) || !n2.IsValid() || n2.IsRoot() ||
	    !n2.IsDetached()) {
	    fprintf(stderr, "test node48 failed (step 3)\n");
	    return 48;
	}
	if (!s.CreateDetachedNode(n3) || !n3.IsValid() || n3.IsRoot() ||
	    !n3.IsDetached()) {
	    fprintf(stderr, "test node48 failed (step 4)\n");
	    return 48;
	}
	n2h = n2;
	n3h = n3;
	rank = 1;
	if (!n1.AddNode("n2", E4_IOAT, rank, n2) ||
	    !n1.IsDetached() ||
	    !n1.IsValid() ||
	    (n1.VertexCount() != 1) ||
	    n2.IsDetached() ||
	    !n2.IsValid() ||
	    (n2.ParentCount() != 1)) {
	    fprintf(stderr, "test node48 failed (step 5)\n");
	    return 48;
	}
	if (!n1.GetVertex("n2", nt) ||
	    !nt.IsValid() ||
	    (nt != n2) ||
	    (nt == n2h) ||
	    !n2h.IsDetached() ||
	    !n2h.IsValid()) {
	    fprintf(stderr, "test node48 failed (step 6)\n");
	    return 48;
	}
	rank = 2;
	if (!n1.AddNode("n3", E4_IOAT, rank, n3) ||
	    !n1.IsDetached() ||
	    !n1.IsValid() ||
	    (n1.VertexCount() != 2) ||
	    n3.IsDetached() ||
	    !n3.IsValid() ||
	    (n3.ParentCount() != 1) ||
	    n2.IsDetached() ||
	    !n2.IsValid() ||
	    (n2.ParentCount() != 1)) {
	    fprintf(stderr, "test node48 failed (step 7)\n");
	    return 48;
	}
	if (!n1.GetVertex("n3", nt) ||
	    !nt.IsValid() ||
	    (nt != n3) ||
	    (nt == n3h) ||
	    !n3h.IsDetached() ||
	    !n3h.IsValid()) {
	    fprintf(stderr, "test node48 failed (step 8)\n");
	    return 48;
	}

	s.Delete();

	if (s.IsValid() ||  n1.IsValid() || n2.IsValid() || n3.IsValid() ||
	    n2h.IsValid() || n3h.IsValid()) {
	    fprintf(stderr, "test node48 failed (step 9)\n");
	    return 48;
	}
    }

    return 0;
}

static int
test_node49()
{
    e4_Node r;
    e4_Vertex v, v1;
    int i, rank, state;

    /*
     * Test GetVertexRefByRank with zero and negative ranks.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node49 failed (step 0)\n");
	    return 49;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node49 failed (step 1)\n");
	    return 49;
	}
	if (!s.GetRootNode(r) || !r.IsValid() || !r.IsRoot() ||
	    (r.VertexCount() != 0)) {
	    fprintf(stderr, "test node49 failed (step 2)\n");
	    return 49;
	}
	for (i = 0; i < 10; i++) {
	    if (!r.AddVertex("f", E4_IOLAST, rank, i) ||
		(rank != (i + 1)) ||
		(r.VertexCount() != (i + 1))) {
		fprintf(stderr, "test node49 failed (step 3.%d)\n", i);
		return 49;
	    }
	}
	if (!r.GetVertexRef("f", 1, v) ||
	    !v.IsValid() ||
	    (!v.Get(i)) ||
	    (i != 0) || 
	    (v.Rank() != 1)) {
	    fprintf(stderr, "test node49 failed (step 4)\n");
	    return 49;
	}
	if (r.GetVertexRefByRank(0, v1) || 
	    v1.IsValid() ||
	    (v == v1)) {
	    fprintf(stderr, "test node49 failed (step 5)\n");
	    return 49;
	}
	v1 = invalidVertex;
	if (r.GetVertexRefByRank(-1, v1) || 
	    v1.IsValid() ||
	    (v == v1)) {
	    fprintf(stderr, "test node49 failed (step 6)\n");
	    return 49;
	}
	v1 = invalidVertex;
	if (r.GetVertexRefByRank(-2, v1) || 
	    v1.IsValid() ||
	    (v == v1)) {
	    fprintf(stderr, "test node49 failed (step 7)\n");
	    return 49;
	}

	s.Delete();

	if (s.IsValid() ||
	    r.IsValid() ||
	    v.IsValid() ||
	    v1.IsValid()) {
	    fprintf(stderr, "test node49 failed (step 8)\n");
	    return 49;
	}

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node49 failed (step 9)\n");
	    return 49;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node49 failed (step 10)\n");
	    return 49;
	}
	state = s.GetState();
	state |= E4_NOVERTEXCACHE;
	(void) s.SetState(state);
	state = s.GetState();
	if ((state & E4_NOVERTEXCACHE) == 0) {
	    fprintf(stderr, "test node49 failed (step 11.1)\n");
	    return 49;
	}
	if (!s.GetRootNode(r) || !r.IsValid() || !r.IsRoot() ||
	    (r.VertexCount() != 0)) {
	    fprintf(stderr, "test node49 failed (step 12)\n");
	    return 49;
	}
	for (i = 0; i < 10; i++) {
	    if (!r.AddVertex("f", E4_IOLAST, rank, i) ||
		(rank != (i + 1)) ||
		(r.VertexCount() != (i + 1))) {
		fprintf(stderr, "test node49 failed (step 13.%d)\n", i);
		return 49;
	    }
	}
	if (!r.GetVertexRef("f", 1, v) ||
	    !v.IsValid() ||
	    (!v.Get(i)) ||
	    (i != 0) || 
	    (v.Rank() != 1)) {
	    fprintf(stderr, "test node49 failed (step 14)\n");
	    return 49;
	}
	if (r.GetVertexRefByRank(0, v1) || 
	    v1.IsValid() ||
	    (v == v1)) {
	    fprintf(stderr, "test node49 failed (step 15)\n");
	    return 49;
	}
	v1 = invalidVertex;
	if (r.GetVertexRefByRank(-1, v1) || 
	    v1.IsValid() ||
	    (v == v1)) {
	    fprintf(stderr, "test node49 failed (step 16)\n");
	    return 49;
	}
	v1 = invalidVertex;
	if (r.GetVertexRefByRank(-2, v1) || 
	    v1.IsValid() ||
	    (v == v1)) {
	    fprintf(stderr, "test node49 failed (step 17)\n");
	    return 49;
	}

	s.Delete();
    }

    return 0;
}

static int
test_node50()
{
    e4_Node r;
    int rank, rank1, rank2, i;
    char buf[128];

    /*
     * Attempt to exercise the vertex cache and flush any remaining bugs.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node50 failed (step 0)\n");
	    return 50;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node50 failed (step 1)\n");
	    return 50;
	}
	if (!s.GetRootNode(r) || !r.IsValid() || !r.IsRoot() ||
	    (r.VertexCount() != 0)) {
	    fprintf(stderr, "test node50 failed (step 2)\n");
	    return 50;
	}
	for (i = 0; i < 100; i++) {
	    sprintf(buf, "v%d", i);
	    if (!r.AddVertex(buf, E4_IOLAST, rank, i) ||
		(rank != (i + 1)) ||
		(r.VertexCount() != (i + 1))) {
		fprintf(stderr, "test node50 failed (step 3.%d)\n", i);
		return 50;
	    }
	}

	rank1 = r.VertexRank("v99");
	if (rank1 != 100) {
	    fprintf(stderr, "test node50 failed (step 4) %d vs. 100\n", rank1);
	    return 50;
	}
	rank2 = r.VertexRank("v99");
	if (rank2 != rank1) {
	    fprintf(stderr,
		    "test node50 failed (step 6) %d vs. %d\n",
		    rank1, rank2);
	    return 50;
	}
    }
    {
        e4_Storage s("foo.db", E4_METAKIT);

	if (!s.IsValid()) {
	    fprintf(stderr, "test node50 failed (step 7)\n");
	    return 50;
	}
	if (!s.GetRootNode(r) || !r.IsValid() || !r.IsRoot() ||
	    (r.VertexCount() != 100)) {
	    fprintf(stderr, "test node50 failed (step 8)\n");
	    return 50;
	}
	rank1 = r.VertexRank("v88");
	if (rank1 != 89) {
	    fprintf(stderr, "test node50 failed (step 9) %d vs 89\n", rank1);
	    return 50;
	}
	rank2 = r.VertexRank("v88");
	if (rank1 != rank2) {
	    fprintf(stderr,
		    "test node50 failed (step 10) %d vs %d\n",
		    rank1, rank2);
	    return 50;
	}
	if (!r.SetVertex("v22", 202)) {
	    fprintf(stderr, "test node50 failed (step 11)\n");
	    return 50;
	}
	rank1 = r.VertexRank("v22");
	if (rank1 != 23) {
	    fprintf(stderr, "test node50 failed (step 12) %d vs 23\n", rank1);
	    return 50;
	}
	if (!r.SetVertex("v22", 101)) {
	    fprintf(stderr, "test node50 failed (step 13)\n");
	    return 50;
	}
	rank2 = r.VertexRank("v22");
	if (rank2 != rank1) {
	    fprintf(stderr,
		    "test node50 failed (step 14) %d vs %d\n",
		    rank1, rank2);
	    return 50;
	}

	s.Delete();
    }

    return 0;
}

static int
test_node51()
{
    e4_Node r;
    int rank, i;
    e4_Vertex v;
    char buf[128];

    /*
     * Exercise e4_Node::AddVertexRef with caching on and off.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test node51 failed (step 0)\n");
	    return 51;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test node51 failed (step 1)\n");
	    return 51;
	}
	if (!s.GetRootNode(r) || !r.IsValid() || !r.IsRoot() ||
	    (r.VertexCount() != 0)) {
	    fprintf(stderr, "test node51 failed (step 2)\n");
	    return 51;
	}
	for (i = 0; i < 10; i++) {
	    sprintf(buf, "v%d", i);
	    if (!r.AddVertex(buf, E4_IOLAST, rank, i) ||
		(rank != (i + 1)) ||
		(r.VertexCount() != (i + 1))) {
		fprintf(stderr, "test node51 failed (step 3.%d)\n", i);
		return 51;
	    }
	}

	/*
	 * Test existing vertex's rank.
	 */

	rank = r.VertexRank("v7");
	if (rank != 8) {
	    fprintf(stderr, "test node51 failed (step 4)\n");
	    return 51;
	}

	/*
	 * Test nonexistent vertex's rank.
	 */

	rank = r.VertexRank("v99");
	if (rank != E4_VERTEXNOTFOUND) {
	    fprintf(stderr, "test node51 failed (step 5)\n");
	    return 51;
	}

	/*
	 * Test adding a vertex with E4_IOAT.
	 */

	rank = 7;
	if (!r.AddVertexRef("xyz", E4_IOAT, rank, 0, v) ||
	    !v.IsValid() ||
	    (rank != 7) ||
	    (r.VertexRank("xyz") != 7) ||
	    (v.Rank() != 7)) {
	    fprintf(stderr, "test node51 failed (step 6) rank = %d\n", rank);
	    return 51;
	}

	/*
	 * Test adding a vertex with E4_IOAT at an impossible rank.
	 */

	v = invalidVertex;
	rank = 30000;
	if (r.AddVertexRef("xxx", E4_IOAT, rank, 0, v) ||
	    v.IsValid()) {
	    fprintf(stderr, "test node51 failed (step 8)\n");
	    return 51;
	}
	rank = -100;
	if (r.AddVertexRef("xxx", E4_IOAT, rank, 0, v) ||
	    v.IsValid()) {
	    fprintf(stderr, "test node51 failed (step 9)\n");
	    return 51;
	}

	/*
	 * Test adding a vertex with E4_IOBEFORE.
	 */

	v = invalidVertex;
	rank = 3;
	if (!r.AddVertexRef("zyx", E4_IOBEFORE, rank, 0, v) ||
	    (!v.IsValid()) ||
	    (rank != 3) ||
	    (v.Rank() != 3)) {
	    fprintf(stderr,
		    "test node51 failed (step 10) r %d valid %d\n",
		    rank, v.IsValid());
	    return 51;
	}

	/*
	 * Test adding a vertex with E4_IOBEFORE at an impossible rank.
	 */

	v = invalidVertex;
	rank = 100000;
	if (r.AddVertexRef("zzz", E4_IOBEFORE, rank, 0, v) ||
	    (v.IsValid())) {
	    fprintf(stderr, "test node51 failed (step 11)\n");
	    return 51;
	}
	rank = -200;
	if (r.AddVertexRef("zzz", E4_IOBEFORE, rank, 0, v) ||
	    (v.IsValid())) {
	    fprintf(stderr, "test node51 failed (step 12)\n");
	    return 51;
	}

	/*
	 * Test adding a vertex with E4_IOAFTER.
	 */

	v = invalidVertex;
	rank = 2;
	if (!r.AddVertexRef("aaa", E4_IOAFTER, rank, 0, v) ||
	    (!v.IsValid()) ||
	    (rank != 3) ||
	    (v.Rank() != 3)) {
	    fprintf(stderr, "test node51 failed (step 13) r = %d\n", rank);
	    return 51;
	}

	/*
	 * Test adding a vertex with E4_IOAFTER with impossible ranks.
	 */

	v = invalidVertex;
	rank = 300000;
	if (r.AddVertexRef("bbb", E4_IOAFTER, rank, 0, v) ||
	    v.IsValid()) {
	    fprintf(stderr, "test node51 failed (step 14)\n");
	    return 51;
	}
	v = invalidVertex;
	rank = -2000;
	if (r.AddVertexRef("bbb", E4_IOAFTER, rank, 0, v) ||
	    v.IsValid()) {
	    fprintf(stderr, "test node51 failed (step 14)\n");
	    return 51;
	}

	s.Delete();
   }

    return 0;
}

int
test_node()
{
    int result = 0;

    fprintf(stderr, "Running e4_Node tests: ");

    result = test_node1();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");

    /*
     * test_node2() and test_node3() have been removed.
     */

    result = test_node4();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node5();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node6();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node7();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node8();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node9();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node10();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node11();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node12();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node13();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node14();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node15();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node16();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node17();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node18();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node19();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node20();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node21();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node22();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node23();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node24();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node25();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node26();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node27();
    if (result != 0) {
	return result;
    }

    /*
     * test_node28 was removed.
     */

    fprintf(stderr, ".");
    result = test_node29();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node30();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node31();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node32();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node33();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node34();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node35();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");

    /*
     * Test test_node36 has been removed.
     */

    result = test_node37();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node38();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node39();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node40();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");

    /*
     * Tests test_node41 and test_node42 were removed.
     */

    result = test_node43();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node44();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node45();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node46();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node47();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node48();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node49();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node50();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_node51();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".\n");
    return 0;
}
