/*###################################################################################
#
#   Embperl - Copyright (c) 1997-2008 Gerald Richter / ecos gmbh  www.ecos.de
#   Embperl - Copyright (c) 2008-2015 Gerald Richter
#   Embperl - Copyright (c) 2015-2023 actevy.io
#
#   You may distribute under the terms of either the GNU General Public
#   License or the Artistic License, as specified in the Perl README file.
#
#   THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
#   IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
#   WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
###################################################################################*/



struct tArrayCtrl
    {
#ifdef DMALLOC
    char    sSig [6] ;
    char *  sFile ;
    int     nLine ;
#endif
    int	    nFill ;	    /* index of last element */
    int	    nMax ;	    /* number of last element for which is space */
    int	    nAdd ;	    /* number of elements to add on grow */
    int	    nElementSize ;  /* number of bytes per element */
    } ;

typedef void  tArray  ;

typedef unsigned char	tUInt8 ;
typedef signed char	tSInt8 ;
typedef unsigned short	tUInt16 ;
typedef signed short	tSInt16 ;
typedef unsigned long	tUInt32 ;
typedef signed long	tSInt32 ;

typedef tSInt32		tIndex ;
typedef tSInt16		tIndexShort ;
typedef tIndex		tStringIndex ;

typedef tUInt8          tNodeType ;
typedef tIndex		tNode	 ;
typedef tIndex		tAttr	 ;
typedef tUInt16         tRepeatLevel ;


struct tNodeData
    {
    tNodeType		nType ;
    tUInt8		bFlags ;
    tIndexShort		xDomTree ;
    tIndex		xNdx ;
    tStringIndex        nText ;
    tNode		xChilds ;
    tUInt16		numAttr ;
    tUInt16             nLinenumber ;
    tNode		xPrev ;
    tNode		xNext ;
    tNode		xParent ;
    tRepeatLevel	nRepeatLevel ;
    } ;

typedef struct tNodeData tNodeData ;

struct tAttrData
    {
    tNodeType		nType ;     /* must be at the same offset as tNodeData.nType ! */
    tUInt8		bFlags ;
    tUInt16		nNodeOffset ;
    tIndex		xNdx ;      /* must be at the same offset as tNodeData.xNdx ! */
    tIndex              xName ;
    tIndex              xValue ;  /* must be at the same offset as tNodeData.xChilds ! */
    } ;

typedef struct tAttrData tAttrData ;


struct tDomNode
    {
    tIndex		xDomTree ;
    tNode		xNode ;
    SV *		pDomNodeSV ;
    } ;

typedef struct tDomNode tDomNode ;


/*
  Node Types
*/

/* ------------------------------------------------------------------------ 

interface Node {
  # NodeType 
  const unsigned short      ELEMENT_NODE                   = 1;
  const unsigned short      ATTRIBUTE_NODE                 = 2;
  const unsigned short      TEXT_NODE                      = 3;
  const unsigned short      CDATA_SECTION_NODE             = 4;
  const unsigned short      ENTITY_REFERENCE_NODE          = 5;
  const unsigned short      ENTITY_NODE                    = 6;
  const unsigned short      PROCESSING_INSTRUCTION_NODE    = 7;
  const unsigned short      COMMENT_NODE                   = 8;
  const unsigned short      DOCUMENT_NODE                  = 9;
  const unsigned short      DOCUMENT_TYPE_NODE             = 10;
  const unsigned short      DOCUMENT_FRAGMENT_NODE         = 11;
  const unsigned short      NOTATION_NODE                  = 12;

*/

enum tNodeTypeValues
    {
    ntypTag	        = 1,
    ntypStartTag        = 1 + 0x20,
    ntypStartEndTag     = 1 + 0x80,
    ntypEndTag	        = 1 + 0x40,
    ntypEndStartTag     = 1 + 0x60,
    ntypAttr	        = 2,
    ntypAttrValue       = 2 + 0x20,
    ntypText	        = 3,
    ntypTextHTML        = 3 + 0x20,  /* same as text, but with html encoding */
    ntypCDATA	        = 4,
    ntypEntityRef       = 5,
    ntypEntity          = 6,
    ntypProcessingInstr = 7,
    ntypComment         = 8,
    ntypDocument        = 9,
    ntypDocumentType    = 10,
    ntypDocumentFraq    = 11,
    ntypNotation        = 12
    } ;

#define ntypMask 0x1f 

enum tNodeFlags
    {
    nflgDeleted	     = 0,
    nflgOK	     = 1,
    nflgEscUrl       = 2,
    nflgEscChar	     = 4,
    nflgIgnore       = 16,	/**< Ignore this node */
    nflgNewLevelNext = 32,	/**< Next sibling has new RepeatLevel */
    nflgNewLevelPrev = 64,	/**< Previous sibling has new RepeatLevel */
    nflgStopOutput   = 8,	/**< Do not make any further output after this node */
    nflgEscUTF8	     = 128
    } ;

enum tAttrFlags
    {
    aflgDeleted	    = 0,
    aflgOK	    = 1,
    aflgAttrValue   = 2,
    aflgAttrChilds  = 4,
    aflgSingleQuote = 8
    } ;

struct tDomTreeOrder
    {
    tNode  xFromNode ;	    
    tNode  xToNode ;
    } ;

typedef struct tDomTreeOrder tDomTreeOrder ;

struct tDomTreeCheckpoint
    {
    tNode  xNode ;	    
    } ;

typedef struct tDomTreeCheckpoint tDomTreeCheckpoint ;

struct tDomTreeCheckpointStatus
    {
    tRepeatLevel    nRepeatLevel ;	 /**< Repeatlevel when last passed this checkpoint */
    tIndex          nCompileCheckpoint ; /**< r -> nCurrCheckpoint when last passed this checkpoint */
    tNode	    xJumpFromNode ;	 /**< node from which backward jump started */
    tNode	    xJumpToNode ;	 /**< node to which backward jump was */
    } ;

typedef struct tDomTreeCheckpointStatus tDomTreeCheckpointStatus ;


struct tRepeatLevelLookupItem
    {
    tNodeData	*	    pNode ;	/* pointer to actual node data */
    struct tRepeatLevelLookupItem *  pNext ;	/* next node with same node index but different nRepeatLevel */
    } ;

typedef struct tRepeatLevelLookupItem tRepeatLevelLookupItem ;

struct tRepeatLevelLookup
    {
    tNode                   xNullNode ; /**< node index of node with RepeatLevel == 0 */
    tRepeatLevel	    numItems ;	/**< size of table (must be 2^n) */
    tRepeatLevel	    nMask ;	/**< mask (usualy numItems - 1) */
    tRepeatLevelLookupItem  items[1] ;	/**< array with numItems items */
    } ;

typedef struct tRepeatLevelLookup tRepeatLevelLookup ;

struct tLookupItem
    {
    void  *	    pLookup ;	/* table for converting tNode and tAttr to pointers */
    tRepeatLevelLookup  * pLookupLevel ; /* hash table used to index xNode/nRepeatLevel */
    } ;

typedef struct tLookupItem tLookupItem ;


struct tDomTree
    {
    tLookupItem *   pLookup ;		/**< \_en  table for converting tNode and tAttr to pointers \endif */
					/**< \_de  Tabelle um tNode und tAttr Indexe zu Zeigern umzuwandeln \endif */
    tDomTreeCheckpoint * pCheckpoints ; /**< \_en  checkpoints in the code, to check against execution order when running \endif*/
					/**< \_de  checkpoints im Code. Diese Liste wird wird der Reiehenfolge der 
                                                  tatsächlichen Ausführung verglichen um den DomTree entsprechend zu modifizieren \endif*/
    tDomTreeCheckpointStatus * pCheckpointStatus ; /**< \_en  status of checkpoint while generating new DomTree \endif */
					/**< \_de  Status eines checkpoints während dem neu Erzeugen eines DomTree \endif */
    tIndexShort	    xNdx ;		/**< \_en  Index of Dom Tree \endif */
					/**< \_de  Index des Dom Tree \endif */    
    tIndexShort	    xSourceNdx ;	/**< \_en  When a cloned DomTree this is the index of the source Dom Tree \endif */
					/**< \_de  Wenn dieser Dom Tree gecloned ist, ist dies der Index des Quellen Dom Tree \endif */    
    tNode	    xDocument ;		/**< \_en  Index of the root document node \endif */
					/**< \_en  Index des Wurzelknotenes des DomTrees \endif */
    tNode           xLastNode ;		/**< last node that was compiled */
    tNode           xCurrNode ;		/**< curr node that is compiled */
    tIndex          xFilename ;		/**< name of source file */
    SV *	    pSV ;		/**< general purpose SV */
    SV *	    pDomTreeSV ;	/**< SV that's hold the Index */
					/**< Domtree will be deleted when this SV is delted */
    tUInt16         nLastLinenumber ;

    AV *            pDependsOn ;        /**< List of DomTree on which this one depends */
    } ;

typedef struct tDomTree tDomTree ;




extern tDomTree  *    pDomTrees ;	     /* Array with all Dom Trees */
extern HE * *	      pStringTableArray  ;   /* Array with pointers to strings */
extern tIndex	      xNoName ;		     /* String index for Attribut with noname */
extern tIndex	      xDomTreeAttr ;	     /* String index for Attribut which holds the DomTree index */
extern tIndex	      xDocument ;	     /* String index for Document */
extern tIndex	      xDocumentFraq ;	     /* String index for Document Fraquent */
extern tIndex	      xOrderIndexAttr ;	     /* String index for Attribute which holds the OrderIndex */

struct tApp ; /* forward */

tStringIndex String2NdxInc (/*in*/ struct tApp * a, 
                            /*in*/ const char *	    sText,
			    /*in*/ int		    nLen,
			    /*in*/ int		    bInc) ;

tStringIndex String2UniqueNdx (/*in*/ struct tApp * a, 
                               /*in*/ const char *	    sText,
  			       /*in*/ int		    nLen) ;

void NdxStringFree (/*in*/ struct tApp * a,
                    /*in*/ tStringIndex             nNdx) ;



#define SV2String(pSV,l)  (SvOK (pSV)?SvPV (pSV, l):(l=0,((char *)NULL)))

#define String2NdxNoInc(a,sText,nLen) String2NdxInc(a,sText,nLen,0)
#define String2Ndx(a,sText,nLen) String2NdxInc(a,sText,nLen,1)

#define Ndx2String(nNdx) (HeKEY (pStringTableArray[nNdx]))
#define Ndx2StringLen(nNdx,sVal,nLen) { HE * pHE = pStringTableArray[nNdx] ; nLen=HeKLEN(pHE) ; sVal = HeKEY (pHE) ; }

#define NdxStringRefcntInc(a,nNdx) (SvREFCNT_inc (HeVAL (pStringTableArray[nNdx])))

#ifdef DMALLOC
int ArrayNew_dbg (/*in*/ struct tApp * a, 
               /*in*/ const tArray * pArray,
	      /*in*/ int	nAdd,
	      /*in*/ int	nElementSize,
	      /*in*/ char *     sFile,
	      /*in*/ int        nLine) ;
int ArrayNewZero_dbg (/*in*/ struct tApp * a, 
              /*in*/ const tArray * pArray,
	      /*in*/ int	nAdd,
	      /*in*/ int	nElementSize,
	      /*in*/ char *     sFile,
	      /*in*/ int        nLine) ;
int ArrayClone_dbg (/*in*/ struct tApp * a, 
                    /*in*/  const tArray * pOrgArray,
	        /*out*/ const tArray * pNewArray,	      
		/*in*/ char *     sFile,
		/*in*/ int        nLine) ;

#undef ArrayNew
#define ArrayNew(app,a,n,s) ArrayNew_dbg(app,a,n,s,__FILE__,__LINE__)
#undef ArrayNewZero
#define ArrayNewZero(app,a,n,s) ArrayNewZero_dbg(app,a,n,s,__FILE__,__LINE__)
#undef ArrayClone
#define ArrayClone(app,o,n) ArrayClone_dbg(app,o,n,__FILE__,__LINE__)

#else

int ArrayNew (/*in*/ struct tApp * a, 
              /*in*/ const tArray * pArray,
	      /*in*/ int	nAdd,
	      /*in*/ int	nElementSize) ;

int ArrayNewZero (/*in*/ struct tApp * a, 
                  /*in*/ const tArray * pArray,
	      /*in*/ int	nAdd,
	      /*in*/ int	nElementSize) ;

int ArrayClone (/*in*/ struct tApp * a, 
                /*in*/  const tArray * pOrgArray,
	        /*out*/ const tArray * pNewArray) ;

#endif

int ArrayFree (/*in*/ struct tApp * a, 
               /*in*/ const tArray * pArray) ;

int ArraySet (/*in*/ struct tApp * a, 
              /*in*/ const tArray * pArray,
	      /*in*/ int	numElements) ;

int ArraySetSize (/*in*/ struct tApp * a, 
                  /*in*/ const tArray * pArray,
	          /*in*/ int	numElements) ;

int ArrayGetSize (/*in*/ struct tApp * a, 
                  /*in*/ const tArray * pArray) ;

int ArrayAdd (/*in*/ struct tApp * a, 
              /*in*/ const tArray * pArray,
	      /*in*/ int	numElements) ;

int ArraySub (/*in*/ struct tApp * a, 
              /*in*/ const tArray * pArray,
	      /*in*/ int	numElements) ;

#ifdef DMALLOC
void StringNew_dbg (/*in*/ struct tApp * a, 
                    /*in*/ char * * pArray,
	      /*in*/ int	nAdd,
	      /*in*/ char *     sFile,
	      /*in*/ int        nLine) ;

#undef StringNew
#define StringNew(app,a,n) StringNew_dbg(app,a,n,__FILE__,__LINE__)

#else
void StringNew (/*in*/ struct tApp * a, 
                /*in*/ char * * pArray,
	      /*in*/ int	nAdd) ;
#endif

void StringFree (/*in*/ struct tApp * a, 
                 /*in*/ char * * pArray) ;

int StringAdd (/*in*/ struct tApp * a, 
               /*in*/ char * *	   pArray,
	       /*in*/ const char * sAdd,
	       /*in*/ int 	   nLen) ;

int DomInit (/*in*/ struct tApp * a) ;

void DomStats (/*in*/ struct tApp * a) ;

int DomTree_clone (/*in*/ struct tApp * a, 
                   /*in*/ tDomTree *	pOrgDomTree,
		   /*out*/tDomTree * *  pNewDomTree,
		   /*in*/ int           bForceDocFraq) ;

int DomTree_new (/*in*/ struct tApp * a, 
                        tDomTree * * pNewLookup) ;

int DomTree_delete (/*in*/ struct tApp * a, 
                           tDomTree * pDomTree) ;

void DomTree_checkpoint (struct tReq * r, tIndex nRunCheckpoint) ;
void DomTree_discardAfterCheckpoint (struct tReq * r, tIndex nRunCheckpoint) ;

#define DomTree_SV(pSV) SvIVX(pSV)
#define DomTree_selfSV(pSV) (DomTree_self(SvIVX(pSV)))
#define SV_DomTree(xDomTree) (DomTree_self (xDomTree) -> pDomTreeSV)
#define SV_DomTree_self(pDomTree) (pDomTree -> pDomTreeSV)
#define DomTree_filename(xDomTree)	    (Ndx2String (DomTree_self(xDomTree) -> xFilename))
#define DomTree_selfFilename(pDomTree)	    (Ndx2String ((pDomTree) -> xFilename))

tNodeData * Node_selfLevelItem (/*in*/ struct tApp * a, 
                                /*in*/ tDomTree *    pDomTree,
				/*in*/ tNode	 xNode,
				/*in*/ tRepeatLevel  nLevel) ;

tNode Node_appendChild (/*in*/ struct tApp * a, 
                        /*in*/  tDomTree *	 pDomTree,
			/*in*/	tNode 		 xParent,
                        /*in*/  tRepeatLevel     nRepeatLevel,
			/*in*/	tNodeType	 nType,
			/*in*/	int              bForceAttrValue,
			/*in*/	const char *	 sText,
			/*in*/	int		 nTextLen,
			/*in*/	int		 nLevel,
			/*in*/	int		 nLinenumber,
			/*in*/	const char *	 sLogMsg) ;



struct tNodeData * Node_selfNthChild (/*in*/ struct tApp * a, 
                                      /*in*/  tDomTree *        pDomTree,
				      /*in*/ struct tNodeData * pNode,
                                      /*in*/  tRepeatLevel      nRepeatLevel,
				      /*in*/ int		nChildNo) ;


tNodeData * Node_selfLastChild   (/*in*/ struct tApp * a, 
                                  /*in*/  tDomTree *   pDomTree,
				  /*in*/  tNodeData *  pNode,
                                  /*in*/  tRepeatLevel nRepeatLevel) ;

tNodeData * Node_selfNextSibling (/*in*/ struct tApp * a, 
                                  /*in*/ tDomTree *  pDomTree,
			          /*in*/ tNodeData * pNode,
                                  /*in*/  tRepeatLevel nRepeatLevel) ;
				  
tNode Node_nextSibling (/*in*/ struct tApp * a, 
                        /*in*/ tDomTree *  pDomTree,
			/*in*/ tNode       xNode,
                        /*in*/  tRepeatLevel nRepeatLevel) ;

tNodeData * Node_selfPreviousSibling (/*in*/ struct tApp * a, 
                                      /*in*/ tDomTree *	    pDomTree,
				      /*in*/ tNodeData *    pNode,
				      /*in*/ tRepeatLevel   nRepeatLevel) ;

tNode Node_previousSibling (/*in*/ struct tApp * a, 
                            /*in*/ tDomTree *	pDomTree,
			    /*in*/ tNode	xNode,
                            /*in*/ tRepeatLevel	nRepeatLevel) ;


#define DomTree_self(xDomTree)		    (&pDomTrees[xDomTree]) 

#define Node_self(pDomTree,xNode)	    ((struct tNodeData *)(pDomTree -> pLookup[xNode].pLookup))
#define Node_selfLevel(a,pDomTree,xNode,nLevel)  \
			    (pDomTree -> pLookup[xNode].pLookup == NULL?NULL:    \
				(((struct tNodeData *)(pDomTree -> pLookup[xNode].pLookup)) -> nRepeatLevel == nLevel? \
				((struct tNodeData *)(pDomTree -> pLookup[xNode].pLookup)): \
				Node_selfLevelItem(a,pDomTree,xNode,nLevel)))

#define Node_selfNotNullLevel(a,pDomTree,xNode,nLevel)	\
			    (pDomTree -> pLookup[xNode].pLookup == NULL?NULL:    \
				(((struct tNodeData *)(pDomTree -> pLookup[xNode].pLookup)) -> xDomTree == pDomTree -> xNdx? \
				((struct tNodeData *)(pDomTree -> pLookup[xNode].pLookup)): \
				Node_selfLevelItem(a,pDomTree,xNode,nLevel)))
#if 0
			    (pDomTree -> pLookup[xNode].pLookup == ?  \
				((((struct tNodeData *)(pDomTree -> pLookup[xNode].pLookup)) -> nRepeatLevel == nLevel || \
				((struct tNodeData *)(pDomTree -> pLookup[xNode].pLookup)) -> nRepeatLevel !=  0 || \
				pDomTree -> pLookup[xNode].pLookupLevel == NULL)?   \
				    ((struct tNodeData *)(pDomTree -> pLookup[xNode].pLookup)):	\
				    Node_selfLevelItem(a,pDomTree,xNode,nLevel)):	\
			    NULL)
#endif

#define xNode_selfLevelNull(pDomTree,pNode)   ((pDomTree) -> pLookup[(pNode)->xNdx].pLookupLevel?(pDomTree) -> pLookup[(pNode)->xNdx].pLookupLevel -> xNullNode:(pNode) -> xNdx)
#define xNode_levelNull(pDomTree,xNode)   ((pDomTree) -> pLookup[(xNode)].pLookupLevel?(pDomTree) -> pLookup[(xNode)].pLookupLevel -> xNullNode:(xNode))


#define Node_parentNode(a,pDomTree,xNode,nLevel)	    (Node_selfLevel(a,pDomTree,xNode,nLevel)->xParent)
#define Node_selfParentNode(a,pDomTree,pNode,nLevel) (Node_selfLevel(a,pDomTree,(pNode)->xParent,nLevel))
#define xNode_selfParentNode(pDomTree,pNode) ((pNode)->xParent)


#define Node_firstChild(a,pDomTree,xNode,nLevel)	    (Node_selfLevel(a,pDomTree,xNode,nLevel)->xChilds)
#define Node_selfFirstChild(a,pDomTree,pNode,nLevel)  (Node_selfLevel(a,pDomTree,(pNode)->xChilds,nLevel))

#define Node_selfNodeNameNdx(pNode)	    ((pNode) -> nText) ;
#define Node_selfNodeName(pNode)	    (Ndx2String ((pNode) -> nText))
#define Node_nodeName(a,pDomTree,xNode,nLevel)	    (Ndx2String (Node_selfLevel (a,pDomTree,xNode,nLevel) -> nText))
#define Node_selfFirstAttr(pNode)	    ((tAttrData *)((pNode) + 1))

tNodeData * Node_selfCloneNode (/*in*/ struct tApp * a, 
                                /*in*/ tDomTree *      pDomTree,
				/*in*/ tNodeData *     pNode,
                                /*in*/ tRepeatLevel    nRepeatLevel,
				/*in*/  int	       bDeep) ;

tNodeData * Node_selfCondCloneNode (/*in*/ struct tApp * a, 
                                    /*in*/ tDomTree *      pDomTree,
				    /*in*/ tNodeData *     pNode,
                                    /*in*/ tRepeatLevel    nRepeatLevel) ;

tNodeData * Node_selfForceLevel(/*in*/ struct tApp * a, 
                                /*in*/ tDomTree *      pDomTree,
				/*in*/ tNode           xNode,
                                /*in*/ tRepeatLevel    nRepeatLevel) ;

tNode Node_cloneNode (/*in*/ struct tApp * a, 
                      /*in*/ tDomTree *      pDomTree,
		      /*in*/ tNode 	     xNode,
                      /*in*/ tRepeatLevel    nRepeatLevel,
		      /*in*/  int	     bDeep) ;


void Node_toString (/*i/o*/ register req *  r,
		    /*in*/ tDomTree *	    pDomTree,
		    /*in*/ tNode	    xNode,
                    /*in*/ tRepeatLevel     nRepeatLevel) ;

struct tNodeData *  Node_selfRemoveChild (/*in*/ struct tApp * a, 
                                          /*in*/ tDomTree *  pDomTree,
					  /*in*/ tNode		    xNode,
					  /*in*/ struct tNodeData *	    pChild) ;

tNode Node_removeChild (/*in*/ struct tApp * a, 
                        /*in*/ tDomTree *   pDomTree,
			/*in*/ tNode	    xNode,
			/*in*/ tNode	    xChild,
                        /*in*/ tRepeatLevel nRepeatLevel) ;

tNode Node_insertBefore_CDATA    (/*in*/ struct tApp * a, 
                                 /*in*/ const char *    sText,
				 /*in*/ int             nTextLen,
			         /*in*/ int		nEscMode,
                                 /*in*/ tDomTree *      pRefNodeDomTree,
				 /*in*/ tNode		xRefNode,
                                 /*in*/ tRepeatLevel    nRefRepeatLevel) ;

tNode Node_insertAfter          (/*in*/ struct tApp * a, 
                                 /*in*/ tDomTree *      pNewNodeDomTree,
				 /*in*/ tNode		xNewNode,
                                 /*in*/ tRepeatLevel    nNewRepeatLevel,
                                 /*in*/ tDomTree *      pRefNodeDomTree,
				 /*in*/ tNode		xRefNode,
                                 /*in*/ tRepeatLevel    nRefRepeatLevel) ;

tNode Node_insertAfter_CDATA    (/*in*/ struct tApp * a, 
                                 /*in*/ const char *    sText,
				 /*in*/ int             nTextLen,
			         /*in*/ int		nEscMode,
                                 /*in*/ tDomTree *      pRefNodeDomTree,
				 /*in*/ tNode		xRefNode,
                                 /*in*/ tRepeatLevel    nRefRepeatLevel) ;

tNode Node_replaceChildWithNode (/*in*/ struct tApp * a, 
                                 /*in*/ tDomTree *      pDomTree,
				 /*in*/ tNode		xNode,
                                 /*in*/ tRepeatLevel    nRepeatLevel,
                                 /*in*/ tDomTree *      pOldChildDomTree,
				 /*in*/ tNode		xOldChild,
                                 /*in*/ tRepeatLevel    nOldRepeatLevel) ;


tNode Node_replaceChildWithCDATA (/*in*/ struct tApp * a, 
                                  /*in*/ tDomTree *	 pDomTree,
				  /*in*/ tNode		 xOldChild,
                                  /*in*/ tRepeatLevel    nRepeatLevel,
                                  /*in*/ const char *	 sText,
				  /*in*/ int		 nTextLen,
				  /*in*/ int		 nEscMode,
				  /*in*/ int		 bFlags) ;

char * Node_childsText (/*in*/ struct tApp * a, 
                        /*in*/ tDomTree *  pDomTree,
		       /*in*/  tNode       xNode,
                       /*in*/ tRepeatLevel nRepeatLevel,
		       /*i/o*/ char * *    ppText,
		       /*in*/  int         bDeep) ;


tAttrData *  Element_selfGetAttribut (/*in*/ struct tApp * a, 
                                      /*in*/ tDomTree *     pDomTree,
				      /*in*/ struct tNodeData * pNode,
				      /*in*/ const char *	sAttrName,
				      /*in*/ int		nAttrNameLen) ;



tAttrData *  Element_selfGetNthAttribut (/*in*/ struct tApp * a, 
                                         /*in*/ tDomTree *	   pDomTree,
			  	         /*in*/ struct tNodeData * pNode,
				         /*in*/ int                n) ;


tAttrData *  Element_selfSetAttribut (/*in*/ struct tApp * a, 
                                      /*in*/ tDomTree *	        pDomTree,
				      /*in*/ struct tNodeData * pNode,
				      /*in*/ tRepeatLevel       nRepeatLevel,
				      /*in*/ const char *	sAttrName,
				      /*in*/ int		nAttrNameLen,
				      /*in*/ const char *       sNewValue, 
				      /*in*/ int		nNewValueLen) ;

tAttrData *  Element_selfRemoveAttributPtr (/*in*/ struct tApp * a, 
                                            /*in*/ tDomTree *	        pDomTree,
				      /*in*/ struct tNodeData * pNode,
				      /*in*/ tRepeatLevel       nRepeatLevel,
				      /*in*/ tAttrData *	pAttr) ;

tAttrData *  Element_selfRemoveNthAttribut (/*in*/ struct tApp * a, 
                                            /*in*/ tDomTree *	        pDomTree,
				      /*in*/ struct tNodeData * pNode,
				      /*in*/ tRepeatLevel       nRepeatLevel,
				      /*in*/ int                n) ;


tAttrData *  Element_selfRemoveAttribut (/*in*/ struct tApp * a, 
                                         /*in*/ tDomTree *	        pDomTree,
				      /*in*/ struct tNodeData * pNode,
				      /*in*/ tRepeatLevel       nRepeatLevel,
				      /*in*/ const char *	sAttrName,
				      /*in*/ int		nAttrNameLen) ;

#define Attr_self(pDomTree,xAttr)	    ((struct tAttrData *)(pDomTree -> pLookup[xAttr].pLookup))
#define Attr_selfNode(pAttr)        ((struct tNodeData * )(((tUInt8 *)pAttr) - pAttr -> nNodeOffset))
#define Attr_selfAttrNum(pAttr)    (pAttr - Node_selfFirstAttr (Attr_selfNode(pAttr)))


char *       Attr_selfValue (/*in*/ struct tApp * a, 
                             /*in*/  tDomTree *	        pDomTree,
			     /*in*/  struct tAttrData * pAttr,
			     /*in*/  tRepeatLevel       nRepeatLevel,
			     /*out*/ char * *		ppAttr) ;


#define NodeAttr_selfParentNode(pDomTree,pNode,nLevel) (pNode->nType == ntypAttr?Attr_selfNode(((tAttrData *)pNode)):(Node_self(pDomTree,(pNode)->xParent)))