/** \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 = (pANTLR3_BASE_TREE)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	= (pANTLR3_BASE_TREE)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	(pANTLR3_BASE_TREE)adaptor->create(adaptor, NULL);
}

static	pANTLR3_BASE_TREE	
dbgNil	    (pANTLR3_BASE_TREE_ADAPTOR adaptor)
{
	pANTLR3_BASE_TREE t;

	t = (pANTLR3_BASE_TREE)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	(pANTLR3_BASE_TREE)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 = (pANTLR3_BASE_TREE)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 = (pANTLR3_BASE_TREE)adaptor->getChild		(adaptor, t, i);
		newSubTree = (pANTLR3_BASE_TREE)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 = (pANTLR3_BASE_TREE)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 = (pANTLR3_BASE_TREE)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 = (pANTLR3_BASE_TREE)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 = (pANTLR3_BASE_TREE)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 = (pANTLR3_BASE_TREE)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	(pANTLR3_BASE_TREE)adaptor->becomeRoot(adaptor, adaptor->create(adaptor, (pANTLR3_COMMON_TOKEN)newRoot), oldRoot);
}
static	pANTLR3_BASE_TREE	
dbgBecomeRootToken	(pANTLR3_BASE_TREE_ADAPTOR adaptor, void * newRoot, pANTLR3_BASE_TREE oldRoot)
{
	pANTLR3_BASE_TREE	t;

	t =	(pANTLR3_BASE_TREE)adaptor->becomeRoot(adaptor, adaptor->create(adaptor, (pANTLR3_COMMON_TOKEN)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	(pANTLR3_BASE_TREE)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	(pANTLR3_BASE_TREE)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	(pANTLR3_BASE_TREE)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);
}
