/** \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);
}
