webengine/wmlengine/src/wml1x/src/WML1XApi.cpp
changeset 0 dd21522fd290
child 36 0ed94ceaa377
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/wmlengine/src/wml1x/src/WML1XApi.cpp	Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,2804 @@
+/*
+* Copyright (c) 2000 - 2001 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+
+/* Includes */
+#include "nwx_string.h"
+#include "nwx_url_utils.h"
+#include "nw_errnotify.h"
+#include "nwx_url_utils.h"
+#include "nwx_http_header.h"
+#include "nw_wml_api.h"
+#include "nw_wml_core.h"
+#include "nwx_logger.h"
+#include "nw_hed_documentroot.h"
+#include "nw_wml1x_wml1xcontenthandler.h"
+#include "nw_wml1x_wml1xeventhandler.h"
+#include "nw_wml1x_wml1xdefaultstylesheet.h"
+#include "nw_lmgr_bidiflowbox.h"
+#include "nw_lmgr_cssproperties.h"
+#include "nw_lmgr_textbox.h"
+#include "nw_lmgr_breakbox.h"
+#include "nw_lmgr_emptybox.h"
+#include "nw_lmgr_statictablebox.h"
+#include "nw_lmgr_statictablerowbox.h"
+#include "nw_lmgr_statictablecellbox.h"
+#include "nw_lmgr_activecontainerbox.h"
+#include "nw_hed_hedeventhandler.h"
+#include "nw_image_cannedimages.h"
+#include "nw_image_virtualimage.h"
+#include "nw_text_ascii.h"
+#include "nw_text_ucs2.h"
+#include "nw_adt_map.h"
+#include "nw_adt_dynamicvector.h"
+#include "nw_fbox_formliaison.h"
+#include "nw_fbox_checkbox.h"
+#include "nw_fbox_radiobox.h"
+#include "nw_fbox_inputbox.h"
+#include "nw_fbox_passwordbox.h"
+#include "nw_wml1x_wml1xactiveevent.h"
+#include "nwx_settings.h"
+#include "nw_lmgr_accesskey.h"
+#include "wml_elm_attr.h"
+#include "nw_markup_wmlvalidator.h"
+#include "nw_system_optionlist.h"
+#include "HEDDocumentListener.h"
+#include "nw_lmgr_rootbox.h"
+#include "nw_lmgr_imgcontainerbox.h"
+#include "nw_lmgr_animatedimagebox.h"
+
+#include "nw_hed_historyvisitor.h"
+#include "urlloader_urlloaderint.h"
+#include "MVCView.h"
+#include "nw_wml1x_wml1xapi.h"
+#include "nwx_http_defs.h"
+#include "BrsrStatusCodes.h"
+#include "BodyPart.h"
+#include "MVCShell.h"
+#include "BrCtl.h"
+#include "MemoryManager.h"
+
+/*
+**-------------------------------------------------------------------------
+**  Local Macros
+**-------------------------------------------------------------------------
+*/
+#define NW_MSEC_PER_WML_TICK 100
+/*
+**-------------------------------------------------------------------------
+**  Internal Prototypes
+**-------------------------------------------------------------------------
+*/
+/* display functions called by the WML Browser */
+static TBrowserStatusCode NW_UI_CreateCard(void *wae);
+static TBrowserStatusCode NW_UI_ShowCard(void *wae);
+static TBrowserStatusCode NW_UI_DestroyCard(void *wae);
+static TBrowserStatusCode NW_UI_AddElement(void *wae, NW_Wml_ElType_e elemType,
+                                    NW_Int16 *elemId);
+static TBrowserStatusCode NW_UI_CleanUp(void *wae);
+static TBrowserStatusCode NW_UI_SetOptState(void *wae, NW_Uint16 elemId, NW_Bool st);
+static TBrowserStatusCode NW_UI_GetOptState(void *wae, NW_Uint16 elemId, NW_Bool* st);
+static TBrowserStatusCode NW_UI_Refresh(void *wae);
+
+static TBrowserStatusCode NW_Wml1x_CreateTimer(void *usrAgent, NW_Uint32 period);
+static TBrowserStatusCode NW_Wml1x_ReadTimer(void *usrAgent, NW_Uint32 *period);
+static TBrowserStatusCode NW_Wml1x_DestroyTimer(void *usrAgent);
+static TBrowserStatusCode NW_Wml1x_ResumeTimer(void *usrAgent);
+static TBrowserStatusCode NW_Wml1x_StopTimer(void *usrAgent);
+static TBrowserStatusCode NW_Wml1x_IsTimerRunning(void *usrAgent, NW_Bool *isRunning);
+/*
+**-------------------------------------------------------------------------
+**  File Scoped Static Variables
+**-------------------------------------------------------------------------
+*/
+
+/* WML Core Routines. */
+static const NW_DisplayApi_t panel_api =
+{
+  NW_UI_CreateCard,
+  NW_UI_ShowCard,
+  NW_UI_DestroyCard,
+  NW_UI_AddElement,
+  NW_UI_CleanUp,
+  NW_UI_GetOptState,
+  NW_UI_SetOptState,
+  NW_UI_Refresh,
+};
+
+/*Timer API wrappers for WML 1.x content handler*/
+static const NW_TimerApi_t Wml1x_timer_api =
+{
+  NW_Wml1x_CreateTimer,
+  NW_Wml1x_ReadTimer,
+  NW_Wml1x_DestroyTimer,
+  NW_Wml1x_ResumeTimer,
+  NW_Wml1x_StopTimer,
+  NW_Wml1x_IsTimerRunning
+};
+
+
+static const NW_WmlApi_t wml_api =
+{
+  &panel_api,
+  &Wml1x_timer_api
+};
+
+/* Additional constants */
+static const NW_Ucs2 monospace[] = {'m', 'o', 'n', 'o', 's', 'p', 'a', 'c', 'e', '\0'};
+static const NW_Ucs2 spaceString[] = {NW_TEXT_UCS2_NBSP,'\0'};
+
+/*
+**-------------------------------------------------------------------------
+**  Internal Functions
+**-------------------------------------------------------------------------
+*/
+
+
+/*****************************************************************
+
+  Name:         NW_UI_SetParagraphProperties()
+
+  Description:  set wrap and alignment paragraph properties
+
+  Parameters:   
+    thisObj - In      - the content handler on behalf of which the work is being done
+    elId    - In      - the element id of the <p> element being processed, used in the WML query service
+    box     - In      - pointer to the box tree node representing the <p> element
+    nowrap  - In/Out  - pointer to boolean in which to maintain current nowrap property value
+
+  Algorithm:    wrap property is 'sticky' from previous paragraphs
+                alignment is left unless attribute set otherwise
+
+  Return Value: KBrsrOutOfMemory
+                KBrsrSuccess
+
+*****************************************************************/
+static
+TBrowserStatusCode
+NW_UI_SetParagraphProperties (NW_Wml1x_ContentHandler_t *thisObj,
+                              NW_Uint16                 elId,
+                              NW_LMgr_Box_t             *box,
+                              NW_Bool                   *nowrap,
+                              NW_LMgr_Box_t             **deleteBox)
+{
+
+  NW_LMgr_ContainerBox_t  *container = NW_LMgr_ContainerBoxOf(box);
+  NW_ADT_DynamicVector_t  *children = NW_LMgr_ContainerBoxOf(box)->children;
+  NW_Ucs2                 *retString = NULL;
+  NW_LMgr_PropertyValue_t value;
+  NW_LMgr_Property_t      prop;
+
+  NW_TRY (status) {
+    /* We must ignore empty P elements, see [WAP WML] */
+    if (NW_ADT_Vector_GetSize(children) == 0) {
+      *deleteBox = box;
+      NW_THROW_SUCCESS(status);
+    }
+    else if (NW_ADT_Vector_GetSize(children) == 1) {
+      NW_LMgr_Box_t *child = NW_LMgr_ContainerBox_GetChild(container, 0);
+      if (NW_Object_IsClass(child, &NW_LMgr_TextBox_Class)) {
+        /* if the box tree were complete here, we could query the text box to see if it is blank
+        but since the text box has not yet been visited by the ShowCard() process, such a query
+        will always return blank!  Instead, query the wmlInterpreter for the STR_VALUE of the element */
+        status = NW_LMgr_Box_GetPropertyValue(child, NW_CSS_Prop_elementId, NW_CSS_ValueType_Integer, &value);
+
+        if (status == KBrsrSuccess) {
+          NW_Uint16 childElId = 0;
+
+          childElId = NW_UINT16_CAST(value.integer);
+          status = NW_Wml_GetAttribute(&(thisObj->wmlInterpreter),
+                                       childElId,
+                                       STR_VALUE,
+                                       &retString);
+          NW_THROW_ON (status, KBrsrOutOfMemory);
+          if (retString == NULL) {
+            /* must delete the child of box here, before the ShowCard() box visitor accesses it. */
+            status = NW_LMgr_ContainerBox_RemoveChild(container,
+                                                      child);
+            NW_Object_Delete(child);
+            *deleteBox = box;
+            NW_THROW_SUCCESS(status);
+          }
+          else {
+            NW_Uint32 i;
+            NW_Uint32 j;
+
+            /* if all the characters are whitespace then throw(success)*/
+            j = NW_Str_Strlen(retString);
+            for (i = 0; i < j; i++) {
+              if (!NW_Str_Isspace(retString[i])) {
+                break;
+              }
+            }
+            if (i == j) {
+              NW_THROW_SUCCESS(status);
+            }
+            NW_Str_Delete(retString);
+            retString = NULL;
+          }
+        }
+      }
+    }
+
+    /* Get the wrap mode attribute */
+    status = NW_Wml_GetAttribute(&(thisObj->wmlInterpreter), 
+                                 elId, 
+                                 MODE_ATTR, 
+                                 &retString);
+    NW_THROW_ON (status, KBrsrOutOfMemory);
+    
+    if (retString != NULL) {
+      if (NW_Str_StricmpConst(retString,WAE_ASC_WRAP_STR)==0) {
+        *nowrap = NW_FALSE;
+      } else if (NW_Str_StricmpConst(retString,WAE_ASC_NOWRAP_STR)==0) {
+        *nowrap = NW_TRUE;
+      }
+
+      NW_Str_Delete(retString);
+      retString = NULL;
+    }
+
+    /* If no wrap mode is set, we inherit the wrap property of the
+       previous paragraph */
+    prop.type = NW_CSS_ValueType_Token;
+    prop.value.token = (*nowrap) ? NW_CSS_PropValue_nowrap : NW_CSS_PropValue_normal;
+    NW_LMgr_Box_SetProperty (box, NW_CSS_Prop_whitespace, &prop);   
+
+    /* Get the alignment attribute */
+    status = NW_Wml_GetAttribute(&(thisObj->wmlInterpreter),
+                                 elId,
+                                 ALIGN_ATTR,
+                                 &retString);
+    NW_THROW_ON (status, KBrsrOutOfMemory);
+
+    if (retString != NULL) {
+      if (NW_Str_StricmpConst(retString,WAE_ASC_CENTER_STR) == 0) {
+        prop.value.token = NW_CSS_PropValue_center;
+      }
+      else if (NW_Str_StricmpConst(retString,WAE_ASC_RIGHT_STR) == 0) {
+        prop.value.token = NW_CSS_PropValue_right;
+      }
+      else {
+        prop.value.token = NW_CSS_PropValue_left;
+      }
+
+      NW_Str_Delete(retString);
+    }
+    else {
+      prop.value.token = NW_CSS_PropValue_left;
+    }
+
+    NW_LMgr_Box_SetProperty (box, NW_CSS_Prop_textAlign, &prop);   
+  }
+  NW_CATCH (status) {
+  }
+  NW_FINALLY {
+    return status;
+  } NW_END_TRY
+}
+
+
+/*****************************************************************
+
+  Name:         NW_UI_SetCellProperties()
+
+  Description:  set cell border properties
+
+  Parameters:   
+    box     - In      - pointer to the box tree node representing the <td> element
+
+  Algorithm:    
+
+  Return Value: KBrsrSuccess
+
+*****************************************************************/
+static
+TBrowserStatusCode
+NW_UI_SetCellProperties (NW_LMgr_Box_t *box)
+{
+  NW_LMgr_Property_t  prop;
+
+  NW_TRY (status) {
+    prop.type = NW_CSS_ValueType_Token;
+    prop.value.token = NW_CSS_PropValue_hidden;
+    status = NW_LMgr_Box_SetProperty (box, NW_CSS_Prop_overflow, &prop);
+
+    _NW_THROW_ON_ERROR (status);
+  }
+  NW_CATCH (status) {
+  }
+  NW_FINALLY {
+    return status;
+  }NW_END_TRY
+}
+
+
+/*****************************************************************
+
+  Name:         NW_UI_NormalizeTable()
+
+  Description:  perform WML table column width processing
+
+  Parameters:   
+    thisObj - In      - the content handler on behalf of which the work is being done
+    elId    - In      - the element id of the element being processed, used in the WML query service
+    box     - In      - pointer to the box tree node representing the element
+
+  Algorithm:    
+
+ * The behavior of WML Tables is not exactly like the behavior of CSS Tables.
+ * Two issues in particular need to be addressed:
+ * 1) Since the CSS Static Algorithm used in the Layout Manager
+ *    calculates the dimensions of the table based on the head row, the table
+ *    will contain only as many columns as there are in the first row.  In WML
+ *    this information is passed in the "columns" attribute.  Here we pad the
+ *    first row if it does not contain enough cells.
+ * 2) in WML, any extra cells in a row are "aggregated" into the last cell.
+
+  Return Value: KBrsrOutOfMemory
+                KBrsrSuccess
+                various other TBrowserStatusCode values 
+
+*****************************************************************/
+static
+TBrowserStatusCode
+NW_UI_NormalizeTable (NW_Wml1x_ContentHandler_t *thisObj,
+                      NW_Uint16                 elId,
+                      NW_LMgr_Box_t             *box)
+{
+  NW_LMgr_Box_t          *newBox = NULL;
+  NW_LMgr_Box_t          *tmpBox = NULL;
+  NW_Text_UCS2_t         *spaceText = NULL;
+  NW_LMgr_ContainerBox_t *newCell = NULL;
+
+  NW_TRY (status) {
+  NW_Ucs2                *retString;
+  NW_ADT_Vector_Metric_t cols = 1;
+  NW_ADT_Vector_Metric_t numRows;
+  NW_ADT_Vector_Metric_t numCells;
+  NW_LMgr_ContainerBox_t *tableContainer = NW_LMgr_ContainerBoxOf(box);
+  NW_LMgr_ContainerBox_t *cell = NULL;
+  NW_LMgr_ContainerBox_t *lastCell = NULL;
+  NW_LMgr_ContainerBox_t *rowContainer = NULL;
+  NW_LMgr_Property_t     prop;
+  NW_ADT_Vector_Metric_t i;
+  NW_ADT_Vector_Metric_t j;
+
+  /* WML table optimization */
+  prop.type = NW_CSS_ValueType_Integer;
+  prop.value.token = NW_CSS_PropValue_flags_wmlTable;
+  NW_LMgr_Box_SetProperty (box, NW_CSS_Prop_flags, &prop);
+
+  /* Set the margin for the table */
+  prop.type = NW_CSS_ValueType_Px;
+  prop.value.integer = 2;
+  NW_LMgr_Box_SetProperty (box, NW_CSS_Prop_margin, &prop);
+
+  /* Get the "columns" attribute */
+  status = NW_Wml_GetAttribute(&(thisObj->wmlInterpreter),
+                               elId,
+                               COLUMNS_ATTR,
+                               &retString);  
+
+  if (status == KBrsrOutOfMemory) {
+    return status;
+  }
+
+  if (retString != NULL) {
+		if(NW_Str_StrIsValidLength(retString))
+		{
+			cols = (NW_ADT_Vector_Metric_t)NW_Str_Atoi (retString);
+		}
+    if (cols == 0) {
+      /* If the attribute value is illegal, we will make the table one column wide */
+      cols = 1;
+    }
+
+    NW_Str_Delete (retString);
+  }
+
+  numRows = NW_LMgr_ContainerBox_GetChildCount(tableContainer);
+
+  for (i = 0; i < numRows; i++) {
+    rowContainer = (NW_LMgr_ContainerBox_t*) NW_LMgr_ContainerBox_GetChild (tableContainer, i);
+
+	if (rowContainer->children == NULL)
+		NW_THROW_SUCCESS(status);
+
+	numCells = NW_LMgr_ContainerBox_GetChildCount(rowContainer);
+
+    if (numCells == cols) {
+      continue;
+    }
+
+    /* If there is an insufficient number of cells in a row,
+     * we must pad it with extra empty boxes */
+    else if (numCells < cols) {
+      for (j = numCells; j < cols; j++) {
+
+        /* Create a new cell container and set its properties */
+        newCell = (NW_LMgr_ContainerBox_t*)NW_LMgr_StaticTableCellBox_New(1);
+          NW_THROW_OOM_ON_NULL (newCell, status);
+
+        NW_UI_SetCellProperties (NW_LMgr_BoxOf(newCell));
+
+        /* Create the text object with a single space */
+        spaceText =
+          NW_Text_UCS2_New((NW_Ucs2*) spaceString, 1, 0);
+          NW_THROW_OOM_ON_NULL (spaceText, status);
+
+        /* Create a text box to hold the space */
+        newBox = (NW_LMgr_Box_t*)
+          NW_LMgr_TextBox_New (1, NW_TextOf (spaceText));
+          NW_THROW_OOM_ON_NULL (newBox, status);
+
+        /* Add the empty box to the cell container */
+        status = NW_LMgr_ContainerBox_AddChild (newCell, NW_LMgr_BoxOf(newBox));
+          _NW_THROW_ON_ERROR(status);
+
+        /* Add the cell to the row container */
+        status = NW_LMgr_ContainerBox_AddChild (rowContainer, NW_LMgr_BoxOf(newCell));
+        if (status != KBrsrSuccess) {
+           (void)NW_LMgr_ContainerBox_RemoveChild (newCell, NW_LMgr_BoxOf(newBox));
+             NW_THROW (status);
+        }
+      }
+    }
+
+    /* If there are extra cells in the row, we must aggregate them into
+     * the last column
+     */
+    else if (numCells > cols) {
+      /* Get the cell in the last column */
+      lastCell = (NW_LMgr_ContainerBox_t*)NW_LMgr_ContainerBox_GetChild (rowContainer, 
+                                            (NW_ADT_Vector_Metric_t)(cols-1));
+      NW_ASSERT (NW_Object_IsInstanceOf(lastCell, &NW_LMgr_ContainerBox_Class));
+
+      /* Aggregate the remaining cells */
+      for (j = cols; j < numCells; j++) {
+        /* Get the first extra cell */
+        tmpBox = NW_LMgr_ContainerBox_GetChild (rowContainer, j);
+        if (!NW_Object_IsInstanceOf(tmpBox, &NW_LMgr_StaticTableCellBox_Class))
+        {
+           status = NW_LMgr_ContainerBox_RemoveChild (rowContainer, NW_LMgr_BoxOf(tmpBox));
+           _NW_THROW_ON_ERROR(status);
+           j--;
+           numCells--;
+           NW_Object_Delete(tmpBox);
+           continue;
+        }
+
+        cell = (NW_LMgr_ContainerBox_t*)tmpBox;
+
+        /* Create the text object with a single space */
+        spaceText =
+          NW_Text_UCS2_New((NW_Ucs2*) spaceString, 1, 0);
+          NW_THROW_OOM_ON_NULL (spaceText, status);
+
+        newBox = (NW_LMgr_Box_t*)
+          NW_LMgr_TextBox_New (1, NW_TextOf (spaceText));
+          NW_THROW_OOM_ON_NULL (newBox, status);
+
+        /* Add the empty box to the last legal cell */
+        status = NW_LMgr_ContainerBox_AddChild (lastCell, NW_LMgr_BoxOf(newBox));
+          _NW_THROW_ON_ERROR(status);
+
+        /* Remove the extra box from the row */
+        status = NW_LMgr_ContainerBox_RemoveChild (rowContainer, NW_LMgr_BoxOf(cell));
+          _NW_THROW_ON_ERROR(status);
+        j--;
+        numCells--;
+
+        /* Append the extra content */
+        status = NW_LMgr_ContainerBox_AppendChildrenOf (lastCell, cell);
+          _NW_THROW_ON_ERROR(status);
+
+        /* We don't want to destroy the cell content, because we have copied it
+         * to lastCell */
+        status = NW_ADT_DynamicVector_Clear (
+          (NW_ADT_DynamicVector_t*)NW_LMgr_ContainerBox_GetChildren(cell));
+          _NW_THROW_ON_ERROR(status);
+
+        /* Finally, delete the cell */
+        NW_Object_Delete(tmpBox);
+      }
+    }
+  }
+
+  } NW_CATCH (status) {
+  NW_Object_Delete(newBox);
+  NW_Object_Delete(spaceText);
+  NW_Object_Delete(newCell);
+
+  } NW_FINALLY {
+  return status;
+  } NW_END_TRY
+}
+
+
+/*****************************************************************
+
+  Name:         NW_UI_SetCellAlignment()
+
+  Description:  set alignment cell properties for a table sub-tree
+
+  Parameters:   
+    thisObj - In      - the content handler on behalf of which the work is being done
+    elId    - In      - the element id of the element being processed, used in the WML query service
+    box     - In      - pointer to the box tree node representing the table
+
+  Algorithm:    alignment is left unless attribute set otherwise
+
+  Return Value: KBrsrOutOfMemory
+                KBrsrSuccess
+
+*****************************************************************/
+static
+TBrowserStatusCode
+NW_UI_SetCellAlignment (NW_Wml1x_ContentHandler_t *thisObj,
+                        NW_Uint16                 elId,
+                        NW_LMgr_Box_t             *box)
+{
+  NW_LMgr_Property_t     prop;
+  NW_Ucs2                *retString;
+  NW_ADT_Vector_Metric_t numRows;
+  NW_ADT_Vector_Metric_t numCells;
+  NW_LMgr_ContainerBox_t *tableContainer = NW_LMgr_ContainerBoxOf(box);
+  NW_LMgr_ContainerBox_t *cell = NULL;
+  NW_LMgr_ContainerBox_t *rowContainer = NULL;
+  TBrowserStatusCode            status;
+  NW_ADT_Vector_Metric_t i;
+  NW_ADT_Vector_Metric_t j;
+
+  /* First get the alignment attribute */
+  status = NW_Wml_GetAttribute(&(thisObj->wmlInterpreter),
+                               elId,
+                               ALIGN_ATTR,
+                               &retString);  
+
+  if (status == KBrsrOutOfMemory) {
+    return status;
+  }
+
+  /* Get the number of rows */
+  numRows = NW_LMgr_ContainerBox_GetChildCount(tableContainer);
+
+  /* Set the alignment properties on the cells */
+  prop.type = NW_CSS_ValueType_Token;
+  if (retString != NULL) {
+    for (i = 0; i < numRows; i++) {
+      /* Get the row */
+      rowContainer = (NW_LMgr_ContainerBox_t*)NW_LMgr_ContainerBox_GetChild (tableContainer, i);
+      numCells = NW_LMgr_ContainerBox_GetChildCount(rowContainer);
+
+      for (j = 0; j < numCells; j++) {
+        /* Get the cell */
+        cell = (NW_LMgr_ContainerBox_t*)NW_LMgr_ContainerBox_GetChild (rowContainer, j);
+
+        if (j < NW_Str_Strlen(retString)) {
+          switch (retString[j]) 
+          {
+          case 'R':
+            prop.value.token = NW_CSS_PropValue_right;
+            status = NW_LMgr_Box_SetProperty (NW_LMgr_BoxOf(cell), NW_CSS_Prop_textAlign, &prop);
+            break;
+
+          case 'C':
+            prop.value.token = NW_CSS_PropValue_center;
+            status = NW_LMgr_Box_SetProperty (NW_LMgr_BoxOf(cell), NW_CSS_Prop_textAlign, &prop);
+            break;
+
+          default:
+            prop.value.token = NW_CSS_PropValue_left;
+            status = NW_LMgr_Box_SetProperty (NW_LMgr_BoxOf(cell), NW_CSS_Prop_textAlign, &prop);
+            break;
+          }
+        }
+      }
+    }
+    
+    NW_Str_Delete(retString);
+  }     
+
+  return status;
+}
+
+
+/*****************************************************************
+
+  Name:         NW_UI_LoadImage()
+
+  Description:  request WML <img> source or localsrc load
+
+  Parameters:   
+    thisObj - In      - the content handler on behalf of which the work is being done    
+    elId    - In      - the element id of the <img> element being processed, used in the WML query service
+
+  Algorithm:    
+
+  Return Value: KBrsrOutOfMemory
+                KBrsrSuccess
+                TBrowserStatusCode value from NW_HED_DocumentRoot_StartLoad()
+
+*****************************************************************/
+TBrowserStatusCode 
+NW_UI_LoadImage (NW_Wml1x_ContentHandler_t *thisObj,                                    
+                 NW_Uint16 elId, NW_Bool showImage )
+{
+  NW_Ucs2                      *imageUrl = NULL;
+  TBrowserStatusCode                  status;
+  NW_Text_UCS2_t               *urlObj;
+  NW_HED_DocumentRoot_t        *documentRoot;
+  NW_HED_UrlRequest_LoadMode_t loadMode = NW_HED_UrlRequest_LoadNormal;
+ 	
+  /* The loadMode flag is to trigger (src=)Url to be loaded after the 
+     (localsrc=)Url load failed */
+
+
+  /* NW_Settings_GetImageEnabled() called to determine whether 
+  autoloading of images is turned on. If not, then just display
+  the initial "x" and alt text, and don't issue any load requests.
+  */
+
+  if (!showImage)
+  {
+    if (!NW_Settings_GetImagesEnabled()) {
+      return KBrsrSuccess;
+    }
+  }
+  
+  status = NW_Wml_GetLocalImageUrl(&(thisObj->wmlInterpreter),
+                                     elId,
+                                     &imageUrl);
+  if (status == KBrsrSuccess) {
+    loadMode = NW_HED_UrlRequest_LoadLocal;
+  }
+  else {
+
+  status = NW_Wml_GetImageUrl(&(thisObj->wmlInterpreter),
+                              elId,
+                              &imageUrl);
+  }
+
+  if (status == KBrsrSuccess) {
+
+    NW_ASSERT(imageUrl);
+
+    urlObj =
+      NW_Text_UCS2_New (imageUrl, 0, NW_Text_Flags_TakeOwnership);
+
+    if (urlObj != NULL) {
+      NW_HED_UrlRequest_t *urlRequest;
+    
+      /* get the documentRoot and invoke the Load method */
+
+      documentRoot =
+        (NW_HED_DocumentRoot_t*) NW_HED_DocumentNode_GetRootNode (thisObj);
+      NW_ASSERT(documentRoot != NULL);
+
+      /* submit the load request */
+      urlRequest = NW_HED_UrlRequest_New (NW_TextOf (urlObj), NW_URL_METHOD_GET, NULL,
+                                          NULL, NW_HED_UrlRequest_Reason_DocLoadChild, 
+                                          loadMode, NW_UrlRequest_Type_Image);
+
+      if (urlRequest != NULL) {
+        NW_Uint32 elId32 = elId;
+        if (NW_Wml1x_ContentHandler_IsSaveddeck(thisObj))
+        {
+          NW_HED_UrlRequest_SetCacheMode(urlRequest, NW_CACHE_ONLYCACHE);
+        }
+        else if (NW_Wml1x_ContentHandler_IsHistload(thisObj))
+        {
+          NW_HED_UrlRequest_SetCacheMode(urlRequest, NW_CACHE_HISTPREV);
+        }
+        else if (NW_Wml1x_ContentHandler_IsReload(thisObj))
+        {
+          NW_HED_UrlRequest_SetCacheMode(urlRequest, NW_CACHE_NOCACHE);
+        }
+
+        // compare url with body part
+        NW_Uint8 freeNeeded;
+        NW_Ucs2* resolvedUrlUcs2 = NW_Text_GetUCS2Buffer( NW_TextOf (urlObj), NULL, NULL, &freeNeeded);
+        CBodyPart* bodyPart = NULL;
+        TBool isUrlInMultipart = _NW_HED_CompositeContentHandler_IsUrlInMultipart( 
+                                                 NW_HED_CompositeContentHandlerOf(thisObj),
+                                                 resolvedUrlUcs2, &bodyPart );
+        if( freeNeeded )
+            {
+            NW_Mem_Free( resolvedUrlUcs2 );
+            }
+
+        if( isUrlInMultipart )
+            {
+            TDataType dataType( bodyPart->ContentType() );
+
+            TUint8* charset = (TUint8*) bodyPart->Charset().Ptr();
+            TInt lenCh = bodyPart->Charset().Length();
+            //R CShell* shell = REINTERPRET_CAST(CShell*, NW_Ctx_Get(NW_CTX_BROWSER_APP, 0));  
+            CShell* shell = NULL;  //R
+            NW_ASSERT(shell);
+            TInt32 uidInt = shell->GetUidFromCharset( charset, lenCh );
+            TUid uid = TUid::Uid( uidInt );
+
+            CBrCtl* brCtl = shell->BrCtl();
+            /*
+            brCtl->LoadDataL( bodyPart->Url(), bodyPart->Body(), dataType, uid, 
+                              NW_HED_DocumentNodeOf (thisObj), (void*)elId32, 
+                              NULL, NULL, urlRequest->loadType, urlRequest->method );
+            */                  
+            }
+        else
+            {
+            status = NW_HED_DocumentRoot_StartRequest (documentRoot, NW_HED_DocumentNodeOf (thisObj),
+                urlRequest, (void*)elId32 );
+
+            if (status != KBrsrSuccess) 
+                {
+                NW_Object_Delete (urlRequest);
+                }
+            }
+      }
+      else {
+        status = KBrsrOutOfMemory;
+      }
+
+      NW_Object_Delete(urlObj);
+    } else {
+      status = KBrsrOutOfMemory; /* NW_Text_UCS2_New() takes care of deleting string when fails */
+    }
+  }
+  
+  if (status == KBrsrSuccess) {
+    thisObj->wmlInterpreter.outstandingLoadCount++;
+  }
+  return status;
+}
+
+
+/*****************************************************************
+
+  Name:         IsThereAltAttrib()
+
+  Description:  Returns "alt" attribute of the "image" element
+
+  Parameters:   
+    thisObj - In      - the content handler on behalf of which the work is being done
+    elId    - In      - the element id of the <img> element being processed
+    altStr  - In/Out  - pointer to variable which will receive address of 
+                UCS2_Text_t object with value of ALT_ATTR from <img> element
+
+  Algorithm:    
+
+  Return Value: -NW_TRUE when string for alt text successfully extructed
+                 *altStr has the value of the string pointer.
+                -NW_FALSE when the attribute does not exist or 
+                 the string was not created. *altStr = NULL
+
+*****************************************************************/
+static NW_Bool IsThereAltAttrib (NW_Wml1x_ContentHandler_t  *thisObj, 
+                                 NW_Uint16                  elId, 
+                                 NW_Text_t                  **altStr)
+{
+  NW_Bool     ret = NW_FALSE;
+  NW_Ucs2     *retString = NULL;
+  
+  (void) NW_Wml_GetAttribute(&(thisObj->wmlInterpreter),
+		                         elId,
+														 ALT_ATTR,
+														 &retString);
+
+  if (retString) {
+    *altStr = (NW_Text_t*)
+      NW_Text_UCS2_New (retString, NW_Str_Strlen(retString), 
+                        NW_Text_Flags_TakeOwnership);
+    if (*altStr) {
+      ret = NW_TRUE;
+    }
+  }
+
+  return ret;
+}
+
+
+/*
+**-------------------------------------------------------------------------
+**  Display API functions called by the WML Browser
+**-------------------------------------------------------------------------
+*/
+
+/*****************************************************************
+
+  Name:         NW_UI_CreateCard()
+
+  Description:  callback for WML interpreter to initialize new card
+
+  Parameters:
+    wae     - In      - the content handler on behalf of which the work is being done
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_CreateCard (void *wae)
+{
+
+  NW_Wml1x_ContentHandler_t *thisObj;
+  NW_HED_CompositeNode_t*   compositeNode;
+  NW_LMgr_Property_t        prop;
+  NW_LMgr_BidiFlowBox_t       *bidiFlowBox;
+
+  NW_TRY (status) {
+
+    NW_LOG0(NW_LOG_LEVEL1, "<card>");
+
+    thisObj = NW_Wml1x_ContentHandlerOf(wae);
+    compositeNode = (NW_HED_CompositeNode_t*) 
+      NW_Object_QueryAggregate (thisObj, &NW_HED_CompositeNode_Class);
+    NW_ASSERT (compositeNode != NULL);
+
+	//Note: There is a iCurrent in MVCView which points to one of the box that has the focus in the boxtree .
+	// Since the boxtree will be deleted in next step, we need to set the iCurrent to null. Otherwise it will
+	// be invalid and can cause problem (It had caused bug). 
+    NW_HED_DocumentRoot_t*   docRoot = (NW_HED_DocumentRoot_t*) NW_HED_DocumentNode_GetRootNode( thisObj );
+  	NW_ASSERT( docRoot != NULL );	
+    //get the root box
+	NW_LMgr_RootBox_t*       rootBox = NW_HED_DocumentRoot_GetRootBox( docRoot );
+    NW_ASSERT( rootBox != NULL );
+	//get the boxtree listener which is a MVCView object
+	if(rootBox && (NW_Object_IsClass(rootBox, &NW_LMgr_RootBox_Class)))
+	{
+	  MBoxTreeListener* btlistener = rootBox->boxTreeListener;
+	  //if the listener is not null, set its iCurrent to null
+	  if(btlistener != NULL)
+	  {
+			  ((CView*)btlistener)->SetCurrentBox(NULL);
+	  }
+	}
+    /* free up all our child nodes; ie.image content handlers */
+    NW_HED_CompositeNode_DeleteChildren (compositeNode);
+
+    /* get rid of the old data */
+    NW_Object_Delete (NW_HED_ContentHandlerOf (thisObj)->boxTree);
+    NW_HED_ContentHandlerOf (thisObj)->boxTree = NULL;
+    NW_Object_Delete(thisObj->optionMap);
+    thisObj->optionMap = NULL;
+    /*
+    ** create a new box tree for the card.  DON'T USE NEW METHOD INSIDE CAST
+    ** AS IT WILL GET CALLED MULTIPLE TIMES WHEN MACRO IS EXPANDED
+    */
+    bidiFlowBox = NW_LMgr_BidiFlowBox_New(0);
+    NW_THROW_OOM_ON_NULL (bidiFlowBox, status);
+
+    prop.type = NW_CSS_ValueType_Token;
+    prop.value.token = NW_CSS_PropValue_display_block;
+    status = NW_LMgr_Box_SetProperty(NW_LMgr_BoxOf(bidiFlowBox), NW_CSS_Prop_display, &prop);
+
+    NW_HED_ContentHandlerOf (thisObj)->boxTree = NW_LMgr_BoxOf(bidiFlowBox);
+    thisObj->currentBox = NW_HED_ContentHandlerOf (thisObj)->boxTree;
+
+    NW_Wml1x_DefaultCardStyle(&prop, NW_LMgr_ContainerBoxOf(bidiFlowBox));
+    
+    /* create a map to associate option element states with option element ids */
+    thisObj->lastId = 0;
+
+    thisObj->optionMap =
+      NW_ADT_ResizableMap_New (sizeof (thisObj->lastId), /* sizeof an element id */
+                              sizeof (NW_Bool),   /* sizeof an element state */
+                              8,                  /* guess at initial number of options */
+                              4);                 /* number to increment by when resizing */
+    NW_THROW_OOM_ON_NULL (thisObj->optionMap, status);
+  }
+  NW_CATCH (status) {
+  }
+  NW_FINALLY {
+    return status;
+  } NW_END_TRY
+}
+
+
+/*****************************************************************
+
+  Name:         NW_UI_ShowCard()
+
+  Description:  callback for WML interpreter to render card
+
+  Parameters:
+    wae     - In      - the content handler on behalf of which the work is being done
+
+  Algorithm:    finish populating the box tree and call
+                  NW_HED_DocumentNode_NodeChanged()
+
+  Return Value:
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_ShowCard (void *wae)
+{
+  NW_Wml1x_ContentHandler_t *thisObj;
+  TBrowserStatusCode               status = KBrsrSuccess;
+  NW_LMgr_BoxVisitor_t      boxVisitor;
+  NW_LMgr_Box_t             *box;
+  NW_LMgr_Box_t             *rootBox;
+  NW_LMgr_ContainerBox_t    *parentBox;
+  NW_LMgr_Box_t             *deleteBox = NULL;
+  NW_LMgr_PropertyValue_t   value;
+  NW_LMgr_Property_t        prop;
+  NW_Wml_ElType_e           elType = UNKNOWN_ELEMENT;
+  NW_Uint16                 elId = 0;
+  NW_Wml_Element_t          *el;
+  NW_Text_UCS2_t            *temptext;
+  NW_Ucs2                   *retString = NULL;
+  NW_HED_DocumentNode_t     *parent;
+  NW_HED_DocumentRoot_t     *docRoot;
+  NW_Bool                   currentSelectMultipleState = NW_FALSE;
+  NW_Int32                  currentSelectTabIndexVal = 0;
+
+  NW_Bool                   nowrap = NW_FALSE;
+  const NW_Text_t           *formatText;
+  NW_FBox_Validator_EmptyOk_t emptyOk;
+  NW_Markup_WmlValidator_t  *validator;
+
+  thisObj = NW_Wml1x_ContentHandlerOf(wae);
+
+  rootBox = NW_HED_ContentHandlerOf (thisObj)->boxTree;
+
+  NW_LOG0(NW_LOG_LEVEL1, "</card>");
+
+  /* The reason to do this here instead of at time of content handler initialize is:
+   * when we come from WML doc to WML doc, the old WML Content Handler is used, no new
+   * content handler is created or initialized. */
+
+  /* Initialize the dynamic item list in the OptionList
+     This is needed for ISA, not for win32  */
+  docRoot = (NW_HED_DocumentRoot_t*) NW_HED_DocumentNode_GetRootNode (thisObj);
+
+  NW_ASSERT(docRoot != NULL);
+  NW_ASSERT(docRoot->appServices != NULL);
+
+  NW_System_OptionList_Initialize ();
+  if (thisObj->optionItemList != NULL) {
+    NW_Wml1x_ContentHandler_DeleteOptionItemList(thisObj->optionItemList);
+    thisObj->optionItemList = NULL;
+  }
+
+  /* initialize the boxVisitor */
+  status =
+    NW_LMgr_BoxVisitor_Initialize (&boxVisitor, NW_LMgr_BoxOf (rootBox));
+  if (status != KBrsrSuccess) {
+    return status;
+  }
+
+  /* traverse the boxTree */
+  while ((box = NW_LMgr_BoxVisitor_NextBox (&boxVisitor, NULL)) != NULL) 
+  {
+
+    /* get rid of leftover values */
+    temptext = NULL;
+    retString = NULL;
+
+    /* check the deleteBox, remove and delete if necessary */
+    if (deleteBox != NULL) 
+    {
+      parentBox = NW_LMgr_Box_GetParent (deleteBox);
+
+      status = NW_LMgr_ContainerBox_RemoveChild(parentBox,
+                                                deleteBox);
+      NW_Object_Delete(deleteBox);
+
+      deleteBox = NULL;
+    }
+
+    /* get into elId the element id we set in the box's properties */
+    status = NW_LMgr_Box_GetPropertyValue(box, NW_CSS_Prop_elementId, NW_CSS_ValueType_Integer, &value);
+
+    if (status == KBrsrSuccess) {
+      elId = NW_UINT16_CAST(value.integer);
+      status = NW_Wml_GetElementType(&(thisObj->wmlInterpreter),
+                                     elId,
+                                     &elType,
+                                     &el);
+    }
+
+    /* don't switch on the element type if the return code was not success */
+    if (status != KBrsrSuccess)
+    {
+      status = KBrsrSuccess;   /* reset status to avoid the failure return at the end of the while loop */
+    }
+    else
+    {
+      NW_ASSERT(elType != END_ELEMENT);
+
+      switch (elType) {
+
+      case  P_ELEMENT:
+        status = NW_UI_SetParagraphProperties(thisObj, elId, box, &nowrap, &deleteBox);
+
+        NW_Wml1x_ParagraphDefaultStyle(&prop, box);
+
+        break;
+
+      case  PRE_ELEMENT:
+        /* Set the white-space property */
+        prop.type = NW_CSS_ValueType_Token;
+        prop.value.token = NW_CSS_PropValue_pre;
+        NW_LMgr_Box_SetProperty (box, NW_CSS_Prop_whitespace, &prop);   
+
+        /* Set the font-family to courier (PRE should be rendered
+         * as fixed-width 
+         */
+        prop.type = NW_CSS_ValueType_Text;
+        prop.value.object =
+          NW_Text_UCS2_New ((NW_Ucs2*) monospace, 0, 0);
+        NW_LMgr_Box_SetProperty (box, NW_CSS_Prop_fontFamily, &prop);   
+
+        break;
+
+      case  STRING_ELEMENT:
+        status = NW_Wml_GetAttribute(&(thisObj->wmlInterpreter),
+                                     elId,
+                                     STR_VALUE,
+                                     &retString);
+        if (status == KBrsrOutOfMemory)
+          return status;
+        if (retString == NULL) {
+          retString = NW_Str_NewcpyConst(" "); /* set some text if none returned */
+        }
+        if (retString == NULL) {
+          return KBrsrOutOfMemory;
+        }
+        temptext =
+          NW_Text_UCS2_New (retString, NW_Str_Strlen(retString), 
+                            NW_Text_Flags_TakeOwnership);
+        if (temptext == NULL) {
+          return KBrsrOutOfMemory;
+        }
+        NW_LMgr_TextBox_SetText (NW_LMgr_TextBoxOf(box), NW_TextOf(temptext));
+
+        break;
+
+      case  A_ELEMENT:
+      case  ANCHOR_ELEMENT:
+        {
+        NW_Text_t*          retUrl = NULL;
+        NW_Bool             inCache = NW_FALSE;
+        NW_Bool             isPrev = NW_FALSE;
+        
+        /* make sure there is some content on the anchor */
+        status = NW_Wml1x_FixupAnchorText(&(thisObj->wmlInterpreter ), 
+          elId, 
+          NW_LMgr_ContainerBoxOf(box),
+          docRoot->appServices);
+        
+        /* get the URL, looking in <go> or <prev> if needed */
+        status = NW_Wml1x_GetURL(&(thisObj->wmlInterpreter), 
+          elId, 
+          &retString,
+          &isPrev);
+        
+        if (isPrev)
+          {
+          const NW_HED_HistoryEntry_t* entry;
+          NW_HED_HistoryStack_t* history;
+          NW_HED_HistoryVisitor_t visitor;
+          NW_Bool freePrevURL= NW_FALSE;
+          
+          if ((history = NW_HED_DocumentRoot_GetHistoryStack (docRoot)) != NULL)
+            {
+            if ((NW_HED_HistoryVisitor_Initialize(&visitor, history, 
+              NW_HED_HistoryVisitor_Loacation_Current))  == KBrsrSuccess) 
+              {
+              entry = NW_HED_HistoryVisitor_Prev(&visitor);
+              if(entry != NULL)
+                {
+                retString = NW_Text_GetUCS2Buffer(entry->urlRequest->url, 
+                              NW_Text_Flags_Copy | NW_Text_Flags_NullTerminated,
+                              NULL, &freePrevURL);
+                }
+              }
+            }
+          }
+        if (retString != NULL && *retString != NULL)
+          {
+          NW_Text_t *url;
+          NW_Ucs2* ucs2Href;
+          NW_Bool freeNeeded;
+          
+          url = NW_Text_New (HTTP_iso_10646_ucs_2, retString, 
+            NW_Str_Strlen(retString), NW_Text_Flags_TakeOwnership);
+          retString = NULL;
+          
+          if (url == NULL)
+            {
+            return KBrsrOutOfMemory;
+            }
+          
+          status = NW_HED_ContentHandler_ResolveURL (thisObj, url, &retUrl);
+          /* We don't check explicitly for out of memory because if we are
+          * out of memory, we will fail later on. All we are interested here
+          * is to check if the url is in cache and set the color.
+          */
+          
+          if (status == KBrsrSuccess)
+            {
+            /* give ownership to url */
+            url = retUrl;
+            retUrl = NULL;
+            
+            /* check whether it is in cache */
+            ucs2Href = NW_Text_GetUCS2Buffer(url, 
+              NW_Text_Flags_Aligned | NW_Text_Flags_NullTerminated,
+              NULL, 
+              &freeNeeded);
+            if (ucs2Href == NULL)
+              {
+              return KBrsrOutOfMemory;
+              }
+            else
+              {
+              NW_Ucs2 *fragment = NW_Url_Fragment(ucs2Href);
+              if (fragment != NULL)
+                {
+                /* strip off the fragment before looking in cache */
+                --fragment;
+                *fragment = 0;
+                }
+              inCache = UrlLoader_IsUrlInCache(ucs2Href);
+              }
+            if (freeNeeded)
+              {
+              NW_Mem_Free(ucs2Href);
+              }
+            } 
+          NW_Object_Delete(url);
+          }
+		  else
+		  {
+			  NW_Str_Delete(retString);
+		  }
+        /* apply default style for anchor */
+        status = NW_Wml1x_AnchorDefaultStyle(&prop, NW_LMgr_ActiveContainerBoxOf (box),
+          inCache);
+        
+        
+        /* get the ACCESSKEY_ATTR */
+        status = NW_Wml_GetAttribute(&(thisObj->wmlInterpreter), 
+          elId, 
+          ACCESSKEY_ATTR,
+          &retString);
+          if (status == KBrsrOutOfMemory)
+            return status;
+        
+        /* convert string to NW_Text_Length_t in inputSize */
+        if (retString != NULL) 
+          {
+          NW_LMgr_AccessKey_t* ak;
+          NW_LMgr_Property_t accesskeyProp;
+          
+          ak = NW_LMgr_AccessKey_New();
+          if (ak){
+            if (NW_LMgr_AccessKey_AddVal(ak, retString, NW_FALSE) == KBrsrSuccess)
+              {                              
+              /* set accesskey on the new box */
+              accesskeyProp.type = NW_CSS_ValueType_Object;
+              accesskeyProp.value.object = ak;
+              NW_LMgr_Box_SetProperty(box, NW_CSS_Prop_accesskey, &accesskeyProp); 
+              }
+            else{
+              NW_Object_Delete(ak);
+              }
+            }            
+          NW_Str_Delete(retString);
+          retString = NULL;
+          if (!ak){
+            return KBrsrOutOfMemory;
+            }
+          }
+        }
+        break;
+
+      case  IMAGE_ELEMENT:
+        {
+         NW_Text_t         *altStr = NULL;
+
+          /* Adding a text box with alternative text from "alt" attribute */
+          if (IsThereAltAttrib(thisObj, elId, &altStr)) {
+            NW_ASSERT(NW_Object_IsDerivedFrom(box, &NW_LMgr_ImgContainerBox_Class));
+            (NW_LMgr_ImgContainerBoxOf(box))->altText = altStr;
+          }
+        }
+
+        status = NW_UI_LoadImage(thisObj, elId, NW_FALSE);
+
+        /* If the status is not KBrsrOutOfMemory, then just ignore it and go
+         * onto the next item. Failure to load an image is not fatal*/
+        if(status != KBrsrOutOfMemory)
+          status = KBrsrSuccess;
+        break;
+
+      case  DO_ELEMENT:
+        status = NW_Wml1x_HandleDo(thisObj, elId, box, &deleteBox);
+        break;
+
+      case  INPUT_ELEMENT:
+        /* the input element is currently represented by a container box (although the 
+         * input element should have no children)
+         * if the attribute type="password", replace the container box with a password box
+         * otherwise replace the container box with an input box
+         */
+        {
+          NW_Wml1x_EventHandler_t *eventHandler;
+          NW_Uint32               elIdAsWord      = elId;               /* NOTE: this exists solely to eliminate a compiler warning */
+          void                    *elIdAsVoidStar = (void *)elIdAsWord; /* NOTE: this exists solely to eliminate a compiler warning */
+          NW_LMgr_Box_t           *inputBox = NULL;
+          NW_LMgr_Box_t           *newBox = NULL;
+          NW_Uint16               inputSize = 0;
+          NW_Int32                tabIndexVal;
+
+
+          /* first, make sure that box is a plain vanilla container box
+           * if this is not true, then ..ShowCard() has been called outside
+           * the expected sequence of ..CreateCard() - [..AddElement()]* - ..ShowCard() - ..DestroyCard()
+           */
+          NW_ASSERT (&NW_LMgr_ContainerBox_Class == ((NW_Object_Core_t*) box)->objClass);
+
+          eventHandler =
+            NW_Wml1x_EventHandler_New (NW_Wml1x_ContentHandlerOf(thisObj));
+
+          if (eventHandler != NULL) {
+
+            /* get the SIZE_ATTR value if any */
+            status = NW_Wml_GetAttribute(&(thisObj->wmlInterpreter), 
+                                         elId, 
+                                         SIZE_ATTR,
+                                         &retString);
+            if (status == KBrsrOutOfMemory)
+              return status;
+
+            /* convert string to NW_Text_Length_t in inputSize */
+            if (retString != NULL) 
+            {
+							if(NW_Str_StrIsValidLength(retString))
+							{
+								inputSize = (NW_Uint16) NW_Str_Atoi(retString);
+							}
+              NW_Str_Delete(retString);
+              retString = NULL;
+            }
+
+            parentBox = NW_LMgr_Box_GetParent (box);
+
+            status = NW_Wml_GetAttribute(&(thisObj->wmlInterpreter), 
+                                         elId, 
+                                         TYPE_ATTR,
+                                         &retString);
+            if (status == KBrsrOutOfMemory)
+              return status;
+
+            if ((retString != NULL) && (NW_Str_StrcmpConst(retString, WAE_ASC_PASSWORD_STR) == 0) )
+            {
+              /* create the passwordBox */
+              inputBox = (NW_LMgr_Box_t*)
+                NW_FBox_PasswordBox_New(0,
+                                       NW_LMgr_EventHandlerOf (eventHandler),
+                                       elIdAsVoidStar,  /* elementNode, */
+                                       NW_FBox_FormLiaisonOf (thisObj->formLiaison),
+                                       inputSize,
+                                       docRoot->appServices);
+              if (inputBox == NULL) {
+                NW_Str_Delete(retString);
+                return KBrsrOutOfMemory;
+              }
+               
+              newBox =  inputBox;
+            }
+            else
+            {
+              inputBox = (NW_LMgr_Box_t*)
+                NW_FBox_InputBox_New(0,
+                                     NW_LMgr_EventHandlerOf (eventHandler),
+                                     elIdAsVoidStar,  /* elementNode, */
+                                     NW_FBox_FormLiaisonOf (thisObj->formLiaison),
+                                     inputSize,
+                                     docRoot->appServices);  
+              newBox = inputBox;
+
+            }
+            NW_Str_Delete(retString);
+            retString = NULL;
+
+            if (inputBox == NULL) {
+              return KBrsrOutOfMemory;
+            }
+
+            /* get the ACCESSKEY_ATTR */
+            status = NW_Wml_GetAttribute(&(thisObj->wmlInterpreter), 
+                                         elId, 
+                                         ACCESSKEY_ATTR,
+                                         &retString);
+            if (status == KBrsrOutOfMemory)
+              return status;
+            /* convert string to NW_Text_Length_t in inputSize */
+            if (retString != NULL) 
+            {
+              NW_LMgr_AccessKey_t* ak;
+              NW_LMgr_Property_t accesskeyProp;
+
+              ak = NW_LMgr_AccessKey_New();
+              if (ak){
+                if (NW_LMgr_AccessKey_AddVal(ak, retString, NW_FALSE) == KBrsrSuccess)
+                {                              
+                  /* set accesskey on the new box */
+                  accesskeyProp.type = NW_CSS_ValueType_Object;
+                  accesskeyProp.value.object = ak;
+                  NW_LMgr_Box_SetProperty(newBox, NW_CSS_Prop_accesskey, &accesskeyProp); 
+                }
+                else{
+                  NW_Object_Delete(ak);
+                }
+              }
+              NW_Str_Delete(retString);
+              retString = NULL;
+              if (!ak){
+                return KBrsrOutOfMemory;
+              }
+            }
+
+            /* get the TITLE_ATTR value if any */
+            retString = NULL;
+            status = NW_Wml_GetAttribute(&(thisObj->wmlInterpreter), 
+                                         elId, 
+                                         TITLE_ATTR,
+                                         &retString);
+            if (status == KBrsrOutOfMemory)
+              return status;
+            NW_FBox_InputBox_SetTitle(inputBox, retString);
+              
+            retString = NULL;
+            /* get the MAXLENGTH_ATTR value if any */
+            status = NW_Wml_GetAttribute(&(thisObj->wmlInterpreter), 
+                                         elId, 
+                                         MAXLENGTH_ATTR,
+                                         &retString);
+            if (status == KBrsrOutOfMemory)
+              return status;
+            if (retString != NULL) 
+            {
+							NW_Int32 maxlength = -1; /* Initialize to invalid length */
+							if(NW_Str_StrIsValidLength(retString))
+							{
+								maxlength = NW_Str_Atoi(retString);
+							}
+              NW_Str_Delete(retString);
+              retString = NULL;
+							if(maxlength >= 0)
+							{
+								NW_FBox_InputBox_t *tmpbox = NW_FBox_InputBoxOf(inputBox);
+								NW_FBox_InputBox_SetMaxChars(tmpbox,(NW_Text_Length_t)maxlength);
+								NW_FBox_InputBox_SetIsMaxlength( tmpbox, NW_TRUE);
+							}
+            }
+
+            /* Create a prefix string validator for the input box. */
+            /* get the EMPTYOK_ATTR value if any */
+            status = NW_Wml_GetAttribute(&(thisObj->wmlInterpreter), 
+                                         elId, 
+                                         EMPTYOK_ATTR,
+                                         &retString);
+            if (status == KBrsrOutOfMemory)
+              return status;   
+            //Allow scrolling on input boxes when empty. If it is not allowed then
+            //let the EMPTYOK_ATTR decides this.
+            emptyOk = NW_FBox_Validator_EmptyOk_True;
+
+            if ( retString != NULL ) {
+              if ( NW_Str_StricmpConst( retString, WAE_ASC_TRUE_STR ) == 0 ) {
+                emptyOk = NW_FBox_Validator_EmptyOk_True;
+              } else if ( NW_Str_StricmpConst( retString, WAE_ASC_FALSE_STR ) == 0 ) {
+                emptyOk = NW_FBox_Validator_EmptyOk_False;
+              }
+              NW_Str_Delete(retString);
+              retString = NULL;
+            }
+
+            /* get the FORMAT_ATTR value if any */
+            status = NW_Wml_GetAttribute(&(thisObj->wmlInterpreter), 
+                                         elId, 
+                                         FORMAT_ATTR,
+                                         &retString);
+            if (status == KBrsrOutOfMemory)
+              return status;
+            if ( retString == NULL ) {
+              /* Not format attribute.  Create an empty string. */
+              formatText = (NW_Text_t*) NW_Text_UCS2_New(NULL, 0, 0); 
+            } else {
+              /* Is a format attribute. Convert to a Text object. */
+              formatText = (const NW_Text_t*) NW_Text_UCS2_New(retString, 
+                                                               NW_Str_Strlen(retString),
+                                                               NW_Text_Flags_TakeOwnership);
+              retString = NULL;
+            }
+
+            validator = NW_Markup_WmlValidator_New( formatText, 
+                                                    NW_FBox_Validator_Mode_None,
+                                                    emptyOk,
+                                                    NW_FALSE);  /* Do a prefix match. */
+            NW_Object_Delete((NW_Text_t*) formatText);
+
+            /* Input box takes ownership of validator. */
+            NW_FBox_InputBox_SetValidator( inputBox, 
+                                           NW_FBox_ValidatorOf(validator) );
+
+            /* get the TABINDEX_ATTR value if any */
+            status = NW_Wml_GetAttribute(&(thisObj->wmlInterpreter), 
+                                         elId, 
+                                         TABINDEX_ATTR,
+                                         &retString);
+            if (status == KBrsrOutOfMemory)
+              return status;
+            /* convert string to NW_Text_Length_t in inputSize */
+            if (retString != NULL) 
+            {
+              tabIndexVal =  NW_Str_Atoi(retString);
+              NW_Str_Delete(retString);
+              retString = NULL;
+
+              /* set tabIndex on the new box */
+               prop.type = NW_CSS_ValueType_Integer;
+               prop.value.integer = (tabIndexVal > 0) ? tabIndexVal : 0;
+               NW_LMgr_Box_SetProperty(inputBox, NW_CSS_Prop_tabIndex, &prop); 
+            }
+
+            parentBox = NW_LMgr_Box_GetParent (box);
+
+            status = NW_LMgr_ContainerBox_InsertChild(parentBox,
+                                                      newBox,
+                                                      box);
+            if (status != KBrsrSuccess) {
+              NW_Object_Delete (newBox);
+              return status;
+            }
+
+            /* removing box here causes problems for the BoxVisitor, 
+             * since that object maintains a "currentBox" pointer which 
+             * at this point is pointing to this box.  The alternative
+             * is to set a pointer to the box to be deleted and then
+             * remove from parent and delete after BoxVisitor has moved on.
+             */
+            deleteBox = box;
+
+            /* replace the element Id on the new box */
+            prop.type = NW_CSS_ValueType_Integer;
+            value.integer = elId;
+            prop.value = value;
+            NW_LMgr_Box_SetProperty(inputBox, NW_CSS_Prop_elementId, &prop);   
+
+            NW_Wml1x_InputDefaultStyle(inputBox);
+
+          }
+        }
+        break;
+
+      case TABLE_ELEMENT:
+
+        status = NW_UI_NormalizeTable(thisObj, elId, box);
+        if (status != KBrsrSuccess) {
+          return status;
+        }
+        status = NW_UI_SetCellAlignment(thisObj, elId, box);
+        if (status != KBrsrSuccess) {
+          return status;
+        }
+        break;
+
+      case  TD_ELEMENT:
+        status = NW_UI_SetCellProperties(box);
+        if (status != KBrsrSuccess) {
+          return status;
+        }
+        break;
+
+      case  SELECT_ELEMENT:
+        status = NW_Wml1x_HandleSelect(thisObj,
+                                      elId,
+                                      box,
+                                      &deleteBox,
+                                      &currentSelectMultipleState,
+                                      &currentSelectTabIndexVal);
+        break;
+
+      case  OPTGRP_ELEMENT:
+        status = NW_Wml1x_HandleOptgroup(thisObj,
+                                        elId,
+                                        box);
+        break;
+
+      case  OPTION_ELEMENT:
+        status = NW_Wml1x_HandleOption(thisObj,
+                                      elId,
+                                      box,
+                                      currentSelectMultipleState,
+                                      currentSelectTabIndexVal);
+        break;
+
+      case  FIELDSET_ELEMENT:
+        /* The <fieldset> element is currently represented by a 
+         * BidiFlowBox, and will (hopefully) have had one or more <input> 
+         * children added. If the element has a TITLE attribute, create a text box
+         * with the TITLE text and insert it as the first child of the BidiFlowBox
+         */
+
+        status = NW_Wml_GetAttribute(&(thisObj->wmlInterpreter),
+                                     elId,
+                                     TITLE_ATTR,
+                                     &retString);
+        if (status == KBrsrOutOfMemory)
+           return status;
+        if (retString != NULL) 
+        {
+          NW_LMgr_Box_t *titleBox;
+          NW_LMgr_Box_t *breakBox;
+
+          /* make a text object containing the title */
+          temptext =
+            NW_Text_UCS2_New (retString, NW_Str_Strlen(retString),
+                              NW_Text_Flags_TakeOwnership);
+          if (temptext == NULL) {
+            return KBrsrOutOfMemory; /* NW_Text_UCS2_New() takes care of deleting string when fails */
+          }
+
+          titleBox = (NW_LMgr_Box_t*) NW_LMgr_TextBox_New(1, NW_TextOf(temptext));
+          breakBox = (NW_LMgr_Box_t*)NW_LMgr_BreakBox_New(0);
+
+          if (titleBox != NULL) 
+          {
+            if (NW_LMgr_ContainerBox_GetChildCount(NW_LMgr_ContainerBoxOf (box)) > 0)
+            {
+              if (breakBox){
+                status = NW_LMgr_ContainerBox_InsertChildAt(NW_LMgr_ContainerBoxOf (box),
+                                                            breakBox, 0);
+              }
+              status = NW_LMgr_ContainerBox_InsertChildAt(NW_LMgr_ContainerBoxOf (box),
+                                                        titleBox, 0);
+            }
+            else
+            {
+              /* no children: just add the title box */
+              status = NW_LMgr_ContainerBox_AddChild( NW_LMgr_ContainerBoxOf (box),
+                                                      titleBox);
+              if (breakBox){
+                status = NW_LMgr_ContainerBox_AddChild(NW_LMgr_ContainerBoxOf (box),
+                                                          breakBox);
+              }
+
+            }
+            if (status != KBrsrSuccess) {
+              return status;
+            }
+          }
+          else 
+          {
+            NW_Object_Delete(temptext);
+            return KBrsrOutOfMemory;
+          }
+        }
+        NW_Wml1x_FieldsetDefaultStyle(box);
+        break;
+
+      case  STRONG_ELEMENT:
+        /* strong default */
+        NW_Wml1x_StrongDefaultStyle(&prop, NW_LMgr_ContainerBoxOf (box));
+        break;
+
+      case  BIG_ELEMENT:
+        /* big default */
+        NW_Wml1x_BigDefaultStyle(&prop, NW_LMgr_ContainerBoxOf (box));
+        break;
+
+      case  ITALIC_ELEMENT:
+        /* italic default */
+        NW_Wml1x_ItalicDefaultStyle(&prop, NW_LMgr_ContainerBoxOf (box));
+        break;
+
+      case  EMPHASIS_ELEMENT:
+        /* emphasis default */
+        NW_Wml1x_EmphasisDefaultStyle(&prop, NW_LMgr_ContainerBoxOf (box));
+        break;
+
+      case  BOLD_ELEMENT:
+        /* bold default */
+        NW_Wml1x_BoldDefaultStyle(&prop, NW_LMgr_ContainerBoxOf (box));
+        break;
+
+      case  UNDERLINE_ELEMENT:
+        /* underline default */
+        NW_Wml1x_UnderlineDefaultStyle(&prop, NW_LMgr_ContainerBoxOf (box));
+        break;
+
+      case  SMALL_ELEMENT:
+        /* small default */
+        NW_Wml1x_SmallDefaultStyle(&prop, NW_LMgr_ContainerBoxOf (box));
+        break;
+
+      default:
+        break;
+      }
+
+      if (status != KBrsrSuccess) {
+        return status;
+      }
+    }
+  }
+    /* finally we inform the document tree that our content has changed */
+
+  parent = NW_HED_DocumentNode_GetParentNode(wae);
+
+  status =
+    NW_HED_DocumentNode_NodeChanged (wae, parent);
+
+  return status;
+}
+
+
+/*****************************************************************
+
+  Name:         NW_UI_DestroyCard()
+
+  Description:  callback for WML interpreter to destroy card
+
+  Parameters:
+    wae     - In      - the content handler on behalf of which the work is being done
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_DestroyCard (void *wae)
+{
+  NW_Wml1x_ContentHandler_t *thisObj;
+  NW_HED_CompositeNode_t* compositeNode;
+
+  thisObj = NW_Wml1x_ContentHandlerOf(wae);
+  compositeNode = (NW_HED_CompositeNode_t*) 
+    NW_Object_QueryAggregate (thisObj, &NW_HED_CompositeNode_Class);
+  NW_ASSERT (compositeNode != NULL);
+
+/*
+** leak the box tree since I don't know how to free script content handler
+** as child AND free the box tree without causing double delete of image
+** content handler which gets freed BOTH in boxTree delete and DeleteChildren.
+
+
+  if (NW_HED_ContentHandlerOf(thisObj)->boxTree != NULL) {
+    NW_Object_Delete( NW_HED_ContentHandlerOf(thisObj)->boxTree );
+    NW_HED_ContentHandlerOf(thisObj)->boxTree = NULL;
+  }
+*/
+
+  if (thisObj->optionMap != NULL) {
+    NW_Object_Delete(thisObj->optionMap);
+    thisObj->optionMap = NULL;
+  }
+  /* free up all our child content handlers; eg:-images */
+  NW_HED_CompositeNode_DeleteChildren(compositeNode);
+
+  /* succesful completion */
+  return KBrsrSuccess;
+}
+
+
+/*****************************************************************
+
+  Name:         NW_UI_AddStringElement()
+
+  Description:  called by NW_UI_AddElement() for text
+
+  Parameters:
+    thisObj   - In      - the content handler on behalf of which the work is being done
+    newboxptr - In/Out  - pointer to variable which will receive address of new box obj
+
+  Algorithm:    create the text box; actual text will be attached
+                  by NW_UI_ShowCard()
+
+  Return Value:
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_AddStringElement (NW_Wml1x_ContentHandler_t  *thisObj,
+                                           NW_LMgr_Box_t              **newboxptr)
+{
+  NW_LMgr_TextBox_t* box;
+
+  NW_TRY (status) {
+    box = NW_LMgr_TextBox_New(1, NULL);
+    NW_THROW_OOM_ON_NULL (box, status);
+
+    status = NW_LMgr_ContainerBox_AddChild(NW_LMgr_ContainerBoxOf(thisObj->currentBox),
+                                           NW_LMgr_BoxOf(box));
+    _NW_THROW_ON_ERROR (status);
+
+    *newboxptr = NW_LMgr_BoxOf(box);
+  }
+  NW_CATCH (status) {
+    NW_Object_Delete (box);
+  }
+  NW_FINALLY {
+    return status;
+  } NW_END_TRY
+}
+
+
+/*****************************************************************
+
+  Name:         NW_UI_AddFlowElement()
+
+  Description:  called by NW_UI_AddElement() for P, PRE, TD,
+                  SELECT, OPTGRP, and FIELDSET elements
+
+  Parameters:
+    thisObj   - In      - the content handler on behalf of which the work is being done
+    newboxptr - In/Out  - pointer to variable which will receive address of new box obj
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_AddFlowElement (NW_Wml1x_ContentHandler_t  *thisObj,
+                                         NW_LMgr_Box_t              **newboxptr)
+{
+  NW_LMgr_BidiFlowBox_t*  box;
+  NW_LMgr_Property_t    prop;
+
+  NW_TRY (status) {
+    box = NW_LMgr_BidiFlowBox_New(2);
+    NW_THROW_OOM_ON_NULL (box, status);
+
+    prop.type = NW_CSS_ValueType_Token;
+    prop.value.token = NW_CSS_PropValue_display_block;
+    NW_LMgr_Box_SetProperty(NW_LMgr_BoxOf(box), NW_CSS_Prop_display, &prop);
+
+    status = NW_LMgr_ContainerBox_AddChild(NW_LMgr_ContainerBoxOf(thisObj->currentBox),
+                                           NW_LMgr_BoxOf(box));
+    _NW_THROW_ON_ERROR (status);
+    
+    *newboxptr = NW_LMgr_BoxOf(box);
+  }
+  NW_CATCH (status) {
+    NW_Object_Delete (box);
+  }
+  NW_FINALLY {
+    return status;
+  } NW_END_TRY
+}
+
+
+/*****************************************************************
+
+  Name:         NW_UI_AddStyleElement()
+
+  Description:  called by NW_UI_AddElement() for EM, B, BIG,
+                  STRONG, I, SMALL, and U elements
+
+  Parameters:
+    thisObj   - In      - the content handler on behalf of which the work is being done
+    newboxptr - In/Out  - pointer to variable which will receive address of new box obj
+    elemType  - In      - token value of element being processed
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_AddStyleElement (NW_Wml1x_ContentHandler_t *thisObj,
+                                          NW_LMgr_Box_t             **newboxptr,
+                                          NW_Wml_ElType_e           elemType)
+{
+  NW_LMgr_ContainerBox_t*   containerBox;
+  
+  NW_REQUIRED_PARAM(elemType);
+
+  NW_TRY (status) {
+    /* add a raw container box then add style property to the container */
+    containerBox = NW_LMgr_ContainerBox_New(2); /* 2: style property and element Id */
+    NW_THROW_OOM_ON_NULL (containerBox, status);
+
+    /* process the elemType */
+    status = NW_LMgr_ContainerBox_AddChild (NW_LMgr_ContainerBoxOf(thisObj->currentBox),
+                                              NW_LMgr_BoxOf (containerBox));
+    _NW_THROW_ON_ERROR (status);
+    *newboxptr = NW_LMgr_BoxOf(containerBox);
+  }
+  NW_CATCH (status) {
+    NW_Object_Delete (containerBox);
+  }
+  NW_FINALLY {
+    return status;
+  } NW_END_TRY
+}
+
+
+
+/*****************************************************************
+
+  Name:         NW_UI_AddActiveElement()
+
+  Description:  called by NW_UI_AddElement() for A elements
+
+  Parameters:
+    thisObj   - In      - the content handler on behalf of which the work is being done
+    newboxptr - In/Out  - pointer to variable which will receive address of new box obj
+    elemType  - In      - token value of element being processed
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_AddActiveElement (NW_Wml1x_ContentHandler_t  *thisObj,
+                                           NW_LMgr_Box_t              **newboxptr,
+                                           NW_Wml_ElType_e            elemType)
+{
+  NW_Wml1x_EventHandler_t*  eventHandler;
+  NW_LMgr_Box_t             *activeBox = NULL;
+
+  NW_REQUIRED_PARAM(elemType);
+
+  NW_TRY (status) {
+    /* create the eventHandler for the active box */
+    eventHandler =
+      NW_Wml1x_EventHandler_New (NW_Wml1x_ContentHandlerOf(thisObj));
+    NW_THROW_OOM_ON_NULL(eventHandler, status);
+
+    /* create the activeBox */
+    switch (elemType)
+    {
+      case A_ELEMENT:
+      case ANCHOR_ELEMENT:
+        /* create a ActiveContainerBox to hold the active element and children*/
+        activeBox = (NW_LMgr_Box_t*)NW_LMgr_ActiveContainerBox_New(
+            0, NW_LMgr_EventHandlerOf (eventHandler), NW_LMgr_ActionType_OpenLink);
+        NW_THROW_OOM_ON_NULL(activeBox, status);
+        break;
+
+      default:
+        /* elemType must be handled before dropping through */
+        NW_ASSERT(0);
+        break;
+    }
+
+    status = NW_LMgr_ContainerBox_AddChild (NW_LMgr_ContainerBoxOf(thisObj->currentBox),
+                                              NW_LMgr_BoxOf (activeBox));
+    _NW_THROW_ON_ERROR (status);
+    *newboxptr = NW_LMgr_BoxOf(activeBox);
+  }
+  NW_CATCH (status) {
+    if(activeBox == NULL) {
+      NW_Object_Delete (eventHandler);
+    }
+    NW_Object_Delete (activeBox);
+  }
+  NW_FINALLY {
+    return status;
+  } NW_END_TRY
+}
+
+
+/*****************************************************************
+
+  Name:         NW_UI_AddContainerElement()
+
+  Description:  called by NW_UI_AddElement() for DO, INPUT and 
+                  OPTION elements
+
+  Parameters:
+    thisObj   - In      - the content handler on behalf of which the work is being done
+    newboxptr - In/Out  - pointer to variable which will receive address of new box obj
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_AddContainerElement (NW_Wml1x_ContentHandler_t *thisObj,
+                                              NW_LMgr_Box_t             **newboxptr)
+{
+  NW_LMgr_ContainerBox_t  *containerBox;
+
+  NW_TRY (status) {
+    /* create the containerBox */
+    containerBox = NW_LMgr_ContainerBox_New (1);
+    NW_THROW_OOM_ON_NULL(containerBox, status);
+
+    status = NW_LMgr_ContainerBox_AddChild (NW_LMgr_ContainerBoxOf(thisObj->currentBox),
+                                              NW_LMgr_BoxOf (containerBox));
+    _NW_THROW_ON_ERROR(status)
+    *newboxptr = NW_LMgr_BoxOf(containerBox); 
+  }
+
+  NW_CATCH (status) {
+    NW_Object_Delete (containerBox);
+  }
+  NW_FINALLY {
+    return status;
+  } NW_END_TRY
+}
+
+
+/*****************************************************************
+
+  Name:         NW_UI_AddBreakElement()
+
+  Description:  called by NW_UI_AddElement() for BR element
+
+  Parameters:
+    thisObj   - In      - the content handler on behalf of which the work is being done
+    newboxptr - In/Out  - pointer to variable which will receive address of new box obj
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_AddBreakElement (NW_Wml1x_ContentHandler_t *thisObj,
+                                          NW_LMgr_Box_t             **newboxptr)
+{
+  NW_LMgr_Box_t*        box;
+
+  NW_TRY (status) {
+    box = (NW_LMgr_Box_t*)NW_LMgr_BreakBox_New((NW_ADT_Vector_Metric_t)1);
+    NW_THROW_OOM_ON_NULL(box, status);
+
+    status = NW_LMgr_ContainerBox_AddChild(NW_LMgr_ContainerBoxOf(thisObj->currentBox),
+                                           NW_LMgr_BoxOf(box));
+    _NW_THROW_ON_ERROR(status);
+    *newboxptr = NW_LMgr_BoxOf(box);
+  }
+  NW_CATCH (status) {
+    NW_Object_Delete (box);
+  }
+  NW_FINALLY {
+    return status;
+  } NW_END_TRY
+}
+
+
+/*****************************************************************
+
+  Name:         NW_UI_AddImageElement()
+
+  Description:  called by NW_UI_AddElement() for IMG element
+
+  Parameters:
+    thisObj   - In      - the content handler on behalf of which the work is being done
+    newboxptr - In/Out  - pointer to variable which will receive address of new box obj
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_AddImageElement (NW_Wml1x_ContentHandler_t *thisObj,
+                                          NW_LMgr_Box_t             **newboxptr)
+{
+  NW_LMgr_Property_t            prop;
+  NW_Image_Virtual_t* virtualImage = NULL;
+
+  NW_TRY (status) 
+  {
+    /* as we have not downloaded the image, we create a
+       substitute ImageBox in which we display our 'missing' image*/
+    NW_HED_DocumentRoot_t* docRoot = NULL;
+    NW_LMgr_RootBox_t* rootBox = NULL;
+    MHEDDocumentListener* documentListener = NULL;
+    NW_Image_AbstractImage_t* cannedImage = NULL;
+
+    docRoot = (NW_HED_DocumentRoot_t*)NW_HED_DocumentNode_GetRootNode( thisObj );
+  	NW_ASSERT( docRoot != NULL );
+
+    documentListener = docRoot->documentListener;
+  	NW_ASSERT( documentListener != NULL );
+
+    rootBox = documentListener->GetRootBox();
+    NW_ASSERT( rootBox != NULL );
+    NW_ASSERT( rootBox->cannedImages != NULL );
+
+    cannedImage = (NW_Image_AbstractImage_t*)
+        NW_Image_CannedImages_GetImage( rootBox->cannedImages, NW_Image_Missing );
+    NW_THROW_OOM_ON_NULL( cannedImage, status );
+
+    virtualImage = NW_Image_Virtual_New( cannedImage );
+    NW_THROW_OOM_ON_NULL( virtualImage, status );
+    // pass image ownership
+    *newboxptr = (NW_LMgr_Box_t*)NW_LMgr_AnimatedImageBox_New(0, NW_Image_AbstractImageOf( virtualImage ), NULL, NW_TRUE );
+    NW_THROW_OOM_ON_NULL(*newboxptr, status);
+    // image container takes image ownership
+    virtualImage = NULL;
+    
+    status = NW_LMgr_ContainerBox_AddChild (NW_LMgr_ContainerBoxOf(thisObj->currentBox),
+                                            *newboxptr);
+    _NW_THROW_ON_ERROR(status);
+      
+    NW_Wml1x_ImageWithinAnchorDefaultStyle(&prop, *newboxptr);
+
+  }
+  NW_CATCH (status) {
+    NW_Object_Delete (*newboxptr);
+    NW_Object_Delete (virtualImage);
+  }
+  NW_FINALLY {
+    return status;
+  } NW_END_TRY
+}
+
+
+/*****************************************************************
+
+  Name:         NW_UI_AddTableElement()
+
+  Description:  called by NW_UI_AddElement() for TABLE element
+
+  Parameters:
+    thisObj   - In      - the content handler on behalf of which the work is being done
+    newboxptr - In/Out  - pointer to variable which will receive address of new box obj
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_AddTableElement (NW_Wml1x_ContentHandler_t *thisObj,
+                                          NW_LMgr_Box_t             **newboxptr)
+{
+  NW_Bool ownsSTB = NW_TRUE;
+  NW_LMgr_Box_t *stb = NULL;
+
+  NW_TRY (status) {
+    NW_LMgr_Property_t prop;
+
+    /* Allocate and initialize the table itself */
+    stb = (NW_LMgr_Box_t*)NW_LMgr_StaticTableBox_New(1);
+    NW_THROW_OOM_ON_NULL (stb, status);
+
+    /* Set the display prop */
+    prop.type = NW_CSS_ValueType_Token;
+    prop.value.token = NW_CSS_PropValue_display_block;
+    NW_LMgr_Box_SetProperty (stb, NW_CSS_Prop_display, &prop);
+
+    status = NW_LMgr_ContainerBox_AddChild(NW_LMgr_ContainerBoxOf(thisObj->currentBox),
+                                            stb);
+    _NW_THROW_ON_ERROR(status);
+    ownsSTB = NW_FALSE;
+
+    *newboxptr = stb;
+
+  } NW_CATCH (status) {
+  } NW_FINALLY {
+    if (ownsSTB) {
+      NW_Object_Delete (stb);
+    }
+    return status;
+  } NW_END_TRY
+}
+
+
+/*****************************************************************
+
+  Name:         NW_UI_AddTrElement()
+
+  Description:  called by NW_UI_AddElement() for TR element
+
+  Parameters:
+    thisObj   - In      - the content handler on behalf of which the work is being done
+    newboxptr - In/Out  - pointer to variable which will receive address of new box obj
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_AddTrElement (NW_Wml1x_ContentHandler_t  *thisObj,
+                                       NW_LMgr_Box_t              **newboxptr)
+{
+  NW_LMgr_Box_t* box = NULL;
+
+  NW_TRY (status) {
+    box = (NW_LMgr_Box_t*) NW_LMgr_StaticTableRowBox_New (1);
+    NW_THROW_OOM_ON_NULL (box, status);
+
+    /* Add the row to the box tree */
+    status = NW_LMgr_ContainerBox_AddChild (NW_LMgr_ContainerBoxOf (thisObj->currentBox),
+                                            box);
+    NW_THROW_ON_ERROR (status);
+    *newboxptr = box;
+
+  } NW_CATCH (status) {
+    NW_Object_Delete (box);
+  } NW_FINALLY {
+    return status;
+  } NW_END_TRY
+}
+
+/*****************************************************************
+
+  Name:         NW_UI_AddTdElement()
+
+  Description:  called by NW_UI_AddElement() for TD element
+
+  Parameters:
+    thisObj   - In      - the content handler on behalf of which the work is being done
+    newboxptr - In/Out  - pointer to variable which will receive address of new box obj
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_AddTdElement (NW_Wml1x_ContentHandler_t  *thisObj,
+                                       NW_LMgr_Box_t              **newboxptr)
+{
+  NW_LMgr_Box_t* box = NULL;
+
+  NW_TRY (status) {
+    box = (NW_LMgr_Box_t*)NW_LMgr_StaticTableCellBox_New(1);
+    NW_THROW_OOM_ON_NULL (box, status);
+
+    /* Add the row to the box tree */
+    status = NW_LMgr_ContainerBox_AddChild (NW_LMgr_ContainerBoxOf (thisObj->currentBox),
+                                            box);
+    NW_THROW_ON_ERROR (status);
+    *newboxptr = box;
+
+  } NW_CATCH (status) {
+    NW_Object_Delete (box);
+  } NW_FINALLY {
+    return status;
+  } NW_END_TRY
+}
+
+
+/*****************************************************************
+
+  Name:         NW_UI_AddUnknownElement()
+
+  Description:  called by NW_UI_AddElement() when element is not
+                  recognized
+
+  Parameters:
+    thisObj   - In      - the content handler on behalf of which the work is being done
+    newboxptr - In/Out  - pointer to variable which will receive address of new box obj
+
+  Algorithm:    create a basic container box for the element so
+                  that any content may be properly rendered
+
+  Return Value:
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_AddUnknownElement (NW_Wml1x_ContentHandler_t *thisObj,
+                                            NW_LMgr_Box_t             **newboxptr)
+{
+  NW_LMgr_ContainerBox_t* box;
+
+  NW_TRY (status) {
+    box = NW_LMgr_ContainerBox_New(1);
+    NW_THROW_OOM_ON_NULL (box, status);
+
+    status = NW_LMgr_ContainerBox_AddChild(NW_LMgr_ContainerBoxOf(thisObj->currentBox),
+                                           NW_LMgr_BoxOf(box));
+    _NW_THROW_ON_ERROR (status);
+    *newboxptr = NW_LMgr_BoxOf(box);
+  }
+  NW_CATCH(status) {
+    NW_Object_Delete (box);
+  }
+  NW_FINALLY {
+    if(status != KBrsrOutOfMemory) {
+      status = KBrsrSuccess;
+    }
+    return status;
+  } NW_END_TRY
+}
+
+
+/*****************************************************************
+
+  Name:         NW_Element_endTagRendered()
+
+  Description:  determines whether an explicit end-tag will be or
+                  will have been generated by RenderCardElements()
+                  for a given elemType.
+
+  Parameters:
+    elemType  - In      - token value of element being processed
+
+  Algorithm:
+    (TODO: This probably ought to be in a different module,
+    like wml_ui.c)
+
+  Return Value:
+
+*****************************************************************/
+NW_Bool NW_Element_endTagRendered (NW_Wml_ElType_e elemType)
+{
+  switch (elemType)
+  {
+  /* Elements for which RenderCardElements() in wml_ui.c generates end-tag: */
+  case A_ELEMENT:
+  case ANCHOR_ELEMENT:
+  case EMPHASIS_ELEMENT:
+  case STRONG_ELEMENT:
+  case ITALIC_ELEMENT:
+  case BOLD_ELEMENT:
+  case UNDERLINE_ELEMENT:
+  case BIG_ELEMENT:
+  case SMALL_ELEMENT:
+  case SELECT_ELEMENT:
+  case P_ELEMENT:
+  case FIELDSET_ELEMENT:
+  case OPTGRP_ELEMENT:
+  case TABLE_ELEMENT:
+  case TR_ELEMENT:
+  case TD_ELEMENT:
+  case OPTION_ELEMENT:
+  case PRE_ELEMENT:
+    return NW_TRUE;
+
+  /* Elements for which RenderCardElements() in wml_ui.c does not generate end-tag: */
+  case DO_ELEMENT:
+  case INPUT_ELEMENT:
+  case BREAK_ELEMENT:
+  case IMAGE_ELEMENT:
+  case STRING_ELEMENT:
+  case END_ELEMENT:
+    return NW_FALSE;
+
+  /* Elements not expected from RenderCardElements() in wml_ui.c */
+  case CARD_ELEMENT:
+  case GO_ELEMENT:
+  case PREV_ELEMENT:
+  case REFRESH_ELEMENT:
+  case NOOP_ELEMENT:
+  case SETVAR_ELEMENT:
+  case ONEVENT_ELEMENT:
+  case WML_ELEMENT:
+  case HEAD_ELEMENT:
+  case TEMPLATE_ELEMENT:
+  case TIMER_ELEMENT:
+  case ACCESS_ELEMENT:
+  case META_ELEMENT:
+  case POSTFIELD_ELEMENT:
+
+  /* All known WML-tags should be handled explicitly in the switch */
+  default:
+    NW_ASSERT(NW_FALSE);
+    return NW_FALSE;
+  }
+}
+
+/*****************************************************************
+
+  Name:         NW_UI_AddElement()
+
+  Description:  callback for WML interpreter to add card elements
+
+  Parameters:
+    wae       - In      - the content handler on behalf of which the work is being done
+    elemType  - In      - token value of element being processed
+    elemId    - In/Out  - pointer to variable which will receive unique 
+                    identifying value to be associated with this element 
+                    for later use with the WML query service to obtain
+                    attribute values
+
+  Algorithm:    for element passed in, create the box on the box
+                  tree for later rendering, and assign a unique
+                  id number to the element
+
+  Return Value:
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_AddElement (void             *wae, 
+                                     NW_Wml_ElType_e  elemType,
+                                     NW_Int16         *elemId)
+{
+  NW_LMgr_Property_t            prop;
+  NW_LMgr_PropertyValue_t       val;
+  NW_Wml1x_ContentHandler_t     *ch;
+  NW_LMgr_Box_t                 *box = NULL;
+
+  NW_TRY (status) {
+    
+    ch = NW_Wml1x_ContentHandlerOf(wae);
+    *elemId = ch->lastId;
+
+    switch( elemType ) {
+
+    case  END_ELEMENT:
+      ch->currentBox = (NW_LMgr_Box_t*) NW_LMgr_Box_GetParent(ch->currentBox);
+      status = KBrsrSuccess;
+      break;
+
+    case  P_ELEMENT:
+    case  PRE_ELEMENT:
+    case  SELECT_ELEMENT:
+    case  OPTGRP_ELEMENT:
+    case  FIELDSET_ELEMENT:
+      status = NW_UI_AddFlowElement(ch, &box);
+      break;
+
+    case  STRING_ELEMENT:
+      status = NW_UI_AddStringElement(ch, &box);
+      break;
+
+    case  BREAK_ELEMENT:
+      status = NW_UI_AddBreakElement(ch, &box);
+      break;
+
+    case  EMPHASIS_ELEMENT:
+    case  STRONG_ELEMENT:
+    case  ITALIC_ELEMENT:
+    case  BOLD_ELEMENT:
+    case  UNDERLINE_ELEMENT:
+    case  BIG_ELEMENT:
+    case  SMALL_ELEMENT:
+      status = NW_UI_AddStyleElement(ch, &box, elemType);
+      break;
+
+    case  IMAGE_ELEMENT:
+      status = NW_UI_AddImageElement(ch, &box);
+      break;
+
+    case  OPTION_ELEMENT:
+    case  INPUT_ELEMENT:
+    case  DO_ELEMENT:
+      status = NW_UI_AddContainerElement(ch, &box);
+      break;
+
+    case  A_ELEMENT:
+    case  ANCHOR_ELEMENT:
+      status = NW_UI_AddActiveElement(ch, &box, elemType);
+      break;
+
+    case  TABLE_ELEMENT:
+      status = NW_UI_AddTableElement(ch, &box);
+      break;
+
+    case  TR_ELEMENT:
+      status = NW_UI_AddTrElement(ch, &box);
+      break;
+
+    case  TD_ELEMENT:
+      status = NW_UI_AddTdElement(ch, &box);
+      break;
+
+    case  UNKNOWN_ELEMENT:
+      status = NW_UI_AddUnknownElement(ch, &box);
+      break;
+
+    case  CARD_ELEMENT:
+    case  GO_ELEMENT:
+    case  PREV_ELEMENT:
+    case  REFRESH_ELEMENT:
+    case  NOOP_ELEMENT:
+    case  SETVAR_ELEMENT:
+    case  ONEVENT_ELEMENT:
+    case  WML_ELEMENT:
+    case  HEAD_ELEMENT:
+    case  TEMPLATE_ELEMENT:
+    case  TIMER_ELEMENT:
+    case  ACCESS_ELEMENT:
+    case  META_ELEMENT:
+    case  POSTFIELD_ELEMENT:
+    default:
+      /* TODO: handle unexpected elements: do nothing? */
+      NW_ASSERT( 0 );
+      break;
+
+    }
+
+    _NW_THROW_ON_ERROR (status);
+
+    if (NW_Element_endTagRendered (elemType) == NW_TRUE) {
+      /* push currentBox pointer down to newly-created element box;
+          End element will pop it up */
+      ch->currentBox = box;
+    }
+    if ((elemType != END_ELEMENT) && (box != NULL)) {
+      prop.type = NW_CSS_ValueType_Integer;
+      val.integer = ch->lastId;
+      prop.value = val;
+      NW_LMgr_Box_SetProperty(box, NW_CSS_Prop_elementId, &prop);
+    }
+    else if ((elemType != END_ELEMENT) && (box == NULL)) {
+    /* TODO:  handle box == NULL, in case Add_x_Element() failed to create a child box */
+      NW_ASSERT( 0 );
+    }
+
+    ch->lastId += 1;
+
+  /*#ifdef _DEBUG */
+  #if 0 /* TODO figure out what to do here */
+    {
+      /* log the elements */
+      NW_Ucs2 *debugStr;
+      debugStr = NW_Str_NewcpyConst(elTypeNames[elemType]);
+      NW_LOG1(NW_LOG_LEVEL1, "<%s>", debugStr);
+      NW_Str_Delete(debugStr);
+    }
+  #endif
+  }
+  NW_CATCH (status) {
+
+  }
+  NW_FINALLY {
+    return status;
+  } NW_END_TRY
+
+}
+
+/*****************************************************************
+
+  Name:         NW_UI_CleanUp()
+
+  Description:  callback for WML interpreter
+
+  Parameters:   
+    wae       - In      - the content handler on behalf of which the work is being done
+
+  Algorithm:   
+
+  Return Value: KBrsrSuccess
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_CleanUp (void *wae)
+{
+  NW_REQUIRED_PARAM(wae);
+  return KBrsrSuccess;
+}
+
+/*****************************************************************
+
+  Name:         NW_UI_SetOptState()
+
+  Description:  callback for WML interpreter to set state of
+                  option element
+
+  Parameters:
+    wae       - In      - the content handler on behalf of which the work is being done
+    elemId    - In      - the element Id of the <option> element affected
+    st        - In      - the state to set the <option> element
+
+  Algorithm:    use a map to associate element Id with state
+
+  Return Value: KBrsrFailure iff unable to find or create
+                      key entry in map vector;
+                KBrsrSuccess otherwise
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_SetOptState (void *wae, NW_Uint16 elemId, NW_Bool st)
+{
+  return NW_ADT_Map_Set (NW_Wml1x_ContentHandlerOf(wae)->optionMap, &elemId, &st);
+}
+
+/*****************************************************************
+
+  Name:         NW_UI_GetOptState()
+
+  Description:  callback for WML interpreter to get state of
+                  option element
+
+  Parameters:   
+    wae       - In      - the content handler on behalf of which the work is being done
+    elemId    - In      - the element Id of the <option> element affected
+    st        - In      - pointer to bool in which state will be copied
+
+  Algorithm:    use the map populated during SetOptState
+                  to return state associated with element Id
+                NOTE that if elemId is not an existing key in
+                  the map, *st will be set to NW_FALSE
+
+  Return Value: KBrsrSuccess
+
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_GetOptState (void *wae, NW_Uint16 elemId, NW_Bool *st)
+{
+  NW_Bool* boolPtr;
+  
+  NW_ASSERT( wae != NULL );
+  NW_ASSERT( st != NULL );
+
+  /* fetch a pointer to the value from the map */
+  /* Returns NULL if item doesn't exist. */
+  boolPtr = (NW_Bool*) NW_ADT_Map_GetUnsafe(
+                            NW_Wml1x_ContentHandlerOf(wae)->optionMap, 
+                            &elemId);
+
+  /* use byte-wise copy to get the unaligned data into the client's variable */
+  /* copy the value into the client's variable */
+  if ((boolPtr != NULL) && (st != NULL))
+  {
+    (void) NW_Mem_memcpy (st, boolPtr, sizeof *st);
+  }
+  else if (st != NULL)
+  {
+    *st = NW_FALSE;
+  }
+
+  return KBrsrSuccess;
+}
+
+/*****************************************************************
+
+  Name:         NW_UI_Refresh()
+
+  Description:  callback for WML interpreter
+
+  Parameters:
+    wae       - In      - the content handler on behalf of which the work is being done
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+static TBrowserStatusCode NW_UI_Refresh (void *wae)
+{
+  /* avoid 'unreferenced formal parameter' warnings */
+  (void) wae;
+
+  /* succesful completion */
+  return KBrsrSuccess;
+}
+
+
+
+/*****************************************************************
+
+  Name:         NW_Api_GetWml1xCB()
+
+  Description:
+
+  Parameters:
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+const NW_WmlApi_t* NW_Api_GetWml1xCB()
+{
+  return &wml_api;
+}
+
+
+/*===============================Timer API wrappers for WML 1.x content handler================*/
+
+/*****************************************************************
+
+  Name:         GetWmlTimer()
+
+  Description:
+
+  Parameters:
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+NW_System_Timer_t* GetWmlTimer (void *usrAgent)
+{
+  NW_Wml1x_ContentHandler_t *thisObj;
+
+  NW_ASSERT(usrAgent!=NULL);
+  thisObj = NW_Wml1x_ContentHandlerOf(usrAgent);
+  return thisObj->wmlTimer;
+}
+
+/*****************************************************************
+
+  Name:         SetWmlTimer()
+
+  Description:
+
+  Parameters:
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+void SetWmlTimer (void *usrAgent, NW_System_Timer_t* wmlTimer)
+{
+  NW_Wml1x_ContentHandler_t *thisObj;
+
+  NW_ASSERT(usrAgent!=NULL);
+  thisObj = NW_Wml1x_ContentHandlerOf(usrAgent);
+  thisObj->wmlTimer = wmlTimer;
+}
+
+
+/*
+**-------------------------------------------------------------------------
+**  Timer API functions called by the WML Browser
+**-------------------------------------------------------------------------
+*/
+
+/*****************************************************************
+
+  Name:         NW_Wml1x_CreateTimer()
+
+  Description:
+
+  Parameters:
+    usrAgent  - In      - the content handler on behalf of which the work is being done
+    period    - In      - timer period
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+TBrowserStatusCode NW_Wml1x_CreateTimer (void *usrAgent, NW_Uint32 period)
+{
+  NW_Wml1x_ContentHandler_t *thisObj;
+  thisObj = NW_Wml1x_ContentHandlerOf(usrAgent);
+
+
+  thisObj->wmlTimer =
+    NW_System_Timer_New (NW_Wml_Timeout, &(thisObj->wmlInterpreter),
+                         period * NW_MSEC_PER_WML_TICK, NW_FALSE);
+  if(thisObj->wmlTimer == NULL)
+  {
+    return KBrsrOutOfMemory;
+  }
+
+  return KBrsrSuccess;
+}
+
+/*****************************************************************
+
+  Name:         NW_Wml1x_ReadTimer()
+
+  Description:
+
+  Parameters:
+    usrAgent  - In      - the content handler on behalf of which the work is being done
+    period    - In/Out  - pointer to variable to receive timer value
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+TBrowserStatusCode NW_Wml1x_ReadTimer (void *usrAgent, NW_Uint32 *period)
+{
+  NW_Uint32 period32;
+  TBrowserStatusCode status;
+  NW_System_Timer_t* wmlTimer = GetWmlTimer(usrAgent);
+
+  if (wmlTimer == NULL) {
+    return KBrsrBadInputParam;
+  }
+  status = NW_System_Timer_Read (wmlTimer, &period32);
+  if(status == KBrsrSuccess)
+  {
+    *period = period32/NW_MSEC_PER_WML_TICK;
+  }
+  return status;
+}
+
+/*****************************************************************
+
+  Name:         NW_Wml1x_DestroyTimer()
+
+  Description:
+
+  Parameters:
+    usrAgent  - In      - the content handler on behalf of which the work is being done
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+TBrowserStatusCode NW_Wml1x_DestroyTimer (void *usrAgent)
+{
+  NW_System_Timer_t* wmlTimer = GetWmlTimer(usrAgent);
+
+  if (wmlTimer == NULL) {
+    return KBrsrBadInputParam;
+  }
+  NW_Object_Delete (wmlTimer);
+  SetWmlTimer(usrAgent, NULL);
+
+  return KBrsrSuccess;
+}
+
+/*****************************************************************
+
+  Name:         NW_Wml1x_ResumeTimer()
+
+  Description:
+
+  Parameters:
+    usrAgent  - In      - the content handler on behalf of which the work is being done
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+TBrowserStatusCode NW_Wml1x_ResumeTimer (void *usrAgent)
+{
+  NW_System_Timer_t* wmlTimer = GetWmlTimer(usrAgent);
+
+  if (wmlTimer == NULL) {
+    return KBrsrBadInputParam;
+  }
+  return NW_System_Timer_Resume (wmlTimer);
+}
+
+/*****************************************************************
+
+  Name:         NW_Wml1x_StopTimer()
+
+  Description:
+
+  Parameters:
+    usrAgent  - In      - the content handler on behalf of which the work is being done
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+TBrowserStatusCode NW_Wml1x_StopTimer (void *usrAgent)
+{
+  NW_System_Timer_t* wmlTimer = GetWmlTimer(usrAgent);
+
+  if (wmlTimer == NULL) {
+    return KBrsrBadInputParam;
+  }
+  return NW_System_Timer_Stop (wmlTimer);
+}
+
+/*****************************************************************
+
+  Name:         NW_Wml1x_IsTimerRunning()
+
+  Description:
+
+  Parameters:
+    usrAgent  - In      - the content handler on behalf of which the work is being done
+    isRunning - In/Out  - pointer to variable to receive state of timer
+
+  Algorithm:
+
+  Return Value:
+
+*****************************************************************/
+TBrowserStatusCode NW_Wml1x_IsTimerRunning (void *usrAgent, NW_Bool *isRunning)
+{
+  NW_System_Timer_t* wmlTimer = GetWmlTimer(usrAgent);
+
+  if (wmlTimer == NULL) {
+    *isRunning = NW_FALSE;
+  } else {
+    (void) NW_System_Timer_IsRunning (wmlTimer, isRunning);
+  }
+  return KBrsrSuccess;
+}