/*
 * testvvisitor.cpp --
 *
 * Tests of the e4_VertexVisitor 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 TV_VERTEXLIMIT	256

static int
test_visitor1()
{
    e4_Node n;

    /*
     * Test node-based constructor.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor1 failed (step 0)\n");
	    return 1;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor1 failed (step 1)\n");
	    return 1;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor1 failed (step 2)\n");
	    return 1;
	}
	e4_VertexVisitor v(n);
	if (!v.IsValid()) {
	    fprintf(stderr, "test vvisitor1 failed (step 6)\n");
	    return 1;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor1 failed (step 7)\n");
	    return 1;
	}
    }

    return 0;
}

static int
test_visitor2()
{
    e4_Node n;
    e4_Vertex f;
    int rank = 0;

    /*
     * Test vertex-based constructor.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor2 failed (step 0)\n");
	    return 2;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor2 failed (step 1)\n");
	    return 2;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor2 failed (step 2)\n");
	    return 2;
	}
	if (!n.AddVertexRef("f1", E4_IOLAST, rank, 32, f)) {
	    fprintf(stderr, "test vvisitor2 failed (step 6)\n");
	    return 2;
	}
	if (!f.IsValid()) {
	    fprintf(stderr, "test vvisitor2 failed (step 7)\n");
	    return 2;
	}
	e4_VertexVisitor v(n);
	if (!v.IsValid()) {
	    fprintf(stderr, "test vvisitor2 failed (step 8)\n");
	    return 2;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor2 failed (step 9)\n");
	    return 2;
	}
    }

    return 0;
}

static int
test_visitor3()
{
    e4_Node n;

    /*
     * Test node-based constructor with invalid node.
     */

    {
	if (n.IsValid()) {
	    fprintf(stderr, "test vvisitor3 failed (step 1)\n");
	    return 3;
	}
	e4_VertexVisitor v(n);
	if (v.IsValid()) {
	    fprintf(stderr, "test vvisitor3 failed (step 2)\n");
	    return 3;
	}
	if (!v.IsDone()) {
	    fprintf(stderr, "test vvisitor3 failed (step 3)\n");
	    return 3;
	}
    }

    return 0;
}

static int
test_visitor4()
{
   e4_Vertex f;

    /*
     * Test node-based constructor with invalid node.
     */

    {
	if (f.IsValid()) {
	    fprintf(stderr, "test vvisitor4 failed (step 1)\n");
	    return 4;
	}
	e4_VertexVisitor v(f);
	if (v.IsValid()) {
	    fprintf(stderr, "test vvisitor4 failed (step 2)\n");
	    return 4;
	}
	if (!v.IsDone()) {
	    fprintf(stderr, "test vvisitor4 failed (step 3)\n");
	    return 4;
	}
    }

    return 0;
}

static int
test_visitor5()
{
    e4_Node n;

    /*
     * Test node-based constructor, operator= and comparison operators.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor5 failed (step 0)\n");
	    return 5;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor5 failed (step 1)\n");
	    return 5;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor5 failed (step 2)\n");
	    return 5;
	}
	e4_VertexVisitor v(n);
	if (!v.IsValid()) {
	    fprintf(stderr, "test vvisitor5 failed (step 6)\n");
	    return 5;
	}
	e4_VertexVisitor vv;
	if (vv.IsValid()) {
	    fprintf(stderr, "test vvisitor5 failed (step 7)\n");
	    return 5;
	}
	if (v == vv) {
	    fprintf(stderr, "test vvisitor5 failed (step 8)\n");
	    return 5;
	}
	vv = v;
	if (!vv.IsValid()) {
	    fprintf(stderr, "test vvisitor5 failed (step 9)\n");
	    return 5;
	}
	if (v != vv) {
	    fprintf(stderr, "test vvisitor5 failed (step 10)\n");
	    return 5;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor5 failed (step 11)\n");
	    return 5;
	}
    }

    return 0;
}

static int
test_visitor6()
{
    e4_Node n;
    e4_Vertex f;
    int rank = 0;

    /*
     * Test vertex-based constructor, operator= and comparison operators.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor6 failed (step 0)\n");
	    return 6;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor6 failed (step 1)\n");
	    return 6;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor6 failed (step 2)\n");
	    return 6;
	}
	if (!n.AddVertexRef("f1", E4_IOLAST, rank, 32, f)) {
	    fprintf(stderr, "test vvisitor6 failed (step 6)\n");
	    return 6;
	}
	if (!f.IsValid()) {
	    fprintf(stderr, "test vvisitor6 failed (step 7)\n");
	    return 6;
	}
	e4_VertexVisitor v(f);
	if (!v.IsValid()) {
	    fprintf(stderr, "test vvisitor6 failed (step 8)\n");
	    return 6;
	}
	e4_VertexVisitor vv;
	if (vv.IsValid()) {
	    fprintf(stderr, "test vvisitor6 failed (step 9)\n");
	    return 6;
	}
	if (v == vv) {
	    fprintf(stderr, "test vvisitor6 failed (step 10)\n");
	    return 6;
	}
	vv = v;
	if (!vv.IsValid()) {
	    fprintf(stderr, "test vvisitor6 failed (step 11)\n");
	    return 6;
	}
	if (v != vv) {
	    fprintf(stderr, "test vvisitor6 failed (step 12)\n");
	    return 6;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor6 failed (step 13)\n");
	    return 6;
	}
    }

    return 0;
}

static int
test_visitor7()
{
    e4_Node n;
    e4_Vertex f;

    /*
     * Test node-based constructor, e4_VertexVisitor::IsValid, 
     * e4_VertexVisitor::IsDone, e4_VertexVisitor::CurrentVertex on empty node.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor7 failed (step 0)\n");
	    return 7;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor7 failed (step 1)\n");
	    return 7;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor7 failed (step 2)\n");
	    return 7;
	}
	e4_VertexVisitor v(n);
	if (!v.IsValid()) {
	    fprintf(stderr, "test vvisitor7 failed (step 6)\n");
	    return 7;
	}
	if (!v.IsDone()) {
	    fprintf(stderr, "test vvisitor7 failed (step 7)\n");
	    return 7;
	}
	if (v.CurrentVertex(f)) {
	    fprintf(stderr, "test vvisitor7 failed (step 8)\n");
	    return 7;
	}
	if (f.IsValid()) {
	    fprintf(stderr, "test vvisitor7 failed (step 9)\n");
	    return 7;
	}
	if (!v.IsDone()) {
	    fprintf(stderr, "test vvisitor7 failed (step 10)\n");
	    return 7;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor7 failed (step 11)\n");
	    return 7;
	}
    }

    return 0;
}

static int
test_visitor8()
{
    e4_Node n;
    e4_Vertex f1, f2;
    int rank = 0;

    /*
     * Test node-based constructor, e4_VertexVisitor::IsValid, 
     * e4_VertexVisitor::IsDone, e4_VertexVisitor::CurrentVertex,
     * e4_VertexVisitor::NextVertex on non-empty node.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor8 failed (step 0)\n");
	    return 8;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor8 failed (step 1)\n");
	    return 8;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor8 failed (step 2)\n");
	    return 8;
	}
	if (!n.AddVertexRef("f1", E4_IOLAST, rank, 32, f1)) {
	    fprintf(stderr, "test vvisitor8 failed (step 6)\n");
	    return 8;
	}
	if (!f1.IsValid()) {
	    fprintf(stderr, "test vvisitor8 failed (step 7)\n");
	    return 8;
	}
	e4_VertexVisitor v(n);
	if (!v.IsValid()) {
	    fprintf(stderr, "test vvisitor8 failed (step 8)\n");
	    return 8;
	}
	if (v.IsDone()) {
	    fprintf(stderr, "test vvisitor8 failed (step 9)\n");
	    return 8;
	}
	if (!v.CurrentVertex(f2)) {
	    fprintf(stderr, "test vvisitor8 failed (step 10)\n");
	    return 8;
	}
	if (!f2.IsValid()) {
	    fprintf(stderr, "test vvisitor8 failed (step 11)\n");
	    return 8;
	}
	if (v.IsDone()) {
	    fprintf(stderr, "test vvisitor8 failed (step 12)\n");
	    return 8;
	}
	if (f1 != f2) {
	    fprintf(stderr, "test vvisitor8 failed (step 13)\n");
	    return 8;
	}
	if (v.NextVertex(f2)) {
	    fprintf(stderr, "test vvisitor8 failed (step 14)\n");
	    return 8;
	}
	if (!v.IsDone()) {
	    fprintf(stderr, "test vvisitor8 failed (step 15)\n");
	    return 8;
	}

	/*
	 * Test that the value of f2 did not change when NextVertex failed.
	 */

	if (f1 != f2) {
	    fprintf(stderr, "test vvisitor8 failed (step 16)\n");
	    return 8;
	}

	/*
	 * Test that v is still valid even though it is "done".
	 */

	if (!v.IsValid()) {
	    fprintf(stderr, "test vvisitor8 failed (step 17)\n");
	    return 8;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor8 failed (step 18)\n");
	    return 8;
	}
    }

    return 0;
}

static int
test_visitor9()
{
    e4_Node n;

    /*
     * Test node-based constructor, e4_VertexVisitor::SetNode
     * and comparison operators.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor9 failed (step 0)\n");
	    return 9;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor9 failed (step 1)\n");
	    return 9;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor9 failed (step 2)\n");
	    return 9;
	}
	e4_VertexVisitor v(n);
	if (!v.IsValid()) {
	    fprintf(stderr, "test vvisitor9 failed (step 6)\n");
	    return 9;
	}
	e4_VertexVisitor vv;
	if (vv.IsValid()) {
	    fprintf(stderr, "test vvisitor9 failed (step 7)\n");
	    return 9;
	}
	if (v == vv) {
	    fprintf(stderr, "test vvisitor9 failed (step 8)\n");
	    return 9;
	}
	if (!vv.SetNode(n)) {
	    fprintf(stderr, "test vvisitor9 failed (step 9)\n");
	    return 9;
	}
	if (!vv.IsValid()) {
	    fprintf(stderr, "test vvisitor9 failed (step 9)\n");
	    return 9;
	}
	if (v != vv) {
	    fprintf(stderr, "test vvisitor9 failed (step 10)\n");
	    return 9;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor9 failed (step 11)\n");
	    return 9;
	}
    }

    return 0;
}

static int
test_visitor10()
{
    e4_Node n;
    e4_Vertex f, f1, f2;
    int rank = 0;

    /*
     * Test node-based constructor, e4_VertexVisitor::SetVertex
     * and comparison operators.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor10 failed (step 0)\n");
	    return 10;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor10 failed (step 1)\n");
	    return 10;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor10 failed (step 2)\n");
	    return 10;
	}
	if (!n.AddVertexRef("f1", E4_IOLAST, rank, 32, f)) {
	    fprintf(stderr, "test vvisitor10 failed (step 6)\n");
	    return 10;
	}
	if (!f.IsValid()) {
	    fprintf(stderr, "test vvisitor10 failed (step 7)\n");
	    return 10;
	}
	e4_VertexVisitor v(n);
	if (!v.IsValid()) {
	    fprintf(stderr, "test vvisitor10 failed (step 8)\n");
	    return 10;
	}
	e4_VertexVisitor vv;
	if (vv.IsValid()) {
	    fprintf(stderr, "test vvisitor10 failed (step 9)\n");
	    return 10;
	}
	if (v == vv) {
	    fprintf(stderr, "test vvisitor10 failed (step 10)\n");
	    return 10;
	}
	if (!vv.SetVertex(f)) {
	    fprintf(stderr, "test vvisitor10 failed (step 11)\n");
	    return 10;
	}
	if (!vv.IsValid()) {
	    fprintf(stderr, "test vvisitor10 failed (step 12)\n");
	    return 10;
	}
	if (v != vv) {
	    fprintf(stderr, "test vvisitor10 failed (step 13)\n");
	    return 10;
	}
	if (!v.CurrentVertex(f1)) {
	    fprintf(stderr, "test vvisitor10 failed (step 14)\n");
	    return 10;
	}
	if (!f1.IsValid()) {
	    fprintf(stderr, "test vvisitor10 failed (step 15)\n");
	    return 10;
	}
	if (!vv.CurrentVertex(f2)) {
	    fprintf(stderr, "test vvisitor10 failed (step 16)\n");
	    return 10;
	}
	if (!f2.IsValid()) {
	    fprintf(stderr, "test vvisitor10 failed (step 17)\n");
	    return 10;
	}
	if ((f1 != f2) || (f1 != f) || (f2 != f)) {
	    fprintf(stderr, "test vvisitor10 failed (step 18)\n");
	    return 10;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor10 failed (step 19)\n");
	    return 10;
	}
    }

    return 0;
}

static int
test_visitor11()
{
    e4_Node n;
    e4_Vertex f;
    int i = 0, j = 0, rank = 0;
    char buf[32];

    /*
     * Test node-based constructor, e4_VertexVisitor::CurrentVertex,
     * e4_VertexVisitor::NextVertex, e4_VertexVisitor::IsDone.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor11 failed (step 0)\n");
	    return 11;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor11 failed (step 1)\n");
	    return 11;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor11 failed (step 2)\n");
	    return 11;
	}
	for (i = 0; i < TV_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i);
	    if (!n.AddVertex(buf, E4_IOLAST, rank, i)) {
		fprintf(stderr, "test vvisitor11 failed (step 6.1.%d)\n", i);
		return 11;
	    }
	    if (rank != i + 1) {
		fprintf(stderr, "test vvisitor11 failed (step 6.2.%d)\n", i);
		return 11;
	    }
	    if (n.VertexCount() != i + 1) {
		fprintf(stderr, "test vvisitor11 failed (step 6.3.%d)\n", i);
		return 11;
	    }
	}
	e4_VertexVisitor v(n);
	for (i = 0; !v.IsDone(); i++, v.NextVertex(f)) {
	    if (!v.CurrentVertex(f)) {
		fprintf(stderr, "test vvisitor11 failed (step 7.1.%d)\n", i);
		return 11;
	    }
	    if (!f.IsValid()) {
		fprintf(stderr, "test vvisitor11 failed (step 7.2.%d)\n", i);
		return 11;
	    }
	    if (v.IsDone()) {
		fprintf(stderr, "test vvisitor11 failed (step 7.3.%d)\n", i);
		return 11;
	    }
	    if (!f.Get(j)) {
		fprintf(stderr, "test vvisitor11 failed (step 7.4.%d)\n", i);
		return 11;
	    }
	    if (j != i) {
		fprintf(stderr, "test vvisitor11 failed (step 7.5.%d)\n", i);
		return 11;
	    }
	    if (f.Rank() != i + 1) {
		fprintf(stderr, "test vvisitor11 failed (step 7.6.%d)\n", i);
		return 11;
	    }
	    sprintf(buf, "f%d", i);
	    if (strcmp(f.Name(), buf) != 0) {
		fprintf(stderr, "test vvisitor11 failed (step 7.7.%d)\n", i);
		return 11;
	    }
	}
	if (i != TV_VERTEXLIMIT) {
	    fprintf(stderr, "test vvisitor11 failed (step 8)\n");
	    return 11;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor11 failed (step 9)\n");
	    return 11;
	}
    }

    return 0;
}

static int
test_visitor12()
{
    e4_Node n;
    e4_Vertex f, hf;
    int i = 0, j = 0, rank = 0;
    char buf[32];

    /*
     * Test node-based constructor, e4_SetVertex, 
     * e4_VertexVisitor::CurrentVertex, e4_VertexVisitor::NextVertex,
     * e4_VertexVisitor::IsDone.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor12 failed (step 0)\n");
	    return 12;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor12 failed (step 1)\n");
	    return 12;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor12 failed (step 2)\n");
	    return 12;
	}
	for (i = 0; i < TV_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i);
	    if (!n.AddVertex(buf, E4_IOLAST, rank, i)) {
		fprintf(stderr, "test vvisitor12 failed (step 6.1.%d)\n", i);
		return 12;
	    }
	    if (rank != i + 1) {
		fprintf(stderr, "test vvisitor12 failed (step 6.2.%d)\n", i);
		return 12;
	    }
	    if (n.VertexCount() != i + 1) {
		fprintf(stderr, "test vvisitor12 failed (step 6.3.%d)\n", i);
		return 12;
	    }
	}
	e4_VertexVisitor v(n);
	for (i = 0; !v.IsDone(); i++, v.NextVertex(f)) {
	    if (!v.CurrentVertex(f)) {
		fprintf(stderr, "test vvisitor12 failed (step 7.1.%d)\n", i);
		return 12;
	    }
	    if (!f.IsValid()) {
		fprintf(stderr, "test vvisitor12 failed (step 7.2.%d)\n", i);
		return 12;
	    }
	    if (i == 0) {
		hf = f;
	    }
	    if (v.IsDone()) {
		fprintf(stderr, "test vvisitor12 failed (step 7.3.%d)\n", i);
		return 12;
	    }
	    if (!f.Get(j)) {
		fprintf(stderr, "test vvisitor12 failed (step 7.4.%d)\n", i);
		return 12;
	    }
	    if (j != i) {
		fprintf(stderr, "test vvisitor12 failed (step 7.5.%d)\n", i);
		return 12;
	    }
	    if (f.Rank() != i + 1) {
		fprintf(stderr, "test vvisitor12 failed (step 7.6.%d)\n", i);
		return 12;
	    }
	    sprintf(buf, "f%d", i);
	    if (strcmp(f.Name(), buf) != 0) {
		fprintf(stderr, "test vvisitor12 failed (step 7.7.%d)\n", i);
		return 12;
	    }
	}
	if (i != TV_VERTEXLIMIT) {
	    fprintf(stderr, "test vvisitor12 failed (step 8)\n");
	    return 12;
	}
	if (!v.SetVertex(hf)) {
	    fprintf(stderr, "test vvisitor12 failed (step 9)\n");
	    return 12;
	}
	if (v.IsDone()) {
	    fprintf(stderr, "test vvisitor12 failed (step 10)\n");
	    return 12;
	}
	if (!v.CurrentVertex(f)) {
	    fprintf(stderr, "test vvisitor12 failed (step 11)\n");
	    return 12;
	}
	if (!f.IsValid()) {
	    fprintf(stderr, "test vvisitor12 failed (step 12)\n");
	    return 12;
	}
	if (f != hf) {
	    fprintf(stderr, "test vvisitor12 failed (step 13)\n");
	    return 12;
	}
	for (i = 0; !v.IsDone(); i++, v.NextVertex(f)) {
	    if (!v.CurrentVertex(f)) {
		fprintf(stderr, "test vvisitor12 failed (step 14.1.%d)\n", i);
		return 12;
	    }
	    if (!f.IsValid()) {
		fprintf(stderr, "test vvisitor12 failed (step 14.2.%d)\n", i);
		return 12;
	    }
	    if (i == 0) {
		hf = f;
	    }
	    if (v.IsDone()) {
		fprintf(stderr, "test vvisitor12 failed (step 14.3.%d)\n", i);
		return 12;
	    }
	    if (!f.Get(j)) {
		fprintf(stderr, "test vvisitor12 failed (step 14.4.%d)\n", i);
		return 12;
	    }
	    if (j != i) {
		fprintf(stderr, "test vvisitor12 failed (step 14.5.%d)\n", i);
		return 12;
	    }
	    if (f.Rank() != i + 1) {
		fprintf(stderr, "test vvisitor12 failed (step 14.6.%d)\n", i);
		return 12;
	    }
	    sprintf(buf, "f%d", i);
	    if (strcmp(f.Name(), buf) != 0) {
		fprintf(stderr, "test vvisitor12 failed (step 14.7.%d)\n", i);
		return 12;
	    }
	}
	if (i != TV_VERTEXLIMIT) {
	    fprintf(stderr, "test vvisitor12 failed (step 15)\n");
	    return 12;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor12 failed (step 16)\n");
	    return 12;
	}
    }

    return 0;
}

static int
test_visitor13()
{
    e4_Node n;
    e4_Vertex f, nf;
    int i = 0, j = 0, rank = 0;
    char buf[32];

    /*
     * Test node-based constructor, e4_VertexVisitor::CurrentVertex,
     * e4_VertexVisitor::NextVertex, e4_VertexVisitor::IsDone with 
     * vertex detaching.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor13 failed (step 0)\n");
	    return 13;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor13 failed (step 1)\n");
	    return 13;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor13 failed (step 2)\n");
	    return 13;
	}
	for (i = 0; i < TV_VERTEXLIMIT; i++) {
	    sprintf(buf, "f%d", i);
	    if (!n.AddVertex(buf, E4_IOLAST, rank, i)) {
		fprintf(stderr, "test vvisitor13 failed (step 6.1.%d)\n", i);
		return 13;
	    }
	    if (rank != i + 1) {
		fprintf(stderr, "test vvisitor13 failed (step 6.2.%d)\n", i);
		return 13;
	    }
	    if (n.VertexCount() != i + 1) {
		fprintf(stderr, "test vvisitor13 failed (step 6.3.%d)\n", i);
		return 13;
	    }
	}
	if (n.VertexCount() != TV_VERTEXLIMIT) {
	    fprintf(stderr, "test vvisitor13 failed (step 7)\n");
	    return 13;
	}
	e4_VertexVisitor v;

	v.SetNode(n);
	for (i = 0; !v.IsDone(); i++) {
	    if (!v.CurrentVertex(f)) {
		fprintf(stderr, "test vvisitor13 failed (step 8.1.%d)\n", i);
		return 13;
	    }
	    if (!f.IsValid()) {
		fprintf(stderr, "test vvisitor13 failed (step 8.2.%d)\n", i);
		return 13;
	    }
	    if (v.IsDone()) {
		fprintf(stderr, "test vvisitor13 failed (step 8.3.%d)\n", i);
		return 13;
	    }
	    if (!f.Get(j)) {
		fprintf(stderr, "test vvisitor13 failed (step 8.4.%d)\n", i);
		return 13;
	    }
	    if (j != i) {
		fprintf(stderr, "test vvisitor13 failed (step 8.5.%d)\n", i);
		return 13;
	    }
	    if (f.Rank() != 1) {
		fprintf(stderr, "test vvisitor13 failed (step 8.6.%d)\n", i);
		return 13;
	    }
	    sprintf(buf, "f%d", i);
	    if (strcmp(f.Name(), buf) != 0) {
		fprintf(stderr, "test vvisitor13 failed (step 8.7.%d)\n", i);
		return 13;
	    }
	    v.NextVertex(nf);
	    f.Detach();
	    f = invalidVertex;
	}
	if (i != TV_VERTEXLIMIT) {
	    fprintf(stderr, "test vvisitor13 failed (step 9)\n");
	    return 13;
	}
	if (n.VertexCount() != 0) {
	    fprintf(stderr, "test vvisitor13 failed (step 10)\n");
	    return 13;
	}
	/*
	 * Setting the visitor from an empty node should cause it to
	 * be "done" right away, but valid.
	 */
	if (!v.SetNode(n)) {
	    fprintf(stderr, "test vvisitor13 failed (step 11)\n");
	    return 13;
	}
	if (!v.IsValid()) {
	    fprintf(stderr, "test vvisitor13 failed (step 12)\n");
	    return 13;
	}
	if (!v.IsDone()) {
	    fprintf(stderr, "test vvisitor13 failed (step 13)\n");
	    return 13;
	}
	if (!v.CurrentVertex(f)) {
	    fprintf(stderr, "test vvisitor13 failed (step 14)\n");
	    return 13;
	}
	if (!f.IsValid()) {
	    fprintf(stderr, "test vvisitor13 failed (step 15)\n");
	    return 13;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor13 failed (step 16)\n");
	    return 13;
	}
    }

    return 0;
}

static int
test_visitor14()
{
    e4_Node n, n1;
    e4_Vertex f;
    int rank = 0;

    /*
     * Test node-based constructor, e4_VertexVisitor::CurrentVertex,
     * e4_VertexVisitor::NextVertex, e4_VertexVisitor::IsDone with 
     * node detaching.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor14 failed (step 0)\n");
	    return 14;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor14 failed (step 1)\n");
	    return 14;
	}
	if (!s.GetRootNode(n) || !n.IsRoot() || !n.IsValid()) {
	    fprintf(stderr, "test vvisitor14 failed (step 2)\n");
	    return 14;
	}
	if (!n.AddNode("f1", E4_IOLAST, rank, n1)) {
	    fprintf(stderr, "test vvisitor14 failed (step 6)\n");
	    return 14;
	}
	if (!n1.IsValid()) {
	    fprintf(stderr, "test vvisitor14 failed (step 7)\n");
	    return 14;
	}
	if (!n1.AddVertex("f1", E4_IOLAST, rank, 32)) {
	    fprintf(stderr, "test vvisitor14 failed (step 8)\n");
	    return 14;
	}
	e4_VertexVisitor v;

	v.SetNode(n1);
	if (!v.IsValid()) {
	    fprintf(stderr, "test vvisitor14 failed (step 9)\n");
	    return 14;
	}
	if (v.IsDone()) {
	    fprintf(stderr, "test vvisitor14 failed (step 10)\n");
	    return 14;
	}
	if (!v.CurrentVertex(f)) {
	    fprintf(stderr, "test vvisitor14 failed (step 11)\n");
	    return 14;
	}
	if (!n1.Detach()) {
	    fprintf(stderr, "test vvisitor14 failed (step 12)\n");
	    return 14;
	}
	if (!f.IsValid() || !n1.IsValid()) {
	    fprintf(stderr, "test vvisitor14 failed (step 13)\n");
	    return 14;
	}
	if (v.IsDone()) {
	    fprintf(stderr, "test vvisitor14 failed (step 14)\n");
	    return 14;
	}
	if (!v.CurrentVertex(f)) {
	    fprintf(stderr, "test vvisitor14 failed (step 15)\n");
	    return 14;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor14 failed (step 16)\n");
	    return 14;
	}
    }

    return 0;
}

static int
test_visitor15()
{
    e4_Node n, n1;
    e4_Vertex f;
    int rank = 0;

    /*
     * Test node-based constructor, e4_VertexVisitor::CurrentVertex,
     * e4_VertexVisitor::NextVertex, e4_VertexVisitor::IsDone
     * with vertex detachment.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor15 failed (step 0)\n");
	    return 15;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor15 failed (step 1)\n");
	    return 15;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor15 failed (step 2)\n");
	    return 15;
	}
	if (!n.AddNode("f1", E4_IOLAST, rank, n1)) {
	    fprintf(stderr, "test vvisitor15 failed (step 6)\n");
	    return 15;
	}
	if (!n1.IsValid()) {
	    fprintf(stderr, "test vvisitor15 failed (step 7)\n");
	    return 15;
	}
	if (!n1.AddVertex("f1", E4_IOLAST, rank, 32)) {
	    fprintf(stderr, "test vvisitor15 failed (step 8)\n");
	    return 15;
	}
	e4_VertexVisitor v;

	v.SetNode(n1);
	if (!v.IsValid()) {
	    fprintf(stderr, "test vvisitor15 failed (step 9)\n");
	    return 15;
	}
	if (v.IsDone()) {
	    fprintf(stderr, "test vvisitor15 failed (step 10)\n");
	    return 15;
	}
	if (!v.CurrentVertex(f)) {
	    fprintf(stderr, "test vvisitor15 failed (step 11)\n");
	    return 15;
	}
	if (!f.Detach() || !f.IsDetached()) {
	    fprintf(stderr, "test vvisitor15 failed (step 12)\n");
	    return 15;
	}
	if (!f.IsValid()) {
	    fprintf(stderr, "test vvisitor15 failed (step 13)\n");
	    return 15;
	}
	if (v.IsDone()) {
	    fprintf(stderr, "test vvisitor15 failed (step 14)\n");
	    return 15;
	}
	if (!v.CurrentVertex(f)) {
	    fprintf(stderr, "test vvisitor15 failed (step 15)\n");
	    return 15;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor15 failed (step 16)\n");
	    return 15;
	}
    }

    return 0;
}

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

    /*
     * Test node-based constructor, assignment operator,
     * construction by reference, e4_VertexVisitor::StorageVisited,
     * e4_VertexVisitor::NodeVisited, e4_VertexVisitor::VisitMethod,
     * e4_VertexVisitor::VisitFilter, e4_VertexVisitor::TypeFilter,
     * e4_VertexVisitor::NameFilter.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor16 failed (step 0)\n");
	    return 16;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor16 failed (step 1)\n");
	    return 16;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor16 failed (step 2)\n");
	    return 16;
	}
	if (!n.AddNode("f1", E4_IOLAST, rank, n1)) {
	    fprintf(stderr, "test vvisitor16 failed (step 6)\n");
	    return 16;
	}
	if (!n1.IsValid()) {
	    fprintf(stderr, "test vvisitor16 failed (step 7)\n");
	    return 16;
	}
	if (!n1.AddVertex("f1", E4_IOLAST, rank, 32)) {
	    fprintf(stderr, "test vvisitor16 failed (step 8)\n");
	    return 16;
	}
	e4_VertexVisitor v(n1);
	if (!v.IsValid()) {
	    fprintf(stderr, "test vvisitor16 failed (step 9)\n");
	    return 16;
	}
	if (!v.NodeVisited(n2)) {
	    fprintf(stderr, "test vvisitor16 failed (step 10)\n");
	    return 16;
	}
	if (n1 != n2) {
	    fprintf(stderr, "test vvisitor16 failed (step 11)\n");
	    return 16;
	}
	e4_Storage s1;
	if (!v.StorageVisited(s1)) {
	    fprintf(stderr, "test vvisitor16 failed (step 12)\n");
	    return 16;
	}
	if (s1 != s) {
	    fprintf(stderr, "test vvisitor16 failed (step 13)\n");
	    return 16;
	}
	if (v.VisitMethod() != E4_VMNODE) {
	    fprintf(stderr, "test vvisitor16 failed (step 14)\n");
	    return 16;
	}
	if (v.VisitFilter() != E4_VFNONE) {
	    fprintf(stderr, "test vvisitor16 failed (step 15)\n");
	    return 16;
	}
	if (v.TypeFilter() != E4_VTUNKNOWN) {
	    fprintf(stderr, "test vvisitor16 failed (step 16)\n");
	    return 16;
	}
	e4_VertexVisitor v1(v);
	if ((v.VisitMethod() != v1.VisitMethod()) ||
	    (v.VisitFilter() != v1.VisitFilter()) ||
	    (v.TypeFilter() != v1.TypeFilter())) {
	    fprintf(stderr, "test vvisitor16 failed (step 17)\n");
	    return 16;
	}
	if ((v.NameFilter() != NULL) && (v1.NameFilter())) {
	    fprintf(stderr, "test vvisitor16 failed (step 18)\n");
	    return 16;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor16 failed (step 19)\n");
	    return 16;
	}
    }

    return 0;
}

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

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor17 failed (step 0)\n");
	    return 17;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor17 failed (step 1)\n");
	    return 17;
	}
	if (!s.GetRootNode(n1) || !n1.IsValid() || !n1.IsRoot()) {
	    fprintf(stderr, "test vvisitor17 failed (step 2)\n");
	    return 17;
	}
	if (!n1.AddVertex("n1f1", E4_IOLAST, rank, 32)) {
	    fprintf(stderr, "test vvisitor17 failed (step 6)\n");
	    return 17;
	}
	if (!s.CreateDetachedNode(n2) || !n2.IsValid() || n2.IsRoot() ||
	    !n2.IsDetached()) {
	    fprintf(stderr, "test vvisitor17 failed (step 7)\n");
	    return 17;
	}
	if (!n2.AddVertex("n2f1", E4_IOLAST, rank, 32)) {
	    fprintf(stderr, "test vvisitor17 failed (step 11)\n");
	    return 17;
	}
	if (!s.CreateDetachedNode(n3) || !n3.IsValid() || n3.IsRoot() ||
	    !n3.IsDetached()) {
	    fprintf(stderr, "test vvisitor17 failed (step 12)\n");
	    return 17;
	}
	if (!n3.AddVertex("n3f1", E4_IOLAST, rank, 32)) {
	    fprintf(stderr, "test vvisitor17 failed (step 16)\n");
	    return 17;
	}
	e4_VertexVisitor v(s);
	if (!v.IsValid()) {
	    fprintf(stderr, "test vvisitor17 failed (step 17)\n");
	    return 17;
	}
	if (v.VisitMethod() != E4_VMSTORAGE) {
	    fprintf(stderr, "test vvisitor17 failed (step 18)\n");
	    return 17;
	}
	if (v.IsDone()) {
	    fprintf(stderr, "test vvisitor17 failed (step 19)\n");
	    return 17;
	}
	for (i = 0; i < 3; i++, (void) v.NextVertex(f)) {
	    if (!v.CurrentVertex(f)) {
	        break;
	    }
	}
	if ((!v.IsDone()) || (i != 3)) {
	    fprintf(stderr, "test vvisitor17 failed (step 20)\n");
	    return 17;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor17 failed (step 21)\n");
	    return 17;
	}
    }

    return 0;
}
    
static int
test_visitor18()
{
    e4_Node n;
    int rank = 0, i = 0;
    e4_Vertex f;

    /*
     * Test that a visitor constructed by assignment from another
     * visitor starts at the same place and visits the same vertices.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor18 failed (step 0)\n");
	    return 18;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor18 failed (step 1)\n");
	    return 18;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor18 failed (step 2)\n");
	    return 18;
	}
	for (i = 0; i < 15; i++) {
	    if (!n.AddVertex("f", E4_IOLAST, rank, i)) {
		fprintf(stderr, "test vvisitor18 failed (step 6.%d)\n", i);
		return 18;
	    }
	}
	e4_VertexVisitor v1(n);
	if (!v1.IsValid()) {
	    fprintf(stderr, "test vvisitor18 failed (step 7)\n");
	    return 18;
	}
	for (i = 0; i < 7; i++, (void) v1.NextVertex(f)) {
	    if (!v1.CurrentVertex(f)) {
		fprintf(stderr, "test vvisitor18 failed (step 8.%d)\n", i);
		return 18;
	    }
	}
	e4_VertexVisitor v2(v1);
	if (!v2.IsValid()) {
	    fprintf(stderr, "test vvisitor18 failed (step 9)\n");
	    return 18;
	}
	for (i = 0; i < 8; i++, (void) v2.NextVertex(f)) {
	    if (!v2.CurrentVertex(f)) {
		break;
	    }
	}
	if ((!v2.IsDone()) || (i != 8)) {
	    fprintf(stderr, "test vvisitor18 failed (step 10)\n");
	    return 18;
	}
	v2 = v1;
	if ((!v2.IsValid()) || (v2.IsDone())) {
	    fprintf(stderr, "test vvisitor18 failed (step 11)\n");
	    return 18;
	}
	for (i = 0; i < 8; i++, (void) v2.NextVertex(f)) {
	    if (!v2.CurrentVertex(f)) {
		break;
	    }
	}
	if ((!v2.IsDone()) || (i != 8)) {
	    fprintf(stderr, "test vvisitor18 failed (step 12)\n");
	    return 18;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor18 failed (step 13)\n");
	    return 18;
	}
    }

    return 0;
}
    
static int
test_visitor19()
{
    e4_Node n;
    int rank = 0, i = 0;
    e4_Vertex f;

    /*
     * Test a visitor created from a node with a name or type filter.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor19 failed (step 0)\n");
	    return 19;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor19 failed (step 1)\n");
	    return 19;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor19 failed (step 2)\n");
	    return 19;
	}
	for (i = 0; i < 15; i++) {
	    if (i == 7) {
		if (!n.AddVertex("f7", E4_IOLAST, rank, i)) {
		    fprintf(stderr, "test vvisitor19 failed (step 6.%d)\n", i);
		    return 19;
		}
	    } else {
	      if (!n.AddVertex("f", E4_IOLAST, rank, i)) {
		  fprintf(stderr, "test vvisitor19 failed (step 6.%d)\n", i);
		  return 19;
	      }
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n.AddVertex("g", E4_IOFIRST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor19 failed (step 7.1.%d)\n", i);
		return 19;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n.AddVertex("g", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor19 failed (step 7.2.%d)\n", i);
		return 19;
	    }
	}
	e4_VertexVisitor v1(n, "f", E4_VTUNKNOWN);
	if ((!v1.IsValid()) || (v1.IsDone())) {
	    fprintf(stderr, "test vvisitor19 failed (step 8)\n");
	    return 19;
	}
	for (i = 0; i < 14; i++, (void) v1.NextVertex(f)) {
	    if (!v1.CurrentVertex(f)) {
		fprintf(stderr, "test vvisitor19 failed (step 9.%d)\n", i);
		return 19;
	    }
	}
	if ((!v1.IsDone()) || (i != 14)) {
	    fprintf(stderr, "test vvisitor19 failed (step 10)\n");
	    return 19;
	}
	e4_VertexVisitor v2(n, NULL, E4_VTINT);
	if (!v2.IsValid()) {
	    fprintf(stderr, "test vvisitor19 failed (step 11)\n");
	    return 19;
	}
	for (i = 0; i < 15; i++, (void) v2.NextVertex(f)) {
	    if (!v2.CurrentVertex(f)) {
		break;
	    }
	}
	if ((!v2.IsDone()) || (i != 15)) {
	    fprintf(stderr, "test vvisitor19 failed (step 12)\n");
	    return 19;
	}

        e4_VertexVisitor v3;
        
        v3.SetNode(n, "f", E4_VTUNKNOWN);
	if ((!v3.IsValid()) || (v3.IsDone())) {
	    fprintf(stderr, "test vvisitor19 failed (step 13)\n");
	    return 19;
	}
	for (i = 0; i < 14; i++, (void) v3.NextVertex(f)) {
	    if (!v3.CurrentVertex(f)) {
		fprintf(stderr, "test vvisitor19 failed (step 14.%d)\n", i);
		return 19;
	    }
	}
	if ((!v3.IsDone()) || (i != 14)) {
	    fprintf(stderr, "test vvisitor19 failed (step 15)\n");
	    return 19;
	}

        e4_VertexVisitor v4;
        
        v4.SetNode(n, NULL, E4_VTINT);
	if (!v4.IsValid()) {
	    fprintf(stderr, "test vvisitor19 failed (step 16)\n");
	    return 19;
	}
	for (i = 0; i < 15; i++, (void) v4.NextVertex(f)) {
	    if (!v4.CurrentVertex(f)) {
		break;
	    }
	}
	if ((!v4.IsDone()) || (i != 15)) {
	    fprintf(stderr, "test vvisitor19 failed (step 17)\n");
	    return 19;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor19 failed (step 18)\n");
	    return 19;
	}
    }

    return 0;
}
    
static int
test_visitor20()
{
    e4_Node n;
    int rank = 0, i = 0;
    e4_Vertex f1, f2;

    /*
     * Test a visitor created from a vertex with name or type filters
     * Uses e4_VertexVisitor::SetVertex.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor20 failed (step 0)\n");
	    return 20;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor20 failed (step 1)\n");
	    return 20;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor20 failed (step 2)\n");
	    return 20;
	}
	for (i = 0; i < 15; i++) {
            if (!n.AddVertex("f", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test vvisitor20 failed (step 6.%d)\n", i);
                return 20;
            }
        }
	for (i = 0; i < 7; i++) {
	    if (!n.AddVertex("g", E4_IOFIRST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor20 failed (step 7.1.%d)\n", i);
		return 20;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n.AddVertex("g", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor20 failed (step 7.2.%d)\n", i);
		return 20;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n.AddVertex("f", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor20 failed (step 7.3.%d)\n", i);
		return 20;
	    }
	}
        if (!n.GetVertexRef("f", 1, f1)) {
            fprintf(stderr, "test vvisitor20 failed (step 8)\n");
            return 20;
        }

        /*
         * This visitor is supposed to visit all vertices named "f" in
         * the node containing the supplied vertex.
         */

        e4_VertexVisitor v1(f1, true, false);
	if ((!v1.IsValid()) || (v1.IsDone())) {
	    fprintf(stderr, "test vvisitor20 failed (step 9)\n");
	    return 20;
	}
	for (i = 0; i < 22; i++, (void) v1.NextVertex(f2)) {
	    if (!v1.CurrentVertex(f2)) {
		fprintf(stderr, "test vvisitor20 failed (step 10.%d)\n", i);
		return 20;
	    }
	}
	if ((!v1.IsDone()) || (i != 22)) {
	    fprintf(stderr, "test vvisitor20 failed (step 11, i == %d)\n", i);
	    return 20;
	}

        /*
         * This visitor is supposed to visit all vertices with type integer
         * in the node containing the supplied vertex.
         */

	e4_VertexVisitor v2(f1, false, true);
	if (!v2.IsValid()) {
	    fprintf(stderr, "test vvisitor20 failed (step 12)\n");
	    return 20;
	}
	for (i = 0; i < 15; i++, (void) v2.NextVertex(f2)) {
	    if (!v2.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v2.IsDone()) || (i != 15)) {
	    fprintf(stderr, "test vvisitor20 failed (step 13)\n");
	    return 20;
	}

        e4_VertexVisitor v3;
        
        /*
         * This visitor is supposed to visit all vertices with name "f" in
         * the node containing the supplied vertex.
         */

        v3.SetVertex(f1, true, false);
	if ((!v3.IsValid()) || (v3.IsDone())) {
	    fprintf(stderr, "test vvisitor20 failed (step 14)\n");
	    return 20;
	}
	for (i = 0; i < 22; i++, (void) v3.NextVertex(f2)) {
	    if (!v3.CurrentVertex(f2)) {
		fprintf(stderr, "test vvisitor20 failed (step 15.%d)\n", i);
		return 20;
	    }
	}
	if ((!v3.IsDone()) || (i != 22)) {
	    fprintf(stderr, "test vvisitor20 failed (step 16)\n");
	    return 20;
	}

        e4_VertexVisitor v4;
        
        /*
         * This visitor is supposed to visit all vertices with type integer
         * in the node containing the supplied vertex.
         */

        v4.SetVertex(f1, false, true);
	if (!v4.IsValid()) {
	    fprintf(stderr, "test vvisitor20 failed (step 17)\n");
	    return 20;
	}
	for (i = 0; i < 15; i++, (void) v4.NextVertex(f2)) {
	    if (!v4.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v4.IsDone()) || (i != 15)) {
	    fprintf(stderr, "test vvisitor20 failed (step 18)\n");
	    return 20;
	}

        /*
         * This visitor is supposed to visit all vertices with name "f" and
         * type integer in the node containing the supplied vertex.
         */

        e4_VertexVisitor v5(f1, true, true);
	if (!v5.IsValid()) {
	    fprintf(stderr, "test vvisitor20 failed (step 19)\n");
	    return 20;
	}
	for (i = 0; i < 15; i++, (void) v5.NextVertex(f2)) {
	    if (!v5.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v5.IsDone()) || (i != 15)) {
	    fprintf(stderr, "test vvisitor20 failed (step 20)\n");
	    return 20;
	}

        e4_VertexVisitor v6;
        
        /*
         * This visitor is supposed to visit all vertices with name "f" and
         * type integer in the node containing the supplied vertex.
         */

        v6.SetVertex(f1, true, true);
	if (!v6.IsValid()) {
	    fprintf(stderr, "test vvisitor20 failed (step 21)\n");
	    return 20;
	}
	for (i = 0; i < 15; i++, (void) v6.NextVertex(f2)) {
	    if (!v6.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v6.IsDone()) || (i != 15)) {
	    fprintf(stderr, "test vvisitor20 failed (step 22)\n");
	    return 20;
	}

        /*
         * This visitor is supposed to visit all vertices after the supplied
         * vertex in the node containing the given vertex (including the
         * given vertex).
         */

        e4_VertexVisitor v7(f1, false, false);
	if (!v7.IsValid()) {
	    fprintf(stderr, "test vvisitor20 failed (step 23)\n");
	    return 20;
	}
	for (i = 0; i < 29; i++, (void) v7.NextVertex(f2)) {
	    if (!v7.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v7.IsDone()) || (i != 29)) {
	    fprintf(stderr, "test vvisitor20 failed (step 24)\n");
	    return 20;
	}

        e4_VertexVisitor v8;

        /*
         * This visitor is supposed to visit all vertices avter the supplied
         * vertex in the node containing the given vertex (including the
         * given vertex).
         */

        v8.SetVertex(f1, false, false);
	if (!v8.IsValid()) {
	    fprintf(stderr, "test vvisitor20 failed (step 25)\n");
	    return 20;
	}
	for (i = 0; i < 29; i++, (void) v8.NextVertex(f2)) {
	    if (!v8.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v8.IsDone()) || (i != 29)) {
	    fprintf(stderr, "test vvisitor20 failed (step 26)\n");
	    return 20;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor20 failed (step 27)\n");
	    return 20;
	}
    }

    return 0;
}
    
static int
test_visitor22()
{
    e4_Node n1, n2, n3;
    int rank = 0, i = 0;
    e4_Vertex f1, f2;

    /*
     * Test a visitor created from a vertex with name or type filters and
     * visit method E4_VMSTORAGE. Uses e4_VertexVisitor::SetVertex.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor22 failed (step 0)\n");
	    return 22;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor22 failed (step 1)\n");
	    return 22;
	}
	if (!s.GetRootNode(n1) || !n1.IsValid() || !n1.IsRoot()) {
	    fprintf(stderr, "test vvisitor22 failed (step 2.1)\n");
	    return 22;
	}
	if (!s.CreateDetachedNode(n2) || !n2.IsValid() || n2.IsRoot() ||
	    !n2.IsDetached()) {
            fprintf(stderr, "test vvisitor22 failed (step 2.2)\n");
            return 22;
        }
	for (i = 0; i < 15; i++) {
            if (!n1.AddVertex("f", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test vvisitor22 failed (step 6.1.%d)\n", i);
                return 22;
            }
        }
	for (i = 0; i < 15; i++) {
            if (!n2.AddVertex("f", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test vvisitor22 failed (step 6.2.%d)\n", i);
                return 22;
            }
        }
	for (i = 0; i < 7; i++) {
	    if (!n1.AddVertex("g", E4_IOFIRST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor22 failed (step 7.1.1.%d)\n", i);
		return 22;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n2.AddVertex("g", E4_IOFIRST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor22 failed (step 7.1.2.%d)\n", i);
		return 22;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n1.AddVertex("g", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor22 failed (step 7.2.1.%d)\n", i);
		return 22;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n2.AddVertex("g", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor22 failed (step 7.2.2.%d)\n", i);
		return 22;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n1.AddVertex("f", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor22 failed (step 7.3.1.%d)\n", i);
		return 22;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n2.AddVertex("f", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor22 failed (step 7.3.2.%d)\n", i);
		return 22;
	    }
	}
        if (!n1.AddNode("boo", E4_IOLAST, rank, n3)) {
            fprintf(stderr, "test vvisitor22 failed (step 7.4)\n");
            return 22;
        }
        for (i = 0; i < 20; i++) {
            if (!n3.AddVertex("f", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test vvisitor22 failed (step 7.5.%d)\n", i);
                return 22;
            }
        }
        for (i = 0; i < 17; i++) {
            if (!n3.AddVertex("f", E4_IOLAST, rank, (double) 7.35)) {
                fprintf(stderr, "test vvisitor22 failed (step 7.6.%d)\n", i);
                return 22;
            }
        }
        if (!n1.GetVertexRef("f", 1, f1)) {
            fprintf(stderr, "test vvisitor22 failed (step 8)\n");
            return 22;
        }

        /*
         * This visitor is supposed to visit all vertices named "f" in
         * the storage containing the supplied vertex.
         */

        e4_VertexVisitor v1(f1, true, false, E4_VMSTORAGE);
	if ((!v1.IsValid()) || (v1.IsDone())) {
	    fprintf(stderr, "test vvisitor22 failed (step 9)\n");
	    return 22;
	}
	for (i = 0; i < 81; i++, (void) v1.NextVertex(f2)) {
	    if (!v1.CurrentVertex(f2)) {
	        break;
	    }
	}
	if ((!v1.IsDone()) || (i != 81)) {
	    fprintf(stderr, "test vvisitor22 failed (step 11, i = %d)\n", i);
	    return 22;
	}

        /*
         * This visitor is supposed to visit all vertices with type integer
         * in the storage containing the supplied vertex.
         */

	e4_VertexVisitor v2(f1, false, true, E4_VMSTORAGE);
	if (!v2.IsValid()) {
	    fprintf(stderr, "test vvisitor22 failed (step 12)\n");
	    return 22;
	}
	for (i = 0; i < 50; i++, (void) v2.NextVertex(f2)) {
	    if (!v2.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v2.IsDone()) || (i != 50)) {
	    fprintf(stderr, "test vvisitor22 failed (step 13)\n");
	    return 22;
	}

        e4_VertexVisitor v3;
        
        /*
         * This visitor is supposed to visit all vertices with name "f" in
         * the storage containing the supplied vertex.
         */

        v3.SetVertex(f1, true, false, E4_VMSTORAGE);
	if ((!v3.IsValid()) || (v3.IsDone())) {
	    fprintf(stderr, "test vvisitor22 failed (step 14)\n");
	    return 22;
	}
	for (i = 0; i < 81; i++, (void) v3.NextVertex(f2)) {
	    if (!v3.CurrentVertex(f2)) {
		fprintf(stderr, "test vvisitor22 failed (step 15.%d)\n", i);
		return 22;
	    }
	}
	if ((!v3.IsDone()) || (i != 81)) {
	    fprintf(stderr, "test vvisitor22 failed (step 16)\n");
	    return 22;
	}

        e4_VertexVisitor v4;
        
        /*
         * This visitor is supposed to visit all vertices with type integer
         * in the storage containing the supplied vertex.
         */

        v4.SetVertex(f1, false, true, E4_VMSTORAGE);
	if (!v4.IsValid()) {
	    fprintf(stderr, "test vvisitor22 failed (step 17)\n");
	    return 22;
	}
	for (i = 0; i < 50; i++, (void) v4.NextVertex(f2)) {
	    if (!v4.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v4.IsDone()) || (i != 50)) {
	    fprintf(stderr, "test vvisitor22 failed (step 18)\n");
	    return 22;
	}

        /*
         * This visitor is supposed to visit all vertices with name "f" and
         * type integer in the storage containing the supplied vertex.
         */

        e4_VertexVisitor v5(f1, true, true, E4_VMSTORAGE);
	if (!v5.IsValid()) {
	    fprintf(stderr, "test vvisitor22 failed (step 19)\n");
	    return 22;
	}
	for (i = 0; i < 50; i++, (void) v5.NextVertex(f2)) {
	    if (!v5.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v5.IsDone()) || (i != 50)) {
	    fprintf(stderr, "test vvisitor22 failed (step 20)\n");
	    return 22;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor22 failed (step 21)\n");
	    return 22;
	}
    }

    return 0;
}
    
static int
test_visitor23()
{
    e4_Node n1, n2, n3;
    int rank = 0, i = 0;
    e4_Vertex f1, f2;

    /*
     * Test a visitor created from a vertex with name or type filters and
     * visit method E4_VMNODE. Uses e4_VertexVisitor::SetVertex.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor23 failed (step 0)\n");
	    return 23;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor23 failed (step 1)\n");
	    return 23;
	}
	if (!s.GetRootNode(n1) || !n1.IsValid() || !n1.IsRoot()) {
	    fprintf(stderr, "test vvisitor23 failed (step 2.1)\n");
	    return 23;
	}
	if (!s.CreateDetachedNode(n2) || !n2.IsValid() || n2.IsRoot() ||
	    !n2.IsDetached()) {
            fprintf(stderr, "test vvisitor23 failed (step 2.2)\n");
            return 23;
        }
	for (i = 0; i < 15; i++) {
            if (!n1.AddVertex("f", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test vvisitor23 failed (step 6.1.%d)\n", i);
                return 23;
            }
        }
	for (i = 0; i < 15; i++) {
            if (!n2.AddVertex("f", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test vvisitor23 failed (step 6.2.%d)\n", i);
                return 23;
            }
        }
	for (i = 0; i < 7; i++) {
	    if (!n1.AddVertex("g", E4_IOFIRST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor23 failed (step 7.1.1.%d)\n", i);
		return 23;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n2.AddVertex("g", E4_IOFIRST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor23 failed (step 7.1.2.%d)\n", i);
		return 23;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n1.AddVertex("g", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor23 failed (step 7.2.1.%d)\n", i);
		return 23;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n2.AddVertex("g", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor23 failed (step 7.2.2.%d)\n", i);
		return 23;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n1.AddVertex("f", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor23 failed (step 7.3.1.%d)\n", i);
		return 23;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n2.AddVertex("f", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor23 failed (step 7.3.2.%d)\n", i);
		return 23;
	    }
	}
        if (!n1.AddNode("boo", E4_IOLAST, rank, n3)) {
            fprintf(stderr, "test vvisitor23 failed (step 7.4)\n");
            return 23;
        }
        for (i = 0; i < 20; i++) {
            if (!n3.AddVertex("f", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test vvisitor23 failed (step 7.5.%d)\n", i);
                return 23;
            }
        }
        for (i = 0; i < 17; i++) {
            if (!n3.AddVertex("f", E4_IOLAST, rank, (double) 7.35)) {
                fprintf(stderr, "test vvisitor23 failed (step 7.6.%d)\n", i);
                return 23;
            }
        }
        if (!n1.GetVertexRef("f", 1, f1)) {
            fprintf(stderr, "test vvisitor23 failed (step 8)\n");
            return 23;
        }

        /*
         * This visitor is supposed to visit all vertices named "f" in
         * the node containing the supplied vertex.
         */

        e4_VertexVisitor v1(f1, true, false, E4_VMNODE);
	if ((!v1.IsValid()) || (v1.IsDone())) {
	    fprintf(stderr, "test vvisitor23 failed (step 9)\n");
	    return 23;
	}
	for (i = 0; i < 22; i++, (void) v1.NextVertex(f2)) {
	    if (!v1.CurrentVertex(f2)) {
	        break;
	    }
	}
	if ((!v1.IsDone()) || (i != 22)) {
	    fprintf(stderr, "test vvisitor23 failed (step 11, i = %d)\n", i);
	    return 23;
	}

        /*
         * This visitor is supposed to visit all vertices with type integer
         * in the node containing the supplied vertex.
         */

	e4_VertexVisitor v2(f1, false, true, E4_VMNODE);
	if (!v2.IsValid()) {
	    fprintf(stderr, "test vvisitor23 failed (step 12)\n");
	    return 23;
	}
	for (i = 0; i < 15; i++, (void) v2.NextVertex(f2)) {
	    if (!v2.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v2.IsDone()) || (i != 15)) {
	    fprintf(stderr, "test vvisitor23 failed (step 13)\n");
	    return 23;
	}

        e4_VertexVisitor v3;
        
        /*
         * This visitor is supposed to visit all vertices with name "f" in
         * the node containing the supplied vertex.
         */

        v3.SetVertex(f1, true, false, E4_VMNODE);
	if ((!v3.IsValid()) || (v3.IsDone())) {
	    fprintf(stderr, "test vvisitor23 failed (step 14)\n");
	    return 23;
	}
	for (i = 0; i < 22; i++, (void) v3.NextVertex(f2)) {
	    if (!v3.CurrentVertex(f2)) {
		fprintf(stderr, "test vvisitor23 failed (step 15.%d)\n", i);
		return 23;
	    }
	}
	if ((!v3.IsDone()) || (i != 22)) {
	    fprintf(stderr, "test vvisitor23 failed (step 16)\n");
	    return 23;
	}

        e4_VertexVisitor v4;
        
        /*
         * This visitor is supposed to visit all vertices with type integer
         * in the node containing the supplied vertex.
         */

        v4.SetVertex(f1, false, true, E4_VMNODE);
	if (!v4.IsValid()) {
	    fprintf(stderr, "test vvisitor23 failed (step 17)\n");
	    return 23;
	}
	for (i = 0; i < 15; i++, (void) v4.NextVertex(f2)) {
	    if (!v4.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v4.IsDone()) || (i != 15)) {
	    fprintf(stderr, "test vvisitor23 failed (step 18)\n");
	    return 23;
	}

        /*
         * This visitor is supposed to visit all vertices with name "f" and
         * type integer in the node containing the supplied vertex.
         */

        e4_VertexVisitor v5(f1, true, true, E4_VMNODE);
	if (!v5.IsValid()) {
	    fprintf(stderr, "test vvisitor23 failed (step 19)\n");
	    return 23;
	}
	for (i = 0; i < 15; i++, (void) v5.NextVertex(f2)) {
	    if (!v5.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v5.IsDone()) || (i != 15)) {
	    fprintf(stderr, "test vvisitor23 failed (step 20)\n");
	    return 23;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor23 failed (step 21)\n");
	    return 23;
	}
    }

    return 0;
}
    
static int
test_visitor26()
{
    e4_Node n1, n2, n3;
    int rank = 0, i = 0;
    e4_Vertex f1, f2;

    /*
     * Test a visitor created from a storage. Also uses
     * e4_VertexVisitor::SetStorage().
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor26 failed (step 0)\n");
	    return 26;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor26 failed (step 1)\n");
	    return 26;
	}
	if (!s.GetRootNode(n1) || !n1.IsValid() || !n1.IsRoot()) {
	    fprintf(stderr, "test vvisitor26 failed (step 2)\n");
	    return 26;
	}
	if (!s.CreateDetachedNode(n2) || !n2.IsValid() || n2.IsRoot() ||
	    !n2.IsDetached()) {
            fprintf(stderr, "test vvisitor26 failed (step 3)\n");
            return 26;
        }
	for (i = 0; i < 15; i++) {
            if (!n1.AddVertex("f", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test vvisitor26 failed (step 4.%d)\n", i);
                return 26;
            }
        }
	for (i = 0; i < 15; i++) {
            if (!n2.AddVertex("f", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test vvisitor26 failed (step 5.%d)\n", i);
                return 26;
            }
        }
	for (i = 0; i < 7; i++) {
	    if (!n1.AddVertex("g", E4_IOFIRST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor26 failed (step 6.%d)\n", i);
		return 26;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n2.AddVertex("g", E4_IOFIRST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor26 failed (step 7.1.2.%d)\n", i);
		return 26;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n1.AddVertex("g", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor26 failed (step 7.2.1.%d)\n", i);
		return 26;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n2.AddVertex("g", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor26 failed (step 7.2.2.%d)\n", i);
		return 26;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n1.AddVertex("f", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor26 failed (step 7.3.1.%d)\n", i);
		return 26;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n2.AddVertex("f", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor26 failed (step 7.3.2.%d)\n", i);
		return 26;
	    }
	}
        if (!n1.AddNode("boo", E4_IOLAST, rank, n3)) {
            fprintf(stderr, "test vvisitor26 failed (step 7.4)\n");
            return 26;
        }
        for (i = 0; i < 20; i++) {
            if (!n3.AddVertex("f", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test vvisitor26 failed (step 7.5.%d)\n", i);
                return 26;
            }
        }
        for (i = 0; i < 17; i++) {
            if (!n3.AddVertex("f", E4_IOLAST, rank, (double) 7.35)) {
                fprintf(stderr, "test vvisitor26 failed (step 7.6.%d)\n", i);
                return 26;
            }
        }
        if (!n1.GetVertexRef("f", 1, f1)) {
            fprintf(stderr, "test vvisitor26 failed (step 8)\n");
            return 26;
        }

        /*
         * This visitor is supposed to visit all vertices in
         * the supplied storage.
         */

        e4_VertexVisitor v1(s);
	if ((!v1.IsValid()) || (v1.IsDone())) {
	    fprintf(stderr, "test vvisitor26 failed (step 9)\n");
	    return 26;
	}
	for (i = 0; i < 110; i++, (void) v1.NextVertex(f2)) {
	    if (!v1.CurrentVertex(f2)) {
	        break;
	    }
	}
	if ((!v1.IsDone()) || (i != 110)) {
	    fprintf(stderr, "test vvisitor26 failed (step 11, i = %d)\n", i);
	    return 26;
	}

	e4_VertexVisitor v2;

	/*
         * This visitor is supposed to visit all in the supplied storage.
         */

	v2.SetStorage(s, E4_DCATTACHED);
	if (!v2.IsValid()) {
	    fprintf(stderr, "test vvisitor26 failed (step 12)\n");
	    return 26;
	}
	for (i = 0; i < 110; i++, (void) v2.NextVertex(f2)) {
	    if (!v2.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v2.IsDone()) || (i != 110)) {
	    fprintf(stderr, "test vvisitor26 failed (step 13)\n");
	    return 26;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor26 failed (step 14)\n");
	    return 26;
	}
    }

    return 0;
}
    
static int
test_visitor27()
{
    e4_Node n1, n2, n3;
    int rank = 0, i = 0;
    e4_Vertex f1, f2;

    /*
     * Test a visitor created from a storage with name or type filters.
     * Also uses e4_VertexVisitor::SetStorage().
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor27 failed (step 0)\n");
	    return 27;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor27 failed (step 1)\n");
	    return 27;
	}
	if (!s.GetRootNode(n1) || !n1.IsValid() || !n1.IsRoot()) {
	    fprintf(stderr, "test vvisitor27 failed (step 2.1)\n");
	    return 27;
	}
	if (!s.CreateDetachedNode(n2) || !n2.IsValid() || n2.IsRoot() ||
	    !n2.IsDetached()) {
            fprintf(stderr, "test vvisitor27 failed (step 2.2)\n");
            return 27;
        }
	for (i = 0; i < 15; i++) {
            if (!n1.AddVertex("f", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test vvisitor27 failed (step 6.1.%d)\n", i);
                return 27;
            }
        }
	for (i = 0; i < 15; i++) {
            if (!n2.AddVertex("f", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test vvisitor27 failed (step 6.2.%d)\n", i);
                return 27;
            }
        }
	for (i = 0; i < 7; i++) {
	    if (!n1.AddVertex("g", E4_IOFIRST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor27 failed (step 7.1.1.%d)\n", i);
		return 27;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n2.AddVertex("g", E4_IOFIRST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor27 failed (step 7.1.2.%d)\n", i);
		return 27;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n1.AddVertex("g", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor27 failed (step 7.2.1.%d)\n", i);
		return 27;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n2.AddVertex("g", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor27 failed (step 7.2.2.%d)\n", i);
		return 27;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n1.AddVertex("f", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor27 failed (step 7.3.1.%d)\n", i);
		return 27;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n2.AddVertex("f", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor27 failed (step 7.3.2.%d)\n", i);
		return 27;
	    }
	}
        if (!n1.AddNode("boo", E4_IOLAST, rank, n3)) {
            fprintf(stderr, "test vvisitor27 failed (step 7.4)\n");
            return 27;
        }
        for (i = 0; i < 20; i++) {
            if (!n3.AddVertex("f", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test vvisitor27 failed (step 7.5.%d)\n", i);
                return 27;
            }
        }
        for (i = 0; i < 17; i++) {
            if (!n3.AddVertex("f", E4_IOLAST, rank, (double) 7.35)) {
                fprintf(stderr, "test vvisitor27 failed (step 7.6.%d)\n", i);
                return 27;
            }
        }
        if (!n1.GetVertexRef("f", 1, f1)) {
            fprintf(stderr, "test vvisitor27 failed (step 8)\n");
            return 27;
        }

        /*
         * This visitor is supposed to visit all vertices named "f" in
         * the supplied storage.
         */

        e4_VertexVisitor v1(s, "f", E4_VTUNKNOWN);
	if ((!v1.IsValid()) || (v1.IsDone())) {
	    fprintf(stderr, "test vvisitor27 failed (step 9)\n");
	    return 27;
	}
	for (i = 0; i < 81; i++, (void) v1.NextVertex(f2)) {
	    if (!v1.CurrentVertex(f2)) {
	        break;
	    }
	}
	if ((!v1.IsDone()) || (i != 81)) {
	    fprintf(stderr, "test vvisitor27 failed (step 11, i = %d)\n", i);
	    return 27;
	}

        /*
         * This visitor is supposed to visit all vertices with type integer
         * in the supplied storage.
         */

	e4_VertexVisitor v2(s, NULL, E4_VTINT);
	if (!v2.IsValid()) {
	    fprintf(stderr, "test vvisitor27 failed (step 12)\n");
	    return 27;
	}
	for (i = 0; i < 50; i++, (void) v2.NextVertex(f2)) {
	    if (!v2.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v2.IsDone()) || (i != 50)) {
	    fprintf(stderr, "test vvisitor27 failed (step 13)\n");
	    return 27;
	}

        e4_VertexVisitor v3;
        
        /*
         * This visitor is supposed to visit all vertices with name "f" in
         * the supplied marker.
         */

        v3.SetStorage(s, "f", E4_VTUNKNOWN, E4_DCATTACHED);
	if ((!v3.IsValid()) || (v3.IsDone())) {
	    fprintf(stderr, "test vvisitor27 failed (step 14)\n");
	    return 27;
	}
	for (i = 0; i < 81; i++, (void) v3.NextVertex(f2)) {
	    if (!v3.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v3.IsDone()) || (i != 81)) {
	    fprintf(stderr, "test vvisitor27 failed (step 16)\n");
	    return 27;
	}

        e4_VertexVisitor v4;
        
        /*
         * This visitor is supposed to visit all vertices with type integer
         * in the supplied storage.
         */

        v4.SetStorage(s, NULL, E4_VTINT, E4_DCATTACHED);
	if (!v4.IsValid()) {
	    fprintf(stderr, "test vvisitor27 failed (step 17)\n");
	    return 27;
	}
	for (i = 0; i < 50; i++, (void) v4.NextVertex(f2)) {
	    if (!v4.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v4.IsDone()) || (i != 50)) {
	    fprintf(stderr, "test vvisitor27 failed (step 18)\n");
	    return 27;
	}

        /*
         * This visitor is supposed to visit all vertices with name "f" and
         * type integer in the supplied storage.
         */

        e4_VertexVisitor v5(s, "f", E4_VTINT);
	if (!v5.IsValid()) {
	    fprintf(stderr, "test vvisitor27 failed (step 19)\n");
	    return 27;
	}
	for (i = 0; i < 50; i++, (void) v5.NextVertex(f2)) {
	    if (!v5.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v5.IsDone()) || (i != 50)) {
	    fprintf(stderr, "test vvisitor27 failed (step 20)\n");
	    return 27;
	}

	e4_VertexVisitor v6;

	/*
	 * This visitor is supposed to visit all vertices with name "f" and
	 * type integer in the supplied storage.
	 */

	v6.SetStorage(s, "f", E4_VTINT, E4_DCATTACHED);
	if (!v6.IsValid()) {
	    fprintf(stderr, "test vvisitor27 failed (step 19)\n");
	    return 27;
	}
	for (i = 0; i < 50; i++, (void) v6.NextVertex(f2)) {
	    if (!v6.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v6.IsDone()) || (i != 50)) {
	    fprintf(stderr, "test vvisitor27 failed (step 20)\n");
	    return 27;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor27 failed (step 21)\n");
	    return 27;
	}
    }

    return 0;
}
    
static int
test_visitor28()
{
    e4_Node n1, n2, n3;
    int rank = 0, i = 0;
    e4_Vertex f1, f2;

    /*
     * Test a visitor created from a storage with name or type filters.
     * Also uses e4_VertexVisitor::SetStorage().
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor28 failed (step 0)\n");
	    return 28;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor28 failed (step 1)\n");
	    return 28;
	}
	if (!s.GetRootNode(n1) || !n1.IsValid() || !n1.IsRoot()) {
	    fprintf(stderr, "test vvisitor28 failed (step 2.1)\n");
	    return 28;
	}
	if (!s.CreateDetachedNode(n2) || !n2.IsValid() || n2.IsRoot() ||
	    !n2.IsDetached()) {
            fprintf(stderr, "test vvisitor28 failed (step 2.2)\n");
            return 28;
        }
	for (i = 0; i < 15; i++) {
            if (!n1.AddVertex("f", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test vvisitor28 failed (step 6.1.%d)\n", i);
                return 28;
            }
        }
	for (i = 0; i < 15; i++) {
            if (!n2.AddVertex("f", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test vvisitor28 failed (step 6.2.%d)\n", i);
                return 28;
            }
        }
	for (i = 0; i < 7; i++) {
	    if (!n1.AddVertex("g", E4_IOFIRST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor28 failed (step 7.1.1.%d)\n", i);
		return 28;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n2.AddVertex("g", E4_IOFIRST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor28 failed (step 7.1.2.%d)\n", i);
		return 28;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n1.AddVertex("g", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor28 failed (step 7.2.1.%d)\n", i);
		return 28;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n2.AddVertex("g", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor28 failed (step 7.2.2.%d)\n", i);
		return 28;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n1.AddVertex("f", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor28 failed (step 7.3.1.%d)\n", i);
		return 28;
	    }
	}
	for (i = 0; i < 7; i++) {
	    if (!n2.AddVertex("f", E4_IOLAST, rank, (double) 7.35)) {
		fprintf(stderr, "test vvisitor28 failed (step 7.3.2.%d)\n", i);
		return 28;
	    }
	}
        if (!n1.AddNode("boo", E4_IOLAST, rank, n3)) {
            fprintf(stderr, "test vvisitor28 failed (step 7.4)\n");
            return 28;
        }
        for (i = 0; i < 20; i++) {
            if (!n3.AddVertex("f", E4_IOLAST, rank, i)) {
                fprintf(stderr, "test vvisitor28 failed (step 7.5.%d)\n", i);
                return 28;
            }
        }
        for (i = 0; i < 17; i++) {
            if (!n3.AddVertex("f", E4_IOLAST, rank, (double) 7.35)) {
                fprintf(stderr, "test vvisitor28 failed (step 7.6.%d)\n", i);
                return 28;
            }
        }
        if (!n1.GetVertexRef("f", 1, f1)) {
            fprintf(stderr, "test vvisitor28 failed (step 8)\n");
            return 28;
        }

        /*
         * This visitor is supposed to visit all vertices named "g" in
         * the supplied storage.
         */

        e4_VertexVisitor v1(s, "g", E4_VTUNKNOWN);
	if ((!v1.IsValid()) || (v1.IsDone())) {
	    fprintf(stderr, "test vvisitor28 failed (step 9)\n");
	    return 28;
	}
	for (i = 0; i < 28; i++, (void) v1.NextVertex(f2)) {
	    if (!v1.CurrentVertex(f2)) {
	        break;
	    }
	}
	if ((!v1.IsDone()) || (i != 28)) {
	    fprintf(stderr, "test vvisitor28 failed (step 11, i = %d)\n", i);
	    return 28;
	}

        /*
         * This visitor is supposed to visit all vertices with type node
         * in the supplied storage.
         */

	e4_VertexVisitor v2(s, NULL, E4_VTNODE);
	if (!v2.IsValid()) {
	    fprintf(stderr, "test vvisitor28 failed (step 12)\n");
	    return 28;
	}
	for (i = 0; i < 1; i++, (void) v2.NextVertex(f2)) {
	    if (!v2.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v2.IsDone()) || (i != 1)) {
	    fprintf(stderr, "test vvisitor28 failed (step 13)\n");
	    return 28;
	}

        e4_VertexVisitor v3;
        
        /*
         * This visitor is supposed to visit all vertices with name "g" in
         * the supplied marker.
         */

        v3.SetStorage(s, "g", E4_VTUNKNOWN, E4_DCATTACHED);
	if ((!v3.IsValid()) || (v3.IsDone())) {
	    fprintf(stderr, "test vvisitor28 failed (step 14)\n");
	    return 28;
	}
	for (i = 0; i < 28; i++, (void) v3.NextVertex(f2)) {
	    if (!v3.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v3.IsDone()) || (i != 28)) {
	    fprintf(stderr, "test vvisitor28 failed (step 16)\n");
	    return 28;
	}

        e4_VertexVisitor v4;
        
        /*
         * This visitor is supposed to visit all vertices with type node
         * in the supplied storage.
         */

        v4.SetStorage(s, NULL, E4_VTNODE, E4_DCATTACHED);
	if (!v4.IsValid()) {
	    fprintf(stderr, "test vvisitor28 failed (step 17)\n");
	    return 28;
	}
	for (i = 0; i < 1; i++, (void) v4.NextVertex(f2)) {
	    if (!v4.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v4.IsDone()) || (i != 1)) {
	    fprintf(stderr, "test vvisitor28 failed (step 18)\n");
	    return 28;
	}

        /*
         * This visitor is supposed to visit all vertices with name "g" and
         * type double in the supplied storage.
         */

        e4_VertexVisitor v5(s, "g", E4_VTDOUBLE);
	if (!v5.IsValid()) {
	    fprintf(stderr, "test vvisitor28 failed (step 19)\n");
	    return 28;
	}
	for (i = 0; i < 28; i++, (void) v5.NextVertex(f2)) {
	    if (!v5.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v5.IsDone()) || (i != 28)) {
	    fprintf(stderr, "test vvisitor28 failed (step 20)\n");
	    return 28;
	}

	e4_VertexVisitor v6;

	/*
	 * This visitor is supposed to visit all vertices with name "g" and
	 * type double in the supplied storage.
	 */

	v6.SetStorage(s, "g", E4_VTDOUBLE, E4_DCATTACHED);
	if (!v6.IsValid()) {
	    fprintf(stderr, "test vvisitor28 failed (step 19)\n");
	    return 28;
	}
	for (i = 0; i < 28; i++, (void) v6.NextVertex(f2)) {
	    if (!v6.CurrentVertex(f2)) {
		break;
	    }
	}
	if ((!v6.IsDone()) || (i != 28)) {
	    fprintf(stderr, "test vvisitor28 failed (step 20)\n");
	    return 28;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor28 failed (step 21)\n");
	    return 28;
	}
    }

    return 0;
}

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

    /*
     * Test operator== and operator!= on e4_VertexVisitor.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor29 failed (step 0)\n");
	    return 29;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor29 failed (step 1)\n");
	    return 29;
	}
	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor29 failed (step 2)\n");
	    return 29;
	}
	for (i = 0; i < 15; i++) {
	    if (!n.AddVertex("f", E4_IOLAST, rank, i)) {
		fprintf(stderr, "test vvisitor29 failed (step 6.%d)\n", i);
		return 29;
	    }
	}
	e4_VertexVisitor v1(n);
	if (!v1.IsValid()) {
	    fprintf(stderr, "test vvisitor29 failed (step 7)\n");
	    return 29;
	}
	for (i = 0; i < 7; i++, (void) v1.NextVertex(f)) {
	    if (!v1.CurrentVertex(f)) {
		fprintf(stderr, "test vvisitor29 failed (step 8.%d)\n", i);
		return 29;
	    }
	}
	e4_VertexVisitor v2(v1);
	if (!v2.IsValid()) {
	    fprintf(stderr, "test vvisitor29 failed (step 9)\n");
	    return 29;
	}
        if (v1 != v2) {
            fprintf(stderr, "test vvisitor29 failed (step 10)\n");
            return 29;
        }
	for (i = 0; i < 8; i++, (void) v2.NextVertex(f)) {
	    if (!v2.CurrentVertex(f)) {
		break;
	    }
	}
        if (v1 == v2) {
            fprintf(stderr, "test vvisitor29 failed (step 11)\n");
            return 29;
        }
	if ((!v2.IsDone()) || (i != 8)) {
	    fprintf(stderr, "test vvisitor29 failed (step 12)\n");
	    return 29;
	}
        for (i = 0; i < 8; i++, (void) v1.NextVertex(f)) {
            if (!v1.CurrentVertex(f)) {
                break;
            }
        }
        if (v1 != v2) {
            fprintf(stderr, "test vvisitor29 failed (step 13)\n");
            return 29;
        }
        if ((!v1.IsDone()) || (i != 8)) {
            fprintf(stderr, "test vvisitor29 failed (step 14)\n");
            return 29;
        }
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor29 failed (step 15)\n");
	    return 29;
	}
    }

    return 0;
}

static int
test_visitor30()
{
    e4_Vertex vs[TV_VERTEXLIMIT];
    e4_Vertex f;
    int i = 0;

    /*
     * Test vertex visiting with only detached vertices.
     */

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor30 failed (step 0)\n");
	    return 30;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor30 failed (step 1)\n");
	    return 30;
	}
	for (i = 0; i < TV_VERTEXLIMIT; i++) {
	    if (!s.CreateDetachedVertex("f", i, vs[i]) ||
		!vs[i].IsValid() ||
		!vs[i].IsDetached()) {
		fprintf(stderr, "test vvisitor30 failed (step 2.%d)\n", i);
		return 30;
	    }
	}

	/*
	 * Create a visitor that will visit only detached vertices.
	 */

	e4_VertexVisitor v(s, E4_DCDETACHED);
	if (!v.IsValid() || (v.VisitMethod() != E4_VMSTORAGE) || v.IsDone()) {
	    fprintf(stderr, "test vvisitor30 failed (step 3), %d %d %d\n",
		    v.IsValid(), (v.VisitMethod() == E4_VMSTORAGE),
		    v.IsDone());
	    return 30;
	}
	for (i = 0; 
	     (!v.IsDone()) && (i < TV_VERTEXLIMIT); 
	     i++, (void) v.NextVertex(f)) {
	    if (!v.CurrentVertex(f) || !f.IsValid() || !f.IsDetached()) {
		fprintf(stderr, "test vvisitor30 failed (step 4.%d)\n", i);
		fprintf(stderr, "f %d v %d d %d o %d\n",
			i, f.IsValid(), f.IsDetached(), v.IsDone());
		return 30;
	    }
	}
	if (!v.IsDone() || (i != TV_VERTEXLIMIT)) {
	    fprintf(stderr, "test vvisitor30 failed (step 5)\n");
	    return 30;
	}
	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor30 failed (step 6)\n");
	    return 30;
	}
    }

    return 0;
}

static int
test_visitor31()
{
    e4_Node n, p, c, c1;
    e4_Vertex v, l;
    int count, rank;
    char buf[128];

    /*
     * Test vertex visiting with parent visiting.
     */

    {
	e4_Storage s;

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

	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor31 failed (step 2)\n");
	    return 31;
	}

	if (!n.AddNode("foo", E4_IOLAST, rank, c) || !c.IsValid()) {
	    fprintf(stderr, "test vvisitor31 failed (step 3)\n");
	    return 31;
	}
	for (count = 0; count < 3; count++) {
	    sprintf(buf, "foo%d", count);
	    if (!n.AddVertex(buf, E4_IOLAST, rank, c)) {
		fprintf(stderr, "test vvisitor31 failed (step 4.%d)\n", count);
		return 31;
	    }
	}

	if ((c.ParentCount() != 1) || (c.OccurrenceCount() != 4) ||
	    (c.OccurrenceCount(n) != 4)) {
	    fprintf(stderr, "test vvisitor31 failed (step 4.2.0)\n");
	    return 31;
	}

	e4_VertexVisitor vv(c, invalidNode, E4_DCBOTH);

	if (!vv.IsValid() || vv.IsDone()) {
	    fprintf(stderr, "test vvisitor31 failed (step 5)\n");
	    return 31;
	}

	for (count = 1, vv.CurrentVertex(v);
	     !vv.IsDone();
	     count++, vv.NextVertex(v)) {
	    if (!v.IsValid() || !v.GetNode(p) ||
		!p.IsValid() || (p != n) ||
		!v.Get(c1) || !c1.IsValid() || (c1 != c)) {
		fprintf(stderr,
			"test vvisitor31 failed (step 6.%d)\n",
			count);
		return 31;
	    }
	}

	if (count != 5) {
	    fprintf(stderr, "test vvisitor31 failed (step 7) %d\n", count);
	    return 31;
	}

	e4_VertexVisitor vv1(c, invalidNode, E4_DCATTACHED);

	if (!vv1.IsValid() || vv1.IsDone()) {
	    fprintf(stderr, "test vvisitor31 failed (step 8)\n");
	    return 31;
	}

	for (count = 1, vv1.CurrentVertex(v);
	     !vv1.IsDone();
	     count++, vv1.NextVertex(v)) {
	    if (!v.IsValid() || !v.GetNode(p) ||
		!p.IsValid() || (p != n) ||
		!v.Get(c1) || !c1.IsValid() || (c1 != c)) {
		fprintf(stderr,
			"test vvisitor31 failed (step 9.%d)\n",
			count);
		return 31;
	    }
	}

	if (count != 5) {
	    fprintf(stderr, "test vvisitor31 failed (step 10) %d\n", count);
	    return 31;
	}

	e4_VertexVisitor vv2(c, invalidNode, E4_DCDETACHED);

	if (!vv2.IsValid() || !vv2.IsDone()) {
	    fprintf(stderr, "test vvisitor31 failed (step 11)\n");
	    return 31;
	}

	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor31 failed (step 12)\n");
	    return 31;
	}
    }

    {
	e4_Storage s;

	if (!clean_storage("foo.db", s)) {
	    fprintf(stderr, "test vvisitor31 failed (step 20)\n");
	    return 31;
	}
	if (!s.IsValid()) {
	    fprintf(stderr, "test vvisitor31 failed (step 21)\n");
	    return 31;
	}

	if (!s.GetRootNode(n) || !n.IsValid() || !n.IsRoot()) {
	    fprintf(stderr, "test vvisitor31 failed (step 22)\n");
	    return 31;
	}

	if (!s.CreateDetachedVertex("blah", n, v) || !v.IsValid() ||
	    !v.Get(c) || !c.IsValid() || (c != n)) {
	    fprintf(stderr, "test vvisitor31 failed (step 23)\n");
	    return 31;
	}

	e4_VertexVisitor vv1(n, invalidNode, E4_DCATTACHED);

	if (!vv1.IsValid() || !vv1.IsDone()) {
	    fprintf(stderr, "test vvisitor31 failed (step 23)\n");
	    return 31;
	}

	e4_VertexVisitor vv2(n, invalidNode, E4_DCBOTH);

	if (!vv2.IsValid() || vv2.IsDone()) {
	    fprintf(stderr, "test vvisitor31 failed (step 24)\n");
	    return 31;
	}

	for (count = 1, vv2.CurrentVertex(l);
	     !vv2.IsDone();
	     count++, vv2.NextVertex(l)) {
	    if (!l.IsValid() || !l.Get(c) ||
		!c.IsValid() || (c != n) ||
		(l != v)) {
		fprintf(stderr,
			"test vvisitor31 failed (step 25.%d)\n",
			count);
		return 31;
	    }
	}

	if (count != 2) {
	    fprintf(stderr, "test vvisitor31 failed (step 26)\n");
	    return 31;
	}

	e4_VertexVisitor vv3(n, invalidNode, E4_DCDETACHED);

	if (!vv3.IsValid() || vv3.IsDone()) {
	    fprintf(stderr, "test vvisitor31 failed (step 27)\n");
	    return 31;
	}

	for (count = 1, vv3.CurrentVertex(l);
	     !vv3.IsDone();
	     count++, vv3.NextVertex(l)) {
	    if (!l.IsValid() || !l.Get(c) ||
		!c.IsValid() || (c != n) ||
		(l != v)) {
		fprintf(stderr,
			"test vvisitor31 failed (step 28.%d)\n",
			count);
		return 31;
	    }
	}

	if (count != 2) {
	    fprintf(stderr, "test vvisitor31 failed (step 29)\n");
	    return 31;
	}

	e4_VertexVisitor vv4(n, invalidNode, E4_DCBOTH);

	if (!vv4.IsValid() || vv4.IsDone()) {
	    fprintf(stderr, "test vvisitor31 failed (step 30)\n");
	    return 31;
	}

	for (count = 1, vv4.CurrentVertex(l);
	     !vv4.IsDone();
	     count++, vv4.NextVertex(l)) {
	    if (!l.IsValid() || !l.Get(c) ||
		!c.IsValid() || (c != n) ||
		(l != v)) {
		fprintf(stderr,
			"test vvisitor31 failed (step 31.%d)\n",
			count);
		return 31;
	    }
	}

	if (count != 2) {
	    fprintf(stderr, "test vvisitor31 failed (step 32)\n");
	    return 31;
	}

	for (count = 0; count < 4; count++) {
	    if (!n.AddVertex("foo", E4_IOLAST, rank, n)) {
		fprintf(stderr,
			"test vvisitor31 failed (step 33.%d)\n",
			count);
		return 31;
	    }
	}

	e4_VertexVisitor vv5(n, invalidNode, E4_DCATTACHED);

	if (!vv5.IsValid() || vv5.IsDone()) {
	    fprintf(stderr, "test vvisitor31 failed (step 34)\n");
	    return 31;
	}

	for (count = 1, vv5.CurrentVertex(l);
	     !vv5.IsDone();
	     count++, vv5.NextVertex(l)) {
	    if (!l.IsValid() || !l.Get(c) || !c.IsValid() || (c != n)) {
		fprintf(stderr,
			"test vvisitor31 failed (step 35.%d)\n",
			count);
		return 31;
	    }
	}

	if (count != 5) {
	    fprintf(stderr, "test vvisitor31 failed (step 36)\n");
	    return 31;
	}

	e4_VertexVisitor vv6(n, invalidNode, E4_DCDETACHED);

	if (!vv6.IsValid() || vv6.IsDone()) {
	    fprintf(stderr, "test vvisitor31 failed (step 37)\n");
	    return 31;
	}

	for (count = 1, vv6.CurrentVertex(l);
	     !vv6.IsDone();
	     count++, vv6.NextVertex(l)) {
	    if (!l.IsValid() || !l.Get(c) ||
		!c.IsValid() || (c != n) ||
		(l != v)) {
		fprintf(stderr,
			"test vvisitor31 failed (step 38.%d)\n",
			count);
		return 31;
	    }
	}

	if (count != 2) {
	    fprintf(stderr, "test vvisitor31 failed (step 39)\n");
	    return 31;
	}

	e4_VertexVisitor vv7(n, invalidNode, E4_DCBOTH);

	if (!vv7.IsValid() || vv7.IsDone()) {
	    fprintf(stderr, "test vvisitor31 failed (step 40)\n");
	    return 31;
	}

	for (count = 1, vv7.CurrentVertex(l);
	     !vv7.IsDone();
	     count++, vv7.NextVertex(l)) {
	    if (!l.IsValid() || !l.Get(c) ||
		!c.IsValid() || (c != n)) {
		fprintf(stderr,
			"test vvisitor31 failed (step 41.%d)\n",
			count);
		return 31;
	    }
	}

	if (count != 6) {
	    fprintf(stderr, "test vvisitor31 failed (step 42)\n");
	    return 31;
	}

	e4_VertexVisitor vv8(n, n, E4_DCBOTH);

	if (!vv8.IsValid() || vv8.IsDone()) {
	    fprintf(stderr, 
		    "test vvisitor31 failed (step 43) %d %d\n",
		    vv8.IsValid(), vv8.IsDone());
	    return 31;
	}

	for (count = 1, vv8.CurrentVertex(l);
	     !vv8.IsDone();
	     count++, vv8.NextVertex(l)) {
	    if (!l.IsValid() || !l.Get(c) || !c.IsValid() || (c != n)) {
		fprintf(stderr,
			"test vvisitor31 failed (step 44.%d)\n",
			count);
		return 31;
	    }
	}

	if (count != 5) {
	    fprintf(stderr, "test vvisitor31 failed (step 45)\n");
	    return 31;
	}

	e4_VertexVisitor vv9(n, n, E4_DCATTACHED);

	if (!vv9.IsValid() || vv9.IsDone()) {
	    fprintf(stderr, "test vvisitor31 failed (step 46)\n");
	    return 31;
	}

	for (count = 1, vv9.CurrentVertex(l);
	     !vv9.IsDone();
	     count++, vv9.NextVertex(l)) {
	    if (!l.IsValid() || !l.Get(c) || !c.IsValid() || (c != n)) {
		fprintf(stderr,
			"test vvisitor31 failed (step 47.%d)\n",
			count);
		return 31;
	    }
	}

	if (count != 5) {
	    fprintf(stderr, "test vvisitor31 failed (step 48)\n");
	    return 31;
	}

	e4_VertexVisitor vva(n, n, E4_DCDETACHED);

	if (!vva.IsValid() || vva.IsDone()) {
	    fprintf(stderr, "test vvisitor31 failed (step 49)\n");
	    return 31;
	}

	for (count = 1, vva.CurrentVertex(l);
	     !vva.IsDone();
	     count++, vva.NextVertex(l)) {
	    if (!l.IsValid() || !l.Get(c) || !c.IsValid() || (c != n)) {
		fprintf(stderr,
			"test vvisitor31 failed (step 50.%d)\n",
			count);
		return 31;
	    }
	}

	if (count != 5) {
	    fprintf(stderr, "test vvisitor31 failed (step 51)\n");
	    return 31;
	}

	s.Delete();
	if (s.IsValid()) {
	    fprintf(stderr, "test vvisitor31 failed (step 30)\n");
	    return 31;
	}
    }

    return 0;
}

int
test_vertexvisitor()
{
    int result = 0;

    fprintf(stderr, "Running e4_VertexVisitor tests: ");
    result = test_visitor1();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor2();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor3();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor4();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor5();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor6();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor7();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor8();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor9();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor10();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor11();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor12();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor13();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor14();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor15();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor16();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor17();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor18();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor19();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor20();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");

    /*
     * Test test_visitor21() has been removed.
     */

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

    /*
     * Tests test_visitor24() and test_visitor25() have been
     * removed.
     */

    result = test_visitor26();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor27();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor28();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor29();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor30();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".");
    result = test_visitor31();
    if (result != 0) {
	return result;
    }
    fprintf(stderr, ".\n");    
    return 0;
}
