/** \file
 * Contains the base functions that all tree adaptors start with.
 * this implementation can then be overridden by any higher implementation.
 * 
 */

// [The "BSD licence"]
// Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
// http://www.temporal-wave.com
// http://www.linkedin.com/in/jimidle
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. The name of the author may not be used to endorse or promote products
//    derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include    <antlr3basetreeadaptor.h>

#ifdef	ANTLR3_WINDOWS
#pragma warning( disable : 4100 )
#endif

/* Interface functions
 */
static	pANTLR3_BASE_TREE	nilNode					(pANTLR3_BASE_TREE_ADAPTOR adaptor);
static	pANTLR3_BASE_TREE	dbgNil					(pANTLR3_BASE_TREE_ADAPTOR adaptor);
static	pANTLR3_BASE_TREE	dupTree					(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t);
static	pANTLR3_BASE_TREE	dbgDupTree				(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t);
static	pANTLR3_BASE_TREE	dupTreeTT				(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE parent);
static	void				addChild				(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE child);
static	void				dbgAddChild				(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE child);
static	pANTLR3_BASE_TREE	becomeRoot				(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE newRoot, pANTLR3_BASE_TREE oldRoot);
static	pANTLR3_BASE_TREE	dbgBecomeRoot			(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE newRoot, pANTLR3_BASE_TREE oldRoot);
static	pANTLR3_BASE_TREE	rulePostProcessing		(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE root);
static	void				addChildToken			(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_COMMON_TOKEN child);
static	void				dbgAddChildToken		(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_COMMON_TOKEN child);
static	pANTLR3_BASE_TREE	becomeRootToken			(pANTLR3_BASE_TREE_ADAPTOR adaptor, void * newRoot, pANTLR3_BASE_TREE oldRoot);
static	pANTLR3_BASE_TREE	dbgBecomeRootToken		(pANTLR3_BASE_TREE_ADAPTOR adaptor, void * newRoot, pANTLR3_BASE_TREE oldRoot);
static	pANTLR3_BASE_TREE	createTypeToken			(pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken);
static	pANTLR3_BASE_TREE	dbgCreateTypeToken		(pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken);
static	pANTLR3_BASE_TREE	createTypeTokenText		(pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken, pANTLR3_UINT8 text);
static	pANTLR3_BASE_TREE	dbgCreateTypeTokenText	(pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken, pANTLR3_UINT8 text);
static	pANTLR3_BASE_TREE	createTypeText			(pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_UINT8 text);
static	pANTLR3_BASE_TREE	dbgCreateTypeText		(pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_UINT8 text);
static	ANTLR3_UINT32		getType					(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t);
static	void				setType					(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, ANTLR3_UINT32 type);
static	pANTLR3_STRING		getText					(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t);
static	void				setText					(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_STRING t);
static	void				setText8				(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 t);
static	pANTLR3_BASE_TREE	getChild				(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, ANTLR3_UINT32 i);
static	ANTLR3_UINT32		getChildCount			(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t);
static	ANTLR3_UINT32		getUniqueID				(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t);
static	ANTLR3_BOOLEAN		isNilNode				(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t);
static	pANTLR3_STRING		makeDot					(pANTLR3_BASE_TREE_ADAPTOR adaptor, void * theTree);

/** Given a pointer to a base tree adaptor structure (which is usually embedded in the
 *  super class the implements the tree adaptor used in the parse), initialize its
 *  function pointers and so on.
 */
ANTLR3_API void
antlr3BaseTreeAdaptorInit(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_DEBUG_EVENT_LISTENER	debugger)
{
	// Initialize the interface
	//
	if	(debugger == NULL)
	{
		adaptor->nilNode				= (void * (*)(pANTLR3_BASE_TREE_ADAPTOR)) 								
																				nilNode;
		adaptor->addChild				= (void   (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))								
																				addChild;
		adaptor->becomeRoot				= (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))				
																				becomeRoot;
		adaptor->addChildToken			= (void   (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, pANTLR3_COMMON_TOKEN))	
																				addChildToken;
		adaptor->becomeRootToken		= (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))
																				becomeRootToken;
		adaptor->createTypeToken		= (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_COMMON_TOKEN))
																				createTypeToken;
		adaptor->createTypeTokenText	= (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_COMMON_TOKEN, pANTLR3_UINT8))
																				createTypeTokenText;
		adaptor->createTypeText			= (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_UINT8))
																				createTypeText;
		adaptor->dupTree				= (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))		 				
																				dupTree;
	}
	else
	{
		adaptor->nilNode				= (void * (*)(pANTLR3_BASE_TREE_ADAPTOR))
                                                                                dbgNil;
		adaptor->addChild				= (void   (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))
                                                                                dbgAddChild;
		adaptor->becomeRoot				= (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))
																				dbgBecomeRoot;
		adaptor->addChildToken			= (void   (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, pANTLR3_COMMON_TOKEN))
                                                                                dbgAddChildToken;
		adaptor->becomeRootToken		= (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))
                                                                                dbgBecomeRootToken;
		adaptor->createTypeToken		= (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_COMMON_TOKEN))
                                                                                dbgCreateTypeToken;
		adaptor->createTypeTokenText	= (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_COMMON_TOKEN, pANTLR3_UINT8))
                                                                                dbgCreateTypeTokenText;
		adaptor->createTypeText			= (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, ANTLR3_UINT32, pANTLR3_UINT8))
                                                                                dbgCreateTypeText;
		adaptor->dupTree				= (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))
                                                                                dbgDupTree;
		debugger->adaptor				= adaptor;
	}

	adaptor->dupTreeTT				=  (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, void *))
                                                                                dupTreeTT;
	adaptor->rulePostProcessing		=  (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))
                                                                                rulePostProcessing;
	adaptor->getType				=  (ANTLR3_UINT32 (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))
                                                                                getType;
	adaptor->setType				=  (void   (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, ANTLR3_UINT32))
																				setType;
	adaptor->getText				=  (pANTLR3_STRING (*) (pANTLR3_BASE_TREE_ADAPTOR, void *))
                                                                                getText;
	adaptor->setText8				=  (void   (*)(pANTLR3_BASE_TREE_ADAPTOR, pANTLR3_UINT8))
																				setText8;
	adaptor->setText				=  (void   (*)(pANTLR3_BASE_TREE_ADAPTOR, pANTLR3_STRING))
                                                                                setText;
	adaptor->getChild				=  (void * (*)(pANTLR3_BASE_TREE_ADAPTOR, void *, ANTLR3_UINT32))
                                                                                getChild;
	adaptor->getChildCount			=  (ANTLR3_UINT32 (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))
                                                                                getChildCount;
	adaptor->getUniqueID			=  (ANTLR3_UINT32 (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))
                                                                                getUniqueID;
	adaptor->isNilNode				=  (ANTLR3_BOOLEAN (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))
                                                                                isNilNode;

	adaptor->makeDot				=  (pANTLR3_STRING  (*)(pANTLR3_BASE_TREE_ADAPTOR, void *))
																				makeDot;
	
	/* Remaining functions filled in by the caller.
	 */
	return;
}

static void
defineDotNodes(pANTLR3_BASE_TREE_ADAPTOR adaptor, void * t, pANTLR3_STRING dotSpec )
{
	// How many nodes are we talking about?
	//
	int	nCount;
	int i;
    pANTLR3_BASE_TREE child;
	char	buff[64];
	pANTLR3_STRING	text;
	int		j;





	// Count the nodes
	//
	nCount = adaptor->getChildCount(adaptor, t);

	if	(nCount == 0)
	{
		// This will already have been included as a child of another node
		// so there is nothing to add.
		//
		return;
	}

	// For each child of the current tree, define a node using the
	// memory address of the node to name it
	//
	for	(i = 0; i<nCount; i++)
	{

		// Pick up a pointer for the child
		//
		child = adaptor->getChild(adaptor, t, i);

		// Name the node
		//
		sprintf(buff, "\tn%p[label=\"", child);
		dotSpec->append8(dotSpec, buff);
		text = adaptor->getText(adaptor, child);
		for (j = 0; j < (ANTLR3_INT32)(text->len); j++)
		{
            switch(text->charAt(text, j))
            {
                case '"':

                    dotSpec->append8(dotSpec, "\\\"");
                    break;

                case '\n':

                    dotSpec->append8(dotSpec, "\\n");
                    break;

                case '\r':

                    dotSpec->append8(dotSpec, "\\r");
                    break;

                default:

                    dotSpec->addc(dotSpec, text->charAt(text, j));
                    break;
            }
		}
		dotSpec->append8(dotSpec, "\"]\n");

		// And now define the children of this child (if any)
		//
		defineDotNodes(adaptor, child, dotSpec);
	}
	
	// Done
	//
	return;
}

static void
defineDotEdges(pANTLR3_BASE_TREE_ADAPTOR adaptor, void * t, pANTLR3_STRING dotSpec)
{
	// How many nodes are we talking about?
	//
	int	nCount;
	int i;

	if	(t == NULL)
	{
		// No tree, so do nothing
		//
		return;
	}

	// Count the nodes
	//
	nCount = adaptor->getChildCount(adaptor, t);

	if	(nCount == 0)
	{
		// This will already have been included as a child of another node
		// so there is nothing to add.
		//
		return;
	}

	// For each child, define an edge from this parent, then process
	// and children of this child in the same way
	//
	for	(i=0; i<nCount; i++)
	{
		pANTLR3_BASE_TREE child;
		char	buff[128];
        pANTLR3_STRING text;
        int                 j;

		// Next child
		//
		child	= adaptor->getChild(adaptor, t, i);

		// Create the edge relation
		//
		sprintf(buff, "\t\tn%p -> n%p\t\t// ",  t, child);
        
		dotSpec->append8(dotSpec, buff);

		// Document the relationship
		//
        text = adaptor->getText(adaptor, t);
		for (j = 0; j < (ANTLR3_INT32)(text->len); j++)
        {
                switch(text->charAt(text, j))
                {
                    case '"':

                        dotSpec->append8(dotSpec, "\\\"");
                        break;

                    case '\n':

                        dotSpec->append8(dotSpec, "\\n");
                        break;

                    case '\r':

                        dotSpec->append8(dotSpec, "\\r");
                        break;

                    default:

                        dotSpec->addc(dotSpec, text->charAt(text, j));
                        break;
                }
        }

        dotSpec->append8(dotSpec, " -> ");

        text = adaptor->getText(adaptor, child);
        for (j = 0; j < (ANTLR3_INT32)(text->len); j++)
        {
                switch(text->charAt(text, j))
                {
                    case '"':

                        dotSpec->append8(dotSpec, "\\\"");
                        break;

                    case '\n':

                        dotSpec->append8(dotSpec, "\\n");
                        break;

                    case '\r':

                        dotSpec->append8(dotSpec, "\\r");
                        break;

                    default:

                        dotSpec->addc(dotSpec, text->charAt(text, j));
                        break;
                }
        }
		dotSpec->append8(dotSpec, "\n");

        
		// Define edges for this child
		//
		defineDotEdges(adaptor, child, dotSpec);
	}

	// Done
	//
	return;
}

/// Produce a DOT specification for graphviz
//
static pANTLR3_STRING
makeDot	(pANTLR3_BASE_TREE_ADAPTOR adaptor, void * theTree)
{
	// The string we are building up
	//
	pANTLR3_STRING		dotSpec;
	char                buff[64];
	pANTLR3_STRING      text;
	int                 j;

	dotSpec = adaptor->strFactory->newStr8
		
		(
			adaptor->strFactory,

			// Default look and feel
			//
			(pANTLR3_UINT8)
			"digraph {\n\n"
			"\tordering=out;\n"
			"\tranksep=.4;\n"
			"\tbgcolor=\"lightgrey\";  node [shape=box, fixedsize=false, fontsize=12, fontname=\"Helvetica-bold\", fontcolor=\"blue\"\n"
			"\twidth=.25, height=.25, color=\"black\", fillcolor=\"white\", style=\"filled, solid, bold\"];\n\n"
			"\tedge [arrowsize=.5, color=\"black\", style=\"bold\"]\n\n"
		);

    if	(theTree == NULL)
	{
		// No tree, so create a blank spec
		//
		dotSpec->append8(dotSpec, "n0[label=\"EMPTY TREE\"]\n");
		return dotSpec;
	}

    sprintf(buff, "\tn%p[label=\"", theTree);
	dotSpec->append8(dotSpec, buff);
    text = adaptor->getText(adaptor, theTree);
    for (j = 0; j < (ANTLR3_INT32)(text->len); j++)
    {
            switch(text->charAt(text, j))
            {
                case '"':

                    dotSpec->append8(dotSpec, "\\\"");
                    break;

                case '\n':

                    dotSpec->append8(dotSpec, "\\n");
                    break;

                case '\r':

                    dotSpec->append8(dotSpec, "\\r");
                    break;

                default:

                    dotSpec->addc(dotSpec, text->charAt(text, j));
                    break;
            }
    }
	dotSpec->append8(dotSpec, "\"]\n");

	// First produce the node defintions
	//
	defineDotNodes(adaptor, theTree, dotSpec);
	dotSpec->append8(dotSpec, "\n");
	defineDotEdges(adaptor, theTree, dotSpec);
	
	// Terminate the spec
	//
	dotSpec->append8(dotSpec, "\n}");

	// Result
	//
	return dotSpec;
}


/** Create and return a nil tree node (no token payload)
 */
static	pANTLR3_BASE_TREE	
nilNode	    (pANTLR3_BASE_TREE_ADAPTOR adaptor)
{
	return	adaptor->create(adaptor, NULL);
}

static	pANTLR3_BASE_TREE	
dbgNil	    (pANTLR3_BASE_TREE_ADAPTOR adaptor)
{
	pANTLR3_BASE_TREE t;

	t = adaptor->create				(adaptor, NULL);
	adaptor->debugger->createNode	(adaptor->debugger, t);

	return	t;
}

/** Return a duplicate of the entire tree (implementation provided by the 
 *  BASE_TREE interface.)
 */
static	pANTLR3_BASE_TREE	
dupTree  (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t)
{
	return	adaptor->dupTreeTT(adaptor, t, NULL);
}

pANTLR3_BASE_TREE
dupTreeTT			(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE parent)
{
	pANTLR3_BASE_TREE	newTree;
	pANTLR3_BASE_TREE	child;
	pANTLR3_BASE_TREE	newSubTree;
	ANTLR3_UINT32		n;
	ANTLR3_UINT32		i;

	if	(t == NULL)
	{
		return NULL;
	}
	newTree = t->dupNode(t);

	// Ensure new subtree root has parent/child index set
	//
	adaptor->setChildIndex		(adaptor, newTree, t->getChildIndex(t));
	adaptor->setParent			(adaptor, newTree, parent);
	n = adaptor->getChildCount	(adaptor, t);

	for	(i=0; i < n; i++)
	{
		child = adaptor->getChild		(adaptor, t, i);
		newSubTree = adaptor->dupTreeTT	(adaptor, child, t);
		adaptor->addChild				(adaptor, newTree, newSubTree);
	}
	return	newTree;
}

/// Sends the required debugging events for duplicating a tree
/// to the debugger.
///
static void
simulateTreeConstruction(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE tree)
{
	ANTLR3_UINT32		n;
	ANTLR3_UINT32		i;
	pANTLR3_BASE_TREE	child;

	// Send the create node event
	//
	adaptor->debugger->createNode(adaptor->debugger, tree);

	n = adaptor->getChildCount(adaptor, tree);
	for	(i = 0; i < n; i++)
	{
		child = adaptor->getChild(adaptor, tree, i);
		simulateTreeConstruction(adaptor, child);
		adaptor->debugger->addChild(adaptor->debugger, tree, child);
	}
}

pANTLR3_BASE_TREE
dbgDupTree		(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE tree)
{
	pANTLR3_BASE_TREE t;

	// Call the normal dup tree mechanism first
	//
	t = adaptor->dupTreeTT(adaptor, tree, NULL);

	// In order to tell the debugger what we have just done, we now
	// simulate the tree building mechanism. THis will fire
	// lots of debugging events to the client and look like we
	// duped the tree..
	//
	simulateTreeConstruction(adaptor, t);

	return t;
}

/** Add a child to the tree t.  If child is a flat tree (a list), make all
 *  in list children of t. Warning: if t has no children, but child does
 *  and child isNilNode then it is ok to move children to t via
 *  t.children = child.children; i.e., without copying the array.  This
 *  is for construction and I'm not sure it's completely general for
 *  a tree's addChild method to work this way.  Make sure you differentiate
 *  between your tree's addChild and this parser tree construction addChild
 *  if it's not ok to move children to t with a simple assignment.
 */
static	void	
addChild (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE child)
{
	if	(t != NULL && child != NULL)
	{
		t->addChild(t, child);
	}
}
static	void	
dbgAddChild (pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_BASE_TREE child)
{
	if	(t != NULL && child != NULL)
	{
		t->addChild(t, child);
		adaptor->debugger->addChild(adaptor->debugger, t, child);
	}
}
/** Use the adaptor implementation to add a child node with the supplied token
 */
static	void		
addChildToken		(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_COMMON_TOKEN child)
{
	if	(t != NULL && child != NULL)
	{
		adaptor->addChild(adaptor, t, adaptor->create(adaptor, child));
	}
}
static	void		
dbgAddChildToken		(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, pANTLR3_COMMON_TOKEN child)
{
	pANTLR3_BASE_TREE	tc;

	if	(t != NULL && child != NULL)
	{
		tc = adaptor->create(adaptor, child);
		adaptor->addChild(adaptor, t, tc);
		adaptor->debugger->addChild(adaptor->debugger, t, tc);
	}
}

/** If oldRoot is a nil root, just copy or move the children to newRoot.
 *  If not a nil root, make oldRoot a child of newRoot.
 *
 * \code
 *    old=^(nil a b c), new=r yields ^(r a b c)
 *    old=^(a b c), new=r yields ^(r ^(a b c))
 * \endcode
 *
 *  If newRoot is a nil-rooted single child tree, use the single
 *  child as the new root node.
 *
 * \code
 *    old=^(nil a b c), new=^(nil r) yields ^(r a b c)
 *    old=^(a b c), new=^(nil r) yields ^(r ^(a b c))
 * \endcode
 *
 *  If oldRoot was null, it's ok, just return newRoot (even if isNilNode).
 *
 * \code
 *    old=null, new=r yields r
 *    old=null, new=^(nil r) yields ^(nil r)
 * \endcode
 *
 *  Return newRoot.  Throw an exception if newRoot is not a
 *  simple node or nil root with a single child node--it must be a root
 *  node.  If newRoot is <code>^(nil x)</endcode> return x as newRoot.
 *
 *  Be advised that it's ok for newRoot to point at oldRoot's
 *  children; i.e., you don't have to copy the list.  We are
 *  constructing these nodes so we should have this control for
 *  efficiency.
 */
static	pANTLR3_BASE_TREE	
becomeRoot	(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE newRootTree, pANTLR3_BASE_TREE oldRootTree)
{
    pANTLR3_BASE_TREE saveRoot;

	/* Protect against tree rewrites if we are in some sort of error
	 * state, but have tried to recover. In C we can end up with a null pointer
	 * for a tree that was not produced.
	 */
	if	(newRootTree == NULL)
	{
		return	oldRootTree;
	}

	/* root is just the new tree as is if there is no
	 * current root tree.
	 */
	if	(oldRootTree == NULL)
	{
		return	newRootTree;
	}

	/* Produce ^(nil real-node)
	 */
	if	(newRootTree->isNilNode(newRootTree))
	{
		if	(newRootTree->getChildCount(newRootTree) > 1)
		{
			/* TODO: Handle tree exceptions 
			 */
			ANTLR3_FPRINTF(stderr, "More than one node as root! TODO: Create tree exception handling\n");
			return newRootTree;
		}

		/* The new root is the first child, keep track of the original newRoot
         * because if it was a Nil Node, then we can reuse it now.
		 */
        saveRoot    = newRootTree;
		newRootTree = newRootTree->getChild(newRootTree, 0);

        // Reclaim the old nilNode()
        //
        saveRoot->reuse(saveRoot);
	}

	/* Add old root into new root. addChild takes care of the case where oldRoot
	 * is a flat list (nill rooted tree). All children of oldroot are added to
	 * new root.
	 */
	newRootTree->addChild(newRootTree, oldRootTree);

    // If the oldroot tree was a nil node, then we know at this point
    // it has become orphaned by the rewrite logic, so we tell it to do
    // whatever it needs to do to be reused.
    //
    if  (oldRootTree->isNilNode(oldRootTree))
    {
        // We have taken an old Root Tree and appended all its children to the new
        // root. In addition though it was a nil node, which means the generated code
        // will not reuse it again, so we will reclaim it here. First we want to zero out
        // any pointers it was carrying around. We are just the baseTree handler so we
        // don't know necessarilly know how to do this for the real node, we just ask the tree itself
        // to do it.
        //
        oldRootTree->reuse(oldRootTree);
    }
	/* Always returns new root structure
	 */
	return	newRootTree;

}
static	pANTLR3_BASE_TREE	
dbgBecomeRoot	(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE newRootTree, pANTLR3_BASE_TREE oldRootTree)
{
	pANTLR3_BASE_TREE t;
	
	t = becomeRoot(adaptor, newRootTree, oldRootTree);

	adaptor->debugger->becomeRoot(adaptor->debugger, newRootTree, oldRootTree);

	return t;
}
/** Transform ^(nil x) to x 
 */
static	pANTLR3_BASE_TREE	
   rulePostProcessing	(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE root)
{
    pANTLR3_BASE_TREE saveRoot;

    // Keep track of the root we are given. If it is a nilNode, then we
    // can reuse it rather than orphaning it!
    //
    saveRoot = root;

	if (root != NULL && root->isNilNode(root))
	{
		if	(root->getChildCount(root) == 0)
		{
			root = NULL;
		}
		else if	(root->getChildCount(root) == 1)
		{
			root = root->getChild(root, 0);
			root->setParent(root, NULL);
			root->setChildIndex(root, -1);

            // The root we were given was a nil node, wiht one child, which means it has
            // been abandoned and would be lost in the node factory. However
            // nodes can be flagged as resuable to prevent this terrible waste
            //
            saveRoot->reuse(saveRoot);
		}
	}

	return root;
}
 
/** Use the adaptor interface to set a new tree node with the supplied token
 *  to the root of the tree.
 */
static	pANTLR3_BASE_TREE	
   becomeRootToken	(pANTLR3_BASE_TREE_ADAPTOR adaptor, void * newRoot, pANTLR3_BASE_TREE oldRoot)
{
	return	adaptor->becomeRoot(adaptor, adaptor->create(adaptor, newRoot), oldRoot);
}
static	pANTLR3_BASE_TREE	
dbgBecomeRootToken	(pANTLR3_BASE_TREE_ADAPTOR adaptor, void * newRoot, pANTLR3_BASE_TREE oldRoot)
{
	pANTLR3_BASE_TREE	t;

	t =	adaptor->becomeRoot(adaptor, adaptor->create(adaptor, newRoot), oldRoot);

	adaptor->debugger->becomeRoot(adaptor->debugger,t, oldRoot);

	return t;
}

/** Use the super class supplied create() method to create a new node
 *  from the supplied token.
 */
static	pANTLR3_BASE_TREE	
createTypeToken	(pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken)
{
	/* Create the new token
	 */
	fromToken = adaptor->createTokenFromToken(adaptor, fromToken);

	/* Set the type of the new token to that supplied
	 */
	fromToken->setType(fromToken, tokenType);

	/* Return a new node based upon this token
	 */
	return	adaptor->create(adaptor, fromToken);
}
static	pANTLR3_BASE_TREE	
dbgCreateTypeToken	(pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken)
{
	pANTLR3_BASE_TREE t;

	t = createTypeToken(adaptor, tokenType, fromToken);

	adaptor->debugger->createNode(adaptor->debugger, t);

	return t;
}

static	pANTLR3_BASE_TREE	
createTypeTokenText	(pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken, pANTLR3_UINT8 text)
{
	/* Create the new token
	 */
	fromToken = adaptor->createTokenFromToken(adaptor, fromToken);

	/* Set the type of the new token to that supplied
	 */
	fromToken->setType(fromToken, tokenType);

	/* Set the text of the token accordingly
	 */
	fromToken->setText8(fromToken, text);

	/* Return a new node based upon this token
	 */
	return	adaptor->create(adaptor, fromToken);
}
static	pANTLR3_BASE_TREE	
dbgCreateTypeTokenText	(pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_COMMON_TOKEN fromToken, pANTLR3_UINT8 text)
{
	pANTLR3_BASE_TREE t;

	t = createTypeTokenText(adaptor, tokenType, fromToken, text);

	adaptor->debugger->createNode(adaptor->debugger, t);

	return t;
}

static	pANTLR3_BASE_TREE	
   createTypeText	(pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_UINT8 text)
{
	pANTLR3_COMMON_TOKEN	fromToken;

	/* Create the new token
	 */
	fromToken = adaptor->createToken(adaptor, tokenType, text);

	/* Return a new node based upon this token
	 */
	return	adaptor->create(adaptor, fromToken);
}
static	pANTLR3_BASE_TREE	
   dbgCreateTypeText	(pANTLR3_BASE_TREE_ADAPTOR adaptor, ANTLR3_UINT32 tokenType, pANTLR3_UINT8 text)
{
	pANTLR3_BASE_TREE t;

	t = createTypeText(adaptor, tokenType, text);

	adaptor->debugger->createNode(adaptor->debugger, t);

	return t;

}
/** Dummy implementation - will be supplied by super class
 */
static	ANTLR3_UINT32	
   getType		(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t)
{
	return	0;
}

/** Dummy implementation - will be supplied by super class
 */
static	void		
   setType		(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, ANTLR3_UINT32 type)
{
	ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement setType()\n");
}

/** Dummy implementation - will be supplied by super class
 */
static	pANTLR3_STRING	
   getText		(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t)
{
	ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement getText()\n");
	return	NULL;
}

/** Dummy implementation - will be supplied by super class
 */
static	void		
   setText		(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_STRING t)
{
	ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement setText()\n");
}
/** Dummy implementation - will be supplied by super class
 */
static	void		
setText8		(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_UINT8 t)
{
	ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement setText()\n");
}

static	pANTLR3_BASE_TREE	
   getChild		(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE tree, ANTLR3_UINT32 i)
{
	ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement getChild()\n");
	return NULL;
}

static	ANTLR3_UINT32	
   getChildCount	(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE tree)
{
	ANTLR3_FPRINTF(stderr, "Internal error - implementor of superclass containing ANTLR3_TREE_ADAPTOR did not implement getChildCount()\n");
	return 0;
}

/** Returns a uniqueID for the node. Because this is the C implementation
 *  we can just use its address suitably converted/cast to an integer.
 */
static	ANTLR3_UINT32	
   getUniqueID		(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE node)
{
	return	ANTLR3_UINT32_CAST(node);
}

static	ANTLR3_BOOLEAN
isNilNode					(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t)
{
	return t->isNilNode(t);
}
