Move xfa/src up to xfa/.

This CL moves the xfa/src files up to the xfa/ directory and fixes the includes,
include guards, and build files.

R=tsepez@chromium.org

Review URL: https://codereview.chromium.org/1803723002 .
diff --git a/xfa/fxfa/app/xfa_checksum.cpp b/xfa/fxfa/app/xfa_checksum.cpp
new file mode 100644
index 0000000..1639c0d
--- /dev/null
+++ b/xfa/fxfa/app/xfa_checksum.cpp
@@ -0,0 +1,190 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_checksum.h"
+
+#include "core/include/fdrm/fx_crypt.h"
+#include "xfa/fgas/crt/fgas_algorithm.h"
+
+CXFA_SAXReaderHandler::CXFA_SAXReaderHandler(CXFA_ChecksumContext* pContext)
+    : m_pContext(pContext) {
+  FXSYS_assert(m_pContext);
+}
+CXFA_SAXReaderHandler::~CXFA_SAXReaderHandler() {}
+void* CXFA_SAXReaderHandler::OnTagEnter(const CFX_ByteStringC& bsTagName,
+                                        FX_SAXNODE eType,
+                                        FX_DWORD dwStartPos) {
+  UpdateChecksum(TRUE);
+  if (eType != FX_SAXNODE_Tag && eType != FX_SAXNODE_Instruction) {
+    return NULL;
+  }
+  m_SAXContext.m_eNode = eType;
+  CFX_ByteTextBuf& textBuf = m_SAXContext.m_TextBuf;
+  textBuf << "<";
+  if (eType == FX_SAXNODE_Instruction) {
+    textBuf << "?";
+  }
+  textBuf << bsTagName;
+  m_SAXContext.m_bsTagName = bsTagName;
+  return &m_SAXContext;
+}
+void CXFA_SAXReaderHandler::OnTagAttribute(void* pTag,
+                                           const CFX_ByteStringC& bsAttri,
+                                           const CFX_ByteStringC& bsValue) {
+  if (pTag == NULL) {
+    return;
+  }
+  CFX_ByteTextBuf& textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;
+  textBuf << " " << bsAttri << "=\"" << bsValue << "\"";
+}
+void CXFA_SAXReaderHandler::OnTagBreak(void* pTag) {
+  if (pTag == NULL) {
+    return;
+  }
+  CFX_ByteTextBuf& textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;
+  textBuf << ">";
+  UpdateChecksum(FALSE);
+}
+void CXFA_SAXReaderHandler::OnTagData(void* pTag,
+                                      FX_SAXNODE eType,
+                                      const CFX_ByteStringC& bsData,
+                                      FX_DWORD dwStartPos) {
+  if (pTag == NULL) {
+    return;
+  }
+  CFX_ByteTextBuf& textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;
+  if (eType == FX_SAXNODE_CharData) {
+    textBuf << "<![CDATA[";
+  }
+  textBuf << bsData;
+  if (eType == FX_SAXNODE_CharData) {
+    textBuf << "]]>";
+  }
+}
+void CXFA_SAXReaderHandler::OnTagClose(void* pTag, FX_DWORD dwEndPos) {
+  if (pTag == NULL) {
+    return;
+  }
+  CXFA_SAXContext* pSAXContext = (CXFA_SAXContext*)pTag;
+  CFX_ByteTextBuf& textBuf = pSAXContext->m_TextBuf;
+  if (pSAXContext->m_eNode == FX_SAXNODE_Instruction) {
+    textBuf << "?>";
+  } else if (pSAXContext->m_eNode == FX_SAXNODE_Tag) {
+    textBuf << "></" << pSAXContext->m_bsTagName << ">";
+  }
+  UpdateChecksum(FALSE);
+}
+void CXFA_SAXReaderHandler::OnTagEnd(void* pTag,
+                                     const CFX_ByteStringC& bsTagName,
+                                     FX_DWORD dwEndPos) {
+  if (pTag == NULL) {
+    return;
+  }
+  CFX_ByteTextBuf& textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;
+  textBuf << "</" << bsTagName << ">";
+  UpdateChecksum(FALSE);
+}
+void CXFA_SAXReaderHandler::OnTargetData(void* pTag,
+                                         FX_SAXNODE eType,
+                                         const CFX_ByteStringC& bsData,
+                                         FX_DWORD dwStartPos) {
+  if (pTag == NULL && eType != FX_SAXNODE_Comment) {
+    return;
+  }
+  if (eType == FX_SAXNODE_Comment) {
+    CFX_ByteTextBuf& textBuf = m_SAXContext.m_TextBuf;
+    textBuf << "<!--" << bsData << "-->";
+    UpdateChecksum(FALSE);
+  } else {
+    CFX_ByteTextBuf& textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;
+    textBuf << " " << bsData;
+  }
+}
+void CXFA_SAXReaderHandler::UpdateChecksum(FX_BOOL bCheckSpace) {
+  int32_t iLength = m_SAXContext.m_TextBuf.GetLength();
+  if (iLength < 1) {
+    return;
+  }
+  uint8_t* pBuffer = m_SAXContext.m_TextBuf.GetBuffer();
+  FX_BOOL bUpdata = TRUE;
+  if (bCheckSpace) {
+    bUpdata = FALSE;
+    for (int32_t i = 0; i < iLength; i++) {
+      bUpdata = (pBuffer[i] > 0x20);
+      if (bUpdata) {
+        break;
+      }
+    }
+  }
+  if (bUpdata) {
+    m_pContext->Update(CFX_ByteStringC(pBuffer, iLength));
+  }
+  m_SAXContext.m_TextBuf.Clear();
+}
+IXFA_ChecksumContext* XFA_Checksum_Create() {
+  return new CXFA_ChecksumContext;
+}
+CXFA_ChecksumContext::CXFA_ChecksumContext()
+    : m_pSAXReader(NULL), m_pByteContext(NULL) {}
+CXFA_ChecksumContext::~CXFA_ChecksumContext() {
+  FinishChecksum();
+}
+FX_BOOL CXFA_ChecksumContext::StartChecksum() {
+  FinishChecksum();
+  m_pByteContext = FX_Alloc(uint8_t, 128);
+  CRYPT_SHA1Start(m_pByteContext);
+  m_bsChecksum.Empty();
+  m_pSAXReader = FX_SAXReader_Create();
+  return m_pSAXReader != NULL;
+}
+FX_BOOL CXFA_ChecksumContext::UpdateChecksum(IFX_FileRead* pSrcFile,
+                                             FX_FILESIZE offset,
+                                             size_t size) {
+  if (m_pSAXReader == NULL) {
+    return FALSE;
+  }
+  if (pSrcFile == NULL) {
+    return FALSE;
+  }
+  if (size < 1) {
+    size = pSrcFile->GetSize();
+  }
+  CXFA_SAXReaderHandler handler(this);
+  m_pSAXReader->SetHandler(&handler);
+  if (m_pSAXReader->StartParse(
+          pSrcFile, (FX_DWORD)offset, (FX_DWORD)size,
+          FX_SAXPARSEMODE_NotSkipSpace | FX_SAXPARSEMODE_NotConvert_amp |
+              FX_SAXPARSEMODE_NotConvert_lt | FX_SAXPARSEMODE_NotConvert_gt |
+              FX_SAXPARSEMODE_NotConvert_sharp) < 0) {
+    return FALSE;
+  }
+  return m_pSAXReader->ContinueParse(NULL) > 99;
+}
+void CXFA_ChecksumContext::FinishChecksum() {
+  if (m_pSAXReader) {
+    m_pSAXReader->Release();
+    m_pSAXReader = NULL;
+  }
+  if (m_pByteContext) {
+    uint8_t digest[20];
+    FXSYS_memset(digest, 0, 20);
+    CRYPT_SHA1Finish(m_pByteContext, digest);
+    int32_t nLen = FX_Base64EncodeA(digest, 20, NULL);
+    FX_CHAR* pBuffer = m_bsChecksum.GetBuffer(nLen);
+    FX_Base64EncodeA(digest, 20, pBuffer);
+    m_bsChecksum.ReleaseBuffer(nLen);
+    FX_Free(m_pByteContext);
+    m_pByteContext = NULL;
+  }
+}
+void CXFA_ChecksumContext::GetChecksum(CFX_ByteString& bsChecksum) {
+  bsChecksum = m_bsChecksum;
+}
+void CXFA_ChecksumContext::Update(const CFX_ByteStringC& bsText) {
+  if (m_pByteContext) {
+    CRYPT_SHA1Update(m_pByteContext, bsText.GetPtr(), bsText.GetLength());
+  }
+}
diff --git a/xfa/fxfa/app/xfa_checksum.h b/xfa/fxfa/app/xfa_checksum.h
new file mode 100644
index 0000000..5331800
--- /dev/null
+++ b/xfa/fxfa/app/xfa_checksum.h
@@ -0,0 +1,73 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_CHECKSUM_H_
+#define XFA_FXFA_APP_XFA_CHECKSUM_H_
+
+#include "xfa/fgas/xml/fgas_sax.h"
+#include "xfa/include/fxfa/fxfa.h"
+
+class CXFA_SAXReaderHandler;
+class CXFA_ChecksumContext;
+
+class CXFA_SAXContext {
+ public:
+  CXFA_SAXContext() : m_eNode(FX_SAXNODE_Unknown) {}
+  CFX_ByteTextBuf m_TextBuf;
+  CFX_ByteString m_bsTagName;
+  FX_SAXNODE m_eNode;
+};
+class CXFA_SAXReaderHandler : public IFX_SAXReaderHandler {
+ public:
+  CXFA_SAXReaderHandler(CXFA_ChecksumContext* pContext);
+  virtual ~CXFA_SAXReaderHandler();
+  virtual void* OnTagEnter(const CFX_ByteStringC& bsTagName,
+                           FX_SAXNODE eType,
+                           FX_DWORD dwStartPos);
+  virtual void OnTagAttribute(void* pTag,
+                              const CFX_ByteStringC& bsAttri,
+                              const CFX_ByteStringC& bsValue);
+  virtual void OnTagBreak(void* pTag);
+  virtual void OnTagData(void* pTag,
+                         FX_SAXNODE eType,
+                         const CFX_ByteStringC& bsData,
+                         FX_DWORD dwStartPos);
+  virtual void OnTagClose(void* pTag, FX_DWORD dwEndPos);
+  virtual void OnTagEnd(void* pTag,
+                        const CFX_ByteStringC& bsTagName,
+                        FX_DWORD dwEndPos);
+
+  virtual void OnTargetData(void* pTag,
+                            FX_SAXNODE eType,
+                            const CFX_ByteStringC& bsData,
+                            FX_DWORD dwStartPos);
+
+ protected:
+  void UpdateChecksum(FX_BOOL bCheckSpace);
+  CXFA_ChecksumContext* m_pContext;
+  CXFA_SAXContext m_SAXContext;
+};
+
+class CXFA_ChecksumContext : public IXFA_ChecksumContext {
+ public:
+  CXFA_ChecksumContext();
+  virtual ~CXFA_ChecksumContext();
+  virtual void Release() { delete this; }
+  virtual FX_BOOL StartChecksum();
+  virtual FX_BOOL UpdateChecksum(IFX_FileRead* pSrcFile,
+                                 FX_FILESIZE offset = 0,
+                                 size_t size = 0);
+  virtual void FinishChecksum();
+  virtual void GetChecksum(CFX_ByteString& bsChecksum);
+  void Update(const CFX_ByteStringC& bsText);
+
+ protected:
+  IFX_SAXReader* m_pSAXReader;
+  uint8_t* m_pByteContext;
+  CFX_ByteString m_bsChecksum;
+};
+
+#endif  // XFA_FXFA_APP_XFA_CHECKSUM_H_
diff --git a/xfa/fxfa/app/xfa_ffapp.cpp b/xfa/fxfa/app/xfa_ffapp.cpp
new file mode 100644
index 0000000..8327d1b
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffapp.cpp
@@ -0,0 +1,190 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffapp.h"
+
+#include <algorithm>
+
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_ffdochandler.h"
+#include "xfa/fxfa/app/xfa_ffwidgethandler.h"
+#include "xfa/fxfa/app/xfa_fontmgr.h"
+#include "xfa/fxfa/app/xfa_fwladapter.h"
+#include "xfa/fxfa/app/xfa_fwltheme.h"
+#include "xfa/include/fwl/core/fwl_widgetmgr.h"
+
+CXFA_FileRead::CXFA_FileRead(const CFX_ArrayTemplate<CPDF_Stream*>& streams) {
+  int32_t iCount = streams.GetSize();
+  for (int32_t i = 0; i < iCount; i++) {
+    CPDF_StreamAcc& acc = m_Data.Add();
+    acc.LoadAllData(streams[i]);
+  }
+}
+FX_FILESIZE CXFA_FileRead::GetSize() {
+  FX_DWORD dwSize = 0;
+  int32_t iCount = m_Data.GetSize();
+  for (int32_t i = 0; i < iCount; i++) {
+    CPDF_StreamAcc& acc = m_Data[i];
+    dwSize += acc.GetSize();
+  }
+  return dwSize;
+}
+FX_BOOL CXFA_FileRead::ReadBlock(void* buffer,
+                                 FX_FILESIZE offset,
+                                 size_t size) {
+  int32_t iCount = m_Data.GetSize();
+  int32_t index = 0;
+  while (index < iCount) {
+    CPDF_StreamAcc& acc = m_Data[index];
+    FX_FILESIZE dwSize = acc.GetSize();
+    if (offset < dwSize) {
+      break;
+    }
+    offset -= dwSize;
+    index++;
+  }
+  while (index < iCount) {
+    CPDF_StreamAcc& acc = m_Data[index];
+    FX_DWORD dwSize = acc.GetSize();
+    size_t dwRead = std::min(size, static_cast<size_t>(dwSize - offset));
+    FXSYS_memcpy(buffer, acc.GetData() + offset, dwRead);
+    size -= dwRead;
+    if (size == 0) {
+      return TRUE;
+    }
+    buffer = (uint8_t*)buffer + dwRead;
+    offset = 0;
+    index++;
+  }
+  return FALSE;
+}
+// static
+IXFA_App* IXFA_App::Create(IXFA_AppProvider* pProvider) {
+  return new CXFA_FFApp(pProvider);
+}
+// virtual
+IXFA_App::~IXFA_App() {}
+CXFA_FFApp::CXFA_FFApp(IXFA_AppProvider* pProvider)
+    : m_pDocHandler(nullptr),
+      m_pFWLTheme(nullptr),
+      m_pProvider(pProvider),
+      m_pFontMgr(nullptr),
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+      m_pFontSource(nullptr),
+#endif
+      m_pAdapterWidgetMgr(nullptr),
+      m_pWidgetMgrDelegate(nullptr),
+      m_pFDEFontMgr(nullptr),
+      m_pMenuHandler(nullptr),
+      m_pAdapterThreadMgr(nullptr) {
+  m_pFWLApp = IFWL_App::Create(this);
+  FWL_SetApp(m_pFWLApp);
+  m_pFWLApp->Initialize();
+  IXFA_TimeZoneProvider::Create();
+}
+CXFA_FFApp::~CXFA_FFApp() {
+  delete m_pDocHandler;
+  if (m_pFWLApp) {
+    m_pFWLApp->Finalize();
+    m_pFWLApp->Release();
+    delete m_pFWLApp;
+  }
+  if (m_pFWLTheme)
+    m_pFWLTheme->Release();
+  delete m_pAdapterWidgetMgr;
+  delete m_pAdapterThreadMgr;
+  delete m_pMenuHandler;
+  IXFA_TimeZoneProvider::Destroy();
+  delete m_pFontMgr;
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+  if (m_pFontSource)
+    m_pFontSource->Release();
+#endif
+  if (m_pFDEFontMgr)
+    m_pFDEFontMgr->Release();
+}
+IXFA_MenuHandler* CXFA_FFApp::GetMenuHandler() {
+  if (!m_pMenuHandler) {
+    m_pMenuHandler = new CXFA_FFMenuHandler;
+  }
+  return m_pMenuHandler;
+}
+IXFA_DocHandler* CXFA_FFApp::GetDocHandler() {
+  if (!m_pDocHandler) {
+    m_pDocHandler = new CXFA_FFDocHandler;
+  }
+  return m_pDocHandler;
+}
+IXFA_Doc* CXFA_FFApp::CreateDoc(IXFA_DocProvider* pProvider,
+                                IFX_FileRead* pStream,
+                                FX_BOOL bTakeOverFile) {
+  CXFA_FFDoc* pDoc = new CXFA_FFDoc(this, pProvider);
+  FX_BOOL bSuccess = pDoc->OpenDoc(pStream, bTakeOverFile);
+  if (!bSuccess) {
+    delete pDoc;
+    pDoc = NULL;
+  }
+  return pDoc;
+}
+IXFA_Doc* CXFA_FFApp::CreateDoc(IXFA_DocProvider* pProvider,
+                                CPDF_Document* pPDFDoc) {
+  if (pPDFDoc == NULL) {
+    return NULL;
+  }
+  CXFA_FFDoc* pDoc = new CXFA_FFDoc(this, pProvider);
+  FX_BOOL bSuccess = pDoc->OpenDoc(pPDFDoc);
+  if (!bSuccess) {
+    delete pDoc;
+    pDoc = NULL;
+  }
+  return pDoc;
+}
+
+void CXFA_FFApp::SetDefaultFontMgr(IXFA_FontMgr* pFontMgr) {
+  if (!m_pFontMgr) {
+    m_pFontMgr = new CXFA_FontMgr();
+  }
+  m_pFontMgr->SetDefFontMgr(pFontMgr);
+}
+CXFA_FontMgr* CXFA_FFApp::GetXFAFontMgr() {
+  return m_pFontMgr;
+}
+IFX_FontMgr* CXFA_FFApp::GetFDEFontMgr() {
+  if (!m_pFDEFontMgr) {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+    m_pFDEFontMgr = IFX_FontMgr::Create(FX_GetDefFontEnumerator());
+#else
+    m_pFontSource = FX_CreateDefaultFontSourceEnum();
+    m_pFDEFontMgr = IFX_FontMgr::Create(m_pFontSource);
+#endif
+  }
+  return m_pFDEFontMgr;
+}
+CXFA_FWLTheme* CXFA_FFApp::GetFWLTheme() {
+  if (!m_pFWLTheme) {
+    m_pFWLTheme = new CXFA_FWLTheme(this);
+  }
+  return m_pFWLTheme;
+}
+IFWL_AdapterWidgetMgr* CXFA_FFApp::GetWidgetMgr(
+    IFWL_WidgetMgrDelegate* pDelegate) {
+  if (!m_pAdapterWidgetMgr) {
+    m_pAdapterWidgetMgr = new CXFA_FWLAdapterWidgetMgr;
+    pDelegate->OnSetCapability(FWL_WGTMGR_DisableThread |
+                               FWL_WGTMGR_DisableForm);
+    m_pWidgetMgrDelegate = pDelegate;
+  }
+  return m_pAdapterWidgetMgr;
+}
+IFWL_AdapterThreadMgr* CXFA_FFApp::GetThreadMgr() {
+  if (!m_pAdapterThreadMgr) {
+    m_pAdapterThreadMgr = new CFWL_SDAdapterThreadMgr;
+  }
+  return m_pAdapterThreadMgr;
+}
+IFWL_AdapterTimerMgr* CXFA_FFApp::GetTimerMgr() {
+  return m_pProvider->GetTimerMgr();
+}
diff --git a/xfa/fxfa/app/xfa_ffapp.h b/xfa/fxfa/app/xfa_ffapp.h
new file mode 100644
index 0000000..0374d4a
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffapp.h
@@ -0,0 +1,81 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFAPP_H_
+#define XFA_FXFA_APP_XFA_FFAPP_H_
+
+#include "core/include/fpdfapi/cpdf_stream.h"
+#include "xfa/fgas/font/fgas_font.h"
+#include "xfa/include/fwl/adapter/fwl_adapternative.h"
+#include "xfa/include/fwl/adapter/fwl_sdadapterimp.h"
+#include "xfa/include/fwl/core/fwl_app.h"
+#include "xfa/include/fxfa/fxfa.h"
+
+class CXFA_FWLAdapterWidgetMgr;
+class CXFA_FWLTheme;
+class CXFA_FFDocHandler;
+class CXFA_FFMenuHandler;
+class CXFA_FontMgr;
+
+class CXFA_FileRead : public IFX_FileRead {
+ public:
+  explicit CXFA_FileRead(const CFX_ArrayTemplate<CPDF_Stream*>& streams);
+
+  virtual FX_FILESIZE GetSize();
+  virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size);
+
+  virtual void Release() { delete this; }
+
+ protected:
+  CFX_ObjectArray<CPDF_StreamAcc> m_Data;
+};
+
+class CXFA_FFApp : public IXFA_App, public IFWL_AdapterNative {
+ public:
+  CXFA_FFApp(IXFA_AppProvider* pProvider);
+  ~CXFA_FFApp() override;
+
+  // IFXFA_App:
+  IXFA_DocHandler* GetDocHandler() override;
+  IXFA_Doc* CreateDoc(IXFA_DocProvider* pProvider,
+                      IFX_FileRead* pStream,
+                      FX_BOOL bTakeOverFile) override;
+  IXFA_Doc* CreateDoc(IXFA_DocProvider* pProvider,
+                      CPDF_Document* pPDFDoc) override;
+  IXFA_AppProvider* GetAppProvider() override { return m_pProvider; }
+  void SetDefaultFontMgr(IXFA_FontMgr* pFontMgr) override;
+  IXFA_MenuHandler* GetMenuHandler() override;
+
+  // IFWL_AdapterNative:
+  IFWL_AdapterWidgetMgr* GetWidgetMgr(
+      IFWL_WidgetMgrDelegate* pDelegate) override;
+  IFWL_AdapterThreadMgr* GetThreadMgr() override;
+  IFWL_AdapterTimerMgr* GetTimerMgr() override;
+
+  CXFA_FontMgr* GetXFAFontMgr();
+  IFX_FontMgr* GetFDEFontMgr();
+  CXFA_FWLTheme* GetFWLTheme();
+  IFWL_WidgetMgrDelegate* GetWidgetMgrDelegate() {
+    return m_pWidgetMgrDelegate;
+  }
+
+ protected:
+  CXFA_FFDocHandler* m_pDocHandler;
+  IFWL_App* m_pFWLApp;
+  CXFA_FWLTheme* m_pFWLTheme;
+  IXFA_AppProvider* m_pProvider;
+  CXFA_FontMgr* m_pFontMgr;
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+  IFX_FontSourceEnum* m_pFontSource;
+#endif
+  CXFA_FWLAdapterWidgetMgr* m_pAdapterWidgetMgr;
+  IFWL_WidgetMgrDelegate* m_pWidgetMgrDelegate;
+  IFX_FontMgr* m_pFDEFontMgr;
+  CXFA_FFMenuHandler* m_pMenuHandler;
+  CFWL_SDAdapterThreadMgr* m_pAdapterThreadMgr;
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFAPP_H_
diff --git a/xfa/fxfa/app/xfa_ffbarcode.cpp b/xfa/fxfa/app/xfa_ffbarcode.cpp
new file mode 100644
index 0000000..2062ca1
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffbarcode.cpp
@@ -0,0 +1,235 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffbarcode.h"
+
+#include "core/include/fxcrt/fx_ext.h"
+#include "xfa/fxfa/app/xfa_fffield.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_fftextedit.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+#include "xfa/fxfa/app/xfa_fwladapter.h"
+#include "xfa/include/fwl/core/fwl_app.h"
+#include "xfa/include/fwl/lightwidget/barcode.h"
+
+static XFA_LPCBARCODETYPEENUMINFO XFA_GetBarcodeTypeByName(
+    const CFX_WideStringC& wsName);
+CXFA_FFBarcode::CXFA_FFBarcode(CXFA_FFPageView* pPageView,
+                               CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFTextEdit(pPageView, pDataAcc) {}
+CXFA_FFBarcode::~CXFA_FFBarcode() {}
+FX_BOOL CXFA_FFBarcode::LoadWidget() {
+  CFWL_Barcode* pFWLBarcode = CFWL_Barcode::Create();
+  if (pFWLBarcode) {
+    pFWLBarcode->Initialize();
+  }
+  m_pNormalWidget = pFWLBarcode;
+  IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
+  m_pNormalWidget->SetPrivateData(pWidget, this, NULL);
+  IFWL_NoteDriver* pNoteDriver = FWL_GetApp()->GetNoteDriver();
+  pNoteDriver->RegisterEventTarget(pWidget, pWidget);
+  m_pOldDelegate = m_pNormalWidget->SetDelegate(this);
+  m_pNormalWidget->LockUpdate();
+  CFX_WideString wsText;
+  m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display);
+  pFWLBarcode->SetText(wsText);
+  UpdateWidgetProperty();
+  m_pNormalWidget->UnlockUpdate();
+  return CXFA_FFField::LoadWidget();
+}
+void CXFA_FFBarcode::RenderWidget(CFX_Graphics* pGS,
+                                  CFX_Matrix* pMatrix,
+                                  FX_DWORD dwStatus,
+                                  int32_t iRotate) {
+  if (!IsMatchVisibleStatus(dwStatus)) {
+    return;
+  }
+  CFX_Matrix mtRotate;
+  GetRotateMatrix(mtRotate);
+  if (pMatrix) {
+    mtRotate.Concat(*pMatrix);
+  }
+  CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+  CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
+  DrawBorder(pGS, borderUI, m_rtUI, &mtRotate);
+  RenderCaption(pGS, &mtRotate);
+  CFX_RectF rtWidget;
+  m_pNormalWidget->GetWidgetRect(rtWidget);
+  CFX_Matrix mt;
+  mt.Set(1, 0, 0, 1, rtWidget.left, rtWidget.top);
+  mt.Concat(mtRotate);
+  m_pNormalWidget->DrawWidget(pGS, &mt);
+}
+void CXFA_FFBarcode::UpdateWidgetProperty() {
+  CXFA_FFTextEdit::UpdateWidgetProperty();
+  CFWL_Barcode* pBarCodeWidget = (CFWL_Barcode*)m_pNormalWidget;
+  CFX_WideString wsType = GetDataAcc()->GetBarcodeType();
+  XFA_LPCBARCODETYPEENUMINFO pBarcodeTypeInfo =
+      XFA_GetBarcodeTypeByName(wsType);
+  pBarCodeWidget->SetType(pBarcodeTypeInfo->eBCType);
+  CXFA_WidgetAcc* pAcc = GetDataAcc();
+  int32_t intVal;
+  FX_CHAR charVal;
+  FX_BOOL boolVal;
+  FX_FLOAT floatVal;
+  if (pAcc->GetBarcodeAttribute_CharEncoding(intVal)) {
+    pBarCodeWidget->SetCharEncoding((BC_CHAR_ENCODING)intVal);
+  }
+  if (pAcc->GetBarcodeAttribute_Checksum(intVal)) {
+    pBarCodeWidget->SetCalChecksum(intVal);
+  }
+  if (pAcc->GetBarcodeAttribute_DataLength(intVal)) {
+    pBarCodeWidget->SetDataLength(intVal);
+  }
+  if (pAcc->GetBarcodeAttribute_StartChar(charVal)) {
+    pBarCodeWidget->SetStartChar(charVal);
+  }
+  if (pAcc->GetBarcodeAttribute_EndChar(charVal)) {
+    pBarCodeWidget->SetEndChar(charVal);
+  }
+  if (pAcc->GetBarcodeAttribute_ECLevel(intVal)) {
+    pBarCodeWidget->SetErrorCorrectionLevel(intVal);
+  }
+  if (pAcc->GetBarcodeAttribute_ModuleWidth(intVal)) {
+    pBarCodeWidget->SetModuleWidth(intVal);
+  }
+  if (pAcc->GetBarcodeAttribute_ModuleHeight(intVal)) {
+    pBarCodeWidget->SetModuleHeight(intVal);
+  }
+  if (pAcc->GetBarcodeAttribute_PrintChecksum(boolVal)) {
+    pBarCodeWidget->SetPrintChecksum(boolVal);
+  }
+  if (pAcc->GetBarcodeAttribute_TextLocation(intVal)) {
+    pBarCodeWidget->SetTextLocation((BC_TEXT_LOC)intVal);
+  }
+  if (pAcc->GetBarcodeAttribute_Truncate(boolVal)) {
+    pBarCodeWidget->SetTruncated(boolVal);
+  }
+  if (pAcc->GetBarcodeAttribute_WideNarrowRatio(floatVal)) {
+    pBarCodeWidget->SetWideNarrowRatio((int32_t)floatVal);
+  }
+  if (pBarcodeTypeInfo->eName == XFA_BARCODETYPE_code3Of9 ||
+      pBarcodeTypeInfo->eName == XFA_BARCODETYPE_ean8 ||
+      pBarcodeTypeInfo->eName == XFA_BARCODETYPE_ean13 ||
+      pBarcodeTypeInfo->eName == XFA_BARCODETYPE_upcA) {
+    pBarCodeWidget->SetPrintChecksum(TRUE);
+  }
+}
+FX_BOOL CXFA_FFBarcode::OnLButtonDown(FX_DWORD dwFlags,
+                                      FX_FLOAT fx,
+                                      FX_FLOAT fy) {
+  CFWL_Barcode* pBarCodeWidget = (CFWL_Barcode*)m_pNormalWidget;
+  if (!pBarCodeWidget || pBarCodeWidget->IsProtectedType()) {
+    return FALSE;
+  }
+  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
+    return FALSE;
+  }
+  return CXFA_FFTextEdit::OnLButtonDown(dwFlags, fx, fy);
+}
+FX_BOOL CXFA_FFBarcode::OnRButtonDown(FX_DWORD dwFlags,
+                                      FX_FLOAT fx,
+                                      FX_FLOAT fy) {
+  CFWL_Barcode* pBarCodeWidget = (CFWL_Barcode*)m_pNormalWidget;
+  if (!pBarCodeWidget || pBarCodeWidget->IsProtectedType()) {
+    return FALSE;
+  }
+  return CXFA_FFTextEdit::OnRButtonDown(dwFlags, fx, fy);
+}
+extern const XFA_BARCODETYPEENUMINFO g_XFABarCodeTypeEnumData[] = {
+    {0x7fb4a18, L"ean13", XFA_BARCODETYPE_ean13, BC_EAN13},
+    {0x8d13a3d, L"code11", XFA_BARCODETYPE_code11, BC_UNKNOWN},
+    {0x8d149a8, L"code49", XFA_BARCODETYPE_code49, BC_UNKNOWN},
+    {0x8d16347, L"code93", XFA_BARCODETYPE_code93, BC_UNKNOWN},
+    {0x91a92e2, L"upsMaxicode", XFA_BARCODETYPE_upsMaxicode, BC_UNKNOWN},
+    {0xa7d48dc, L"fim", XFA_BARCODETYPE_fim, BC_UNKNOWN},
+    {0xb359fe9, L"msi", XFA_BARCODETYPE_msi, BC_UNKNOWN},
+    {0x121f738c, L"code2Of5Matrix", XFA_BARCODETYPE_code2Of5Matrix, BC_UNKNOWN},
+    {0x15358616, L"ucc128", XFA_BARCODETYPE_ucc128, BC_UNKNOWN},
+    {0x1f4bfa05, L"rfid", XFA_BARCODETYPE_rfid, BC_UNKNOWN},
+    {0x1fda71bc, L"rss14Stacked", XFA_BARCODETYPE_rss14Stacked, BC_UNKNOWN},
+    {0x22065087, L"ean8add2", XFA_BARCODETYPE_ean8add2, BC_UNKNOWN},
+    {0x2206508a, L"ean8add5", XFA_BARCODETYPE_ean8add5, BC_UNKNOWN},
+    {0x2278366c, L"codabar", XFA_BARCODETYPE_codabar, BC_CODABAR},
+    {0x2a039a8d, L"telepen", XFA_BARCODETYPE_telepen, BC_UNKNOWN},
+    {0x323ed337, L"upcApwcd", XFA_BARCODETYPE_upcApwcd, BC_UNKNOWN},
+    {0x347a1846, L"postUSIMB", XFA_BARCODETYPE_postUSIMB, BC_UNKNOWN},
+    {0x391bb836, L"code128", XFA_BARCODETYPE_code128, BC_CODE128},
+    {0x398eddaf, L"dataMatrix", XFA_BARCODETYPE_dataMatrix, BC_DATAMATRIX},
+    {0x3cff60a8, L"upcEadd2", XFA_BARCODETYPE_upcEadd2, BC_UNKNOWN},
+    {0x3cff60ab, L"upcEadd5", XFA_BARCODETYPE_upcEadd5, BC_UNKNOWN},
+    {0x402cb188, L"code2Of5Standard", XFA_BARCODETYPE_code2Of5Standard,
+     BC_UNKNOWN},
+    {0x411764f7, L"aztec", XFA_BARCODETYPE_aztec, BC_UNKNOWN},
+    {0x44d4e84c, L"ean8", XFA_BARCODETYPE_ean8, BC_EAN8},
+    {0x48468902, L"ucc128sscc", XFA_BARCODETYPE_ucc128sscc, BC_UNKNOWN},
+    {0x4880aea4, L"upcAadd2", XFA_BARCODETYPE_upcAadd2, BC_UNKNOWN},
+    {0x4880aea7, L"upcAadd5", XFA_BARCODETYPE_upcAadd5, BC_UNKNOWN},
+    {0x54f18256, L"code2Of5Industrial", XFA_BARCODETYPE_code2Of5Industrial,
+     BC_UNKNOWN},
+    {0x58e15f25, L"rss14Limited", XFA_BARCODETYPE_rss14Limited, BC_UNKNOWN},
+    {0x5c08d1b9, L"postAUSReplyPaid", XFA_BARCODETYPE_postAUSReplyPaid,
+     BC_UNKNOWN},
+    {0x5fa700bd, L"rss14", XFA_BARCODETYPE_rss14, BC_UNKNOWN},
+    {0x631a7e35, L"logmars", XFA_BARCODETYPE_logmars, BC_UNKNOWN},
+    {0x6a236236, L"pdf417", XFA_BARCODETYPE_pdf417, BC_PDF417},
+    {0x6d098ece, L"upcean2", XFA_BARCODETYPE_upcean2, BC_UNKNOWN},
+    {0x6d098ed1, L"upcean5", XFA_BARCODETYPE_upcean5, BC_UNKNOWN},
+    {0x76b04eed, L"code3Of9extended", XFA_BARCODETYPE_code3Of9extended,
+     BC_UNKNOWN},
+    {0x7c7db84a, L"maxicode", XFA_BARCODETYPE_maxicode, BC_UNKNOWN},
+    {0x8266f7f7, L"ucc128random", XFA_BARCODETYPE_ucc128random, BC_UNKNOWN},
+    {0x83eca147, L"postUSDPBC", XFA_BARCODETYPE_postUSDPBC, BC_UNKNOWN},
+    {0x8dd71de0, L"postAUSStandard", XFA_BARCODETYPE_postAUSStandard,
+     BC_UNKNOWN},
+    {0x98adad85, L"plessey", XFA_BARCODETYPE_plessey, BC_UNKNOWN},
+    {0x9f84cce6, L"ean13pwcd", XFA_BARCODETYPE_ean13pwcd, BC_UNKNOWN},
+    {0xb514fbe9, L"upcA", XFA_BARCODETYPE_upcA, BC_UPCA},
+    {0xb514fbed, L"upcE", XFA_BARCODETYPE_upcE, BC_UNKNOWN},
+    {0xb5c6a853, L"ean13add2", XFA_BARCODETYPE_ean13add2, BC_UNKNOWN},
+    {0xb5c6a856, L"ean13add5", XFA_BARCODETYPE_ean13add5, BC_UNKNOWN},
+    {0xb81fc512, L"postUKRM4SCC", XFA_BARCODETYPE_postUKRM4SCC, BC_UNKNOWN},
+    {0xbad34b22, L"code128SSCC", XFA_BARCODETYPE_code128SSCC, BC_UNKNOWN},
+    {0xbfbe0cf6, L"postUS5Zip", XFA_BARCODETYPE_postUS5Zip, BC_UNKNOWN},
+    {0xc56618e8, L"pdf417macro", XFA_BARCODETYPE_pdf417macro, BC_UNKNOWN},
+    {0xca730f8a, L"code2Of5Interleaved", XFA_BARCODETYPE_code2Of5Interleaved,
+     BC_UNKNOWN},
+    {0xd0097ac6, L"rss14Expanded", XFA_BARCODETYPE_rss14Expanded, BC_UNKNOWN},
+    {0xd25a0240, L"postAUSCust2", XFA_BARCODETYPE_postAUSCust2, BC_UNKNOWN},
+    {0xd25a0241, L"postAUSCust3", XFA_BARCODETYPE_postAUSCust3, BC_UNKNOWN},
+    {0xd53ed3e7, L"rss14Truncated", XFA_BARCODETYPE_rss14Truncated, BC_UNKNOWN},
+    {0xe72bcd57, L"code128A", XFA_BARCODETYPE_code128A, BC_UNKNOWN},
+    {0xe72bcd58, L"code128B", XFA_BARCODETYPE_code128B, BC_CODE128_B},
+    {0xe72bcd59, L"code128C", XFA_BARCODETYPE_code128C, BC_CODE128_C},
+    {0xee83c50f, L"rss14StackedOmni", XFA_BARCODETYPE_rss14StackedOmni,
+     BC_UNKNOWN},
+    {0xf2a18f7e, L"QRCode", XFA_BARCODETYPE_QRCode, BC_QR_CODE},
+    {0xfaeaf37f, L"postUSStandard", XFA_BARCODETYPE_postUSStandard, BC_UNKNOWN},
+    {0xfb48155c, L"code3Of9", XFA_BARCODETYPE_code3Of9, BC_CODE39},
+};
+extern const int32_t g_iXFABarcodeTypeCount =
+    sizeof(g_XFABarCodeTypeEnumData) / sizeof(XFA_BARCODETYPEENUMINFO);
+static XFA_LPCBARCODETYPEENUMINFO XFA_GetBarcodeTypeByName(
+    const CFX_WideStringC& wsName) {
+  int32_t iLength = wsName.GetLength();
+  if (iLength == 0) {
+    return NULL;
+  }
+  uint32_t uHash = FX_HashCode_String_GetW(wsName.GetPtr(), iLength, TRUE);
+  int32_t iStart = 0, iEnd = g_iXFABarcodeTypeCount - 1;
+  do {
+    int32_t iMid = (iStart + iEnd) / 2;
+    XFA_LPCBARCODETYPEENUMINFO pInfo = g_XFABarCodeTypeEnumData + iMid;
+    if (uHash == pInfo->uHash) {
+      return pInfo;
+    } else if (uHash < pInfo->uHash) {
+      iEnd = iMid - 1;
+    } else {
+      iStart = iMid + 1;
+    }
+  } while (iStart <= iEnd);
+  return NULL;
+}
diff --git a/xfa/fxfa/app/xfa_ffbarcode.h b/xfa/fxfa/app/xfa_ffbarcode.h
new file mode 100644
index 0000000..114a492
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffbarcode.h
@@ -0,0 +1,101 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFBARCODE_H_
+#define XFA_FXFA_APP_XFA_FFBARCODE_H_
+
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_fftextedit.h"
+#include "xfa/include/fxbarcode/BC_BarCode.h"
+
+class CXFA_FFBarcode : public CXFA_FFTextEdit {
+ public:
+  CXFA_FFBarcode(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFBarcode();
+  virtual FX_BOOL LoadWidget();
+  virtual void RenderWidget(CFX_Graphics* pGS,
+                            CFX_Matrix* pMatrix = NULL,
+                            FX_DWORD dwStatus = 0,
+                            int32_t iRotate = 0);
+  virtual void UpdateWidgetProperty();
+  virtual FX_BOOL OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnRButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+};
+
+enum XFA_BARCODETYPEENUM {
+  XFA_BARCODETYPE_aztec,
+  XFA_BARCODETYPE_codabar,
+  XFA_BARCODETYPE_code11,
+  XFA_BARCODETYPE_code128,
+  XFA_BARCODETYPE_code128A,
+  XFA_BARCODETYPE_code128B,
+  XFA_BARCODETYPE_code128C,
+  XFA_BARCODETYPE_code128SSCC,
+  XFA_BARCODETYPE_code2Of5Industrial,
+  XFA_BARCODETYPE_code2Of5Interleaved,
+  XFA_BARCODETYPE_code2Of5Matrix,
+  XFA_BARCODETYPE_code2Of5Standard,
+  XFA_BARCODETYPE_code3Of9,
+  XFA_BARCODETYPE_code3Of9extended,
+  XFA_BARCODETYPE_code49,
+  XFA_BARCODETYPE_code93,
+  XFA_BARCODETYPE_dataMatrix,
+  XFA_BARCODETYPE_ean13,
+  XFA_BARCODETYPE_ean13add2,
+  XFA_BARCODETYPE_ean13add5,
+  XFA_BARCODETYPE_ean13pwcd,
+  XFA_BARCODETYPE_ean8,
+  XFA_BARCODETYPE_ean8add2,
+  XFA_BARCODETYPE_ean8add5,
+  XFA_BARCODETYPE_fim,
+  XFA_BARCODETYPE_logmars,
+  XFA_BARCODETYPE_maxicode,
+  XFA_BARCODETYPE_msi,
+  XFA_BARCODETYPE_pdf417,
+  XFA_BARCODETYPE_pdf417macro,
+  XFA_BARCODETYPE_plessey,
+  XFA_BARCODETYPE_postAUSCust2,
+  XFA_BARCODETYPE_postAUSCust3,
+  XFA_BARCODETYPE_postAUSReplyPaid,
+  XFA_BARCODETYPE_postAUSStandard,
+  XFA_BARCODETYPE_postUKRM4SCC,
+  XFA_BARCODETYPE_postUS5Zip,
+  XFA_BARCODETYPE_postUSDPBC,
+  XFA_BARCODETYPE_postUSIMB,
+  XFA_BARCODETYPE_postUSStandard,
+  XFA_BARCODETYPE_QRCode,
+  XFA_BARCODETYPE_rfid,
+  XFA_BARCODETYPE_rss14,
+  XFA_BARCODETYPE_rss14Expanded,
+  XFA_BARCODETYPE_rss14Limited,
+  XFA_BARCODETYPE_rss14Stacked,
+  XFA_BARCODETYPE_rss14StackedOmni,
+  XFA_BARCODETYPE_rss14Truncated,
+  XFA_BARCODETYPE_telepen,
+  XFA_BARCODETYPE_ucc128,
+  XFA_BARCODETYPE_ucc128random,
+  XFA_BARCODETYPE_ucc128sscc,
+  XFA_BARCODETYPE_upcA,
+  XFA_BARCODETYPE_upcAadd2,
+  XFA_BARCODETYPE_upcAadd5,
+  XFA_BARCODETYPE_upcApwcd,
+  XFA_BARCODETYPE_upcE,
+  XFA_BARCODETYPE_upcEadd2,
+  XFA_BARCODETYPE_upcEadd5,
+  XFA_BARCODETYPE_upcean2,
+  XFA_BARCODETYPE_upcean5,
+  XFA_BARCODETYPE_upsMaxicode
+};
+struct XFA_BARCODETYPEENUMINFO {
+  uint32_t uHash;
+  const FX_WCHAR* pName;
+  XFA_BARCODETYPEENUM eName;
+  BC_TYPE eBCType;
+};
+typedef XFA_BARCODETYPEENUMINFO const* XFA_LPCBARCODETYPEENUMINFO;
+extern const XFA_BARCODETYPEENUMINFO g_XFABarCodeTypeEnumData[];
+
+#endif  // XFA_FXFA_APP_XFA_FFBARCODE_H_
diff --git a/xfa/fxfa/app/xfa_ffcheckbutton.cpp b/xfa/fxfa/app/xfa_ffcheckbutton.cpp
new file mode 100644
index 0000000..862a2cd
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffcheckbutton.cpp
@@ -0,0 +1,335 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffcheckbutton.h"
+
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_ffdocview.h"
+#include "xfa/fxfa/app/xfa_ffexclgroup.h"
+#include "xfa/fxfa/app/xfa_fffield.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+#include "xfa/include/fwl/core/fwl_widgetmgr.h"
+#include "xfa/include/fwl/lightwidget/checkbox.h"
+
+CXFA_FFCheckButton::CXFA_FFCheckButton(CXFA_FFPageView* pPageView,
+                                       CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFField(pPageView, pDataAcc), m_pOldDelegate(NULL) {
+  m_rtCheckBox.Set(0, 0, 0, 0);
+}
+CXFA_FFCheckButton::~CXFA_FFCheckButton() {}
+FX_BOOL CXFA_FFCheckButton::LoadWidget() {
+  CFWL_CheckBox* pCheckBox = CFWL_CheckBox::Create();
+  pCheckBox->Initialize();
+  m_pNormalWidget = pCheckBox;
+  IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
+  m_pNormalWidget->SetPrivateData(pWidget, this, NULL);
+  IFWL_NoteDriver* pNoteDriver = FWL_GetApp()->GetNoteDriver();
+  pNoteDriver->RegisterEventTarget(pWidget, pWidget);
+  m_pOldDelegate = m_pNormalWidget->SetDelegate(this);
+  if (m_pDataAcc->IsRadioButton()) {
+    pCheckBox->ModifyStylesEx(FWL_STYLEEXT_CKB_RadioButton, 0xFFFFFFFF);
+  }
+  m_pNormalWidget = (CFWL_Widget*)pCheckBox;
+  m_pNormalWidget->SetPrivateData(m_pNormalWidget->GetWidget(), this, NULL);
+  m_pNormalWidget->LockUpdate();
+  UpdateWidgetProperty();
+  XFA_CHECKSTATE eState = m_pDataAcc->GetCheckState();
+  SetFWLCheckState(eState);
+  m_pNormalWidget->UnlockUpdate();
+  return CXFA_FFField::LoadWidget();
+}
+void CXFA_FFCheckButton::UpdateWidgetProperty() {
+  CFWL_CheckBox* pCheckBox = (CFWL_CheckBox*)m_pNormalWidget;
+  if (!m_pNormalWidget) {
+    return;
+  }
+  FX_FLOAT fSize = m_pDataAcc->GetCheckButtonSize();
+  pCheckBox->SetBoxSize(fSize);
+  FX_DWORD dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCross;
+  int32_t iCheckMark = m_pDataAcc->GetCheckButtonMark();
+  switch (iCheckMark) {
+    case XFA_ATTRIBUTEENUM_Check:
+      dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCheck;
+      break;
+    case XFA_ATTRIBUTEENUM_Circle:
+      dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCircle;
+      break;
+    case XFA_ATTRIBUTEENUM_Cross:
+      break;
+    case XFA_ATTRIBUTEENUM_Diamond:
+      dwStyleEx = FWL_STYLEEXT_CKB_SignShapeDiamond;
+      break;
+    case XFA_ATTRIBUTEENUM_Square:
+      dwStyleEx = FWL_STYLEEXT_CKB_SignShapeSquare;
+      break;
+    case XFA_ATTRIBUTEENUM_Star:
+      dwStyleEx = FWL_STYLEEXT_CKB_SignShapeStar;
+      break;
+    default: {
+      int32_t iShape = m_pDataAcc->GetCheckButtonShape();
+      if (iShape == XFA_ATTRIBUTEENUM_Round) {
+        dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCircle;
+      }
+    } break;
+  }
+  if (m_pDataAcc->IsAllowNeutral()) {
+    dwStyleEx |= FWL_STYLEEXT_CKB_3State;
+  }
+  pCheckBox->ModifyStylesEx(
+      dwStyleEx, FWL_STYLEEXT_CKB_SignShapeMask | FWL_STYLEEXT_CKB_3State);
+}
+FX_BOOL CXFA_FFCheckButton::PerformLayout() {
+  CXFA_FFWidget::PerformLayout();
+  FX_FLOAT fCheckSize = m_pDataAcc->GetCheckButtonSize();
+  CXFA_Margin mgWidget = m_pDataAcc->GetMargin();
+  CFX_RectF rtWidget;
+  GetRectWithoutRotate(rtWidget);
+  if (mgWidget) {
+    XFA_RectWidthoutMargin(rtWidget, mgWidget);
+  }
+  int32_t iCapPlacement = -1;
+  FX_FLOAT fCapReserve = 0;
+  CXFA_Caption caption = m_pDataAcc->GetCaption();
+  if (caption && caption.GetPresence()) {
+    m_rtCaption.Set(rtWidget.left, rtWidget.top, rtWidget.width,
+                    rtWidget.height);
+    iCapPlacement = caption.GetPlacementType();
+    fCapReserve = caption.GetReserve();
+    if (fCapReserve <= 0) {
+      if (iCapPlacement == XFA_ATTRIBUTEENUM_Top ||
+          iCapPlacement == XFA_ATTRIBUTEENUM_Bottom) {
+        fCapReserve = rtWidget.height - fCheckSize;
+      } else {
+        fCapReserve = rtWidget.width - fCheckSize;
+      }
+    }
+  }
+  int32_t iHorzAlign = XFA_ATTRIBUTEENUM_Left;
+  int32_t iVertAlign = XFA_ATTRIBUTEENUM_Top;
+  if (CXFA_Para para = m_pDataAcc->GetPara()) {
+    iHorzAlign = para.GetHorizontalAlign();
+    iVertAlign = para.GetVerticalAlign();
+  }
+  m_rtUI = rtWidget;
+  CXFA_Margin mgCap = caption.GetMargin();
+  switch (iCapPlacement) {
+    case XFA_ATTRIBUTEENUM_Left: {
+      m_rtCaption.width = fCapReserve;
+      CapLeftRightPlacement(mgCap);
+      m_rtUI.width -= fCapReserve;
+      m_rtUI.left += fCapReserve;
+    } break;
+    case XFA_ATTRIBUTEENUM_Top: {
+      m_rtCaption.height = fCapReserve;
+      XFA_RectWidthoutMargin(m_rtCaption, mgCap);
+      m_rtUI.height -= fCapReserve;
+      m_rtUI.top += fCapReserve;
+    } break;
+    case XFA_ATTRIBUTEENUM_Right: {
+      m_rtCaption.left = m_rtCaption.right() - fCapReserve;
+      m_rtCaption.width = fCapReserve;
+      CapLeftRightPlacement(mgCap);
+      m_rtUI.width -= fCapReserve;
+    } break;
+    case XFA_ATTRIBUTEENUM_Bottom: {
+      m_rtCaption.top = m_rtCaption.bottom() - fCapReserve;
+      m_rtCaption.height = fCapReserve;
+      XFA_RectWidthoutMargin(m_rtCaption, mgCap);
+      m_rtUI.height -= fCapReserve;
+    } break;
+    case XFA_ATTRIBUTEENUM_Inline:
+      break;
+    default:
+      iHorzAlign = XFA_ATTRIBUTEENUM_Right;
+      break;
+  }
+  if (iHorzAlign == XFA_ATTRIBUTEENUM_Center) {
+    m_rtUI.left += (m_rtUI.width - fCheckSize) / 2;
+  } else if (iHorzAlign == XFA_ATTRIBUTEENUM_Right) {
+    m_rtUI.left = m_rtUI.right() - fCheckSize;
+  }
+  if (iVertAlign == XFA_ATTRIBUTEENUM_Middle) {
+    m_rtUI.top += (m_rtUI.height - fCheckSize) / 2;
+  } else if (iVertAlign == XFA_ATTRIBUTEENUM_Bottom) {
+    m_rtUI.top = m_rtUI.bottom() - fCheckSize;
+  }
+  m_rtUI.width = fCheckSize;
+  m_rtUI.height = fCheckSize;
+  AddUIMargin(iCapPlacement);
+  m_rtCheckBox = m_rtUI;
+  CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
+  if (borderUI) {
+    CXFA_Margin margin = borderUI.GetMargin();
+    if (margin) {
+      XFA_RectWidthoutMargin(m_rtUI, margin);
+    }
+  }
+  m_rtUI.Normalize();
+  LayoutCaption();
+  SetFWLRect();
+  if (m_pNormalWidget) {
+    m_pNormalWidget->Update();
+  }
+  return TRUE;
+}
+void CXFA_FFCheckButton::CapLeftRightPlacement(CXFA_Margin mgCap) {
+  XFA_RectWidthoutMargin(m_rtCaption, mgCap);
+  if (m_rtCaption.height < 0) {
+    m_rtCaption.top += m_rtCaption.height;
+  }
+  if (m_rtCaption.width < 0) {
+    m_rtCaption.left += m_rtCaption.width;
+    m_rtCaption.width = -m_rtCaption.width;
+  }
+}
+void CXFA_FFCheckButton::AddUIMargin(int32_t iCapPlacement) {
+  CFX_RectF rtUIMargin;
+  m_pDataAcc->GetUIMargin(rtUIMargin);
+  m_rtUI.top -= rtUIMargin.top / 2 - rtUIMargin.height / 2;
+  FX_FLOAT fLeftAddRight = rtUIMargin.left + rtUIMargin.width;
+  FX_FLOAT fTopAddBottom = rtUIMargin.top + rtUIMargin.height;
+  if (m_rtUI.width < fLeftAddRight) {
+    if (iCapPlacement == XFA_ATTRIBUTEENUM_Right ||
+        iCapPlacement == XFA_ATTRIBUTEENUM_Left) {
+      m_rtUI.left -= fLeftAddRight - m_rtUI.width;
+    } else {
+      m_rtUI.left -= 2 * (fLeftAddRight - m_rtUI.width);
+    }
+    m_rtUI.width += 2 * (fLeftAddRight - m_rtUI.width);
+  }
+  if (m_rtUI.height < fTopAddBottom) {
+    if (iCapPlacement == XFA_ATTRIBUTEENUM_Right) {
+      m_rtUI.left -= fTopAddBottom - m_rtUI.height;
+    }
+    m_rtUI.top -= fTopAddBottom - m_rtUI.height;
+    m_rtUI.height += 2 * (fTopAddBottom - m_rtUI.height);
+  }
+}
+void CXFA_FFCheckButton::RenderWidget(CFX_Graphics* pGS,
+                                      CFX_Matrix* pMatrix,
+                                      FX_DWORD dwStatus,
+                                      int32_t iRotate) {
+  if (!IsMatchVisibleStatus(dwStatus)) {
+    return;
+  }
+  CFX_Matrix mtRotate;
+  GetRotateMatrix(mtRotate);
+  if (pMatrix) {
+    mtRotate.Concat(*pMatrix);
+  }
+  CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+  CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
+  DrawBorder(pGS, borderUI, m_rtUI, &mtRotate,
+             m_pDataAcc->GetCheckButtonShape() == XFA_ATTRIBUTEENUM_Round
+                 ? XFA_DRAWBOX_ForceRound
+                 : 0);
+  RenderCaption(pGS, &mtRotate);
+  DrawHighlight(pGS, &mtRotate, dwStatus,
+                m_pDataAcc->GetCheckButtonShape() == XFA_ATTRIBUTEENUM_Round);
+  CFX_Matrix mt;
+  mt.Set(1, 0, 0, 1, m_rtCheckBox.left, m_rtCheckBox.top);
+  mt.Concat(mtRotate);
+  GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget->GetWidget(),
+                                                 pGS, &mt);
+}
+FX_BOOL CXFA_FFCheckButton::OnLButtonUp(FX_DWORD dwFlags,
+                                        FX_FLOAT fx,
+                                        FX_FLOAT fy) {
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  if (!IsButtonDown()) {
+    return FALSE;
+  }
+  SetButtonDown(FALSE);
+  CFWL_MsgMouse ms;
+  ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonUp;
+  ms.m_dwFlags = dwFlags;
+  ms.m_fx = fx;
+  ms.m_fy = fy;
+  FWLToClient(ms.m_fx, ms.m_fy);
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  TranslateFWLMessage(&ms);
+  return TRUE;
+}
+XFA_CHECKSTATE CXFA_FFCheckButton::FWLState2XFAState() {
+  XFA_CHECKSTATE eCheckState = XFA_CHECKSTATE_Off;
+  FX_DWORD dwState = m_pNormalWidget->GetStates();
+  if (dwState & FWL_STATE_CKB_Checked) {
+    eCheckState = XFA_CHECKSTATE_On;
+  } else if (dwState & FWL_STATE_CKB_Neutral) {
+    eCheckState = XFA_CHECKSTATE_Neutral;
+  }
+  return eCheckState;
+}
+FX_BOOL CXFA_FFCheckButton::CommitData() {
+  XFA_CHECKSTATE eCheckState = FWLState2XFAState();
+  m_pDataAcc->SetCheckState(eCheckState, TRUE);
+  return TRUE;
+}
+FX_BOOL CXFA_FFCheckButton::IsDataChanged() {
+  XFA_CHECKSTATE eCheckState = FWLState2XFAState();
+  return m_pDataAcc->GetCheckState() != eCheckState;
+}
+void CXFA_FFCheckButton::SetFWLCheckState(XFA_CHECKSTATE eCheckState) {
+  if (eCheckState == XFA_CHECKSTATE_Neutral) {
+    m_pNormalWidget->SetStates(FWL_STATE_CKB_Neutral, TRUE);
+  } else {
+    m_pNormalWidget->SetStates(FWL_STATE_CKB_Checked,
+                               eCheckState == XFA_CHECKSTATE_On);
+  }
+}
+FX_BOOL CXFA_FFCheckButton::UpdateFWLData() {
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  XFA_CHECKSTATE eState = m_pDataAcc->GetCheckState();
+  SetFWLCheckState(eState);
+  m_pNormalWidget->Update();
+  return TRUE;
+}
+int32_t CXFA_FFCheckButton::OnProcessMessage(CFWL_Message* pMessage) {
+  return m_pOldDelegate->OnProcessMessage(pMessage);
+}
+FWL_ERR CXFA_FFCheckButton::OnProcessEvent(CFWL_Event* pEvent) {
+  CXFA_FFField::OnProcessEvent(pEvent);
+  FX_DWORD dwEventID = pEvent->GetClassID();
+  switch (dwEventID) {
+    case FWL_EVTHASH_CKB_CheckStateChanged: {
+      CXFA_EventParam eParam;
+      eParam.m_eType = XFA_EVENT_Change;
+      m_pDataAcc->GetValue(eParam.m_wsNewText, XFA_VALUEPICTURE_Raw);
+      CXFA_WidgetAcc* pFFExclGroup = m_pDataAcc->GetExclGroup();
+      if (ProcessCommittedData()) {
+        eParam.m_pTarget = pFFExclGroup;
+        if (pFFExclGroup) {
+          m_pDocView->AddValidateWidget(pFFExclGroup);
+          m_pDocView->AddCalculateWidgetAcc(pFFExclGroup);
+          pFFExclGroup->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
+        }
+        eParam.m_pTarget = m_pDataAcc;
+        m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
+      } else {
+        SetFWLCheckState(m_pDataAcc->GetCheckState());
+      }
+      if (pFFExclGroup) {
+        eParam.m_pTarget = pFFExclGroup;
+        pFFExclGroup->ProcessEvent(XFA_ATTRIBUTEENUM_Click, &eParam);
+      }
+      eParam.m_pTarget = m_pDataAcc;
+      m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Click, &eParam);
+      break;
+    }
+    default: {}
+  }
+  return m_pOldDelegate->OnProcessEvent(pEvent);
+}
+FWL_ERR CXFA_FFCheckButton::OnDrawWidget(CFX_Graphics* pGraphics,
+                                         const CFX_Matrix* pMatrix) {
+  return m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix);
+}
diff --git a/xfa/fxfa/app/xfa_ffcheckbutton.h b/xfa/fxfa/app/xfa_ffcheckbutton.h
new file mode 100644
index 0000000..8527365
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffcheckbutton.h
@@ -0,0 +1,43 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFCHECKBUTTON_H_
+#define XFA_FXFA_APP_XFA_FFCHECKBUTTON_H_
+
+#include "xfa/fxfa/app/xfa_fffield.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+
+class CXFA_FFCheckButton : public CXFA_FFField {
+ public:
+  CXFA_FFCheckButton(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFCheckButton();
+  virtual void RenderWidget(CFX_Graphics* pGS,
+                            CFX_Matrix* pMatrix = NULL,
+                            FX_DWORD dwStatus = 0,
+                            int32_t iRotate = 0);
+
+  virtual FX_BOOL LoadWidget();
+  virtual FX_BOOL PerformLayout();
+  virtual FX_BOOL UpdateFWLData();
+  virtual void UpdateWidgetProperty();
+  virtual FX_BOOL OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  void SetFWLCheckState(XFA_CHECKSTATE eCheckState);
+  virtual int32_t OnProcessMessage(CFWL_Message* pMessage);
+  virtual FWL_ERR OnProcessEvent(CFWL_Event* pEvent);
+  virtual FWL_ERR OnDrawWidget(CFX_Graphics* pGraphics,
+                               const CFX_Matrix* pMatrix = NULL);
+
+ protected:
+  virtual FX_BOOL CommitData();
+  virtual FX_BOOL IsDataChanged();
+  void CapLeftRightPlacement(CXFA_Margin mgCap);
+  void AddUIMargin(int32_t iCapPlacement);
+  XFA_CHECKSTATE FWLState2XFAState();
+  IFWL_WidgetDelegate* m_pOldDelegate;
+  CFX_RectF m_rtCheckBox;
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFCHECKBUTTON_H_
diff --git a/xfa/fxfa/app/xfa_ffchoicelist.cpp b/xfa/fxfa/app/xfa_ffchoicelist.cpp
new file mode 100644
index 0000000..2789e07
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffchoicelist.cpp
@@ -0,0 +1,530 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffchoicelist.h"
+
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_ffdocview.h"
+#include "xfa/fxfa/app/xfa_fffield.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+#include "xfa/fxfa/app/xfa_fwladapter.h"
+#include "xfa/include/fwl/basewidget/fwl_edit.h"
+#include "xfa/include/fwl/core/fwl_app.h"
+#include "xfa/include/fwl/lightwidget/combobox.h"
+#include "xfa/include/fwl/lightwidget/listbox.h"
+
+CXFA_FFListBox::CXFA_FFListBox(CXFA_FFPageView* pPageView,
+                               CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFField(pPageView, pDataAcc), m_pOldDelegate(NULL) {}
+CXFA_FFListBox::~CXFA_FFListBox() {
+  if (m_pNormalWidget) {
+    IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
+    IFWL_NoteDriver* pNoteDriver = FWL_GetApp()->GetNoteDriver();
+    pNoteDriver->UnregisterEventTarget(pWidget);
+  }
+}
+FX_BOOL CXFA_FFListBox::LoadWidget() {
+  CFWL_ListBox* pListBox = CFWL_ListBox::Create();
+  pListBox->Initialize();
+  pListBox->ModifyStyles(FWL_WGTSTYLE_VScroll | FWL_WGTSTYLE_NoBackground,
+                         0xFFFFFFFF);
+  m_pNormalWidget = (CFWL_Widget*)pListBox;
+  IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
+  m_pNormalWidget->SetPrivateData(pWidget, this, NULL);
+  IFWL_NoteDriver* pNoteDriver = FWL_GetApp()->GetNoteDriver();
+  pNoteDriver->RegisterEventTarget(pWidget, pWidget);
+  m_pOldDelegate = m_pNormalWidget->SetDelegate(this);
+  m_pNormalWidget->LockUpdate();
+  CFX_WideStringArray wsLabelArray;
+  m_pDataAcc->GetChoiceListItems(wsLabelArray, FALSE);
+  int32_t iItems = wsLabelArray.GetSize();
+  for (int32_t i = 0; i < iItems; i++) {
+    pListBox->AddString(wsLabelArray[i]);
+  }
+  FX_DWORD dwExtendedStyle = FWL_STYLEEXT_LTB_ShowScrollBarFocus;
+  if (m_pDataAcc->GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
+    dwExtendedStyle |= FWL_STYLEEXT_LTB_MultiSelection;
+  }
+  dwExtendedStyle |= GetAlignment();
+  m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
+  CFX_Int32Array iSelArray;
+  m_pDataAcc->GetSelectedItems(iSelArray);
+  int32_t iSelCount = iSelArray.GetSize();
+  for (int32_t j = 0; j < iSelCount; j++) {
+    FWL_HLISTITEM item = pListBox->GetItem(iSelArray[j]);
+    pListBox->SetSelItem(item, TRUE);
+  }
+  m_pNormalWidget->UnlockUpdate();
+  return CXFA_FFField::LoadWidget();
+}
+FX_BOOL CXFA_FFListBox::OnKillFocus(CXFA_FFWidget* pNewFocus) {
+  FX_BOOL flag = ProcessCommittedData();
+  if (!flag) {
+    UpdateFWLData();
+  }
+  CXFA_FFField::OnKillFocus(pNewFocus);
+  return TRUE;
+}
+FX_BOOL CXFA_FFListBox::CommitData() {
+  CFWL_ListBox* pListBox = static_cast<CFWL_ListBox*>(m_pNormalWidget);
+  int32_t iSels = pListBox->CountSelItems();
+  CFX_Int32Array iSelArray;
+  for (int32_t i = 0; i < iSels; i++) {
+    iSelArray.Add(pListBox->GetSelIndex(i));
+  }
+  m_pDataAcc->SetSelectdItems(iSelArray, TRUE);
+  return TRUE;
+}
+FX_BOOL CXFA_FFListBox::IsDataChanged() {
+  CFX_Int32Array iSelArray;
+  m_pDataAcc->GetSelectedItems(iSelArray);
+  int32_t iOldSels = iSelArray.GetSize();
+  CFWL_ListBox* pListBox = (CFWL_ListBox*)m_pNormalWidget;
+  int32_t iSels = pListBox->CountSelItems();
+  if (iOldSels == iSels) {
+    int32_t iIndex = 0;
+    for (; iIndex < iSels; iIndex++) {
+      FWL_HLISTITEM hlistItem = pListBox->GetItem(iSelArray[iIndex]);
+      if (!(pListBox->GetItemStates(hlistItem) && FWL_ITEMSTATE_LTB_Selected)) {
+        break;
+      }
+    }
+    if (iIndex == iSels) {
+      return FALSE;
+    }
+  }
+  return TRUE;
+}
+FX_DWORD CXFA_FFListBox::GetAlignment() {
+  FX_DWORD dwExtendedStyle = 0;
+  if (CXFA_Para para = m_pDataAcc->GetPara()) {
+    int32_t iHorz = para.GetHorizontalAlign();
+    switch (iHorz) {
+      case XFA_ATTRIBUTEENUM_Center:
+        dwExtendedStyle |= FWL_STYLEEXT_LTB_CenterAlign;
+        break;
+      case XFA_ATTRIBUTEENUM_Justify:
+        break;
+      case XFA_ATTRIBUTEENUM_JustifyAll:
+        break;
+      case XFA_ATTRIBUTEENUM_Radix:
+        break;
+      case XFA_ATTRIBUTEENUM_Right:
+        dwExtendedStyle |= FWL_STYLEEXT_LTB_RightAlign;
+        break;
+      default:
+        dwExtendedStyle |= FWL_STYLEEXT_LTB_LeftAlign;
+        break;
+    }
+  }
+  return dwExtendedStyle;
+}
+FX_BOOL CXFA_FFListBox::UpdateFWLData() {
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  CFWL_ListBox* pListBox = ((CFWL_ListBox*)m_pNormalWidget);
+  CFX_ArrayTemplate<FWL_HLISTITEM> selItemArray;
+  CFX_Int32Array iSelArray;
+  m_pDataAcc->GetSelectedItems(iSelArray);
+  int32_t iSelCount = iSelArray.GetSize();
+  for (int32_t j = 0; j < iSelCount; j++) {
+    FWL_HLISTITEM lpItemSel = pListBox->GetSelItem(iSelArray[j]);
+    selItemArray.Add(lpItemSel);
+  }
+  pListBox->SetSelItem(pListBox->GetSelItem(-1), FALSE);
+  for (int32_t i = 0; i < iSelCount; i++) {
+    ((CFWL_ListBox*)m_pNormalWidget)->SetSelItem(selItemArray[i], TRUE);
+  }
+  m_pNormalWidget->Update();
+  return TRUE;
+}
+void CXFA_FFListBox::OnSelectChanged(IFWL_Widget* pWidget,
+                                     const CFX_Int32Array& arrSels) {
+  CXFA_EventParam eParam;
+  eParam.m_eType = XFA_EVENT_Change;
+  eParam.m_pTarget = m_pDataAcc;
+  m_pDataAcc->GetValue(eParam.m_wsPrevText, XFA_VALUEPICTURE_Raw);
+  CFWL_ListBox* pListBox = (CFWL_ListBox*)m_pNormalWidget;
+  int32_t iSels = pListBox->CountSelItems();
+  if (iSels > 0) {
+    pListBox->GetItemText(pListBox->GetSelItem(0), eParam.m_wsNewText);
+  }
+  m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
+}
+void CXFA_FFListBox::SetItemState(int32_t nIndex, FX_BOOL bSelected) {
+  FWL_HLISTITEM item = ((CFWL_ListBox*)m_pNormalWidget)->GetSelItem(nIndex);
+  ((CFWL_ListBox*)m_pNormalWidget)->SetSelItem(item, bSelected);
+  m_pNormalWidget->Update();
+  AddInvalidateRect();
+}
+void CXFA_FFListBox::InsertItem(const CFX_WideStringC& wsLabel,
+                                int32_t nIndex) {
+  CFX_WideString wsTemp(wsLabel);
+  ((CFWL_ListBox*)m_pNormalWidget)->AddString(wsTemp);
+  m_pNormalWidget->Update();
+  AddInvalidateRect();
+}
+void CXFA_FFListBox::DeleteItem(int32_t nIndex) {
+  if (nIndex < 0) {
+    ((CFWL_ListBox*)m_pNormalWidget)->DeleteAll();
+  } else {
+    ((CFWL_ListBox*)m_pNormalWidget)
+        ->DeleteString(((CFWL_ListBox*)m_pNormalWidget)->GetItem(nIndex));
+  }
+  m_pNormalWidget->Update();
+  AddInvalidateRect();
+}
+int32_t CXFA_FFListBox::OnProcessMessage(CFWL_Message* pMessage) {
+  return m_pOldDelegate->OnProcessMessage(pMessage);
+}
+FWL_ERR CXFA_FFListBox::OnProcessEvent(CFWL_Event* pEvent) {
+  CXFA_FFField::OnProcessEvent(pEvent);
+  FX_DWORD dwEventID = pEvent->GetClassID();
+  switch (dwEventID) {
+    case FWL_EVTHASH_LTB_SelChanged: {
+      CFX_Int32Array arrSels;
+      OnSelectChanged(m_pNormalWidget->GetWidget(), arrSels);
+      break;
+    }
+    default: {}
+  }
+  return m_pOldDelegate->OnProcessEvent(pEvent);
+}
+FWL_ERR CXFA_FFListBox::OnDrawWidget(CFX_Graphics* pGraphics,
+                                     const CFX_Matrix* pMatrix) {
+  return m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix);
+}
+
+CXFA_FFComboBox::CXFA_FFComboBox(CXFA_FFPageView* pPageView,
+                                 CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFField(pPageView, pDataAcc), m_pOldDelegate(NULL) {}
+
+CXFA_FFComboBox::~CXFA_FFComboBox() {}
+
+FX_BOOL CXFA_FFComboBox::GetBBox(CFX_RectF& rtBox,
+                                 FX_DWORD dwStatus,
+                                 FX_BOOL bDrawFocus) {
+  if (bDrawFocus)
+    return FALSE;
+  return CXFA_FFWidget::GetBBox(rtBox, dwStatus);
+}
+
+FX_BOOL CXFA_FFComboBox::PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy) {
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  CFX_RectF rtWidget;
+  ((CFWL_ComboBox*)m_pNormalWidget)->GetBBox(rtWidget);
+  if (rtWidget.Contains(fx, fy)) {
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_FFComboBox::LoadWidget() {
+  CFWL_ComboBox* pComboBox = CFWL_ComboBox::Create();
+  pComboBox->Initialize();
+  m_pNormalWidget = (CFWL_Widget*)pComboBox;
+  IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
+  m_pNormalWidget->SetPrivateData(pWidget, this, NULL);
+  IFWL_NoteDriver* pNoteDriver = FWL_GetApp()->GetNoteDriver();
+  pNoteDriver->RegisterEventTarget(pWidget, pWidget);
+  m_pOldDelegate = m_pNormalWidget->SetDelegate(this);
+  m_pNormalWidget->LockUpdate();
+  CFX_WideStringArray wsLabelArray;
+  m_pDataAcc->GetChoiceListItems(wsLabelArray, FALSE);
+  int32_t iItems = wsLabelArray.GetSize();
+  for (int32_t i = 0; i < iItems; i++) {
+    pComboBox->AddString(wsLabelArray[i]);
+  }
+  CFX_Int32Array iSelArray;
+  m_pDataAcc->GetSelectedItems(iSelArray);
+  int32_t iSelCount = iSelArray.GetSize();
+  if (iSelCount > 0) {
+    pComboBox->SetCurSel(iSelArray[0]);
+  } else {
+    CFX_WideString wsText;
+    m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Raw);
+    pComboBox->SetEditText(wsText);
+  }
+  UpdateWidgetProperty();
+  m_pNormalWidget->UnlockUpdate();
+  return CXFA_FFField::LoadWidget();
+}
+void CXFA_FFComboBox::UpdateWidgetProperty() {
+  CFWL_ComboBox* pComboBox = (CFWL_ComboBox*)m_pNormalWidget;
+  if (!pComboBox) {
+    return;
+  }
+  FX_DWORD dwExtendedStyle = 0;
+  FX_DWORD dwEditStyles =
+      FWL_STYLEEXT_EDT_ReadOnly | FWL_STYLEEXT_EDT_LastLineHeight;
+  dwExtendedStyle |= UpdateUIProperty();
+  if (m_pDataAcc->IsChoiceListAllowTextEntry()) {
+    dwEditStyles &= ~FWL_STYLEEXT_EDT_ReadOnly;
+    dwExtendedStyle |= FWL_STYLEEXT_CMB_DropDown;
+  }
+  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
+      !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+    dwEditStyles |= FWL_STYLEEXT_EDT_ReadOnly;
+    dwExtendedStyle |= FWL_STYLEEXT_CMB_ReadOnly;
+  }
+  dwExtendedStyle |= GetAlignment();
+  m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
+  if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
+    dwEditStyles |= FWL_STYLEEXT_EDT_AutoHScroll;
+  }
+  pComboBox->EditModifyStylesEx(dwEditStyles, 0xFFFFFFFF);
+}
+FX_BOOL CXFA_FFComboBox::OnRButtonUp(FX_DWORD dwFlags,
+                                     FX_FLOAT fx,
+                                     FX_FLOAT fy) {
+  if (!CXFA_FFField::OnRButtonUp(dwFlags, fx, fy))
+    return FALSE;
+
+  GetDoc()->GetDocProvider()->PopupMenu(this, CFX_PointF(fx, fy), nullptr);
+  return TRUE;
+}
+FX_BOOL CXFA_FFComboBox::OnKillFocus(CXFA_FFWidget* pNewWidget) {
+  FX_BOOL flag = ProcessCommittedData();
+  if (!flag) {
+    UpdateFWLData();
+  }
+  CXFA_FFField::OnKillFocus(pNewWidget);
+  return TRUE;
+}
+void CXFA_FFComboBox::OpenDropDownList() {
+  ((CFWL_ComboBox*)m_pNormalWidget)->OpenDropDownList(TRUE);
+}
+FX_BOOL CXFA_FFComboBox::CommitData() {
+  return m_pDataAcc->SetValue(m_wsNewValue, XFA_VALUEPICTURE_Raw);
+}
+FX_BOOL CXFA_FFComboBox::IsDataChanged() {
+  CFWL_ComboBox* pFWLcombobox = ((CFWL_ComboBox*)m_pNormalWidget);
+  CFX_WideString wsText;
+  pFWLcombobox->GetEditText(wsText);
+  int32_t iCursel = pFWLcombobox->GetCurSel();
+  if (iCursel >= 0) {
+    CFX_WideString wsSel;
+    pFWLcombobox->GetTextByIndex(iCursel, wsSel);
+    if (wsSel == wsText) {
+      m_pDataAcc->GetChoiceListItem(wsText, iCursel, TRUE);
+    }
+  }
+  CFX_WideString wsOldValue;
+  m_pDataAcc->GetValue(wsOldValue, XFA_VALUEPICTURE_Raw);
+  if (wsOldValue != wsText) {
+    m_wsNewValue = wsText;
+    return TRUE;
+  }
+  return FALSE;
+}
+void CXFA_FFComboBox::FWLEventSelChange(CXFA_EventParam* pParam) {
+  pParam->m_eType = XFA_EVENT_Change;
+  pParam->m_pTarget = m_pDataAcc;
+  CFWL_ComboBox* pFWLcombobox = ((CFWL_ComboBox*)m_pNormalWidget);
+  pFWLcombobox->GetEditText(pParam->m_wsNewText);
+  m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, pParam);
+}
+FX_DWORD CXFA_FFComboBox::GetAlignment() {
+  FX_DWORD dwExtendedStyle = 0;
+  if (CXFA_Para para = m_pDataAcc->GetPara()) {
+    int32_t iHorz = para.GetHorizontalAlign();
+    switch (iHorz) {
+      case XFA_ATTRIBUTEENUM_Center:
+        dwExtendedStyle |=
+            FWL_STYLEEXT_CMB_EditHCenter | FWL_STYLEEXT_CMB_ListItemCenterAlign;
+        break;
+      case XFA_ATTRIBUTEENUM_Justify:
+        dwExtendedStyle |= FWL_STYLEEXT_CMB_EditJustified;
+        break;
+      case XFA_ATTRIBUTEENUM_JustifyAll:
+        break;
+      case XFA_ATTRIBUTEENUM_Radix:
+        break;
+      case XFA_ATTRIBUTEENUM_Right:
+        break;
+      default:
+        dwExtendedStyle |=
+            FWL_STYLEEXT_CMB_EditHNear | FWL_STYLEEXT_CMB_ListItemLeftAlign;
+        break;
+    }
+    int32_t iVert = para.GetVerticalAlign();
+    switch (iVert) {
+      case XFA_ATTRIBUTEENUM_Middle:
+        dwExtendedStyle |= FWL_STYLEEXT_CMB_EditVCenter;
+        break;
+      case XFA_ATTRIBUTEENUM_Bottom:
+        dwExtendedStyle |= FWL_STYLEEXT_CMB_EditVFar;
+        break;
+      default:
+        dwExtendedStyle |= FWL_STYLEEXT_CMB_EditVNear;
+        break;
+    }
+  }
+  return dwExtendedStyle;
+}
+FX_BOOL CXFA_FFComboBox::UpdateFWLData() {
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  CFX_Int32Array iSelArray;
+  m_pDataAcc->GetSelectedItems(iSelArray);
+  int32_t iSelCount = iSelArray.GetSize();
+  if (iSelCount > 0) {
+    ((CFWL_ComboBox*)m_pNormalWidget)->SetCurSel(iSelArray[0]);
+  } else {
+    CFX_WideString wsText;
+    ((CFWL_ComboBox*)m_pNormalWidget)->SetCurSel(-1);
+    m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Raw);
+    ((CFWL_ComboBox*)m_pNormalWidget)->SetEditText(wsText);
+  }
+  m_pNormalWidget->Update();
+  return TRUE;
+}
+FX_BOOL CXFA_FFComboBox::CanUndo() {
+  return m_pDataAcc->IsChoiceListAllowTextEntry() &&
+         ((CFWL_ComboBox*)m_pNormalWidget)->EditCanUndo();
+}
+FX_BOOL CXFA_FFComboBox::CanRedo() {
+  return m_pDataAcc->IsChoiceListAllowTextEntry() &&
+         ((CFWL_ComboBox*)m_pNormalWidget)->EditCanRedo();
+}
+FX_BOOL CXFA_FFComboBox::Undo() {
+  return m_pDataAcc->IsChoiceListAllowTextEntry() &&
+         ((CFWL_ComboBox*)m_pNormalWidget)->EditUndo();
+}
+FX_BOOL CXFA_FFComboBox::Redo() {
+  return m_pDataAcc->IsChoiceListAllowTextEntry() &&
+         ((CFWL_ComboBox*)m_pNormalWidget)->EditRedo();
+}
+FX_BOOL CXFA_FFComboBox::CanCopy() {
+  return ((CFWL_ComboBox*)m_pNormalWidget)->EditCanCopy();
+}
+FX_BOOL CXFA_FFComboBox::CanCut() {
+  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
+    return FALSE;
+  }
+  return m_pDataAcc->IsChoiceListAllowTextEntry() &&
+         ((CFWL_ComboBox*)m_pNormalWidget)->EditCanCut();
+}
+FX_BOOL CXFA_FFComboBox::CanPaste() {
+  return m_pDataAcc->IsChoiceListAllowTextEntry() &&
+         (m_pDataAcc->GetAccess() == XFA_ATTRIBUTEENUM_Open);
+}
+FX_BOOL CXFA_FFComboBox::CanSelectAll() {
+  return ((CFWL_ComboBox*)m_pNormalWidget)->EditCanSelectAll();
+}
+FX_BOOL CXFA_FFComboBox::Copy(CFX_WideString& wsCopy) {
+  return ((CFWL_ComboBox*)m_pNormalWidget)->EditCopy(wsCopy);
+}
+FX_BOOL CXFA_FFComboBox::Cut(CFX_WideString& wsCut) {
+  return m_pDataAcc->IsChoiceListAllowTextEntry() &&
+         ((CFWL_ComboBox*)m_pNormalWidget)->EditCut(wsCut);
+}
+FX_BOOL CXFA_FFComboBox::Paste(const CFX_WideString& wsPaste) {
+  return m_pDataAcc->IsChoiceListAllowTextEntry() &&
+         ((CFWL_ComboBox*)m_pNormalWidget)->EditPaste(wsPaste);
+}
+FX_BOOL CXFA_FFComboBox::SelectAll() {
+  return ((CFWL_ComboBox*)m_pNormalWidget)->EditSelectAll();
+}
+FX_BOOL CXFA_FFComboBox::Delete() {
+  return ((CFWL_ComboBox*)m_pNormalWidget)->EditDelete();
+}
+FX_BOOL CXFA_FFComboBox::DeSelect() {
+  return ((CFWL_ComboBox*)m_pNormalWidget)->EditDeSelect();
+}
+void CXFA_FFComboBox::SetItemState(int32_t nIndex, FX_BOOL bSelected) {
+  if (bSelected) {
+    ((CFWL_ComboBox*)m_pNormalWidget)->SetCurSel(nIndex);
+  } else {
+    ((CFWL_ComboBox*)m_pNormalWidget)->SetCurSel(-1);
+  }
+  m_pNormalWidget->Update();
+  AddInvalidateRect();
+}
+void CXFA_FFComboBox::InsertItem(const CFX_WideStringC& wsLabel,
+                                 int32_t nIndex) {
+  ((CFWL_ComboBox*)m_pNormalWidget)->AddString(wsLabel);
+  m_pNormalWidget->Update();
+  AddInvalidateRect();
+}
+void CXFA_FFComboBox::DeleteItem(int32_t nIndex) {
+  if (nIndex < 0) {
+    ((CFWL_ComboBox*)m_pNormalWidget)->RemoveAll();
+  } else {
+    ((CFWL_ComboBox*)m_pNormalWidget)->RemoveAt(nIndex);
+  }
+  m_pNormalWidget->Update();
+  AddInvalidateRect();
+}
+void CXFA_FFComboBox::OnTextChanged(IFWL_Widget* pWidget,
+                                    const CFX_WideString& wsChanged) {
+  CXFA_EventParam eParam;
+  m_pDataAcc->GetValue(eParam.m_wsPrevText, XFA_VALUEPICTURE_Raw);
+  eParam.m_wsChange = wsChanged;
+  FWLEventSelChange(&eParam);
+}
+void CXFA_FFComboBox::OnSelectChanged(IFWL_Widget* pWidget,
+                                      const CFX_Int32Array& arrSels,
+                                      FX_BOOL bLButtonUp) {
+  CXFA_EventParam eParam;
+  m_pDataAcc->GetValue(eParam.m_wsPrevText, XFA_VALUEPICTURE_Raw);
+  FWLEventSelChange(&eParam);
+  if (m_pDataAcc->GetChoiceListCommitOn() == XFA_ATTRIBUTEENUM_Select &&
+      bLButtonUp) {
+    m_pDocView->SetFocusWidgetAcc(NULL);
+  }
+}
+void CXFA_FFComboBox::OnPreOpen(IFWL_Widget* pWidget) {
+  CXFA_EventParam eParam;
+  eParam.m_eType = XFA_EVENT_PreOpen;
+  eParam.m_pTarget = m_pDataAcc;
+  m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_PreOpen, &eParam);
+}
+void CXFA_FFComboBox::OnPostOpen(IFWL_Widget* pWidget) {
+  CXFA_EventParam eParam;
+  eParam.m_eType = XFA_EVENT_PostOpen;
+  eParam.m_pTarget = m_pDataAcc;
+  m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_PostOpen, &eParam);
+}
+
+int32_t CXFA_FFComboBox::OnProcessMessage(CFWL_Message* pMessage) {
+  return m_pOldDelegate->OnProcessMessage(pMessage);
+}
+FWL_ERR CXFA_FFComboBox::OnProcessEvent(CFWL_Event* pEvent) {
+  CXFA_FFField::OnProcessEvent(pEvent);
+  FX_DWORD dwEventID = pEvent->GetClassID();
+  switch (dwEventID) {
+    case FWL_EVTHASH_CMB_SelChanged: {
+      CFWL_EvtCmbSelChanged* postEvent = (CFWL_EvtCmbSelChanged*)pEvent;
+      OnSelectChanged(m_pNormalWidget->GetWidget(), postEvent->iArraySels,
+                      postEvent->bLButtonUp);
+      break;
+    }
+    case FWL_EVTHASH_CMB_EditChanged: {
+      CFX_WideString wsChanged;
+      OnTextChanged(m_pNormalWidget->GetWidget(), wsChanged);
+      break;
+    }
+    case FWL_EVTHASH_CMB_PreDropDown: {
+      OnPreOpen(m_pNormalWidget->GetWidget());
+      break;
+    }
+    case FWL_EVTHASH_CMB_PostDropDown: {
+      OnPostOpen(m_pNormalWidget->GetWidget());
+      break;
+    }
+    default: {}
+  }
+  return m_pOldDelegate->OnProcessEvent(pEvent);
+}
+FWL_ERR CXFA_FFComboBox::OnDrawWidget(CFX_Graphics* pGraphics,
+                                      const CFX_Matrix* pMatrix) {
+  return m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix);
+}
diff --git a/xfa/fxfa/app/xfa_ffchoicelist.h b/xfa/fxfa/app/xfa_ffchoicelist.h
new file mode 100644
index 0000000..1699b18
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffchoicelist.h
@@ -0,0 +1,96 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFCHOICELIST_H_
+#define XFA_FXFA_APP_XFA_FFCHOICELIST_H_
+
+#include "xfa/fxfa/app/xfa_fffield.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+
+class CXFA_FFListBox : public CXFA_FFField {
+ public:
+  CXFA_FFListBox(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFListBox();
+  virtual FX_BOOL LoadWidget();
+  virtual FX_BOOL OnKillFocus(CXFA_FFWidget* pNewWidget);
+
+ protected:
+  virtual FX_BOOL CommitData();
+  virtual FX_BOOL UpdateFWLData();
+  virtual FX_BOOL IsDataChanged();
+  FX_DWORD GetAlignment();
+
+ public:
+  void OnSelectChanged(IFWL_Widget* pWidget, const CFX_Int32Array& arrSels);
+  void SetItemState(int32_t nIndex, FX_BOOL bSelected);
+  void InsertItem(const CFX_WideStringC& wsLabel, int32_t nIndex = -1);
+  void DeleteItem(int32_t nIndex);
+  virtual int32_t OnProcessMessage(CFWL_Message* pMessage);
+  virtual FWL_ERR OnProcessEvent(CFWL_Event* pEvent);
+  virtual FWL_ERR OnDrawWidget(CFX_Graphics* pGraphics,
+                               const CFX_Matrix* pMatrix = NULL);
+
+ protected:
+  IFWL_WidgetDelegate* m_pOldDelegate;
+};
+class CXFA_FFComboBox : public CXFA_FFField {
+ public:
+  CXFA_FFComboBox(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFComboBox();
+  virtual FX_BOOL GetBBox(CFX_RectF& rtBox,
+                          FX_DWORD dwStatus,
+                          FX_BOOL bDrawFocus = FALSE);
+  virtual FX_BOOL LoadWidget();
+  virtual void UpdateWidgetProperty();
+  virtual FX_BOOL OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnKillFocus(CXFA_FFWidget* pNewWidget);
+  virtual FX_BOOL CanUndo();
+  virtual FX_BOOL CanRedo();
+  virtual FX_BOOL Undo();
+  virtual FX_BOOL Redo();
+
+  virtual FX_BOOL CanCopy();
+  virtual FX_BOOL CanCut();
+  virtual FX_BOOL CanPaste();
+  virtual FX_BOOL CanSelectAll();
+  virtual FX_BOOL Copy(CFX_WideString& wsCopy);
+  virtual FX_BOOL Cut(CFX_WideString& wsCut);
+  virtual FX_BOOL Paste(const CFX_WideString& wsPaste);
+  virtual FX_BOOL SelectAll();
+  virtual FX_BOOL Delete();
+  virtual FX_BOOL DeSelect();
+  void OpenDropDownList();
+
+ protected:
+  virtual FX_BOOL PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL CommitData();
+  virtual FX_BOOL UpdateFWLData();
+  virtual FX_BOOL IsDataChanged();
+  FX_DWORD GetAlignment();
+  void FWLEventSelChange(CXFA_EventParam* pParam);
+
+  CFX_WideString m_wsNewValue;
+
+ public:
+  void OnTextChanged(IFWL_Widget* pWidget, const CFX_WideString& wsChanged);
+  void OnSelectChanged(IFWL_Widget* pWidget,
+                       const CFX_Int32Array& arrSels,
+                       FX_BOOL bLButtonUp);
+  void OnPreOpen(IFWL_Widget* pWidget);
+  void OnPostOpen(IFWL_Widget* pWidget);
+  void SetItemState(int32_t nIndex, FX_BOOL bSelected);
+  void InsertItem(const CFX_WideStringC& wsLabel, int32_t nIndex = -1);
+  void DeleteItem(int32_t nIndex);
+  virtual int32_t OnProcessMessage(CFWL_Message* pMessage);
+  virtual FWL_ERR OnProcessEvent(CFWL_Event* pEvent);
+  virtual FWL_ERR OnDrawWidget(CFX_Graphics* pGraphics,
+                               const CFX_Matrix* pMatrix = NULL);
+
+ protected:
+  IFWL_WidgetDelegate* m_pOldDelegate;
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFCHOICELIST_H_
diff --git a/xfa/fxfa/app/xfa_ffdoc.cpp b/xfa/fxfa/app/xfa_ffdoc.cpp
new file mode 100644
index 0000000..e33dd4f
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffdoc.cpp
@@ -0,0 +1,431 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+
+#include "core/include/fpdfapi/cpdf_array.h"
+#include "core/include/fpdfapi/cpdf_document.h"
+#include "core/include/fpdfdoc/fpdf_doc.h"
+#include "core/include/fxcrt/fx_ext.h"
+#include "xfa/fgas/crt/fgas_algorithm.h"
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/fxfa/app/xfa_ffdocview.h"
+#include "xfa/fxfa/app/xfa_ffnotify.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+#include "xfa/fxfa/app/xfa_fontmgr.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/include/fwl/core/fwl_note.h"
+
+CXFA_FFDoc::CXFA_FFDoc(CXFA_FFApp* pApp, IXFA_DocProvider* pDocProvider)
+    : m_pDocProvider(pDocProvider),
+      m_pDocument(nullptr),
+      m_pStream(nullptr),
+      m_pApp(pApp),
+      m_pNotify(nullptr),
+      m_pPDFDoc(nullptr),
+      m_dwDocType(XFA_DOCTYPE_Static),
+      m_bOwnStream(TRUE) {}
+CXFA_FFDoc::~CXFA_FFDoc() {
+  CloseDoc();
+}
+FX_DWORD CXFA_FFDoc::GetDocType() {
+  return m_dwDocType;
+}
+int32_t CXFA_FFDoc::StartLoad() {
+  m_pNotify = new CXFA_FFNotify(this);
+  IXFA_DocParser* pDocParser = IXFA_DocParser::Create(m_pNotify);
+  int32_t iStatus = pDocParser->StartParse(m_pStream);
+  m_pDocument = pDocParser->GetDocument();
+  return iStatus;
+}
+FX_BOOL XFA_GetPDFContentsFromPDFXML(IFDE_XMLNode* pPDFElement,
+                                     uint8_t*& pByteBuffer,
+                                     int32_t& iBufferSize) {
+  IFDE_XMLElement* pDocumentElement = NULL;
+  for (IFDE_XMLNode* pXMLNode =
+           pPDFElement->GetNodeItem(IFDE_XMLNode::FirstChild);
+       pXMLNode; pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+    if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
+      CFX_WideString wsTagName;
+      IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLNode;
+      pXMLElement->GetTagName(wsTagName);
+      if (wsTagName.Equal(FX_WSTRC(L"document"))) {
+        pDocumentElement = pXMLElement;
+        break;
+      }
+    }
+  }
+  if (!pDocumentElement) {
+    return FALSE;
+  }
+  IFDE_XMLElement* pChunkElement = NULL;
+  for (IFDE_XMLNode* pXMLNode =
+           pDocumentElement->GetNodeItem(IFDE_XMLNode::FirstChild);
+       pXMLNode; pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+    if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
+      CFX_WideString wsTagName;
+      IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLNode;
+      pXMLElement->GetTagName(wsTagName);
+      if (wsTagName.Equal(FX_WSTRC(L"chunk"))) {
+        pChunkElement = pXMLElement;
+        break;
+      }
+    }
+  }
+  if (!pChunkElement) {
+    return FALSE;
+  }
+  CFX_WideString wsPDFContent;
+  pChunkElement->GetTextData(wsPDFContent);
+  iBufferSize = FX_Base64DecodeW(wsPDFContent, wsPDFContent.GetLength(), NULL);
+  pByteBuffer = FX_Alloc(uint8_t, iBufferSize + 1);
+  pByteBuffer[iBufferSize] = '0';  // FIXME: I bet this is wrong.
+  FX_Base64DecodeW(wsPDFContent, wsPDFContent.GetLength(), pByteBuffer);
+  return TRUE;
+}
+void XFA_XPDPacket_MergeRootNode(CXFA_Node* pOriginRoot, CXFA_Node* pNewRoot) {
+  CXFA_Node* pChildNode = pNewRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
+  while (pChildNode) {
+    CXFA_Node* pOriginChild =
+        pOriginRoot->GetFirstChildByName(pChildNode->GetNameHash());
+    if (pOriginChild) {
+      pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+    } else {
+      CXFA_Node* pNextSibling =
+          pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+      pNewRoot->RemoveChild(pChildNode);
+      pOriginRoot->InsertChild(pChildNode);
+      pChildNode = pNextSibling;
+      pNextSibling = NULL;
+    }
+  }
+}
+int32_t CXFA_FFDoc::DoLoad(IFX_Pause* pPause) {
+  int32_t iStatus = m_pDocument->GetParser()->DoParse(pPause);
+  if (iStatus == XFA_PARSESTATUS_Done && !m_pPDFDoc) {
+    CXFA_Node* pPDFNode = ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Pdf));
+    if (!pPDFNode) {
+      return XFA_PARSESTATUS_SyntaxErr;
+    }
+    IFDE_XMLNode* pPDFXML = pPDFNode->GetXMLMappingNode();
+    if (pPDFXML->GetType() != FDE_XMLNODE_Element) {
+      return XFA_PARSESTATUS_SyntaxErr;
+    }
+    int32_t iBufferSize = 0;
+    uint8_t* pByteBuffer = NULL;
+    IFX_FileRead* pXFAReader = NULL;
+    if (XFA_GetPDFContentsFromPDFXML(pPDFXML, pByteBuffer, iBufferSize)) {
+      pXFAReader = FX_CreateMemoryStream(pByteBuffer, iBufferSize, TRUE);
+    } else {
+      CFX_WideString wsHref;
+      ((IFDE_XMLElement*)pPDFXML)->GetString(L"href", wsHref);
+      if (!wsHref.IsEmpty()) {
+        pXFAReader = GetDocProvider()->OpenLinkedFile(this, wsHref);
+      }
+    }
+    if (!pXFAReader) {
+      return XFA_PARSESTATUS_SyntaxErr;
+    }
+    CPDF_Document* pPDFDocument =
+        GetDocProvider()->OpenPDF(this, pXFAReader, TRUE);
+    FXSYS_assert(!m_pPDFDoc);
+    if (!OpenDoc(pPDFDocument)) {
+      return XFA_PARSESTATUS_SyntaxErr;
+    }
+    IXFA_Parser* pParser = IXFA_Parser::Create(m_pDocument, TRUE);
+    if (!pParser) {
+      return XFA_PARSESTATUS_SyntaxErr;
+    }
+    CXFA_Node* pRootNode = NULL;
+    if (pParser->StartParse(m_pStream) == XFA_PARSESTATUS_Ready &&
+        pParser->DoParse(NULL) == XFA_PARSESTATUS_Done) {
+      pRootNode = pParser->GetRootNode();
+    }
+    if (pRootNode && m_pDocument->GetRoot()) {
+      XFA_XPDPacket_MergeRootNode(m_pDocument->GetRoot(), pRootNode);
+      iStatus = XFA_PARSESTATUS_Done;
+    } else {
+      iStatus = XFA_PARSESTATUS_StatusErr;
+    }
+    pParser->Release();
+    pParser = NULL;
+  }
+  return iStatus;
+}
+void CXFA_FFDoc::StopLoad() {
+  m_pApp->GetXFAFontMgr()->LoadDocFonts(this);
+  m_dwDocType = XFA_DOCTYPE_Static;
+  CXFA_Node* pConfig = ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Config));
+  if (!pConfig) {
+    return;
+  }
+  CXFA_Node* pAcrobat = pConfig->GetFirstChildByClass(XFA_ELEMENT_Acrobat);
+  if (!pAcrobat) {
+    return;
+  }
+  CXFA_Node* pAcrobat7 = pAcrobat->GetFirstChildByClass(XFA_ELEMENT_Acrobat7);
+  if (!pAcrobat7) {
+    return;
+  }
+  CXFA_Node* pDynamicRender =
+      pAcrobat7->GetFirstChildByClass(XFA_ELEMENT_DynamicRender);
+  if (!pDynamicRender) {
+    return;
+  }
+  CFX_WideString wsType;
+  if (pDynamicRender->TryContent(wsType) && wsType == FX_WSTRC(L"required")) {
+    m_dwDocType = XFA_DOCTYPE_Dynamic;
+  }
+}
+IXFA_DocView* CXFA_FFDoc::CreateDocView(FX_DWORD dwView) {
+  CXFA_FFDocView* pDocView =
+      (CXFA_FFDocView*)m_mapTypeToDocView.GetValueAt((void*)(uintptr_t)dwView);
+  if (!pDocView) {
+    pDocView = new CXFA_FFDocView(this);
+    m_mapTypeToDocView.SetAt((void*)(uintptr_t)dwView, pDocView);
+  }
+  return pDocView;
+}
+CXFA_FFDocView* CXFA_FFDoc::GetDocView(IXFA_DocLayout* pLayout) {
+  FX_POSITION ps = m_mapTypeToDocView.GetStartPosition();
+  while (ps) {
+    void* pType;
+    CXFA_FFDocView* pDocView;
+    m_mapTypeToDocView.GetNextAssoc(ps, pType, (void*&)pDocView);
+    if (pDocView->GetXFALayout() == pLayout) {
+      return pDocView;
+    }
+  }
+  return NULL;
+}
+CXFA_FFDocView* CXFA_FFDoc::GetDocView() {
+  FX_POSITION ps = m_mapTypeToDocView.GetStartPosition();
+  if (ps) {
+    void* pType;
+    CXFA_FFDocView* pDocView;
+    m_mapTypeToDocView.GetNextAssoc(ps, pType, (void*&)pDocView);
+    return pDocView;
+  }
+  return NULL;
+}
+FX_BOOL CXFA_FFDoc::OpenDoc(IFX_FileRead* pStream, FX_BOOL bTakeOverFile) {
+  m_bOwnStream = bTakeOverFile;
+  m_pStream = pStream;
+  return TRUE;
+}
+FX_BOOL CXFA_FFDoc::OpenDoc(CPDF_Document* pPDFDoc) {
+  if (pPDFDoc == NULL) {
+    return FALSE;
+  }
+  CPDF_Dictionary* pRoot = pPDFDoc->GetRoot();
+  if (pRoot == NULL) {
+    return FALSE;
+  }
+  CPDF_Dictionary* pAcroForm = pRoot->GetDictBy("AcroForm");
+  if (pAcroForm == NULL) {
+    return FALSE;
+  }
+  CPDF_Object* pElementXFA = pAcroForm->GetElementValue("XFA");
+  if (pElementXFA == NULL) {
+    return FALSE;
+  }
+  CFX_ArrayTemplate<CPDF_Stream*> xfaStreams;
+  if (pElementXFA->IsArray()) {
+    CPDF_Array* pXFAArray = (CPDF_Array*)pElementXFA;
+    FX_DWORD count = pXFAArray->GetCount() / 2;
+    for (FX_DWORD i = 0; i < count; i++) {
+      if (CPDF_Stream* pStream = pXFAArray->GetStreamAt(i * 2 + 1))
+        xfaStreams.Add(pStream);
+    }
+  } else if (pElementXFA->IsStream()) {
+    xfaStreams.Add((CPDF_Stream*)pElementXFA);
+  }
+  if (xfaStreams.GetSize() < 1) {
+    return FALSE;
+  }
+  IFX_FileRead* pFileRead = new CXFA_FileRead(xfaStreams);
+  m_pPDFDoc = pPDFDoc;
+  if (m_pStream) {
+    m_pStream->Release();
+    m_pStream = NULL;
+  }
+  m_pStream = pFileRead;
+  m_bOwnStream = TRUE;
+  return TRUE;
+}
+FX_BOOL CXFA_FFDoc::CloseDoc() {
+  FX_POSITION psClose = m_mapTypeToDocView.GetStartPosition();
+  while (psClose) {
+    void* pType;
+    CXFA_FFDocView* pDocView;
+    m_mapTypeToDocView.GetNextAssoc(psClose, pType, (void*&)pDocView);
+    pDocView->RunDocClose();
+  }
+  if (m_pDocument) {
+    m_pDocument->ClearLayoutData();
+  }
+  FX_POSITION ps = m_mapTypeToDocView.GetStartPosition();
+  while (ps) {
+    void* pType;
+    CXFA_FFDocView* pDocView;
+    m_mapTypeToDocView.GetNextAssoc(ps, pType, (void*&)pDocView);
+    delete pDocView;
+  }
+  m_mapTypeToDocView.RemoveAll();
+  if (m_pDocument) {
+    IXFA_Parser* pParser = m_pDocument->GetParser();
+    pParser->Release();
+    m_pDocument = NULL;
+  }
+  if (m_pNotify) {
+    delete m_pNotify;
+    m_pNotify = NULL;
+  }
+  m_pApp->GetXFAFontMgr()->ReleaseDocFonts(this);
+  if (m_dwDocType != XFA_DOCTYPE_XDP && m_pStream && m_bOwnStream) {
+    m_pStream->Release();
+    m_pStream = NULL;
+  }
+  ps = m_mapNamedImages.GetStartPosition();
+  while (ps) {
+    void* pName;
+    FX_IMAGEDIB_AND_DPI* pImage = NULL;
+    m_mapNamedImages.GetNextAssoc(ps, pName, (void*&)pImage);
+    if (pImage) {
+      delete pImage->pDibSource;
+      pImage->pDibSource = NULL;
+      FX_Free(pImage);
+      pImage = NULL;
+    }
+  }
+  m_mapNamedImages.RemoveAll();
+  IFWL_NoteDriver* pNoteDriver = FWL_GetApp()->GetNoteDriver();
+  pNoteDriver->ClearEventTargets(FALSE);
+  return TRUE;
+}
+void CXFA_FFDoc::SetDocType(FX_DWORD dwType) {
+  m_dwDocType = dwType;
+}
+CPDF_Document* CXFA_FFDoc::GetPDFDoc() {
+  return m_pPDFDoc;
+}
+
+CFX_DIBitmap* CXFA_FFDoc::GetPDFNamedImage(const CFX_WideStringC& wsName,
+                                           int32_t& iImageXDpi,
+                                           int32_t& iImageYDpi) {
+  if (!m_pPDFDoc)
+    return nullptr;
+
+  FX_DWORD dwHash =
+      FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength(), FALSE);
+  FX_IMAGEDIB_AND_DPI* imageDIBDpi = nullptr;
+  if (m_mapNamedImages.Lookup((void*)(uintptr_t)dwHash, (void*&)imageDIBDpi)) {
+    iImageXDpi = imageDIBDpi->iImageXDpi;
+    iImageYDpi = imageDIBDpi->iImageYDpi;
+    return static_cast<CFX_DIBitmap*>(imageDIBDpi->pDibSource);
+  }
+
+  CPDF_Dictionary* pRoot = m_pPDFDoc->GetRoot();
+  if (!pRoot)
+    return nullptr;
+
+  CPDF_Dictionary* pNames = pRoot->GetDictBy("Names");
+  if (!pNames)
+    return nullptr;
+
+  CPDF_Dictionary* pXFAImages = pNames->GetDictBy("XFAImages");
+  if (!pXFAImages)
+    return nullptr;
+
+  CPDF_NameTree nametree(pXFAImages);
+  CFX_ByteString bsName = PDF_EncodeText(wsName.GetPtr(), wsName.GetLength());
+  CPDF_Object* pObject = nametree.LookupValue(bsName);
+  if (!pObject) {
+    int32_t iCount = nametree.GetCount();
+    for (int32_t i = 0; i < iCount; i++) {
+      CFX_ByteString bsTemp;
+      CPDF_Object* pTempObject = nametree.LookupValue(i, bsTemp);
+      if (bsTemp == bsName) {
+        pObject = pTempObject;
+        break;
+      }
+    }
+  }
+
+  if (!pObject || !pObject->IsStream())
+    return nullptr;
+
+  if (!imageDIBDpi) {
+    imageDIBDpi = FX_Alloc(FX_IMAGEDIB_AND_DPI, 1);
+    imageDIBDpi->pDibSource = nullptr;
+    imageDIBDpi->iImageXDpi = 0;
+    imageDIBDpi->iImageYDpi = 0;
+    CPDF_StreamAcc streamAcc;
+    streamAcc.LoadAllData((CPDF_Stream*)pObject);
+    IFX_FileRead* pImageFileRead = FX_CreateMemoryStream(
+        (uint8_t*)streamAcc.GetData(), streamAcc.GetSize());
+    imageDIBDpi->pDibSource = XFA_LoadImageFromBuffer(
+        pImageFileRead, FXCODEC_IMAGE_UNKNOWN, iImageXDpi, iImageYDpi);
+    imageDIBDpi->iImageXDpi = iImageXDpi;
+    imageDIBDpi->iImageYDpi = iImageYDpi;
+    pImageFileRead->Release();
+  }
+  m_mapNamedImages.SetAt((void*)(uintptr_t)dwHash, imageDIBDpi);
+  return (CFX_DIBitmap*)imageDIBDpi->pDibSource;
+}
+
+IFDE_XMLElement* CXFA_FFDoc::GetPackageData(const CFX_WideStringC& wsPackage) {
+  FX_DWORD packetHash =
+      FX_HashCode_String_GetW(wsPackage.GetPtr(), wsPackage.GetLength());
+  CXFA_Node* pNode = ToNode(m_pDocument->GetXFAObject(packetHash));
+  if (!pNode) {
+    return NULL;
+  }
+  IFDE_XMLNode* pXMLNode = pNode->GetXMLMappingNode();
+  return (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element)
+             ? (IFDE_XMLElement*)pXMLNode
+             : NULL;
+}
+FX_BOOL CXFA_FFDoc::SavePackage(const CFX_WideStringC& wsPackage,
+                                IFX_FileWrite* pFile,
+                                IXFA_ChecksumContext* pCSContext) {
+  IXFA_PacketExport* pExport = IXFA_PacketExport::Create(m_pDocument);
+  if (!pExport) {
+    return FALSE;
+  }
+  FX_DWORD packetHash =
+      FX_HashCode_String_GetW(wsPackage.GetPtr(), wsPackage.GetLength());
+  CXFA_Node* pNode = NULL;
+  if (packetHash == XFA_HASHCODE_Xfa) {
+    pNode = m_pDocument->GetRoot();
+  } else {
+    pNode = ToNode(m_pDocument->GetXFAObject(packetHash));
+  }
+  FX_BOOL bFlags = FALSE;
+  if (pNode) {
+    CFX_ByteString bsChecksum;
+    if (pCSContext) {
+      pCSContext->GetChecksum(bsChecksum);
+    }
+    bFlags = pExport->Export(pFile, pNode, 0, bsChecksum.GetLength()
+                                                  ? (const FX_CHAR*)bsChecksum
+                                                  : NULL);
+  } else {
+    bFlags = pExport->Export(pFile);
+  }
+  pExport->Release();
+  return bFlags;
+}
+FX_BOOL CXFA_FFDoc::ImportData(IFX_FileRead* pStream, FX_BOOL bXDP) {
+  FX_BOOL bRet = FALSE;
+  IXFA_PacketImport* pImport = IXFA_PacketImport::Create(m_pDocument);
+  if (pImport) {
+    bRet = pImport->ImportData(pStream);
+    pImport->Release();
+  }
+  return bRet;
+}
diff --git a/xfa/fxfa/app/xfa_ffdoc.h b/xfa/fxfa/app/xfa_ffdoc.h
new file mode 100644
index 0000000..d656d30
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffdoc.h
@@ -0,0 +1,64 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFDOC_H_
+#define XFA_FXFA_APP_XFA_FFDOC_H_
+
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/include/fxfa/fxfa.h"
+
+class CXFA_FFApp;
+class CXFA_FFNotify;
+class CXFA_FFDocView;
+
+struct FX_IMAGEDIB_AND_DPI {
+  CFX_DIBSource* pDibSource;
+  int32_t iImageXDpi;
+  int32_t iImageYDpi;
+};
+
+class CXFA_FFDoc : public IXFA_Doc {
+ public:
+  CXFA_FFDoc(CXFA_FFApp* pApp, IXFA_DocProvider* pDocProvider);
+  ~CXFA_FFDoc();
+  IXFA_DocProvider* GetDocProvider() { return m_pDocProvider; }
+  FX_DWORD GetDocType();
+  int32_t StartLoad();
+  int32_t DoLoad(IFX_Pause* pPause = NULL);
+  void StopLoad();
+  IXFA_DocView* CreateDocView(FX_DWORD dwView = 0);
+  FX_BOOL OpenDoc(IFX_FileRead* pStream, FX_BOOL bTakeOverFile);
+  FX_BOOL OpenDoc(CPDF_Document* pPDFDoc);
+  FX_BOOL CloseDoc();
+  void SetDocType(FX_DWORD dwType);
+  CXFA_Document* GetXFADoc() { return m_pDocument; }
+  CXFA_FFApp* GetApp() { return m_pApp; }
+  CXFA_FFDocView* GetDocView(IXFA_DocLayout* pLayout);
+  CXFA_FFDocView* GetDocView();
+  CPDF_Document* GetPDFDoc();
+  CFX_DIBitmap* GetPDFNamedImage(const CFX_WideStringC& wsName,
+                                 int32_t& iImageXDpi,
+                                 int32_t& iImageYDpi);
+  IFDE_XMLElement* GetPackageData(const CFX_WideStringC& wsPackage);
+  FX_BOOL SavePackage(const CFX_WideStringC& wsPackage,
+                      IFX_FileWrite* pFile,
+                      IXFA_ChecksumContext* pCSContext = NULL);
+  FX_BOOL ImportData(IFX_FileRead* pStream, FX_BOOL bXDP = TRUE);
+
+ protected:
+  IXFA_DocProvider* m_pDocProvider;
+  CXFA_Document* m_pDocument;
+  IFX_FileRead* m_pStream;
+  CXFA_FFApp* m_pApp;
+  CXFA_FFNotify* m_pNotify;
+  CPDF_Document* m_pPDFDoc;
+  CFX_MapPtrToPtr m_mapNamedImages;
+  CFX_MapPtrToPtr m_mapTypeToDocView;
+  FX_DWORD m_dwDocType;
+  FX_BOOL m_bOwnStream;
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFDOC_H_
diff --git a/xfa/fxfa/app/xfa_ffdochandler.cpp b/xfa/fxfa/app/xfa_ffdochandler.cpp
new file mode 100644
index 0000000..5ea7884
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffdochandler.cpp
@@ -0,0 +1,110 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffdochandler.h"
+
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+
+CXFA_FFDocHandler::CXFA_FFDocHandler() {}
+CXFA_FFDocHandler::~CXFA_FFDocHandler() {}
+void CXFA_FFDocHandler::ReleaseDoc(IXFA_Doc* hDoc) {
+  delete hDoc;  // virtual dtor.
+}
+IXFA_DocProvider* CXFA_FFDocHandler::GetDocProvider(IXFA_Doc* hDoc) {
+  return static_cast<CXFA_FFDoc*>(hDoc)->GetDocProvider();
+}
+FX_DWORD CXFA_FFDocHandler::GetDocType(IXFA_Doc* hDoc) {
+  return static_cast<CXFA_FFDoc*>(hDoc)->GetDocType();
+}
+int32_t CXFA_FFDocHandler::StartLoad(IXFA_Doc* hDoc) {
+  return static_cast<CXFA_FFDoc*>(hDoc)->StartLoad();
+}
+int32_t CXFA_FFDocHandler::DoLoad(IXFA_Doc* hDoc, IFX_Pause* pPause) {
+  return static_cast<CXFA_FFDoc*>(hDoc)->DoLoad(pPause);
+}
+void CXFA_FFDocHandler::StopLoad(IXFA_Doc* hDoc) {
+  static_cast<CXFA_FFDoc*>(hDoc)->StopLoad();
+}
+
+IXFA_DocView* CXFA_FFDocHandler::CreateDocView(IXFA_Doc* hDoc,
+                                               FX_DWORD dwView) {
+  return static_cast<CXFA_FFDoc*>(hDoc)->CreateDocView(dwView);
+}
+int32_t CXFA_FFDocHandler::CountPackages(IXFA_Doc* hDoc) {
+  return 0;
+}
+void CXFA_FFDocHandler::GetPackageName(IXFA_Doc* hDoc,
+                                       int32_t iPackage,
+                                       CFX_WideStringC& wsPackage) {}
+IFDE_XMLElement* CXFA_FFDocHandler::GetPackageData(
+    IXFA_Doc* hDoc,
+    const CFX_WideStringC& wsPackage) {
+  return static_cast<CXFA_FFDoc*>(hDoc)->GetPackageData(wsPackage);
+}
+FX_BOOL CXFA_FFDocHandler::SavePackage(IXFA_Doc* hDoc,
+                                       const CFX_WideStringC& wsPackage,
+                                       IFX_FileWrite* pFile,
+                                       IXFA_ChecksumContext* pCSContext) {
+  return static_cast<CXFA_FFDoc*>(hDoc)
+      ->SavePackage(wsPackage, pFile, pCSContext);
+}
+FX_BOOL CXFA_FFDocHandler::CloseDoc(IXFA_Doc* hDoc) {
+  return static_cast<CXFA_FFDoc*>(hDoc)->CloseDoc();
+}
+
+FX_BOOL CXFA_FFDocHandler::ImportData(IXFA_Doc* hDoc,
+                                      IFX_FileRead* pStream,
+                                      FX_BOOL bXDP) {
+  return static_cast<CXFA_FFDoc*>(hDoc)->ImportData(pStream, bXDP);
+}
+void CXFA_FFDocHandler::SetJSERuntime(IXFA_Doc* hDoc, FXJSE_HRUNTIME hRuntime) {
+  static_cast<CXFA_FFDoc*>(hDoc)->GetXFADoc()->InitScriptContext(hRuntime);
+}
+FXJSE_HVALUE CXFA_FFDocHandler::GetXFAScriptObject(IXFA_Doc* hDoc) {
+  CXFA_Document* pXFADoc = static_cast<CXFA_FFDoc*>(hDoc)->GetXFADoc();
+  if (!pXFADoc) {
+    return NULL;
+  }
+  IXFA_ScriptContext* pScriptContext = pXFADoc->GetScriptContext();
+  if (!pScriptContext) {
+    return NULL;
+  }
+  return pScriptContext->GetJSValueFromMap(pXFADoc->GetRoot());
+}
+XFA_ATTRIBUTEENUM CXFA_FFDocHandler::GetRestoreState(IXFA_Doc* hDoc) {
+  CXFA_Document* pXFADoc = static_cast<CXFA_FFDoc*>(hDoc)->GetXFADoc();
+  if (!pXFADoc) {
+    return XFA_ATTRIBUTEENUM_Unknown;
+  }
+  CXFA_Node* pForm = ToNode(pXFADoc->GetXFAObject(XFA_HASHCODE_Form));
+  if (!pForm) {
+    return XFA_ATTRIBUTEENUM_Unknown;
+  }
+  CXFA_Node* pSubForm = pForm->GetFirstChildByClass(XFA_ELEMENT_Subform);
+  if (!pSubForm) {
+    return XFA_ATTRIBUTEENUM_Unknown;
+  }
+  return pSubForm->GetEnum(XFA_ATTRIBUTE_RestoreState);
+}
+FX_BOOL CXFA_FFDocHandler::RunDocScript(IXFA_Doc* hDoc,
+                                        XFA_SCRIPTTYPE eScriptType,
+                                        const CFX_WideStringC& wsScript,
+                                        FXJSE_HVALUE hRetValue,
+                                        FXJSE_HVALUE hThisObject) {
+  CXFA_Document* pXFADoc = static_cast<CXFA_FFDoc*>(hDoc)->GetXFADoc();
+  if (!pXFADoc) {
+    return FALSE;
+  }
+  IXFA_ScriptContext* pScriptContext = pXFADoc->GetScriptContext();
+  if (!pScriptContext) {
+    return FALSE;
+  }
+  return pScriptContext->RunScript(
+      (XFA_SCRIPTLANGTYPE)eScriptType, wsScript, hRetValue,
+      hThisObject ? (CXFA_Object*)FXJSE_Value_ToObject(hThisObject, NULL)
+                  : NULL);
+}
diff --git a/xfa/fxfa/app/xfa_ffdochandler.h b/xfa/fxfa/app/xfa_ffdochandler.h
new file mode 100644
index 0000000..47dd85f
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffdochandler.h
@@ -0,0 +1,50 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFDOCHANDLER_H_
+#define XFA_FXFA_APP_XFA_FFDOCHANDLER_H_
+
+#include "xfa/include/fxfa/fxfa.h"
+
+class CXFA_FFDocHandler : public IXFA_DocHandler {
+ public:
+  CXFA_FFDocHandler();
+  ~CXFA_FFDocHandler();
+  virtual void ReleaseDoc(IXFA_Doc* hDoc);
+  virtual IXFA_DocProvider* GetDocProvider(IXFA_Doc* hDoc);
+  virtual FX_DWORD GetDocType(IXFA_Doc* hDoc);
+  virtual int32_t StartLoad(IXFA_Doc* hDoc);
+  virtual int32_t DoLoad(IXFA_Doc* hDoc, IFX_Pause* pPause = NULL);
+  virtual void StopLoad(IXFA_Doc* hDoc);
+
+  virtual IXFA_DocView* CreateDocView(IXFA_Doc* hDoc, FX_DWORD dwView = 0);
+  virtual int32_t CountPackages(IXFA_Doc* hDoc);
+  virtual void GetPackageName(IXFA_Doc* hDoc,
+                              int32_t iPackage,
+                              CFX_WideStringC& wsPackage);
+  virtual IFDE_XMLElement* GetPackageData(IXFA_Doc* hDoc,
+                                          const CFX_WideStringC& wsPackage);
+  virtual FX_BOOL SavePackage(IXFA_Doc* hDoc,
+                              const CFX_WideStringC& wsPackage,
+                              IFX_FileWrite* pFile,
+                              IXFA_ChecksumContext* pCSContext = NULL);
+  virtual FX_BOOL CloseDoc(IXFA_Doc* hDoc);
+  virtual FX_BOOL ImportData(IXFA_Doc* hDoc,
+                             IFX_FileRead* pStream,
+                             FX_BOOL bXDP = TRUE);
+  virtual void SetJSERuntime(IXFA_Doc* hDoc, FXJSE_HRUNTIME hRuntime);
+  virtual FXJSE_HVALUE GetXFAScriptObject(IXFA_Doc* hDoc);
+  virtual XFA_ATTRIBUTEENUM GetRestoreState(IXFA_Doc* hDoc);
+  virtual FX_BOOL RunDocScript(IXFA_Doc* hDoc,
+                               XFA_SCRIPTTYPE eScriptType,
+                               const CFX_WideStringC& wsScript,
+                               FXJSE_HVALUE hRetValue,
+                               FXJSE_HVALUE hThisObject);
+
+ protected:
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFDOCHANDLER_H_
diff --git a/xfa/fxfa/app/xfa_ffdocview.cpp b/xfa/fxfa/app/xfa_ffdocview.cpp
new file mode 100644
index 0000000..082ca2b
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffdocview.cpp
@@ -0,0 +1,932 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffdocview.h"
+
+#include "core/include/fxcrt/fx_ext.h"
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/fxfa/app/xfa_ffbarcode.h"
+#include "xfa/fxfa/app/xfa_ffcheckbutton.h"
+#include "xfa/fxfa/app/xfa_ffchoicelist.h"
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_ffdraw.h"
+#include "xfa/fxfa/app/xfa_ffexclgroup.h"
+#include "xfa/fxfa/app/xfa_fffield.h"
+#include "xfa/fxfa/app/xfa_ffimage.h"
+#include "xfa/fxfa/app/xfa_ffimageedit.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffpath.h"
+#include "xfa/fxfa/app/xfa_ffpushbutton.h"
+#include "xfa/fxfa/app/xfa_ffsignature.h"
+#include "xfa/fxfa/app/xfa_ffsubform.h"
+#include "xfa/fxfa/app/xfa_fftext.h"
+#include "xfa/fxfa/app/xfa_fftextedit.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+#include "xfa/fxfa/app/xfa_ffwidgetacc.h"
+#include "xfa/fxfa/app/xfa_ffwidgethandler.h"
+#include "xfa/fxfa/app/xfa_fwladapter.h"
+#include "xfa/fxfa/app/xfa_textlayout.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+
+extern const XFA_ATTRIBUTEENUM gs_EventActivity[] = {
+    XFA_ATTRIBUTEENUM_Click,      XFA_ATTRIBUTEENUM_Change,
+    XFA_ATTRIBUTEENUM_DocClose,   XFA_ATTRIBUTEENUM_DocReady,
+    XFA_ATTRIBUTEENUM_Enter,      XFA_ATTRIBUTEENUM_Exit,
+    XFA_ATTRIBUTEENUM_Full,       XFA_ATTRIBUTEENUM_IndexChange,
+    XFA_ATTRIBUTEENUM_Initialize, XFA_ATTRIBUTEENUM_MouseDown,
+    XFA_ATTRIBUTEENUM_MouseEnter, XFA_ATTRIBUTEENUM_MouseExit,
+    XFA_ATTRIBUTEENUM_MouseUp,    XFA_ATTRIBUTEENUM_PostExecute,
+    XFA_ATTRIBUTEENUM_PostOpen,   XFA_ATTRIBUTEENUM_PostPrint,
+    XFA_ATTRIBUTEENUM_PostSave,   XFA_ATTRIBUTEENUM_PostSign,
+    XFA_ATTRIBUTEENUM_PostSubmit, XFA_ATTRIBUTEENUM_PreExecute,
+    XFA_ATTRIBUTEENUM_PreOpen,    XFA_ATTRIBUTEENUM_PrePrint,
+    XFA_ATTRIBUTEENUM_PreSave,    XFA_ATTRIBUTEENUM_PreSign,
+    XFA_ATTRIBUTEENUM_PreSubmit,  XFA_ATTRIBUTEENUM_Ready,
+    XFA_ATTRIBUTEENUM_Unknown,
+};
+CXFA_FFDocView::CXFA_FFDocView(CXFA_FFDoc* pDoc)
+    : m_bLayoutEvent(FALSE),
+      m_pListFocusWidget(nullptr),
+      m_bInLayoutStatus(FALSE),
+      m_pDoc(pDoc),
+      m_pWidgetHandler(nullptr),
+      m_pXFADocLayout(nullptr),
+      m_pFocusAcc(nullptr),
+      m_pFocusWidget(nullptr),
+      m_pOldFocusWidget(nullptr),
+      m_iStatus(XFA_DOCVIEW_LAYOUTSTATUS_None),
+      m_iLock(0) {}
+CXFA_FFDocView::~CXFA_FFDocView() {
+  DestroyDocView();
+  if (m_pWidgetHandler) {
+    delete m_pWidgetHandler;
+  }
+  m_pWidgetHandler = NULL;
+}
+void CXFA_FFDocView::InitLayout(CXFA_Node* pNode) {
+  RunBindItems();
+  ExecEventActivityByDeepFirst(pNode, XFA_EVENT_Initialize);
+  ExecEventActivityByDeepFirst(pNode, XFA_EVENT_IndexChange);
+}
+int32_t CXFA_FFDocView::StartLayout(int32_t iStartPage) {
+  m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_Start;
+  m_pDoc->GetXFADoc()->DoProtoMerge();
+  m_pDoc->GetXFADoc()->DoDataMerge();
+  m_pXFADocLayout = GetXFALayout();
+  int32_t iStatus = m_pXFADocLayout->StartLayout();
+  if (iStatus < 0) {
+    return iStatus;
+  }
+  CXFA_Node* pRootItem =
+      ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form));
+  if (!pRootItem) {
+    return iStatus;
+  }
+  InitLayout(pRootItem);
+  InitCalculate(pRootItem);
+  InitValidate(pRootItem);
+  ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_Ready, TRUE);
+  m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_Start;
+  return iStatus;
+}
+int32_t CXFA_FFDocView::DoLayout(IFX_Pause* pPause) {
+  int32_t iStatus = 100;
+  iStatus = m_pXFADocLayout->DoLayout(pPause);
+  if (iStatus != 100) {
+    return iStatus;
+  }
+  m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_Doing;
+  return iStatus;
+}
+void CXFA_FFDocView::StopLayout() {
+  CXFA_Node* pRootItem =
+      ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form));
+  if (!pRootItem) {
+    return;
+  }
+  CXFA_Node* pSubformNode = pRootItem->GetChild(0, XFA_ELEMENT_Subform);
+  if (!pSubformNode) {
+    return;
+  }
+  CXFA_Node* pPageSetNode =
+      pSubformNode->GetFirstChildByClass(XFA_ELEMENT_PageSet);
+  if (!pPageSetNode) {
+    return;
+  }
+  RunCalculateWidgets();
+  RunValidate();
+  InitLayout(pPageSetNode);
+  InitCalculate(pPageSetNode);
+  InitValidate(pPageSetNode);
+  ExecEventActivityByDeepFirst(pPageSetNode, XFA_EVENT_Ready, TRUE);
+  ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_Ready);
+  ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_DocReady);
+  RunCalculateWidgets();
+  RunValidate();
+  if (RunLayout()) {
+    ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_Ready);
+  }
+  m_CalculateAccs.RemoveAll();
+  if (m_pFocusAcc && !m_pFocusWidget) {
+    SetFocusWidgetAcc(m_pFocusAcc);
+  }
+  m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_End;
+}
+int32_t CXFA_FFDocView::GetLayoutStatus() {
+  return m_iStatus;
+}
+void CXFA_FFDocView::ShowNullTestMsg() {
+  int32_t iCount = m_arrNullTestMsg.GetSize();
+  CXFA_FFApp* pApp = m_pDoc->GetApp();
+  IXFA_AppProvider* pAppProvider = pApp->GetAppProvider();
+  if (pAppProvider && iCount) {
+    int32_t iRemain = iCount > 7 ? iCount - 7 : 0;
+    iCount -= iRemain;
+    CFX_WideString wsMsg;
+    for (int32_t i = 0; i < iCount; i++) {
+      wsMsg += m_arrNullTestMsg[i] + FX_WSTRC(L"\n");
+    }
+    if (iRemain > 0) {
+      CFX_WideString wsLimit;
+      pAppProvider->LoadString(XFA_IDS_ValidateLimit, wsLimit);
+      if (!wsLimit.IsEmpty()) {
+        CFX_WideString wsTemp;
+        wsTemp.Format((const FX_WCHAR*)wsLimit, iRemain);
+        wsMsg += FX_WSTRC(L"\n") + wsTemp;
+      }
+    }
+    CFX_WideString wsTitle;
+    pAppProvider->LoadString(XFA_IDS_AppName, wsTitle);
+    pAppProvider->MsgBox(wsMsg, wsTitle, XFA_MBICON_Status, XFA_MB_OK);
+  }
+  m_arrNullTestMsg.RemoveAll();
+}
+void CXFA_FFDocView::UpdateDocView() {
+  if (IsUpdateLocked()) {
+    return;
+  }
+  LockUpdate();
+  int32_t iNewAdds = m_NewAddedNodes.GetSize();
+  for (int32_t i = 0; i < iNewAdds; i++) {
+    CXFA_Node* pNode = reinterpret_cast<CXFA_Node*>(m_NewAddedNodes[i]);
+    InitCalculate(pNode);
+    InitValidate(pNode);
+    ExecEventActivityByDeepFirst(pNode, XFA_EVENT_Ready, TRUE);
+  }
+  m_NewAddedNodes.RemoveAll();
+  RunSubformIndexChange();
+  RunCalculateWidgets();
+  RunValidate();
+  ShowNullTestMsg();
+  if (RunLayout() && m_bLayoutEvent) {
+    RunEventLayoutReady();
+  }
+  m_bLayoutEvent = FALSE;
+  m_CalculateAccs.RemoveAll();
+  RunInvalidate();
+  UnlockUpdate();
+}
+int32_t CXFA_FFDocView::CountPageViews() {
+  if (!m_pXFADocLayout) {
+    return 0;
+  }
+  return m_pXFADocLayout->CountPages();
+}
+IXFA_PageView* CXFA_FFDocView::GetPageView(int32_t nIndex) {
+  if (!m_pXFADocLayout) {
+    return NULL;
+  }
+  return static_cast<CXFA_FFPageView*>(m_pXFADocLayout->GetPage(nIndex));
+}
+IXFA_Widget* CXFA_FFDocView::GetWidgetByName(const CFX_WideStringC& wsName) {
+  return GetWidgetByName(wsName, NULL);
+}
+CXFA_WidgetAcc* CXFA_FFDocView::GetWidgetAccByName(
+    const CFX_WideStringC& wsName) {
+  return GetWidgetAccByName(wsName, NULL);
+}
+IXFA_DocLayout* CXFA_FFDocView::GetXFALayout() const {
+  return m_pDoc->GetXFADoc()->GetDocLayout();
+}
+FX_BOOL CXFA_FFDocView::ResetSingleWidgetAccData(CXFA_WidgetAcc* pWidgetAcc) {
+  CXFA_Node* pNode = pWidgetAcc->GetNode();
+  XFA_ELEMENT eType = pNode->GetClassID();
+  if (eType != XFA_ELEMENT_Field && eType != XFA_ELEMENT_ExclGroup) {
+    return FALSE;
+  }
+  FX_BOOL bNotify = IsStaticNotify();
+  pWidgetAcc->ResetData();
+  pWidgetAcc->UpdateUIDisplay();
+  if (bNotify) {
+    pWidgetAcc->NotifyEvent(XFA_WIDGETEVENT_PostContentChanged, NULL, NULL,
+                            NULL);
+  }
+  if (CXFA_Validate validate = pWidgetAcc->GetValidate()) {
+    AddValidateWidget(pWidgetAcc);
+    validate.GetNode()->SetFlag(XFA_NODEFLAG_NeedsInitApp, TRUE, FALSE);
+  }
+  return TRUE;
+}
+void CXFA_FFDocView::ResetWidgetData(CXFA_WidgetAcc* pWidgetAcc) {
+  m_bLayoutEvent = TRUE;
+  FX_BOOL bChanged = FALSE;
+  CXFA_Node* pFormNode = NULL;
+  if (pWidgetAcc) {
+    bChanged = ResetSingleWidgetAccData(pWidgetAcc);
+    pFormNode = pWidgetAcc->GetNode();
+  } else {
+    pFormNode = GetRootSubform();
+  }
+  if (!pFormNode) {
+    return;
+  }
+  if (pFormNode->GetClassID() != XFA_ELEMENT_Field &&
+      pFormNode->GetClassID() != XFA_ELEMENT_ExclGroup) {
+    CXFA_WidgetAccIterator Iterator(this, pFormNode);
+    while (CXFA_WidgetAcc* pAcc = Iterator.MoveToNext()) {
+      bChanged |= ResetSingleWidgetAccData(pAcc);
+      if (pAcc->GetNode()->GetClassID() == XFA_ELEMENT_ExclGroup) {
+        Iterator.SkipTree();
+      }
+    }
+  }
+  if (bChanged) {
+    m_pDoc->GetDocProvider()->SetChangeMark(m_pDoc);
+  }
+}
+int32_t CXFA_FFDocView::ProcessWidgetEvent(CXFA_EventParam* pParam,
+                                           CXFA_WidgetAcc* pWidgetAcc) {
+  if (pParam == NULL) {
+    return XFA_EVENTERROR_Error;
+  }
+  if (pParam->m_eType == XFA_EVENT_Validate) {
+    CFX_WideString wsValidateStr = FX_WSTRC(L"preSubmit");
+    CXFA_Node* pConfigItem =
+        ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Config));
+    if (pConfigItem) {
+      CXFA_Node* pValidateNode = NULL;
+      CXFA_Node* pAcrobatNode = pConfigItem->GetChild(0, XFA_ELEMENT_Acrobat);
+      pValidateNode =
+          pAcrobatNode ? pAcrobatNode->GetChild(0, XFA_ELEMENT_Validate) : NULL;
+      if (!pValidateNode) {
+        CXFA_Node* pPresentNode = pConfigItem->GetChild(0, XFA_ELEMENT_Present);
+        pValidateNode = pPresentNode
+                            ? pPresentNode->GetChild(0, XFA_ELEMENT_Validate)
+                            : NULL;
+      }
+      if (pValidateNode) {
+        wsValidateStr = pValidateNode->GetContent();
+      }
+    }
+    FX_BOOL bValidate = FALSE;
+    switch (pParam->m_iValidateActivities) {
+      case XFA_VALIDATE_preSubmit:
+        bValidate = wsValidateStr.Find(L"preSubmit") != -1;
+        break;
+      case XFA_VALIDATE_prePrint:
+        bValidate = wsValidateStr.Find(L"prePrint") != -1;
+        break;
+      case XFA_VALIDATE_preExecute:
+        bValidate = wsValidateStr.Find(L"preExecute") != -1;
+        break;
+      case XFA_VALIDATE_preSave:
+        bValidate = wsValidateStr.Find(L"preSave") != -1;
+        break;
+    }
+    if (!bValidate) {
+      return XFA_EVENTERROR_Sucess;
+    }
+  }
+  CXFA_Node* pNode = pWidgetAcc ? pWidgetAcc->GetNode() : NULL;
+  if (!pNode) {
+    CXFA_Node* pRootItem =
+        ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form));
+    if (!pRootItem) {
+      return XFA_EVENTERROR_Error;
+    }
+    pNode = pRootItem->GetChild(0, XFA_ELEMENT_Subform);
+  }
+  ExecEventActivityByDeepFirst(pNode, pParam->m_eType, pParam->m_bIsFormReady);
+  return XFA_EVENTERROR_Sucess;
+}
+IXFA_WidgetHandler* CXFA_FFDocView::GetWidgetHandler() {
+  if (!m_pWidgetHandler) {
+    m_pWidgetHandler = new CXFA_FFWidgetHandler(this);
+  }
+  return m_pWidgetHandler;
+}
+IXFA_WidgetIterator* CXFA_FFDocView::CreateWidgetIterator() {
+  CXFA_Node* pFormRoot = GetRootSubform();
+  if (!pFormRoot) {
+    return NULL;
+  }
+  return new CXFA_FFDocWidgetIterator(this, pFormRoot);
+}
+IXFA_WidgetAccIterator* CXFA_FFDocView::CreateWidgetAccIterator(
+    XFA_WIDGETORDER eOrder) {
+  CXFA_Node* pFormRoot = GetRootSubform();
+  if (!pFormRoot) {
+    return NULL;
+  }
+  return new CXFA_WidgetAccIterator(this, pFormRoot);
+}
+IXFA_Widget* CXFA_FFDocView::GetFocusWidget() {
+  return m_pFocusWidget;
+}
+void CXFA_FFDocView::KillFocus() {
+  if (m_pFocusWidget &&
+      (m_pFocusWidget->GetStatus() & XFA_WIDGETSTATUS_Focused)) {
+    (m_pFocusWidget)->OnKillFocus(NULL);
+  }
+  m_pFocusAcc = NULL;
+  m_pFocusWidget = NULL;
+  m_pOldFocusWidget = NULL;
+}
+FX_BOOL CXFA_FFDocView::SetFocus(IXFA_Widget* hWidget) {
+  CXFA_FFWidget* pNewFocus = (CXFA_FFWidget*)hWidget;
+  if (m_pOldFocusWidget == pNewFocus) {
+    return FALSE;
+  }
+  CXFA_FFWidget* pOldFocus = m_pOldFocusWidget;
+  m_pOldFocusWidget = pNewFocus;
+  if (pOldFocus) {
+    if (m_pFocusWidget != m_pOldFocusWidget &&
+        (pOldFocus->GetStatus() & XFA_WIDGETSTATUS_Focused)) {
+      m_pFocusWidget = pOldFocus;
+      pOldFocus->OnKillFocus(pNewFocus);
+    } else if ((pOldFocus->GetStatus() & XFA_WIDGETSTATUS_Visible)) {
+      if (!pOldFocus->IsLoaded()) {
+        pOldFocus->LoadWidget();
+      }
+      pOldFocus->OnSetFocus(m_pFocusWidget);
+      m_pFocusWidget = pOldFocus;
+      pOldFocus->OnKillFocus(pNewFocus);
+    }
+  }
+  if (m_pFocusWidget == m_pOldFocusWidget) {
+    return FALSE;
+  }
+  pNewFocus = m_pOldFocusWidget;
+  if (m_pListFocusWidget && pNewFocus == m_pListFocusWidget) {
+    m_pFocusAcc = NULL;
+    m_pFocusWidget = NULL;
+    m_pListFocusWidget = NULL;
+    m_pOldFocusWidget = NULL;
+    return FALSE;
+  }
+  if (pNewFocus && (pNewFocus->GetStatus() & XFA_WIDGETSTATUS_Visible)) {
+    if (!pNewFocus->IsLoaded()) {
+      pNewFocus->LoadWidget();
+    }
+    pNewFocus->OnSetFocus(m_pFocusWidget);
+  }
+  m_pFocusAcc = pNewFocus ? pNewFocus->GetDataAcc() : NULL;
+  m_pFocusWidget = pNewFocus;
+  m_pOldFocusWidget = m_pFocusWidget;
+  return TRUE;
+}
+CXFA_WidgetAcc* CXFA_FFDocView::GetFocusWidgetAcc() {
+  return m_pFocusAcc;
+}
+void CXFA_FFDocView::SetFocusWidgetAcc(CXFA_WidgetAcc* pWidgetAcc) {
+  CXFA_FFWidget* pNewFocus =
+      pWidgetAcc ? pWidgetAcc->GetNextWidget(NULL) : NULL;
+  if (SetFocus(pNewFocus)) {
+    m_pFocusAcc = pWidgetAcc;
+    if (m_iStatus == XFA_DOCVIEW_LAYOUTSTATUS_End) {
+      m_pDoc->GetDocProvider()->SetFocusWidget(m_pDoc, m_pFocusWidget);
+    }
+  }
+}
+void CXFA_FFDocView::DeleteLayoutItem(CXFA_FFWidget* pWidget) {
+  if (m_pFocusAcc == pWidget->GetDataAcc()) {
+    m_pFocusAcc = NULL;
+    m_pFocusWidget = NULL;
+    m_pOldFocusWidget = NULL;
+  }
+}
+static int32_t XFA_ProcessEvent(CXFA_FFDocView* pDocView,
+                                CXFA_WidgetAcc* pWidgetAcc,
+                                CXFA_EventParam* pParam) {
+  if (!pParam || pParam->m_eType == XFA_EVENT_Unknown) {
+    return XFA_EVENTERROR_NotExist;
+  }
+  if (!pWidgetAcc || pWidgetAcc->GetClassID() == XFA_ELEMENT_Draw) {
+    return XFA_EVENTERROR_NotExist;
+  }
+  switch (pParam->m_eType) {
+    case XFA_EVENT_Calculate:
+      return pWidgetAcc->ProcessCalculate();
+    case XFA_EVENT_Validate:
+      if (((CXFA_FFDoc*)pDocView->GetDoc())
+              ->GetDocProvider()
+              ->IsValidationsEnabled(pDocView->GetDoc())) {
+        return pWidgetAcc->ProcessValidate(0x01);
+      }
+      return XFA_EVENTERROR_Disabled;
+    case XFA_EVENT_InitCalculate: {
+      CXFA_Calculate calc = pWidgetAcc->GetCalculate();
+      if (!calc) {
+        return XFA_EVENTERROR_NotExist;
+      }
+      if (pWidgetAcc->GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
+        return XFA_EVENTERROR_Disabled;
+      }
+      CXFA_Script script = calc.GetScript();
+      return pWidgetAcc->ExecuteScript(script, pParam);
+    }
+    default:
+      break;
+  }
+  int32_t iRet =
+      pWidgetAcc->ProcessEvent(gs_EventActivity[pParam->m_eType], pParam);
+  return iRet;
+}
+int32_t CXFA_FFDocView::ExecEventActivityByDeepFirst(CXFA_Node* pFormNode,
+                                                     XFA_EVENTTYPE eEventType,
+                                                     FX_BOOL bIsFormReady,
+                                                     FX_BOOL bRecursive,
+                                                     CXFA_Node* pExclude) {
+  int32_t iRet = XFA_EVENTERROR_NotExist;
+  if (pFormNode == pExclude) {
+    return iRet;
+  }
+  XFA_ELEMENT elementType = pFormNode->GetClassID();
+  if (elementType == XFA_ELEMENT_Field) {
+    if (eEventType == XFA_EVENT_IndexChange) {
+      return iRet;
+    }
+    CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pFormNode->GetWidgetData();
+    if (pWidgetAcc == NULL) {
+      return iRet;
+    }
+    CXFA_EventParam eParam;
+    eParam.m_eType = eEventType;
+    eParam.m_pTarget = pWidgetAcc;
+    eParam.m_bIsFormReady = bIsFormReady;
+    return XFA_ProcessEvent(this, pWidgetAcc, &eParam);
+  }
+  if (bRecursive) {
+    for (CXFA_Node* pNode = pFormNode->GetNodeItem(
+             XFA_NODEITEM_FirstChild, XFA_OBJECTTYPE_ContainerNode);
+         pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling,
+                                           XFA_OBJECTTYPE_ContainerNode)) {
+      elementType = pNode->GetClassID();
+      if (elementType != XFA_ELEMENT_Variables &&
+          elementType != XFA_ELEMENT_Draw) {
+        iRet |= ExecEventActivityByDeepFirst(pNode, eEventType, bIsFormReady,
+                                             bRecursive, pExclude);
+      }
+    }
+  }
+  CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pFormNode->GetWidgetData();
+  if (pWidgetAcc == NULL) {
+    return iRet;
+  }
+  CXFA_EventParam eParam;
+  eParam.m_eType = eEventType;
+  eParam.m_pTarget = pWidgetAcc;
+  eParam.m_bIsFormReady = bIsFormReady;
+  iRet |= XFA_ProcessEvent(this, pWidgetAcc, &eParam);
+  return iRet;
+}
+CXFA_FFWidget* CXFA_FFDocView::GetWidgetByName(const CFX_WideStringC& wsName,
+                                               CXFA_FFWidget* pRefWidget) {
+  CXFA_WidgetAcc* pRefAcc = pRefWidget ? pRefWidget->GetDataAcc() : NULL;
+  if (CXFA_WidgetAcc* pAcc = GetWidgetAccByName(wsName, pRefAcc)) {
+    return pAcc->GetNextWidget(NULL);
+  }
+  return NULL;
+}
+CXFA_WidgetAcc* CXFA_FFDocView::GetWidgetAccByName(
+    const CFX_WideStringC& wsName,
+    CXFA_WidgetAcc* pRefWidgetAcc) {
+  CFX_WideString wsExpression;
+  FX_DWORD dwStyle = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
+                     XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent;
+  IXFA_ScriptContext* pScriptContext = m_pDoc->GetXFADoc()->GetScriptContext();
+  if (!pScriptContext) {
+    return NULL;
+  }
+  CXFA_Node* refNode = NULL;
+  if (pRefWidgetAcc) {
+    refNode = pRefWidgetAcc->GetNode();
+    wsExpression = wsName;
+  } else {
+    wsExpression = L"$form." + wsName;
+  }
+  XFA_RESOLVENODE_RS resoveNodeRS;
+  int32_t iRet = pScriptContext->ResolveObjects(refNode, wsExpression,
+                                                resoveNodeRS, dwStyle);
+  if (iRet < 1) {
+    return NULL;
+  }
+  if (resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
+    CXFA_Node* pNode = resoveNodeRS.nodes[0]->AsNode();
+    if (pNode) {
+      return (CXFA_WidgetAcc*)pNode->GetWidgetData();
+    }
+  }
+  return NULL;
+}
+void CXFA_FFDocView::OnPageEvent(IXFA_LayoutPage* pSender,
+                                 XFA_PAGEEVENT eEvent,
+                                 int32_t iPageIndex) {
+  CXFA_FFPageView* pFFPageView = static_cast<CXFA_FFPageView*>(pSender);
+  if (eEvent == XFA_PAGEEVENT_PageRemoved) {
+    m_pDoc->GetDocProvider()->PageViewEvent(pFFPageView,
+                                            XFA_PAGEVIEWEVENT_PostRemoved);
+    return;
+  }
+  m_pDoc->GetDocProvider()->PageViewEvent(pFFPageView,
+                                          XFA_PAGEVIEWEVENT_PostAdded);
+  pFFPageView->LoadPageView();
+}
+void CXFA_FFDocView::LockUpdate() {
+  m_iLock++;
+}
+void CXFA_FFDocView::UnlockUpdate() {
+  m_iLock--;
+}
+FX_BOOL CXFA_FFDocView::IsUpdateLocked() {
+  return m_iLock;
+}
+void CXFA_FFDocView::ClearInvalidateList() {
+  FX_POSITION ps = m_mapPageInvalidate.GetStartPosition();
+  while (ps) {
+    void* pPageView = NULL;
+    CFX_RectF* pRect = NULL;
+    m_mapPageInvalidate.GetNextAssoc(ps, pPageView, (void*&)pRect);
+    delete pRect;
+  }
+  m_mapPageInvalidate.RemoveAll();
+}
+void CXFA_FFDocView::AddInvalidateRect(CXFA_FFWidget* pWidget,
+                                       const CFX_RectF& rtInvalidate) {
+  AddInvalidateRect(pWidget->GetPageView(), rtInvalidate);
+}
+void CXFA_FFDocView::AddInvalidateRect(IXFA_PageView* pPageView,
+                                       const CFX_RectF& rtInvalidate) {
+  CFX_RectF* pRect = (CFX_RectF*)m_mapPageInvalidate.GetValueAt(pPageView);
+  if (!pRect) {
+    pRect = new CFX_RectF;
+    pRect->Set(rtInvalidate.left, rtInvalidate.top, rtInvalidate.width,
+               rtInvalidate.height);
+    m_mapPageInvalidate.SetAt(pPageView, pRect);
+  } else {
+    pRect->Union(rtInvalidate);
+  }
+}
+void CXFA_FFDocView::RunInvalidate() {
+  FX_POSITION ps = m_mapPageInvalidate.GetStartPosition();
+  while (ps) {
+    IXFA_PageView* pPageView = NULL;
+    CFX_RectF* pRect = NULL;
+    m_mapPageInvalidate.GetNextAssoc(ps, (void*&)pPageView, (void*&)pRect);
+    m_pDoc->GetDocProvider()->InvalidateRect(pPageView, *pRect);
+    delete pRect;
+  }
+  m_mapPageInvalidate.RemoveAll();
+}
+FX_BOOL CXFA_FFDocView::RunLayout() {
+  LockUpdate();
+  m_bInLayoutStatus = TRUE;
+  if (!m_pXFADocLayout->IncrementLayout() &&
+      m_pXFADocLayout->StartLayout() < 100) {
+    m_pXFADocLayout->DoLayout();
+    UnlockUpdate();
+    m_bInLayoutStatus = FALSE;
+    return TRUE;
+  }
+  m_bInLayoutStatus = FALSE;
+  UnlockUpdate();
+  return FALSE;
+}
+void CXFA_FFDocView::RunSubformIndexChange() {
+  int32_t iSubforms = m_IndexChangedSubforms.GetSize();
+  for (int32_t i = 0; i < iSubforms; i++) {
+    CXFA_Node* pSubformNode =
+        reinterpret_cast<CXFA_Node*>(m_IndexChangedSubforms[i]);
+    CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pSubformNode->GetWidgetData();
+    if (!pWidgetAcc) {
+      continue;
+    }
+    CXFA_EventParam eParam;
+    eParam.m_eType = XFA_EVENT_IndexChange;
+    eParam.m_pTarget = pWidgetAcc;
+    pWidgetAcc->ProcessEvent(XFA_ATTRIBUTEENUM_IndexChange, &eParam);
+  }
+  m_IndexChangedSubforms.RemoveAll();
+}
+void CXFA_FFDocView::AddNewFormNode(CXFA_Node* pNode) {
+  m_NewAddedNodes.Add(pNode);
+  InitLayout(pNode);
+}
+void CXFA_FFDocView::AddIndexChangedSubform(CXFA_Node* pNode) {
+  FXSYS_assert(pNode->GetClassID() == XFA_ELEMENT_Subform);
+  m_IndexChangedSubforms.Add(pNode);
+}
+void CXFA_FFDocView::RunDocClose() {
+  CXFA_Node* pRootItem =
+      ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form));
+  if (!pRootItem) {
+    return;
+  }
+  ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_DocClose);
+}
+void CXFA_FFDocView::DestroyDocView() {
+  ClearInvalidateList();
+  m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_None;
+  m_iLock = 0;
+  m_ValidateAccs.RemoveAll();
+  m_bindItems.RemoveAll();
+  m_CalculateAccs.RemoveAll();
+}
+FX_BOOL CXFA_FFDocView::IsStaticNotify() {
+  return m_pDoc->GetDocType() == XFA_DOCTYPE_Static;
+}
+void CXFA_FFDocView::AddCalculateWidgetAcc(CXFA_WidgetAcc* pWidgetAcc) {
+  int32_t iAccs = m_CalculateAccs.GetSize();
+  CXFA_WidgetAcc* pCurrentAcc =
+      (iAccs < 1) ? (CXFA_WidgetAcc*)NULL
+                  : (CXFA_WidgetAcc*)m_CalculateAccs[iAccs - 1];
+  if (pCurrentAcc != pWidgetAcc) {
+    m_CalculateAccs.Add(pWidgetAcc);
+  }
+}
+void CXFA_FFDocView::AddCalculateNodeNotify(CXFA_Node* pNodeChange) {
+  CXFA_CalcData* pGlobalData =
+      (CXFA_CalcData*)pNodeChange->GetUserData(XFA_CalcData);
+  int32_t iCount = pGlobalData ? pGlobalData->m_Globals.GetSize() : 0;
+  for (int32_t i = 0; i < iCount; i++) {
+    CXFA_WidgetAcc* pResultAcc = (CXFA_WidgetAcc*)pGlobalData->m_Globals[i];
+    if (pResultAcc->GetNode()->HasFlag(XFA_NODEFLAG_HasRemoved)) {
+      continue;
+    }
+    int32_t iAccs = m_CalculateAccs.GetSize();
+    CXFA_WidgetAcc* pCurrentAcc =
+        (iAccs < 1) ? (CXFA_WidgetAcc*)NULL
+                    : (CXFA_WidgetAcc*)m_CalculateAccs[iAccs - 1];
+    if (pCurrentAcc != pResultAcc) {
+      m_CalculateAccs.Add(pResultAcc);
+    }
+  }
+}
+void CXFA_FFDocView::RunCalculateRecursive(int32_t& iIndex) {
+  while (iIndex < m_CalculateAccs.GetSize()) {
+    CXFA_WidgetAcc* pCurAcc = (CXFA_WidgetAcc*)m_CalculateAccs[iIndex];
+    AddCalculateNodeNotify(pCurAcc->GetNode());
+    int32_t iRefCount =
+        (int32_t)(uintptr_t)pCurAcc->GetNode()->GetUserData(XFA_CalcRefCount);
+    iRefCount++;
+    pCurAcc->GetNode()->SetUserData(XFA_CalcRefCount,
+                                    (void*)(uintptr_t)iRefCount);
+    if (iRefCount > 11) {
+      break;
+    }
+    if ((pCurAcc->ProcessCalculate()) == XFA_EVENTERROR_Sucess) {
+      AddValidateWidget(pCurAcc);
+    }
+    iIndex++;
+    RunCalculateRecursive(iIndex);
+  }
+}
+int32_t CXFA_FFDocView::RunCalculateWidgets() {
+  if (!m_pDoc->GetDocProvider()->IsCalculationsEnabled(m_pDoc)) {
+    return XFA_EVENTERROR_Disabled;
+  }
+  int32_t iCounts = m_CalculateAccs.GetSize();
+  int32_t iIndex = 0;
+  if (iCounts > 0) {
+    RunCalculateRecursive(iIndex);
+  }
+  for (int32_t i = 0; i < m_CalculateAccs.GetSize(); i++) {
+    CXFA_WidgetAcc* pCurAcc = (CXFA_WidgetAcc*)m_CalculateAccs[i];
+    pCurAcc->GetNode()->SetUserData(XFA_CalcRefCount, (void*)(uintptr_t)0);
+  }
+  m_CalculateAccs.RemoveAll();
+  return XFA_EVENTERROR_Sucess;
+}
+void CXFA_FFDocView::AddValidateWidget(CXFA_WidgetAcc* pWidget) {
+  if (m_ValidateAccs.Find(pWidget) < 0) {
+    m_ValidateAccs.Add(pWidget);
+  }
+}
+FX_BOOL CXFA_FFDocView::InitCalculate(CXFA_Node* pNode) {
+  ExecEventActivityByDeepFirst(pNode, XFA_EVENT_InitCalculate);
+  return TRUE;
+}
+FX_BOOL CXFA_FFDocView::InitValidate(CXFA_Node* pNode) {
+  if (!m_pDoc->GetDocProvider()->IsValidationsEnabled(m_pDoc)) {
+    return FALSE;
+  }
+  ExecEventActivityByDeepFirst(pNode, XFA_EVENT_Validate);
+  m_ValidateAccs.RemoveAll();
+  return TRUE;
+}
+FX_BOOL CXFA_FFDocView::RunValidate() {
+  if (!m_pDoc->GetDocProvider()->IsValidationsEnabled(m_pDoc)) {
+    return FALSE;
+  }
+  int32_t iCounts = m_ValidateAccs.GetSize();
+  for (int32_t i = 0; i < iCounts; i++) {
+    CXFA_WidgetAcc* pAcc = (CXFA_WidgetAcc*)m_ValidateAccs[i];
+    if (pAcc->GetNode()->HasFlag(XFA_NODEFLAG_HasRemoved)) {
+      continue;
+    }
+    pAcc->ProcessValidate();
+  }
+  m_ValidateAccs.RemoveAll();
+  return TRUE;
+}
+FX_BOOL CXFA_FFDocView::RunEventLayoutReady() {
+  CXFA_Node* pRootItem =
+      ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form));
+  if (!pRootItem) {
+    return FALSE;
+  }
+  ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_Ready);
+  RunLayout();
+  return TRUE;
+}
+void CXFA_FFDocView::RunBindItems() {
+  int32_t iCount = m_bindItems.GetSize();
+  for (int32_t i = 0; i < iCount; i++) {
+    if (reinterpret_cast<CXFA_Node*>(m_bindItems[i])
+            ->HasFlag(XFA_NODEFLAG_HasRemoved)) {
+      continue;
+    }
+    CXFA_Node* pWidgetNode = reinterpret_cast<CXFA_Node*>(m_bindItems[i])
+                                 ->GetNodeItem(XFA_NODEITEM_Parent);
+    CXFA_WidgetAcc* pAcc = (CXFA_WidgetAcc*)pWidgetNode->GetWidgetData();
+    if (!pAcc) {
+      continue;
+    }
+    CXFA_BindItems binditems(reinterpret_cast<CXFA_Node*>(m_bindItems[i]));
+    IXFA_ScriptContext* pScriptContext =
+        pWidgetNode->GetDocument()->GetScriptContext();
+    CFX_WideStringC wsRef;
+    binditems.GetRef(wsRef);
+    FX_DWORD dwStyle = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
+                       XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent |
+                       XFA_RESOLVENODE_ALL;
+    XFA_RESOLVENODE_RS rs;
+    pScriptContext->ResolveObjects(pWidgetNode, wsRef, rs, dwStyle);
+    int32_t iCount = rs.nodes.GetSize();
+    pAcc->DeleteItem(-1);
+    if (rs.dwFlags != XFA_RESOVENODE_RSTYPE_Nodes || iCount < 1) {
+      continue;
+    }
+    CFX_WideStringC wsValueRef, wsLabelRef;
+    binditems.GetValueRef(wsValueRef);
+    binditems.GetLabelRef(wsLabelRef);
+    const bool bUseValue = wsLabelRef.IsEmpty() || wsLabelRef == wsValueRef;
+    const bool bLabelUseContent =
+        wsLabelRef.IsEmpty() || wsLabelRef == FX_WSTRC(L"$");
+    const bool bValueUseContent =
+        wsValueRef.IsEmpty() || wsValueRef == FX_WSTRC(L"$");
+    CFX_WideString wsValue, wsLabel;
+    FX_DWORD uValueHash = FX_HashCode_String_GetW(CFX_WideString(wsValueRef),
+                                                  wsValueRef.GetLength());
+    for (int32_t i = 0; i < iCount; i++) {
+      CXFA_Object* refObj = rs.nodes[i];
+      if (!refObj->IsNode()) {
+        continue;
+      }
+      CXFA_Node* refNode = refObj->AsNode();
+      if (bValueUseContent) {
+        wsValue = refNode->GetContent();
+      } else {
+        CXFA_Node* nodeValue = refNode->GetFirstChildByName(uValueHash);
+        if (nodeValue == NULL) {
+          wsValue = refNode->GetContent();
+        } else {
+          wsValue = nodeValue->GetContent();
+        }
+      }
+      if (!bUseValue) {
+        if (bLabelUseContent) {
+          wsLabel = refNode->GetContent();
+        } else {
+          CXFA_Node* nodeLabel = refNode->GetFirstChildByName(wsLabelRef);
+          if (nodeLabel)
+            wsLabel = nodeLabel->GetContent();
+        }
+      } else {
+        wsLabel = wsValue;
+      }
+      pAcc->InsertItem(wsLabel, wsValue);
+    }
+  }
+  m_bindItems.RemoveAll();
+}
+void CXFA_FFDocView::SetChangeMark() {
+  if (m_iStatus < XFA_DOCVIEW_LAYOUTSTATUS_End) {
+    return;
+  }
+  m_pDoc->GetDocProvider()->SetChangeMark(m_pDoc);
+}
+CXFA_Node* CXFA_FFDocView::GetRootSubform() {
+  CXFA_Node* pFormPacketNode =
+      ToNode(m_pDoc->GetXFADoc()->GetXFAObject(XFA_HASHCODE_Form));
+  if (!pFormPacketNode) {
+    return NULL;
+  }
+  return pFormPacketNode->GetFirstChildByClass(XFA_ELEMENT_Subform);
+}
+CXFA_FFDocWidgetIterator::CXFA_FFDocWidgetIterator(CXFA_FFDocView* pDocView,
+                                                   CXFA_Node* pTravelRoot)
+    : m_ContentIterator(pTravelRoot) {
+  m_pDocView = pDocView;
+  m_pCurWidget = NULL;
+}
+CXFA_FFDocWidgetIterator::~CXFA_FFDocWidgetIterator() {}
+void CXFA_FFDocWidgetIterator::Reset() {
+  m_ContentIterator.Reset();
+  m_pCurWidget = NULL;
+}
+IXFA_Widget* CXFA_FFDocWidgetIterator::MoveToFirst() {
+  return NULL;
+}
+IXFA_Widget* CXFA_FFDocWidgetIterator::MoveToLast() {
+  return NULL;
+}
+IXFA_Widget* CXFA_FFDocWidgetIterator::MoveToNext() {
+  CXFA_Node* pItem = m_pCurWidget ? m_ContentIterator.MoveToNext()
+                                  : m_ContentIterator.GetCurrent();
+  while (pItem) {
+    if (CXFA_WidgetAcc* pAcc = (CXFA_WidgetAcc*)pItem->GetWidgetData()) {
+      while ((m_pCurWidget = pAcc->GetNextWidget(NULL))) {
+        if (!m_pCurWidget->IsLoaded() &&
+            (m_pCurWidget->GetStatus() & XFA_WIDGETSTATUS_Visible)) {
+          m_pCurWidget->LoadWidget();
+        }
+        return m_pCurWidget;
+      }
+    }
+    pItem = m_ContentIterator.MoveToNext();
+  }
+  return NULL;
+}
+IXFA_Widget* CXFA_FFDocWidgetIterator::MoveToPrevious() {
+  return NULL;
+}
+IXFA_Widget* CXFA_FFDocWidgetIterator::GetCurrentWidget() {
+  return NULL;
+}
+FX_BOOL CXFA_FFDocWidgetIterator::SetCurrentWidget(IXFA_Widget* hWidget) {
+  return FALSE;
+}
+IXFA_WidgetAccIterator* XFA_WidgetAccIterator_Create(
+    CXFA_WidgetAcc* pTravelRoot,
+    XFA_WIDGETORDER eOrder) {
+  if (!pTravelRoot) {
+    return NULL;
+  }
+  return new CXFA_WidgetAccIterator(pTravelRoot->GetDocView(),
+                                    pTravelRoot->GetNode());
+}
+CXFA_WidgetAccIterator::CXFA_WidgetAccIterator(CXFA_FFDocView* pDocView,
+                                               CXFA_Node* pTravelRoot)
+    : m_ContentIterator(pTravelRoot) {
+  m_pDocView = pDocView;
+  m_pCurWidgetAcc = NULL;
+}
+CXFA_WidgetAccIterator::~CXFA_WidgetAccIterator() {}
+void CXFA_WidgetAccIterator::Reset() {
+  m_pCurWidgetAcc = NULL;
+  m_ContentIterator.Reset();
+}
+CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToFirst() {
+  return NULL;
+}
+CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToLast() {
+  return NULL;
+}
+CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToNext() {
+  CXFA_Node* pItem = m_pCurWidgetAcc ? m_ContentIterator.MoveToNext()
+                                     : m_ContentIterator.GetCurrent();
+  while (pItem) {
+    if ((m_pCurWidgetAcc = (CXFA_WidgetAcc*)pItem->GetWidgetData())) {
+      return m_pCurWidgetAcc;
+    }
+    pItem = m_ContentIterator.MoveToNext();
+  }
+  return NULL;
+}
+CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToPrevious() {
+  return NULL;
+}
+CXFA_WidgetAcc* CXFA_WidgetAccIterator::GetCurrentWidgetAcc() {
+  return NULL;
+}
+FX_BOOL CXFA_WidgetAccIterator::SetCurrentWidgetAcc(CXFA_WidgetAcc* hWidget) {
+  return FALSE;
+}
+void CXFA_WidgetAccIterator::SkipTree() {
+  m_ContentIterator.SkipChildrenAndMoveToNext();
+  m_pCurWidgetAcc = NULL;
+}
diff --git a/xfa/fxfa/app/xfa_ffdocview.h b/xfa/fxfa/app/xfa_ffdocview.h
new file mode 100644
index 0000000..284a32f
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffdocview.h
@@ -0,0 +1,170 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFDOCVIEW_H_
+#define XFA_FXFA_APP_XFA_FFDOCVIEW_H_
+
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+
+class CXFA_FFWidgetHandler;
+class CXFA_FFDoc;
+class CXFA_FFWidget;
+extern const XFA_ATTRIBUTEENUM gs_EventActivity[];
+enum XFA_DOCVIEW_LAYOUTSTATUS {
+  XFA_DOCVIEW_LAYOUTSTATUS_None,
+  XFA_DOCVIEW_LAYOUTSTATUS_Start,
+  XFA_DOCVIEW_LAYOUTSTATUS_FormInitialize,
+  XFA_DOCVIEW_LAYOUTSTATUS_FormInitCalculate,
+  XFA_DOCVIEW_LAYOUTSTATUS_FormInitValidate,
+  XFA_DOCVIEW_LAYOUTSTATUS_FormFormReady,
+  XFA_DOCVIEW_LAYOUTSTATUS_Doing,
+  XFA_DOCVIEW_LAYOUTSTATUS_PagesetInitialize,
+  XFA_DOCVIEW_LAYOUTSTATUS_PagesetInitCalculate,
+  XFA_DOCVIEW_LAYOUTSTATUS_PagesetInitValidate,
+  XFA_DOCVIEW_LAYOUTSTATUS_PagesetFormReady,
+  XFA_DOCVIEW_LAYOUTSTATUS_LayoutReady,
+  XFA_DOCVIEW_LAYOUTSTATUS_DocReady,
+  XFA_DOCVIEW_LAYOUTSTATUS_End
+};
+class CXFA_FFDocView : public IXFA_DocView {
+ public:
+  CXFA_FFDocView(CXFA_FFDoc* pDoc);
+  ~CXFA_FFDocView();
+
+  virtual IXFA_Doc* GetDoc() { return m_pDoc; }
+  virtual int32_t StartLayout(int32_t iStartPage = 0);
+  virtual int32_t DoLayout(IFX_Pause* pPause = NULL);
+  virtual void StopLayout();
+  virtual int32_t GetLayoutStatus();
+  virtual void UpdateDocView();
+  virtual int32_t CountPageViews();
+  virtual IXFA_PageView* GetPageView(int32_t nIndex);
+  virtual IXFA_Widget* GetWidgetByName(const CFX_WideStringC& wsName);
+  virtual CXFA_WidgetAcc* GetWidgetAccByName(const CFX_WideStringC& wsName);
+  virtual void ResetWidgetData(CXFA_WidgetAcc* pWidgetAcc = NULL);
+  virtual int32_t ProcessWidgetEvent(CXFA_EventParam* pParam,
+                                     CXFA_WidgetAcc* pWidgetAcc = NULL);
+  virtual IXFA_WidgetHandler* GetWidgetHandler();
+  virtual IXFA_WidgetIterator* CreateWidgetIterator();
+  virtual IXFA_WidgetAccIterator* CreateWidgetAccIterator(
+      XFA_WIDGETORDER eOrder = XFA_WIDGETORDER_PreOrder);
+  virtual IXFA_Widget* GetFocusWidget();
+  virtual void KillFocus();
+  virtual FX_BOOL SetFocus(IXFA_Widget* hWidget);
+  CXFA_FFWidget* GetWidgetByName(const CFX_WideStringC& wsName,
+                                 CXFA_FFWidget* pRefWidget = NULL);
+  CXFA_WidgetAcc* GetWidgetAccByName(const CFX_WideStringC& wsName,
+                                     CXFA_WidgetAcc* pRefWidgetAcc = NULL);
+  IXFA_DocLayout* GetXFALayout() const;
+  void OnPageEvent(IXFA_LayoutPage* pSender,
+                   XFA_PAGEEVENT eEvent,
+                   int32_t iPageIndex);
+  void LockUpdate();
+  void UnlockUpdate();
+  FX_BOOL IsUpdateLocked();
+  void ClearInvalidateList();
+  void AddInvalidateRect(CXFA_FFWidget* pWidget, const CFX_RectF& rtInvalidate);
+  void AddInvalidateRect(IXFA_PageView* pPageView,
+                         const CFX_RectF& rtInvalidate);
+  void RunInvalidate();
+  void RunDocClose();
+  void DestroyDocView();
+
+  FX_BOOL InitValidate(CXFA_Node* pNode);
+  FX_BOOL RunValidate();
+
+  void SetChangeMark();
+
+  void AddValidateWidget(CXFA_WidgetAcc* pWidget);
+  void AddCalculateNodeNotify(CXFA_Node* pNodeChange);
+  void AddCalculateWidgetAcc(CXFA_WidgetAcc* pWidgetAcc);
+  int32_t RunCalculateWidgets();
+  FX_BOOL IsStaticNotify();
+  FX_BOOL RunLayout();
+  void RunSubformIndexChange();
+  void AddNewFormNode(CXFA_Node* pNode);
+  void AddIndexChangedSubform(CXFA_Node* pNode);
+  CXFA_WidgetAcc* GetFocusWidgetAcc();
+  void SetFocusWidgetAcc(CXFA_WidgetAcc* pWidgetAcc);
+  void DeleteLayoutItem(CXFA_FFWidget* pWidget);
+  int32_t ExecEventActivityByDeepFirst(CXFA_Node* pFormNode,
+                                       XFA_EVENTTYPE eEventType,
+                                       FX_BOOL bIsFormReady = FALSE,
+                                       FX_BOOL bRecursive = TRUE,
+                                       CXFA_Node* pExclude = NULL);
+  FX_BOOL m_bLayoutEvent;
+  CFX_WideStringArray m_arrNullTestMsg;
+  CXFA_FFWidget* m_pListFocusWidget;
+  FX_BOOL m_bInLayoutStatus;
+
+ protected:
+  FX_BOOL RunEventLayoutReady();
+  void RunBindItems();
+  FX_BOOL InitCalculate(CXFA_Node* pNode);
+  void InitLayout(CXFA_Node* pNode);
+  void RunCalculateRecursive(int32_t& iIndex);
+  void ShowNullTestMsg();
+  FX_BOOL ResetSingleWidgetAccData(CXFA_WidgetAcc* pWidgetAcc);
+  CXFA_Node* GetRootSubform();
+
+  CXFA_FFDoc* m_pDoc;
+  CXFA_FFWidgetHandler* m_pWidgetHandler;
+  IXFA_DocLayout* m_pXFADocLayout;
+  CXFA_WidgetAcc* m_pFocusAcc;
+  CXFA_FFWidget* m_pFocusWidget;
+  CXFA_FFWidget* m_pOldFocusWidget;
+  CFX_MapPtrToPtr m_mapPageInvalidate;
+  CFX_PtrArray m_ValidateAccs;
+  CFX_PtrArray m_bindItems;
+  CFX_PtrArray m_CalculateAccs;
+
+  CFX_PtrArray m_NewAddedNodes;
+  CFX_PtrArray m_IndexChangedSubforms;
+  XFA_DOCVIEW_LAYOUTSTATUS m_iStatus;
+  int32_t m_iLock;
+  friend class CXFA_FFNotify;
+};
+class CXFA_FFDocWidgetIterator : public IXFA_WidgetIterator {
+ public:
+  CXFA_FFDocWidgetIterator(CXFA_FFDocView* pDocView, CXFA_Node* pTravelRoot);
+  virtual ~CXFA_FFDocWidgetIterator();
+
+  virtual void Release() { delete this; }
+
+  virtual void Reset();
+  virtual IXFA_Widget* MoveToFirst();
+  virtual IXFA_Widget* MoveToLast();
+  virtual IXFA_Widget* MoveToNext();
+  virtual IXFA_Widget* MoveToPrevious();
+  virtual IXFA_Widget* GetCurrentWidget();
+  virtual FX_BOOL SetCurrentWidget(IXFA_Widget* hWidget);
+
+ protected:
+  CXFA_ContainerIterator m_ContentIterator;
+  CXFA_FFDocView* m_pDocView;
+  CXFA_FFWidget* m_pCurWidget;
+};
+class CXFA_WidgetAccIterator : public IXFA_WidgetAccIterator {
+ public:
+  CXFA_WidgetAccIterator(CXFA_FFDocView* pDocView, CXFA_Node* pTravelRoot);
+  virtual ~CXFA_WidgetAccIterator();
+  virtual void Release() { delete this; }
+  virtual void Reset();
+  virtual CXFA_WidgetAcc* MoveToFirst();
+  virtual CXFA_WidgetAcc* MoveToLast();
+  virtual CXFA_WidgetAcc* MoveToNext();
+  virtual CXFA_WidgetAcc* MoveToPrevious();
+  virtual CXFA_WidgetAcc* GetCurrentWidgetAcc();
+  virtual FX_BOOL SetCurrentWidgetAcc(CXFA_WidgetAcc* hWidget);
+  virtual void SkipTree();
+
+ protected:
+  CXFA_ContainerIterator m_ContentIterator;
+  CXFA_FFDocView* m_pDocView;
+  CXFA_WidgetAcc* m_pCurWidgetAcc;
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFDOCVIEW_H_
diff --git a/xfa/fxfa/app/xfa_ffdraw.cpp b/xfa/fxfa/app/xfa_ffdraw.cpp
new file mode 100644
index 0000000..06cfdfe
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffdraw.cpp
@@ -0,0 +1,16 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffdraw.h"
+
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+
+CXFA_FFDraw::CXFA_FFDraw(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFWidget(pPageView, pDataAcc) {}
+CXFA_FFDraw::~CXFA_FFDraw() {}
diff --git a/xfa/fxfa/app/xfa_ffdraw.h b/xfa/fxfa/app/xfa_ffdraw.h
new file mode 100644
index 0000000..a5db598
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffdraw.h
@@ -0,0 +1,19 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFDRAW_H_
+#define XFA_FXFA_APP_XFA_FFDRAW_H_
+
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+
+class CXFA_FFDraw : public CXFA_FFWidget {
+ public:
+  CXFA_FFDraw(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFDraw();
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFDRAW_H_
diff --git a/xfa/fxfa/app/xfa_ffexclgroup.cpp b/xfa/fxfa/app/xfa_ffexclgroup.cpp
new file mode 100644
index 0000000..4e24218
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffexclgroup.cpp
@@ -0,0 +1,31 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffexclgroup.h"
+
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+
+CXFA_FFExclGroup::CXFA_FFExclGroup(CXFA_FFPageView* pPageView,
+                                   CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFWidget(pPageView, pDataAcc) {}
+CXFA_FFExclGroup::~CXFA_FFExclGroup() {}
+void CXFA_FFExclGroup::RenderWidget(CFX_Graphics* pGS,
+                                    CFX_Matrix* pMatrix,
+                                    FX_DWORD dwStatus,
+                                    int32_t iRotate) {
+  if (!IsMatchVisibleStatus(dwStatus)) {
+    return;
+  }
+  CFX_Matrix mtRotate;
+  GetRotateMatrix(mtRotate);
+  if (pMatrix) {
+    mtRotate.Concat(*pMatrix);
+  }
+  CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+}
diff --git a/xfa/fxfa/app/xfa_ffexclgroup.h b/xfa/fxfa/app/xfa_ffexclgroup.h
new file mode 100644
index 0000000..fd3f4d8
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffexclgroup.h
@@ -0,0 +1,24 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFEXCLGROUP_H_
+#define XFA_FXFA_APP_XFA_FFEXCLGROUP_H_
+
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+
+class CXFA_FFExclGroup : public CXFA_FFWidget {
+ public:
+  CXFA_FFExclGroup(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFExclGroup();
+
+  virtual void RenderWidget(CFX_Graphics* pGS,
+                            CFX_Matrix* pMatrix = NULL,
+                            FX_DWORD dwStatus = 0,
+                            int32_t iRotate = 0);
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFEXCLGROUP_H_
diff --git a/xfa/fxfa/app/xfa_fffield.cpp b/xfa/fxfa/app/xfa_fffield.cpp
new file mode 100644
index 0000000..39e7ee5
--- /dev/null
+++ b/xfa/fxfa/app/xfa_fffield.cpp
@@ -0,0 +1,835 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_fffield.h"
+
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_ffdocview.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+#include "xfa/fxfa/app/xfa_fwltheme.h"
+#include "xfa/fxfa/app/xfa_textlayout.h"
+#include "xfa/include/fwl/basewidget/fwl_edit.h"
+#include "xfa/include/fwl/core/fwl_widgetmgr.h"
+#include "xfa/include/fwl/lightwidget/edit.h"
+#include "xfa/include/fwl/lightwidget/picturebox.h"
+
+CXFA_FFField::CXFA_FFField(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFWidget(pPageView, pDataAcc), m_pNormalWidget(NULL) {
+  m_rtUI.Set(0, 0, 0, 0);
+  m_rtCaption.Set(0, 0, 0, 0);
+}
+CXFA_FFField::~CXFA_FFField() {
+  CXFA_FFField::UnloadWidget();
+}
+
+FX_BOOL CXFA_FFField::GetBBox(CFX_RectF& rtBox,
+                              FX_DWORD dwStatus,
+                              FX_BOOL bDrawFocus) {
+  if (!bDrawFocus)
+    return CXFA_FFWidget::GetBBox(rtBox, dwStatus);
+
+  XFA_ELEMENT type = (XFA_ELEMENT)m_pDataAcc->GetUIType();
+  if (type == XFA_ELEMENT_Button || type == XFA_ELEMENT_CheckButton ||
+      type == XFA_ELEMENT_ImageEdit || type == XFA_ELEMENT_Signature ||
+      type == XFA_ELEMENT_ChoiceList) {
+    rtBox = m_rtUI;
+    CFX_Matrix mt;
+    GetRotateMatrix(mt);
+    mt.TransformRect(rtBox);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+void CXFA_FFField::RenderWidget(CFX_Graphics* pGS,
+                                CFX_Matrix* pMatrix,
+                                FX_DWORD dwStatus,
+                                int32_t iRotate) {
+  if (!IsMatchVisibleStatus(dwStatus)) {
+    return;
+  }
+  CFX_Matrix mtRotate;
+  GetRotateMatrix(mtRotate);
+  if (pMatrix) {
+    mtRotate.Concat(*pMatrix);
+  }
+  CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+  CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
+  DrawBorder(pGS, borderUI, m_rtUI, &mtRotate);
+  RenderCaption(pGS, &mtRotate);
+  DrawHighlight(pGS, &mtRotate, dwStatus, FALSE);
+  CFX_RectF rtWidget;
+  m_pNormalWidget->GetWidgetRect(rtWidget);
+  CFX_Matrix mt;
+  mt.Set(1, 0, 0, 1, rtWidget.left, rtWidget.top);
+  mt.Concat(mtRotate);
+  GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget->GetWidget(),
+                                                 pGS, &mt);
+}
+void CXFA_FFField::DrawHighlight(CFX_Graphics* pGS,
+                                 CFX_Matrix* pMatrix,
+                                 FX_DWORD dwStatus,
+                                 FX_BOOL bEllipse) {
+  if (m_rtUI.IsEmpty() || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+    return;
+  }
+  if ((dwStatus & XFA_WIDGETSTATUS_Highlight) &&
+      m_pDataAcc->GetAccess() == XFA_ATTRIBUTEENUM_Open) {
+    CXFA_FFDoc* pDoc = GetDoc();
+    CFX_Color crHighlight(pDoc->GetDocProvider()->GetHighlightColor(pDoc));
+    pGS->SetFillColor(&crHighlight);
+    CFX_Path path;
+    path.Create();
+    if (bEllipse) {
+      path.AddEllipse(m_rtUI);
+    } else {
+      path.AddRectangle(m_rtUI.left, m_rtUI.top, m_rtUI.width, m_rtUI.height);
+    }
+    pGS->FillPath(&path, FXFILL_WINDING, pMatrix);
+  }
+}
+void CXFA_FFField::DrawFocus(CFX_Graphics* pGS, CFX_Matrix* pMatrix) {
+  if (m_dwStatus & XFA_WIDGETSTATUS_Focused) {
+    CFX_Color cr(0xFF000000);
+    pGS->SetStrokeColor(&cr);
+    FX_FLOAT DashPattern[2] = {1, 1};
+    pGS->SetLineDash(0.0f, DashPattern, 2);
+    pGS->SetLineWidth(0, FALSE);
+    CFX_Path path;
+    path.Create();
+    path.AddRectangle(m_rtUI.left, m_rtUI.top, m_rtUI.width, m_rtUI.height);
+    pGS->StrokePath(&path, pMatrix);
+  }
+}
+void CXFA_FFField::SetFWLThemeProvider() {
+  if (m_pNormalWidget) {
+    m_pNormalWidget->m_pIface->SetThemeProvider(GetApp()->GetFWLTheme());
+  }
+}
+FX_BOOL CXFA_FFField::IsLoaded() {
+  return m_pNormalWidget && CXFA_FFWidget::IsLoaded();
+}
+FX_BOOL CXFA_FFField::LoadWidget() {
+  SetFWLThemeProvider();
+  m_pDataAcc->LoadCaption();
+  PerformLayout();
+  return TRUE;
+}
+void CXFA_FFField::UnloadWidget() {
+  delete m_pNormalWidget;
+  m_pNormalWidget = nullptr;
+}
+void CXFA_FFField::SetEditScrollOffset() {
+  XFA_ELEMENT eType = m_pDataAcc->GetUIType();
+  if (eType == XFA_ELEMENT_TextEdit || eType == XFA_ELEMENT_NumericEdit ||
+      eType == XFA_ELEMENT_PasswordEdit) {
+    FX_FLOAT fScrollOffset = 0;
+    CXFA_FFField* pPrev = static_cast<CXFA_FFField*>(GetPrev());
+    if (pPrev) {
+      CFX_RectF rtMargin;
+      m_pDataAcc->GetUIMargin(rtMargin);
+      fScrollOffset = -rtMargin.top;
+    }
+    while (pPrev) {
+      fScrollOffset += pPrev->m_rtUI.height;
+      pPrev = static_cast<CXFA_FFField*>(pPrev->GetPrev());
+    }
+    ((CFWL_Edit*)m_pNormalWidget)->SetScrollOffset(fScrollOffset);
+  }
+}
+FX_BOOL CXFA_FFField::PerformLayout() {
+  CXFA_FFWidget::PerformLayout();
+  CapPlacement();
+  LayoutCaption();
+  SetFWLRect();
+  SetEditScrollOffset();
+  if (m_pNormalWidget) {
+    m_pNormalWidget->Update();
+  }
+  return TRUE;
+}
+void CXFA_FFField::CapPlacement() {
+  CFX_RectF rtWidget;
+  GetRectWithoutRotate(rtWidget);
+  CXFA_Margin mgWidget = m_pDataAcc->GetMargin();
+  if (mgWidget) {
+    CXFA_LayoutItem* pItem = this;
+    FX_FLOAT fLeftInset = 0, fRightInset = 0, fTopInset = 0, fBottomInset = 0;
+    mgWidget.GetLeftInset(fLeftInset);
+    mgWidget.GetRightInset(fRightInset);
+    mgWidget.GetTopInset(fTopInset);
+    mgWidget.GetBottomInset(fBottomInset);
+    if (pItem->GetPrev() == NULL && pItem->GetNext() == NULL) {
+      rtWidget.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset);
+    } else {
+      if (pItem->GetPrev() == NULL) {
+        rtWidget.Deflate(fLeftInset, fTopInset, fRightInset, 0);
+      } else if (pItem->GetNext() == NULL) {
+        rtWidget.Deflate(fLeftInset, 0, fRightInset, fBottomInset);
+      } else {
+        rtWidget.Deflate(fLeftInset, 0, fRightInset, 0);
+      }
+    }
+  }
+  XFA_ATTRIBUTEENUM iCapPlacement = XFA_ATTRIBUTEENUM_Unknown;
+  FX_FLOAT fCapReserve = 0;
+  CXFA_Caption caption = m_pDataAcc->GetCaption();
+  if (caption && caption.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) {
+    iCapPlacement = (XFA_ATTRIBUTEENUM)caption.GetPlacementType();
+    if (iCapPlacement == XFA_ATTRIBUTEENUM_Top && GetPrev()) {
+      m_rtCaption.Set(0, 0, 0, 0);
+    } else if (iCapPlacement == XFA_ATTRIBUTEENUM_Bottom && GetNext()) {
+      m_rtCaption.Set(0, 0, 0, 0);
+    } else {
+      fCapReserve = caption.GetReserve();
+      CXFA_LayoutItem* pItem = this;
+      if (pItem->GetPrev() == NULL && pItem->GetNext() == NULL) {
+        m_rtCaption.Set(rtWidget.left, rtWidget.top, rtWidget.width,
+                        rtWidget.height);
+      } else {
+        pItem = pItem->GetFirst();
+        pItem->GetRect(m_rtCaption);
+        pItem = pItem->GetNext();
+        while (pItem) {
+          CFX_RectF rtRect;
+          pItem->GetRect(rtRect);
+          m_rtCaption.height += rtRect.Height();
+          pItem = pItem->GetNext();
+        }
+        XFA_RectWidthoutMargin(m_rtCaption, mgWidget);
+      }
+      CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout();
+      if (fCapReserve <= 0 && pCapTextLayout) {
+        CFX_SizeF size;
+        CFX_SizeF minSize;
+        CFX_SizeF maxSize;
+        pCapTextLayout->CalcSize(minSize, maxSize, size);
+        if (iCapPlacement == XFA_ATTRIBUTEENUM_Top ||
+            iCapPlacement == XFA_ATTRIBUTEENUM_Bottom) {
+          fCapReserve = size.y;
+        } else {
+          fCapReserve = size.x;
+        }
+      }
+    }
+  }
+  m_rtUI = rtWidget;
+  switch (iCapPlacement) {
+    case XFA_ATTRIBUTEENUM_Left: {
+      m_rtCaption.width = fCapReserve;
+      CapLeftRightPlacement(caption, rtWidget, iCapPlacement);
+      m_rtUI.width -= fCapReserve;
+      m_rtUI.left += fCapReserve;
+    } break;
+    case XFA_ATTRIBUTEENUM_Top: {
+      m_rtCaption.height = fCapReserve;
+      CapTopBottomPlacement(caption, rtWidget, iCapPlacement);
+      m_rtUI.top += fCapReserve;
+      m_rtUI.height -= fCapReserve;
+    } break;
+    case XFA_ATTRIBUTEENUM_Right: {
+      m_rtCaption.left = m_rtCaption.right() - fCapReserve;
+      m_rtCaption.width = fCapReserve;
+      CapLeftRightPlacement(caption, rtWidget, iCapPlacement);
+      m_rtUI.width -= fCapReserve;
+    } break;
+    case XFA_ATTRIBUTEENUM_Bottom: {
+      m_rtCaption.top = m_rtCaption.bottom() - fCapReserve;
+      m_rtCaption.height = fCapReserve;
+      CapTopBottomPlacement(caption, rtWidget, iCapPlacement);
+      m_rtUI.height -= fCapReserve;
+    } break;
+    case XFA_ATTRIBUTEENUM_Inline:
+      break;
+    default:
+      break;
+  }
+  CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
+  if (borderUI) {
+    CXFA_Margin margin = borderUI.GetMargin();
+    if (margin) {
+      XFA_RectWidthoutMargin(m_rtUI, margin);
+    }
+  }
+  m_rtUI.Normalize();
+}
+void CXFA_FFField::CapTopBottomPlacement(CXFA_Caption caption,
+                                         const CFX_RectF& rtWidget,
+                                         int32_t iCapPlacement) {
+  CFX_RectF rtUIMargin;
+  m_pDataAcc->GetUIMargin(rtUIMargin);
+  m_rtCaption.left += rtUIMargin.left;
+  if (CXFA_Margin mgCap = caption.GetMargin()) {
+    XFA_RectWidthoutMargin(m_rtCaption, mgCap);
+    if (m_rtCaption.height < 0) {
+      m_rtCaption.top += m_rtCaption.height;
+    }
+  }
+  FX_FLOAT fWidth = rtUIMargin.left + rtUIMargin.width;
+  FX_FLOAT fHeight = m_rtCaption.height + rtUIMargin.top + rtUIMargin.height;
+  if (fWidth > rtWidget.width) {
+    m_rtUI.width += fWidth - rtWidget.width;
+  }
+  if (fHeight == XFA_DEFAULTUI_HEIGHT && m_rtUI.height < XFA_MINUI_HEIGHT) {
+    m_rtUI.height = XFA_MINUI_HEIGHT;
+    m_rtCaption.top += rtUIMargin.top + rtUIMargin.height;
+  } else if (fHeight > rtWidget.height) {
+    m_rtUI.height += fHeight - rtWidget.height;
+    if (iCapPlacement == XFA_ATTRIBUTEENUM_Bottom) {
+      m_rtCaption.top += fHeight - rtWidget.height;
+    }
+  }
+}
+void CXFA_FFField::CapLeftRightPlacement(CXFA_Caption caption,
+                                         const CFX_RectF& rtWidget,
+                                         int32_t iCapPlacement) {
+  CFX_RectF rtUIMargin;
+  m_pDataAcc->GetUIMargin(rtUIMargin);
+  m_rtCaption.top += rtUIMargin.top;
+  m_rtCaption.height -= rtUIMargin.top;
+  if (CXFA_Margin mgCap = caption.GetMargin()) {
+    XFA_RectWidthoutMargin(m_rtCaption, mgCap);
+    if (m_rtCaption.height < 0) {
+      m_rtCaption.top += m_rtCaption.height;
+    }
+  }
+  FX_FLOAT fWidth = m_rtCaption.width + rtUIMargin.left + rtUIMargin.width;
+  FX_FLOAT fHeight = rtUIMargin.top + rtUIMargin.height;
+  if (fWidth > rtWidget.width) {
+    m_rtUI.width += fWidth - rtWidget.width;
+    if (iCapPlacement == XFA_ATTRIBUTEENUM_Right) {
+      m_rtCaption.left += fWidth - rtWidget.width;
+    }
+  }
+  if (fHeight == XFA_DEFAULTUI_HEIGHT && m_rtUI.height < XFA_MINUI_HEIGHT) {
+    m_rtUI.height = XFA_MINUI_HEIGHT;
+    m_rtCaption.top += rtUIMargin.top + rtUIMargin.height;
+  } else if (fHeight > rtWidget.height) {
+    m_rtUI.height += fHeight - rtWidget.height;
+  }
+}
+void CXFA_FFField::UpdateFWL() {
+  if (m_pNormalWidget) {
+    m_pNormalWidget->Update();
+  }
+}
+FX_DWORD CXFA_FFField::UpdateUIProperty() {
+  CXFA_Node* pUiNode = m_pDataAcc->GetUIChild();
+  FX_DWORD dwStyle = 0;
+  if (pUiNode && pUiNode->GetClassID() == XFA_ELEMENT_DefaultUi) {
+    dwStyle = FWL_STYLEEXT_EDT_ReadOnly;
+  }
+  return dwStyle;
+}
+void CXFA_FFField::SetFWLRect() {
+  if (!m_pNormalWidget) {
+    return;
+  }
+  CFX_RectF rtUi = m_rtUI;
+  if (rtUi.width < 1.0) {
+    FXSYS_assert(rtUi.width < 1.0);
+    rtUi.width = 1.0;
+  }
+  if (!m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+    FX_FLOAT fFontSize = m_pDataAcc->GetFontSize();
+    if (rtUi.height < fFontSize) {
+      rtUi.height = fFontSize;
+    }
+  }
+  m_pNormalWidget->SetWidgetRect(rtUi);
+}
+FX_BOOL CXFA_FFField::OnMouseEnter() {
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  CFWL_MsgMouse ms;
+  ms.m_dwCmd = FWL_MSGMOUSECMD_MouseEnter;
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  ms.m_pSrcTarget = NULL;
+  TranslateFWLMessage(&ms);
+  return TRUE;
+}
+FX_BOOL CXFA_FFField::OnMouseExit() {
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  CFWL_MsgMouse ms;
+  ms.m_dwCmd = FWL_MSGMOUSECMD_MouseLeave;
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  TranslateFWLMessage(&ms);
+  return TRUE;
+}
+void CXFA_FFField::FWLToClient(FX_FLOAT& fx, FX_FLOAT& fy) {
+  if (!m_pNormalWidget) {
+    return;
+  }
+  CFX_RectF rtWidget;
+  m_pNormalWidget->GetWidgetRect(rtWidget);
+  fx -= rtWidget.left;
+  fy -= rtWidget.top;
+}
+FX_BOOL CXFA_FFField::OnLButtonDown(FX_DWORD dwFlags,
+                                    FX_FLOAT fx,
+                                    FX_FLOAT fy) {
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
+      !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+    return FALSE;
+  }
+  if (!PtInActiveRect(fx, fy)) {
+    return FALSE;
+  }
+  SetButtonDown(TRUE);
+  CFWL_MsgMouse ms;
+  ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonDown;
+  ms.m_dwFlags = dwFlags;
+  ms.m_fx = fx;
+  ms.m_fy = fy;
+  FWLToClient(ms.m_fx, ms.m_fy);
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  TranslateFWLMessage(&ms);
+  return TRUE;
+}
+FX_BOOL CXFA_FFField::OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  if (!IsButtonDown()) {
+    return FALSE;
+  }
+  SetButtonDown(FALSE);
+  CFWL_MsgMouse ms;
+  ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonUp;
+  ms.m_dwFlags = dwFlags;
+  ms.m_fx = fx;
+  ms.m_fy = fy;
+  FWLToClient(ms.m_fx, ms.m_fy);
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  TranslateFWLMessage(&ms);
+  return TRUE;
+}
+FX_BOOL CXFA_FFField::OnLButtonDblClk(FX_DWORD dwFlags,
+                                      FX_FLOAT fx,
+                                      FX_FLOAT fy) {
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  CFWL_MsgMouse ms;
+  ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonDblClk;
+  ms.m_dwFlags = dwFlags;
+  ms.m_fx = fx;
+  ms.m_fy = fy;
+  FWLToClient(ms.m_fx, ms.m_fy);
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  TranslateFWLMessage(&ms);
+  return TRUE;
+}
+FX_BOOL CXFA_FFField::OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  CFWL_MsgMouse ms;
+  ms.m_dwCmd = FWL_MSGMOUSECMD_MouseMove;
+  ms.m_dwFlags = dwFlags;
+  ms.m_fx = fx;
+  ms.m_fy = fy;
+  FWLToClient(ms.m_fx, ms.m_fy);
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  TranslateFWLMessage(&ms);
+  return TRUE;
+}
+FX_BOOL CXFA_FFField::OnMouseWheel(FX_DWORD dwFlags,
+                                   int16_t zDelta,
+                                   FX_FLOAT fx,
+                                   FX_FLOAT fy) {
+  return FALSE;
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  CFWL_MsgMouseWheel ms;
+  ms.m_dwFlags = dwFlags;
+  ms.m_fx = fx;
+  ms.m_fy = fy;
+  FWLToClient(ms.m_fx, ms.m_fy);
+  ms.m_fDeltaX = zDelta;
+  ms.m_fDeltaY = 0;
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  TranslateFWLMessage(&ms);
+  return TRUE;
+}
+FX_BOOL CXFA_FFField::OnRButtonDown(FX_DWORD dwFlags,
+                                    FX_FLOAT fx,
+                                    FX_FLOAT fy) {
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
+      !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+    return FALSE;
+  }
+  if (!PtInActiveRect(fx, fy)) {
+    return FALSE;
+  }
+  SetButtonDown(TRUE);
+  CFWL_MsgMouse ms;
+  ms.m_dwCmd = FWL_MSGMOUSECMD_RButtonDown;
+  ms.m_dwFlags = dwFlags;
+  ms.m_fx = fx;
+  ms.m_fy = fy;
+  FWLToClient(ms.m_fx, ms.m_fy);
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  TranslateFWLMessage(&ms);
+  return TRUE;
+}
+FX_BOOL CXFA_FFField::OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  if (!IsButtonDown()) {
+    return FALSE;
+  }
+  SetButtonDown(FALSE);
+  CFWL_MsgMouse ms;
+  ms.m_dwCmd = FWL_MSGMOUSECMD_RButtonUp;
+  ms.m_dwFlags = dwFlags;
+  ms.m_fx = fx;
+  ms.m_fy = fy;
+  FWLToClient(ms.m_fx, ms.m_fy);
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  TranslateFWLMessage(&ms);
+  return TRUE;
+}
+FX_BOOL CXFA_FFField::OnRButtonDblClk(FX_DWORD dwFlags,
+                                      FX_FLOAT fx,
+                                      FX_FLOAT fy) {
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  CFWL_MsgMouse ms;
+  ms.m_dwCmd = FWL_MSGMOUSECMD_RButtonDblClk;
+  ms.m_dwFlags = dwFlags;
+  ms.m_fx = fx;
+  ms.m_fy = fy;
+  FWLToClient(ms.m_fx, ms.m_fy);
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  TranslateFWLMessage(&ms);
+  return TRUE;
+}
+
+FX_BOOL CXFA_FFField::OnSetFocus(CXFA_FFWidget* pOldWidget) {
+  CXFA_FFWidget::OnSetFocus(pOldWidget);
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  CFWL_MsgSetFocus ms;
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  ms.m_pSrcTarget = NULL;
+  TranslateFWLMessage(&ms);
+  m_dwStatus |= XFA_WIDGETSTATUS_Focused;
+  AddInvalidateRect();
+  return TRUE;
+}
+FX_BOOL CXFA_FFField::OnKillFocus(CXFA_FFWidget* pNewWidget) {
+  if (!m_pNormalWidget) {
+    return CXFA_FFWidget::OnKillFocus(pNewWidget);
+  }
+  CFWL_MsgKillFocus ms;
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  ms.m_pSrcTarget = NULL;
+  TranslateFWLMessage(&ms);
+  m_dwStatus &= ~XFA_WIDGETSTATUS_Focused;
+  AddInvalidateRect();
+  CXFA_FFWidget::OnKillFocus(pNewWidget);
+  return TRUE;
+}
+FX_BOOL CXFA_FFField::OnKeyDown(FX_DWORD dwKeyCode, FX_DWORD dwFlags) {
+  if (!m_pNormalWidget || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+    return FALSE;
+  }
+  CFWL_MsgKey ms;
+  ms.m_dwCmd = FWL_MSGKEYCMD_KeyDown;
+  ms.m_dwFlags = dwFlags;
+  ms.m_dwKeyCode = dwKeyCode;
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  ms.m_pSrcTarget = NULL;
+  TranslateFWLMessage(&ms);
+  return TRUE;
+}
+FX_BOOL CXFA_FFField::OnKeyUp(FX_DWORD dwKeyCode, FX_DWORD dwFlags) {
+  if (!m_pNormalWidget || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+    return FALSE;
+  }
+  CFWL_MsgKey ms;
+  ms.m_dwCmd = FWL_MSGKEYCMD_KeyUp;
+  ms.m_dwFlags = dwFlags;
+  ms.m_dwKeyCode = dwKeyCode;
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  ms.m_pSrcTarget = NULL;
+  TranslateFWLMessage(&ms);
+  return TRUE;
+}
+FX_BOOL CXFA_FFField::OnChar(FX_DWORD dwChar, FX_DWORD dwFlags) {
+  if (!m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+    return FALSE;
+  }
+  if (dwChar == FWL_VKEY_Tab) {
+    return TRUE;
+  }
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
+    return FALSE;
+  }
+  CFWL_MsgKey ms;
+  ms.m_dwCmd = FWL_MSGKEYCMD_Char;
+  ms.m_dwFlags = dwFlags;
+  ms.m_dwKeyCode = dwChar;
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  ms.m_pSrcTarget = NULL;
+  TranslateFWLMessage(&ms);
+  return TRUE;
+}
+FX_DWORD CXFA_FFField::OnHitTest(FX_FLOAT fx, FX_FLOAT fy) {
+  if (m_pNormalWidget) {
+    FX_FLOAT ffx = fx, ffy = fy;
+    FWLToClient(ffx, ffy);
+    FX_DWORD dwWidgetHit = m_pNormalWidget->HitTest(ffx, ffy);
+    if (dwWidgetHit != FWL_WGTHITTEST_Unknown) {
+      return FWL_WGTHITTEST_Client;
+    }
+  }
+  CFX_RectF rtBox;
+  GetRectWithoutRotate(rtBox);
+  if (!rtBox.Contains(fx, fy)) {
+    return FWL_WGTHITTEST_Unknown;
+  }
+  if (m_rtCaption.Contains(fx, fy)) {
+    return FWL_WGTHITTEST_Titlebar;
+  }
+  return FWL_WGTHITTEST_Border;
+}
+FX_BOOL CXFA_FFField::OnSetCursor(FX_FLOAT fx, FX_FLOAT fy) {
+  return TRUE;
+}
+FX_BOOL CXFA_FFField::PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy) {
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  CFX_RectF rtWidget;
+  m_pNormalWidget->GetWidgetRect(rtWidget);
+  if (rtWidget.Contains(fx, fy)) {
+    return TRUE;
+  }
+  return FALSE;
+}
+void CXFA_FFField::LayoutCaption() {
+  CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout();
+  if (!pCapTextLayout)
+    return;
+
+  FX_FLOAT fHeight = 0;
+  pCapTextLayout->Layout(CFX_SizeF(m_rtCaption.width, m_rtCaption.height),
+                         &fHeight);
+  if (m_rtCaption.height < fHeight)
+    m_rtCaption.height = fHeight;
+}
+void CXFA_FFField::RenderCaption(CFX_Graphics* pGS, CFX_Matrix* pMatrix) {
+  CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout();
+  if (!pCapTextLayout) {
+    return;
+  }
+  CXFA_Caption caption = m_pDataAcc->GetCaption();
+  if (caption && caption.GetPresence() == XFA_ATTRIBUTEENUM_Visible) {
+    if (!pCapTextLayout->IsLoaded()) {
+      pCapTextLayout->Layout(CFX_SizeF(m_rtCaption.width, m_rtCaption.height));
+    }
+    CFX_RectF rtWidget;
+    GetRectWithoutRotate(rtWidget);
+    CFX_RectF rtClip = m_rtCaption;
+    rtClip.Intersect(rtWidget);
+    CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
+    CFX_Matrix mt;
+    mt.Set(1, 0, 0, 1, m_rtCaption.left, m_rtCaption.top);
+    if (pMatrix) {
+      pMatrix->TransformRect(rtClip);
+      mt.Concat(*pMatrix);
+    }
+    pCapTextLayout->DrawString(pRenderDevice, mt, rtClip);
+  }
+}
+FX_BOOL CXFA_FFField::ProcessCommittedData() {
+  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
+    return FALSE;
+  }
+  if (!IsDataChanged()) {
+    return FALSE;
+  }
+  if (CalculateOverride() != 1) {
+    return FALSE;
+  }
+  if (!CommitData()) {
+    return FALSE;
+  }
+  m_pDocView->SetChangeMark();
+  m_pDocView->AddValidateWidget(m_pDataAcc);
+  return TRUE;
+}
+int32_t CXFA_FFField::CalculateOverride() {
+  CXFA_WidgetAcc* pAcc = m_pDataAcc->GetExclGroup();
+  if (!pAcc) {
+    return CalculateWidgetAcc(m_pDataAcc);
+  }
+  if (CalculateWidgetAcc(pAcc) == 0) {
+    return 0;
+  }
+  CXFA_Node* pNode = pAcc->GetExclGroupFirstMember();
+  if (!pNode) {
+    return 1;
+  }
+  CXFA_WidgetAcc* pWidgetAcc = NULL;
+  while (pNode) {
+    pWidgetAcc = (CXFA_WidgetAcc*)pNode->GetWidgetData();
+    if (!pWidgetAcc) {
+      return 1;
+    }
+    if (CalculateWidgetAcc(pWidgetAcc) == 0) {
+      return 0;
+    }
+    pNode = pWidgetAcc->GetExclGroupNextMember(pNode);
+  }
+  return 1;
+}
+int32_t CXFA_FFField::CalculateWidgetAcc(CXFA_WidgetAcc* pAcc) {
+  CXFA_Calculate calc = pAcc->GetCalculate();
+  if (!calc) {
+    return 1;
+  }
+  XFA_VERSION version = pAcc->GetDoc()->GetXFADoc()->GetCurVersionMode();
+  if (calc) {
+    int32_t iOverride = calc.GetOverride();
+    switch (iOverride) {
+      case XFA_ATTRIBUTEENUM_Error: {
+        if (version <= XFA_VERSION_204) {
+          return 1;
+        }
+        IXFA_AppProvider* pAppProvider = GetApp()->GetAppProvider();
+        if (pAppProvider) {
+          CFX_WideString wsMessage;
+          CFX_WideString wsWarning;
+          pAppProvider->LoadString(XFA_IDS_NotModifyField, wsWarning);
+          wsMessage += wsWarning;
+          CFX_WideString wsTitle;
+          pAppProvider->LoadString(XFA_IDS_CalcOverride, wsTitle);
+          pAppProvider->MsgBox(wsMessage, wsTitle, XFA_MBICON_Warning,
+                               XFA_MB_OK);
+        }
+      }
+        return 0;
+      case XFA_ATTRIBUTEENUM_Warning: {
+        if (version <= XFA_VERSION_204) {
+          CXFA_Script script = calc.GetScript();
+          if (!script) {
+            return 1;
+          }
+          CFX_WideString wsExpression;
+          script.GetExpression(wsExpression);
+          if (wsExpression.IsEmpty()) {
+            return 1;
+          }
+        }
+        if (pAcc->GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
+          return 1;
+        }
+        IXFA_AppProvider* pAppProvider = GetApp()->GetAppProvider();
+        if (pAppProvider) {
+          CFX_WideString wsMessage;
+          calc.GetMessageText(wsMessage);
+          if (!wsMessage.IsEmpty()) {
+            wsMessage += L"\r\n";
+          }
+          CFX_WideString wsWarning;
+          pAppProvider->LoadString(XFA_IDS_ModifyField, wsWarning);
+          wsMessage += wsWarning;
+          CFX_WideString wsTitle;
+          pAppProvider->LoadString(XFA_IDS_CalcOverride, wsTitle);
+          if (pAppProvider->MsgBox(wsMessage, wsTitle, XFA_MBICON_Warning,
+                                   XFA_MB_YesNo) == XFA_IDYes) {
+            pAcc->GetNode()->SetFlag(XFA_NODEFLAG_UserInteractive, TRUE, FALSE);
+            return 1;
+          }
+        }
+        return 0;
+      }
+      case XFA_ATTRIBUTEENUM_Ignore:
+        return 0;
+      case XFA_ATTRIBUTEENUM_Disabled:
+        pAcc->GetNode()->SetFlag(XFA_NODEFLAG_UserInteractive, TRUE, FALSE);
+      default:
+        return 1;
+    }
+  }
+  return 1;
+}
+FX_BOOL CXFA_FFField::CommitData() {
+  return FALSE;
+}
+FX_BOOL CXFA_FFField::IsDataChanged() {
+  return FALSE;
+}
+void CXFA_FFField::TranslateFWLMessage(CFWL_Message* pMessage) {
+  GetApp()->GetWidgetMgrDelegate()->OnProcessMessageToForm(pMessage);
+}
+int32_t CXFA_FFField::OnProcessMessage(CFWL_Message* pMessage) {
+  return FWL_ERR_Succeeded;
+}
+FWL_ERR CXFA_FFField::OnProcessEvent(CFWL_Event* pEvent) {
+  FX_DWORD dwEventID = pEvent->GetClassID();
+  switch (dwEventID) {
+    case FWL_EVTHASH_Mouse: {
+      CFWL_EvtMouse* event = (CFWL_EvtMouse*)pEvent;
+      if (event->m_dwCmd == FWL_MSGMOUSECMD_MouseEnter) {
+        CXFA_EventParam eParam;
+        eParam.m_eType = XFA_EVENT_MouseEnter;
+        eParam.m_pTarget = m_pDataAcc;
+        m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_MouseEnter, &eParam);
+      } else if (event->m_dwCmd == FWL_MSGMOUSECMD_MouseLeave) {
+        CXFA_EventParam eParam;
+        eParam.m_eType = XFA_EVENT_MouseExit;
+        eParam.m_pTarget = m_pDataAcc;
+        m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_MouseExit, &eParam);
+      } else if (event->m_dwCmd == FWL_MSGMOUSECMD_LButtonDown) {
+        CXFA_EventParam eParam;
+        eParam.m_eType = XFA_EVENT_MouseDown;
+        eParam.m_pTarget = m_pDataAcc;
+        m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_MouseDown, &eParam);
+      } else if (event->m_dwCmd == FWL_MSGMOUSECMD_LButtonUp) {
+        CXFA_EventParam eParam;
+        eParam.m_eType = XFA_EVENT_MouseUp;
+        eParam.m_pTarget = m_pDataAcc;
+        m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_MouseUp, &eParam);
+      }
+      break;
+    }
+    case FWL_EVTHASH_Click: {
+      CXFA_EventParam eParam;
+      eParam.m_eType = XFA_EVENT_Click;
+      eParam.m_pTarget = m_pDataAcc;
+      m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Click, &eParam);
+      break;
+    }
+    default: {}
+  }
+  return FWL_ERR_Succeeded;
+}
+FWL_ERR CXFA_FFField::OnDrawWidget(CFX_Graphics* pGraphics,
+                                   const CFX_Matrix* pMatrix) {
+  return FWL_ERR_Succeeded;
+}
diff --git a/xfa/fxfa/app/xfa_fffield.h b/xfa/fxfa/app/xfa_fffield.h
new file mode 100644
index 0000000..4f816ce
--- /dev/null
+++ b/xfa/fxfa/app/xfa_fffield.h
@@ -0,0 +1,100 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFFIELD_H_
+#define XFA_FXFA_APP_XFA_FFFIELD_H_
+
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+#include "xfa/include/fwl/adapter/fwl_sdadapterimp.h"
+#include "xfa/include/fwl/core/fwl_widget.h"
+#include "xfa/include/fwl/lightwidget/widget.h"
+
+#define XFA_MINUI_HEIGHT 4.32f
+#define XFA_DEFAULTUI_HEIGHT 2.0f
+
+class CXFA_FFField : public CXFA_FFWidget, public IFWL_WidgetDelegate {
+ public:
+  CXFA_FFField(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFField();
+
+  virtual FX_BOOL GetBBox(CFX_RectF& rtBox,
+                          FX_DWORD dwStatus,
+                          FX_BOOL bDrawFocus = FALSE);
+  virtual void RenderWidget(CFX_Graphics* pGS,
+                            CFX_Matrix* pMatrix = NULL,
+                            FX_DWORD dwStatus = 0,
+                            int32_t iRotate = 0);
+  virtual FX_BOOL IsLoaded();
+  virtual FX_BOOL LoadWidget();
+  virtual void UnloadWidget();
+  virtual FX_BOOL PerformLayout();
+  virtual void UpdateFWL();
+  FX_DWORD UpdateUIProperty();
+  virtual FX_BOOL OnMouseEnter();
+  virtual FX_BOOL OnMouseExit();
+  virtual FX_BOOL OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnLButtonDblClk(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnMouseWheel(FX_DWORD dwFlags,
+                               int16_t zDelta,
+                               FX_FLOAT fx,
+                               FX_FLOAT fy);
+  virtual FX_BOOL OnRButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnRButtonDblClk(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+
+  virtual FX_BOOL OnSetFocus(CXFA_FFWidget* pOldWidget);
+  virtual FX_BOOL OnKillFocus(CXFA_FFWidget* pNewWidget);
+  virtual FX_BOOL OnKeyDown(FX_DWORD dwKeyCode, FX_DWORD dwFlags);
+  virtual FX_BOOL OnKeyUp(FX_DWORD dwKeyCode, FX_DWORD dwFlags);
+  virtual FX_BOOL OnChar(FX_DWORD dwChar, FX_DWORD dwFlags);
+  virtual FX_DWORD OnHitTest(FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnSetCursor(FX_FLOAT fx, FX_FLOAT fy);
+
+ protected:
+  virtual FX_BOOL PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy);
+  virtual void SetFWLRect();
+  void SetFWLThemeProvider();
+  CFWL_Widget* GetNormalWidget() { return m_pNormalWidget; }
+  void FWLToClient(FX_FLOAT& fx, FX_FLOAT& fy);
+  void LayoutCaption();
+  void RenderCaption(CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL);
+
+  int32_t CalculateOverride();
+  int32_t CalculateWidgetAcc(CXFA_WidgetAcc* pAcc);
+  FX_BOOL ProcessCommittedData();
+  virtual FX_BOOL CommitData();
+  virtual FX_BOOL IsDataChanged();
+  void DrawHighlight(CFX_Graphics* pGS,
+                     CFX_Matrix* pMatrix,
+                     FX_DWORD dwStatus,
+                     FX_BOOL bEllipse = FALSE);
+  void DrawFocus(CFX_Graphics* pGS, CFX_Matrix* pMatrix);
+  void TranslateFWLMessage(CFWL_Message* pMessage);
+  void CapPlacement();
+  void CapTopBottomPlacement(CXFA_Caption caption,
+                             const CFX_RectF& rtWidget,
+                             int32_t iCapPlacement);
+  void CapLeftRightPlacement(CXFA_Caption caption,
+                             const CFX_RectF& rtWidget,
+                             int32_t iCapPlacement);
+  void SetEditScrollOffset();
+
+ public:
+  virtual int32_t OnProcessMessage(CFWL_Message* pMessage);
+  virtual FWL_ERR OnProcessEvent(CFWL_Event* pEvent);
+  virtual FWL_ERR OnDrawWidget(CFX_Graphics* pGraphics,
+                               const CFX_Matrix* pMatrix = NULL);
+
+ protected:
+  CFWL_Widget* m_pNormalWidget;
+  CFX_RectF m_rtUI;
+  CFX_RectF m_rtCaption;
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFFIELD_H_
diff --git a/xfa/fxfa/app/xfa_ffimage.cpp b/xfa/fxfa/app/xfa_ffimage.cpp
new file mode 100644
index 0000000..c17273d
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffimage.cpp
@@ -0,0 +1,67 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffimage.h"
+
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_ffdraw.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+
+CXFA_FFImage::CXFA_FFImage(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFDraw(pPageView, pDataAcc) {}
+CXFA_FFImage::~CXFA_FFImage() {
+  CXFA_FFImage::UnloadWidget();
+}
+FX_BOOL CXFA_FFImage::IsLoaded() {
+  return GetDataAcc()->GetImageImage() != NULL;
+}
+FX_BOOL CXFA_FFImage::LoadWidget() {
+  if (GetDataAcc()->GetImageImage()) {
+    return TRUE;
+  }
+  GetDataAcc()->LoadImageImage();
+  return CXFA_FFDraw::LoadWidget();
+}
+void CXFA_FFImage::UnloadWidget() {
+  GetDataAcc()->SetImageImage(NULL);
+}
+void CXFA_FFImage::RenderWidget(CFX_Graphics* pGS,
+                                CFX_Matrix* pMatrix,
+                                FX_DWORD dwStatus,
+                                int32_t iRotate) {
+  if (!IsMatchVisibleStatus(dwStatus)) {
+    return;
+  }
+  CFX_Matrix mtRotate;
+  GetRotateMatrix(mtRotate);
+  if (pMatrix) {
+    mtRotate.Concat(*pMatrix);
+  }
+  CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+  if (CFX_DIBitmap* pDIBitmap = GetDataAcc()->GetImageImage()) {
+    CFX_RectF rtImage;
+    GetRectWithoutRotate(rtImage);
+    if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
+      XFA_RectWidthoutMargin(rtImage, mgWidget);
+    }
+    int32_t iHorzAlign = XFA_ATTRIBUTEENUM_Left;
+    int32_t iVertAlign = XFA_ATTRIBUTEENUM_Top;
+    if (CXFA_Para para = m_pDataAcc->GetPara()) {
+      iHorzAlign = para.GetHorizontalAlign();
+      iVertAlign = para.GetVerticalAlign();
+    }
+    CXFA_Value value = m_pDataAcc->GetFormValue();
+    CXFA_Image imageObj = value.GetImage();
+    int32_t iAspect = imageObj.GetAspect();
+    int32_t iImageXDpi = 0;
+    int32_t iImageYDpi = 0;
+    m_pDataAcc->GetImageDpi(iImageXDpi, iImageYDpi);
+    XFA_DrawImage(pGS, rtImage, &mtRotate, pDIBitmap, iAspect, iImageXDpi,
+                  iImageYDpi, iHorzAlign, iVertAlign);
+  }
+}
diff --git a/xfa/fxfa/app/xfa_ffimage.h b/xfa/fxfa/app/xfa_ffimage.h
new file mode 100644
index 0000000..71bb495
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffimage.h
@@ -0,0 +1,25 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFIMAGE_H_
+#define XFA_FXFA_APP_XFA_FFIMAGE_H_
+
+#include "xfa/fxfa/app/xfa_ffdraw.h"
+
+class CXFA_FFImage : public CXFA_FFDraw {
+ public:
+  CXFA_FFImage(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFImage();
+  virtual void RenderWidget(CFX_Graphics* pGS,
+                            CFX_Matrix* pMatrix = NULL,
+                            FX_DWORD dwStatus = 0,
+                            int32_t iRotate = 0);
+  virtual FX_BOOL IsLoaded();
+  virtual FX_BOOL LoadWidget();
+  virtual void UnloadWidget();
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFIMAGE_H_
diff --git a/xfa/fxfa/app/xfa_ffimageedit.cpp b/xfa/fxfa/app/xfa_ffimageedit.cpp
new file mode 100644
index 0000000..4f9f6c6
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffimageedit.cpp
@@ -0,0 +1,183 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffimageedit.h"
+
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_ffdocview.h"
+#include "xfa/fxfa/app/xfa_fffield.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+#include "xfa/include/fwl/core/fwl_app.h"
+#include "xfa/include/fwl/lightwidget/picturebox.h"
+
+CXFA_FFImageEdit::CXFA_FFImageEdit(CXFA_FFPageView* pPageView,
+                                   CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFField(pPageView, pDataAcc), m_pOldDelegate(NULL) {}
+CXFA_FFImageEdit::~CXFA_FFImageEdit() {
+  CXFA_FFImageEdit::UnloadWidget();
+}
+FX_BOOL CXFA_FFImageEdit::LoadWidget() {
+  CFWL_PictureBox* pPictureBox = new CFWL_PictureBox;
+  if (pPictureBox) {
+    pPictureBox->Initialize();
+  }
+  m_pNormalWidget = (CFWL_Widget*)pPictureBox;
+  IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
+  m_pNormalWidget->SetPrivateData(pWidget, this, NULL);
+  IFWL_NoteDriver* pNoteDriver = FWL_GetApp()->GetNoteDriver();
+  pNoteDriver->RegisterEventTarget(pWidget, pWidget);
+  m_pOldDelegate = pPictureBox->SetDelegate(this);
+  CXFA_FFField::LoadWidget();
+  if (m_pDataAcc->GetImageEditImage()) {
+    return TRUE;
+  }
+  UpdateFWLData();
+  return TRUE;
+}
+void CXFA_FFImageEdit::UnloadWidget() {
+  m_pDataAcc->SetImageEditImage(NULL);
+  CXFA_FFField::UnloadWidget();
+}
+void CXFA_FFImageEdit::RenderWidget(CFX_Graphics* pGS,
+                                    CFX_Matrix* pMatrix,
+                                    FX_DWORD dwStatus,
+                                    int32_t iRotate) {
+  if (!IsMatchVisibleStatus(dwStatus)) {
+    return;
+  }
+  CFX_Matrix mtRotate;
+  GetRotateMatrix(mtRotate);
+  if (pMatrix) {
+    mtRotate.Concat(*pMatrix);
+  }
+  CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+  CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
+  DrawBorder(pGS, borderUI, m_rtUI, &mtRotate);
+  RenderCaption(pGS, &mtRotate);
+  if (CFX_DIBitmap* pDIBitmap = m_pDataAcc->GetImageEditImage()) {
+    CFX_RectF rtImage;
+    m_pNormalWidget->GetWidgetRect(rtImage);
+    int32_t iHorzAlign = XFA_ATTRIBUTEENUM_Left;
+    int32_t iVertAlign = XFA_ATTRIBUTEENUM_Top;
+    if (CXFA_Para para = m_pDataAcc->GetPara()) {
+      iHorzAlign = para.GetHorizontalAlign();
+      iVertAlign = para.GetVerticalAlign();
+    }
+    int32_t iAspect = XFA_ATTRIBUTEENUM_Fit;
+    if (CXFA_Value value = m_pDataAcc->GetFormValue()) {
+      if (CXFA_Image imageObj = value.GetImage()) {
+        iAspect = imageObj.GetAspect();
+      }
+    }
+    int32_t iImageXDpi = 0;
+    int32_t iImageYDpi = 0;
+    m_pDataAcc->GetImageEditDpi(iImageXDpi, iImageYDpi);
+    XFA_DrawImage(pGS, rtImage, &mtRotate, pDIBitmap, iAspect, iImageXDpi,
+                  iImageYDpi, iHorzAlign, iVertAlign);
+  }
+}
+FX_BOOL CXFA_FFImageEdit::OnLButtonDown(FX_DWORD dwFlags,
+                                        FX_FLOAT fx,
+                                        FX_FLOAT fy) {
+  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
+    return FALSE;
+  }
+  if (!PtInActiveRect(fx, fy)) {
+    return FALSE;
+  }
+  SetButtonDown(TRUE);
+  CFWL_MsgMouse ms;
+  ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonDown;
+  ms.m_dwFlags = dwFlags;
+  ms.m_fx = fx;
+  ms.m_fy = fy;
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  FWLToClient(ms.m_fx, ms.m_fy);
+  TranslateFWLMessage(&ms);
+  IXFA_AppProvider* pAppProvider = GetAppProvider();
+  if (!pAppProvider) {
+    return TRUE;
+  }
+  CFX_WideString wsTitle;
+  CFX_WideString wsFilter;
+  pAppProvider->LoadString(XFA_IDS_ImageFilter, wsFilter);
+  CFX_WideStringArray wsPathArray;
+  pAppProvider->ShowFileDialog(wsTitle, wsFilter, wsPathArray);
+  int32_t iSize = wsPathArray.GetSize();
+  if (iSize < 1) {
+    return TRUE;
+  }
+  CFX_WideString wsFilePath = wsPathArray[0];
+  FX_STRSIZE nLen = wsFilePath.GetLength();
+  FX_STRSIZE nIndex = nLen - 1;
+  while (nIndex > 0 && wsFilePath[nIndex] != '.') {
+    nIndex--;
+  }
+  if (nIndex <= 0) {
+    return TRUE;
+  }
+  CFX_WideString wsContentType(L"image/");
+  wsContentType += wsFilePath.Right(nLen - nIndex - 1);
+  wsContentType.MakeLower();
+  FXCODEC_IMAGE_TYPE eImageType = XFA_GetImageType(wsContentType);
+  if (eImageType == FXCODEC_IMAGE_UNKNOWN) {
+    return TRUE;
+  }
+  CFX_WideString wsImage;
+  IFX_FileRead* pFileRead = FX_CreateFileRead(wsFilePath);
+  if (pFileRead) {
+    int32_t nDataSize = pFileRead->GetSize();
+    if (nDataSize > 0) {
+      CFX_ByteString bsBuf;
+      FX_CHAR* pImageBuffer = bsBuf.GetBuffer(nDataSize);
+      pFileRead->ReadBlock(pImageBuffer, 0, nDataSize);
+      bsBuf.ReleaseBuffer();
+      if (!bsBuf.IsEmpty()) {
+        FX_CHAR* pData = XFA_Base64Encode(bsBuf, nDataSize);
+        wsImage = CFX_WideString::FromLocal(pData);
+        FX_Free(pData);
+      }
+    }
+    m_pDataAcc->SetImageEditImage(NULL);
+    pFileRead->Release();
+  }
+  m_pDataAcc->SetImageEdit(wsContentType, CFX_WideStringC(), wsImage);
+  m_pDataAcc->LoadImageEditImage();
+  AddInvalidateRect();
+  m_pDocView->SetChangeMark();
+  return TRUE;
+}
+void CXFA_FFImageEdit::SetFWLRect() {
+  if (!m_pNormalWidget) {
+    return;
+  }
+  CFX_RectF rtUIMargin;
+  m_pDataAcc->GetUIMargin(rtUIMargin);
+  CFX_RectF rtImage(m_rtUI);
+  rtImage.Deflate(rtUIMargin.left, rtUIMargin.top, rtUIMargin.width,
+                  rtUIMargin.height);
+  m_pNormalWidget->SetWidgetRect(rtImage);
+}
+FX_BOOL CXFA_FFImageEdit::CommitData() {
+  return TRUE;
+}
+FX_BOOL CXFA_FFImageEdit::UpdateFWLData() {
+  m_pDataAcc->SetImageEditImage(NULL);
+  m_pDataAcc->LoadImageEditImage();
+  return TRUE;
+}
+int32_t CXFA_FFImageEdit::OnProcessMessage(CFWL_Message* pMessage) {
+  return m_pOldDelegate->OnProcessMessage(pMessage);
+}
+FWL_ERR CXFA_FFImageEdit::OnProcessEvent(CFWL_Event* pEvent) {
+  CXFA_FFField::OnProcessEvent(pEvent);
+  return m_pOldDelegate->OnProcessEvent(pEvent);
+}
+FWL_ERR CXFA_FFImageEdit::OnDrawWidget(CFX_Graphics* pGraphics,
+                                       const CFX_Matrix* pMatrix) {
+  return m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix);
+}
diff --git a/xfa/fxfa/app/xfa_ffimageedit.h b/xfa/fxfa/app/xfa_ffimageedit.h
new file mode 100644
index 0000000..7ecd18a
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffimageedit.h
@@ -0,0 +1,36 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFIMAGEEDIT_H_
+#define XFA_FXFA_APP_XFA_FFIMAGEEDIT_H_
+
+#include "xfa/fxfa/app/xfa_fffield.h"
+
+class CXFA_FFImageEdit : public CXFA_FFField {
+ public:
+  CXFA_FFImageEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFImageEdit();
+
+  virtual void RenderWidget(CFX_Graphics* pGS,
+                            CFX_Matrix* pMatrix = NULL,
+                            FX_DWORD dwStatus = 0,
+                            int32_t iRotate = 0);
+  virtual FX_BOOL LoadWidget();
+  virtual void UnloadWidget();
+  virtual FX_BOOL OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual int32_t OnProcessMessage(CFWL_Message* pMessage);
+  virtual FWL_ERR OnProcessEvent(CFWL_Event* pEvent);
+  virtual FWL_ERR OnDrawWidget(CFX_Graphics* pGraphics,
+                               const CFX_Matrix* pMatrix = NULL);
+
+ protected:
+  virtual void SetFWLRect();
+  virtual FX_BOOL UpdateFWLData();
+  virtual FX_BOOL CommitData();
+  IFWL_WidgetDelegate* m_pOldDelegate;
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFIMAGEEDIT_H_
diff --git a/xfa/fxfa/app/xfa_ffnotify.cpp b/xfa/fxfa/app/xfa_ffnotify.cpp
new file mode 100644
index 0000000..845f7b8
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffnotify.cpp
@@ -0,0 +1,648 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffnotify.h"
+
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/fxfa/app/xfa_ffbarcode.h"
+#include "xfa/fxfa/app/xfa_ffcheckbutton.h"
+#include "xfa/fxfa/app/xfa_ffchoicelist.h"
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_ffdocview.h"
+#include "xfa/fxfa/app/xfa_ffdraw.h"
+#include "xfa/fxfa/app/xfa_ffexclgroup.h"
+#include "xfa/fxfa/app/xfa_fffield.h"
+#include "xfa/fxfa/app/xfa_ffimage.h"
+#include "xfa/fxfa/app/xfa_ffimageedit.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffpath.h"
+#include "xfa/fxfa/app/xfa_ffpushbutton.h"
+#include "xfa/fxfa/app/xfa_ffsignature.h"
+#include "xfa/fxfa/app/xfa_ffsubform.h"
+#include "xfa/fxfa/app/xfa_fftext.h"
+#include "xfa/fxfa/app/xfa_fftextedit.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+#include "xfa/fxfa/app/xfa_ffwidgetacc.h"
+#include "xfa/fxfa/app/xfa_ffwidgethandler.h"
+#include "xfa/fxfa/app/xfa_fwladapter.h"
+#include "xfa/fxfa/app/xfa_textlayout.h"
+
+static void XFA_FFDeleteWidgetAcc(void* pData) {
+  delete static_cast<CXFA_WidgetAcc*>(pData);
+}
+static XFA_MAPDATABLOCKCALLBACKINFO gs_XFADeleteWidgetAcc = {
+    XFA_FFDeleteWidgetAcc, NULL};
+CXFA_FFNotify::CXFA_FFNotify(CXFA_FFDoc* pDoc) : m_pDoc(pDoc) {}
+CXFA_FFNotify::~CXFA_FFNotify() {}
+void CXFA_FFNotify::OnPageEvent(IXFA_LayoutPage* pSender,
+                                XFA_PAGEEVENT eEvent,
+                                void* pParam) {
+  CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pSender->GetLayout());
+  if (!pDocView) {
+    return;
+  }
+  pDocView->OnPageEvent(pSender, eEvent, (int32_t)(uintptr_t)pParam);
+}
+void CXFA_FFNotify::OnNodeEvent(CXFA_Node* pSender,
+                                XFA_NODEEVENT eEvent,
+                                void* pParam,
+                                void* pParam2,
+                                void* pParam3,
+                                void* pParam4) {
+  switch (eEvent) {
+    case XFA_NODEEVENT_Ready:
+      OnNodeReady(pSender);
+      break;
+    case XFA_NODEEVENT_ValueChanging:
+      OnValueChanging(pSender, pParam, pParam2);
+      break;
+    case XFA_NODEEVENT_ValueChanged:
+      OnValueChanged(pSender, pParam, pParam2, pParam3, pParam4);
+      break;
+    case XFA_NODEEVENT_ChildAdded:
+      OnChildAdded(pSender, pParam, pParam2);
+      break;
+    case XFA_NODEEVENT_ChildRemoved:
+      OnChildRemoved(pSender, pParam, pParam2);
+      break;
+  }
+}
+void CXFA_FFNotify::OnWidgetDataEvent(CXFA_WidgetData* pSender,
+                                      FX_DWORD dwEvent,
+                                      void* pParam,
+                                      void* pAdditional,
+                                      void* pAdditional2) {
+  CXFA_WidgetAcc* pWidgetAcc = static_cast<CXFA_WidgetAcc*>(pSender);
+  switch (dwEvent) {
+    case XFA_WIDGETEVENT_ListItemAdded: {
+      if (pWidgetAcc->GetUIType() != XFA_ELEMENT_ChoiceList) {
+        return;
+      }
+      FX_BOOL bStaticNotify = pWidgetAcc->GetDocView()->IsStaticNotify();
+      CXFA_FFWidget* pWidget = pWidgetAcc->GetNextWidget(NULL);
+      if (!pWidget) {
+        if (bStaticNotify) {
+          pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent(
+              pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemAdded, pParam,
+              pAdditional);
+        }
+        return;
+      }
+      while (pWidget) {
+        if (pWidget->IsLoaded()) {
+          if (pWidgetAcc->IsListBox()) {
+            static_cast<CXFA_FFListBox*>(pWidget)
+                ->InsertItem((const CFX_WideStringC&)(const FX_WCHAR*)pParam,
+                             (int32_t)(uintptr_t)pAdditional2);
+          } else {
+            static_cast<CXFA_FFComboBox*>(pWidget)
+                ->InsertItem((const CFX_WideStringC&)(const FX_WCHAR*)pParam,
+                             (int32_t)(uintptr_t)pAdditional2);
+          }
+        }
+        if (bStaticNotify) {
+          pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent(
+              pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemAdded, pParam,
+              pAdditional);
+        }
+        pWidget = pWidgetAcc->GetNextWidget(pWidget);
+      }
+    } break;
+    case XFA_WIDGETEVENT_ListItemRemoved: {
+      if (pWidgetAcc->GetUIType() != XFA_ELEMENT_ChoiceList) {
+        return;
+      }
+      FX_BOOL bStaticNotify = pWidgetAcc->GetDocView()->IsStaticNotify();
+      CXFA_FFWidget* pWidget = pWidgetAcc->GetNextWidget(NULL);
+      if (!pWidget) {
+        if (bStaticNotify) {
+          pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent(
+              pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemRemoved, pParam,
+              pAdditional);
+        }
+        return;
+      }
+      while (pWidget) {
+        if (pWidget->IsLoaded()) {
+          if (pWidgetAcc->IsListBox()) {
+            static_cast<CXFA_FFListBox*>(pWidget)
+                ->DeleteItem((int32_t)(uintptr_t)pParam);
+          } else {
+            static_cast<CXFA_FFComboBox*>(pWidget)
+                ->DeleteItem((int32_t)(uintptr_t)pParam);
+          }
+        }
+        if (bStaticNotify) {
+          pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent(
+              pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemRemoved, pParam,
+              pAdditional);
+        }
+        pWidget = pWidgetAcc->GetNextWidget(pWidget);
+      }
+    } break;
+  }
+}
+CXFA_LayoutItem* CXFA_FFNotify::OnCreateLayoutItem(CXFA_Node* pNode) {
+  IXFA_DocLayout* pLayout = m_pDoc->GetXFADoc()->GetDocLayout();
+  CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout);
+  XFA_ELEMENT eType = pNode->GetClassID();
+  if (eType == XFA_ELEMENT_PageArea) {
+    return new CXFA_FFPageView(pDocView, pNode);
+  }
+  if (eType == XFA_ELEMENT_ContentArea) {
+    return new CXFA_ContainerLayoutItem(pNode);
+  }
+  CXFA_WidgetAcc* pAcc = static_cast<CXFA_WidgetAcc*>(pNode->GetWidgetData());
+  if (!pAcc) {
+    return new CXFA_ContentLayoutItem(pNode);
+  }
+  CXFA_FFPageView* pPageView = NULL;
+  CXFA_FFWidget* pWidget = NULL;
+  switch (pAcc->GetUIType()) {
+    case XFA_ELEMENT_Barcode:
+      pWidget = new CXFA_FFBarcode(pPageView, pAcc);
+      break;
+    case XFA_ELEMENT_Button:
+      pWidget = new CXFA_FFPushButton(pPageView, pAcc);
+      break;
+    case XFA_ELEMENT_CheckButton:
+      pWidget = new CXFA_FFCheckButton(pPageView, pAcc);
+      break;
+    case XFA_ELEMENT_ChoiceList: {
+      if (pAcc->IsListBox()) {
+        pWidget = new CXFA_FFListBox(pPageView, pAcc);
+      } else {
+        pWidget = new CXFA_FFComboBox(pPageView, pAcc);
+      }
+    } break;
+    case XFA_ELEMENT_DateTimeEdit:
+      pWidget = new CXFA_FFDateTimeEdit(pPageView, pAcc);
+      break;
+    case XFA_ELEMENT_ImageEdit:
+      pWidget = new CXFA_FFImageEdit(pPageView, pAcc);
+      break;
+    case XFA_ELEMENT_NumericEdit:
+      pWidget = new CXFA_FFNumericEdit(pPageView, pAcc);
+      break;
+    case XFA_ELEMENT_PasswordEdit:
+      pWidget = new CXFA_FFPasswordEdit(pPageView, pAcc);
+      break;
+    case XFA_ELEMENT_Signature:
+      pWidget = new CXFA_FFSignature(pPageView, pAcc);
+      break;
+    case XFA_ELEMENT_TextEdit:
+      pWidget = new CXFA_FFTextEdit(pPageView, pAcc);
+      break;
+    case XFA_ELEMENT_Arc:
+      pWidget = new CXFA_FFArc(pPageView, pAcc);
+      break;
+    case XFA_ELEMENT_Line:
+      pWidget = new CXFA_FFLine(pPageView, pAcc);
+      break;
+    case XFA_ELEMENT_Rectangle:
+      pWidget = new CXFA_FFRectangle(pPageView, pAcc);
+      break;
+    case XFA_ELEMENT_Text:
+      pWidget = new CXFA_FFText(pPageView, pAcc);
+      break;
+    case XFA_ELEMENT_Image:
+      pWidget = new CXFA_FFImage(pPageView, pAcc);
+      break;
+    case XFA_ELEMENT_Draw:
+      pWidget = new CXFA_FFDraw(pPageView, pAcc);
+      break;
+    case XFA_ELEMENT_Subform:
+      pWidget = new CXFA_FFSubForm(pPageView, pAcc);
+      break;
+    case XFA_ELEMENT_ExclGroup:
+      pWidget = new CXFA_FFExclGroup(pPageView, pAcc);
+      break;
+    case XFA_ELEMENT_DefaultUi:
+    default:
+      pWidget = NULL;
+      break;
+  }
+  if (!pWidget) {
+    return NULL;
+  }
+  pWidget->SetDocView(pDocView);
+  return pWidget;
+}
+void CXFA_FFNotify::OnLayoutEvent(IXFA_DocLayout* pLayout,
+                                  CXFA_LayoutItem* pSender,
+                                  XFA_LAYOUTEVENT eEvent,
+                                  void* pParam,
+                                  void* pParam2) {
+  CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout);
+  if (!pDocView || !XFA_GetWidgetFromLayoutItem(pSender)) {
+    return;
+  }
+  switch (eEvent) {
+    case XFA_LAYOUTEVENT_ItemAdded:
+      OnLayoutItemAdd(pDocView, pLayout, pSender, pParam, pParam2);
+      break;
+    case XFA_LAYOUTEVENT_ItemRemoving:
+      OnLayoutItemRemoving(pDocView, pLayout, pSender, pParam, pParam2);
+      break;
+    case XFA_LAYOUTEVENT_RectChanged:
+      OnLayoutItemRectChanged(pDocView, pLayout, pSender, pParam, pParam2);
+      break;
+    case XFA_LAYOUTEVENT_StatusChanged:
+      OnLayoutItemStatustChanged(pDocView, pLayout, pSender, pParam, pParam2);
+      break;
+  }
+}
+void CXFA_FFNotify::StartFieldDrawLayout(CXFA_Node* pItem,
+                                         FX_FLOAT& fCalcWidth,
+                                         FX_FLOAT& fCalcHeight) {
+  CXFA_WidgetAcc* pAcc = static_cast<CXFA_WidgetAcc*>(pItem->GetWidgetData());
+  if (!pAcc) {
+    return;
+  }
+  pAcc->StartWidgetLayout(fCalcWidth, fCalcHeight);
+}
+FX_BOOL CXFA_FFNotify::FindSplitPos(CXFA_Node* pItem,
+                                    int32_t iBlockIndex,
+                                    FX_FLOAT& fCalcHeightPos) {
+  CXFA_WidgetAcc* pAcc = static_cast<CXFA_WidgetAcc*>(pItem->GetWidgetData());
+  if (!pAcc) {
+    return FALSE;
+  }
+  return (XFA_LAYOUTRESULT)pAcc->FindSplitPos(iBlockIndex, fCalcHeightPos);
+}
+FX_BOOL CXFA_FFNotify::RunScript(CXFA_Node* pScript, CXFA_Node* pFormItem) {
+  FX_BOOL bRet = FALSE;
+  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+  if (!pDocView) {
+    return bRet;
+  }
+  CXFA_WidgetAcc* pWidgetAcc =
+      static_cast<CXFA_WidgetAcc*>(pFormItem->GetWidgetData());
+  if (!pWidgetAcc) {
+    return bRet;
+  }
+  CXFA_EventParam EventParam;
+  EventParam.m_eType = XFA_EVENT_Unknown;
+  FXJSE_HVALUE pRetValue = NULL;
+  int32_t iRet =
+      pWidgetAcc->ExecuteScript(CXFA_Script(pScript), &EventParam, &pRetValue);
+  if (iRet == XFA_EVENTERROR_Sucess && pRetValue) {
+    bRet = FXJSE_Value_ToBoolean(pRetValue);
+    FXJSE_Value_Release(pRetValue);
+  }
+  return bRet;
+}
+int32_t CXFA_FFNotify::ExecEventByDeepFirst(CXFA_Node* pFormNode,
+                                            XFA_EVENTTYPE eEventType,
+                                            FX_BOOL bIsFormReady,
+                                            FX_BOOL bRecursive,
+                                            CXFA_WidgetAcc* pExclude) {
+  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+  if (!pDocView) {
+    return XFA_EVENTERROR_NotExist;
+  }
+  return pDocView->ExecEventActivityByDeepFirst(
+      pFormNode, eEventType, bIsFormReady, bRecursive,
+      pExclude ? pExclude->GetNode() : NULL);
+}
+void CXFA_FFNotify::AddCalcValidate(CXFA_Node* pNode) {
+  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+  if (!pDocView) {
+    return;
+  }
+  CXFA_WidgetAcc* pWidgetAcc =
+      static_cast<CXFA_WidgetAcc*>(pNode->GetWidgetData());
+  if (!pWidgetAcc) {
+    return;
+  }
+  pDocView->AddCalculateWidgetAcc(pWidgetAcc);
+  pDocView->AddValidateWidget(pWidgetAcc);
+}
+IXFA_Doc* CXFA_FFNotify::GetHDOC() {
+  return m_pDoc;
+}
+IXFA_DocProvider* CXFA_FFNotify::GetDocProvider() {
+  return m_pDoc->GetDocProvider();
+}
+IXFA_AppProvider* CXFA_FFNotify::GetAppProvider() {
+  return m_pDoc->GetApp()->GetAppProvider();
+}
+IXFA_WidgetHandler* CXFA_FFNotify::GetWidgetHandler() {
+  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+  return pDocView ? pDocView->GetWidgetHandler() : NULL;
+}
+IXFA_Widget* CXFA_FFNotify::GetHWidget(CXFA_LayoutItem* pLayoutItem) {
+  return XFA_GetWidgetFromLayoutItem(pLayoutItem);
+}
+void CXFA_FFNotify::OpenDropDownList(IXFA_Widget* hWidget) {
+  CXFA_FFWidget* pWidget = static_cast<CXFA_FFWidget*>(hWidget);
+  if (pWidget->GetDataAcc()->GetUIType() != XFA_ELEMENT_ChoiceList) {
+    return;
+  }
+  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+  pDocView->LockUpdate();
+  static_cast<CXFA_FFComboBox*>(pWidget)->OpenDropDownList();
+  pDocView->UnlockUpdate();
+  pDocView->UpdateDocView();
+}
+CFX_WideString CXFA_FFNotify::GetCurrentDateTime() {
+  CFX_Unitime dataTime;
+  dataTime.Now();
+  CFX_WideString wsDateTime;
+  wsDateTime.Format(L"%d%02d%02dT%02d%02d%02d", dataTime.GetYear(),
+                    dataTime.GetMonth(), dataTime.GetDay(), dataTime.GetHour(),
+                    dataTime.GetMinute(), dataTime.GetSecond());
+  return wsDateTime;
+}
+void CXFA_FFNotify::ResetData(CXFA_WidgetData* pWidgetData) {
+  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+  if (!pDocView) {
+    return;
+  }
+  pDocView->ResetWidgetData(static_cast<CXFA_WidgetAcc*>(pWidgetData));
+}
+int32_t CXFA_FFNotify::GetLayoutStatus() {
+  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+  return pDocView ? pDocView->GetLayoutStatus() : 0;
+}
+void CXFA_FFNotify::RunNodeInitialize(CXFA_Node* pNode) {
+  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+  if (!pDocView) {
+    return;
+  }
+  pDocView->AddNewFormNode(pNode);
+}
+void CXFA_FFNotify::RunSubformIndexChange(CXFA_Node* pSubformNode) {
+  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+  if (!pDocView) {
+    return;
+  }
+  pDocView->AddIndexChangedSubform(pSubformNode);
+}
+CXFA_Node* CXFA_FFNotify::GetFocusWidgetNode() {
+  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+  if (!pDocView) {
+    return NULL;
+  }
+  CXFA_WidgetAcc* pAcc = pDocView->GetFocusWidgetAcc();
+  return pAcc ? pAcc->GetNode() : NULL;
+}
+void CXFA_FFNotify::SetFocusWidgetNode(CXFA_Node* pNode) {
+  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+  if (!pDocView) {
+    return;
+  }
+  CXFA_WidgetAcc* pAcc =
+      pNode ? static_cast<CXFA_WidgetAcc*>(pNode->GetWidgetData()) : nullptr;
+  pDocView->SetFocusWidgetAcc(pAcc);
+}
+void CXFA_FFNotify::OnNodeReady(CXFA_Node* pNode) {
+  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+  if (!pDocView) {
+    return;
+  }
+  XFA_ELEMENT iType = pNode->GetClassID();
+  if (XFA_IsCreateWidget(iType)) {
+    CXFA_WidgetAcc* pAcc =
+        new CXFA_WidgetAcc(pDocView, static_cast<CXFA_Node*>(pNode));
+    pNode->SetObject(XFA_ATTRIBUTE_WidgetData, pAcc, &gs_XFADeleteWidgetAcc);
+    return;
+  }
+  switch (iType) {
+    case XFA_ELEMENT_BindItems:
+      pDocView->m_bindItems.Add(pNode);
+      break;
+    case XFA_ELEMENT_Validate: {
+      pNode->SetFlag(XFA_NODEFLAG_NeedsInitApp, TRUE, FALSE);
+    } break;
+    default:
+      break;
+  }
+}
+void CXFA_FFNotify::OnValueChanging(CXFA_Node* pSender,
+                                    void* pParam,
+                                    void* pParam2) {
+  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+  if (!pDocView) {
+    return;
+  }
+  if (pDocView->GetLayoutStatus() < XFA_DOCVIEW_LAYOUTSTATUS_End) {
+    return;
+  }
+  FX_DWORD dwPacket = pSender->GetPacketID();
+  if (dwPacket & XFA_XDPPACKET_Datasets) {
+  } else if (pSender->IsFormContainer()) {
+    XFA_ATTRIBUTE eAttr = (XFA_ATTRIBUTE)(uintptr_t)pParam;
+    if (eAttr == XFA_ATTRIBUTE_Presence) {
+      CXFA_WidgetAcc* pWidgetAcc =
+          static_cast<CXFA_WidgetAcc*>(pSender->GetWidgetData());
+      if (!pWidgetAcc) {
+        return;
+      }
+      CXFA_FFWidget* pWidget = NULL;
+      while ((pWidget = pWidgetAcc->GetNextWidget(pWidget))) {
+        if (pWidget->IsLoaded()) {
+          pWidget->AddInvalidateRect();
+        }
+      }
+    }
+  }
+}
+void CXFA_FFNotify::OnValueChanged(CXFA_Node* pSender,
+                                   void* pParam,
+                                   void* pParam2,
+                                   void* pParam3,
+                                   void* pParam4) {
+  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+  if (!pDocView) {
+    return;
+  }
+  FX_DWORD dwPacket = pSender->GetPacketID();
+  XFA_ATTRIBUTE eAttr = (XFA_ATTRIBUTE)(uintptr_t)pParam;
+  if (dwPacket & XFA_XDPPACKET_Form) {
+    CXFA_Node* pParentNode = static_cast<CXFA_Node*>(pParam3);
+    CXFA_Node* pWidgetNode = static_cast<CXFA_Node*>(pParam4);
+    XFA_ELEMENT ePType = pParentNode->GetClassID();
+    FX_BOOL bIsContainerNode = pParentNode->IsContainerNode();
+    CXFA_WidgetAcc* pWidgetAcc =
+        static_cast<CXFA_WidgetAcc*>(pWidgetNode->GetWidgetData());
+    if (!pWidgetAcc) {
+      return;
+    }
+    FX_BOOL bUpdateProperty = FALSE;
+    pDocView->SetChangeMark();
+    switch (ePType) {
+      case XFA_ELEMENT_Caption: {
+        CXFA_TextLayout* pCapOut = pWidgetAcc->GetCaptionTextLayout();
+        if (!pCapOut) {
+          return;
+        }
+        pCapOut->Unload();
+      } break;
+      case XFA_ELEMENT_Ui:
+      case XFA_ELEMENT_Para:
+        bUpdateProperty = TRUE;
+        break;
+      case XFA_ELEMENT_Font:
+      case XFA_ELEMENT_Margin:
+      case XFA_ELEMENT_Value:
+      case XFA_ELEMENT_Items:
+        break;
+      default:
+        break;
+    }
+    if (bIsContainerNode && eAttr == XFA_ATTRIBUTE_Access) {
+      bUpdateProperty = TRUE;
+      FX_BOOL bNotify = pDocView->IsStaticNotify();
+      if (bNotify) {
+        pWidgetAcc->NotifyEvent(XFA_WIDGETEVENT_AccessChanged, NULL, pParam2,
+                                NULL);
+      }
+    }
+    if (eAttr == XFA_ATTRIBUTE_Value) {
+      pDocView->AddCalculateNodeNotify(pSender);
+      if (ePType == XFA_ELEMENT_Value || bIsContainerNode) {
+        FX_BOOL bNotify = pDocView->IsStaticNotify();
+        if (bIsContainerNode) {
+          pWidgetAcc->UpdateUIDisplay();
+          pDocView->AddCalculateWidgetAcc(pWidgetAcc);
+          pDocView->AddValidateWidget(pWidgetAcc);
+        } else if (pWidgetNode->GetNodeItem(XFA_NODEITEM_Parent)
+                       ->GetClassID() == XFA_ELEMENT_ExclGroup) {
+          pWidgetAcc->UpdateUIDisplay();
+        }
+        if (bNotify) {
+          pWidgetAcc->NotifyEvent(XFA_WIDGETEVENT_PostContentChanged, NULL,
+                                  NULL, NULL);
+        }
+        return;
+      }
+    }
+    CXFA_FFWidget* pWidget = NULL;
+    while ((pWidget = pWidgetAcc->GetNextWidget(pWidget))) {
+      if (!pWidget->IsLoaded()) {
+        continue;
+      }
+      if (bUpdateProperty) {
+        pWidget->UpdateWidgetProperty();
+      }
+      pWidget->PerformLayout();
+      pWidget->AddInvalidateRect();
+    }
+  } else {
+    if (eAttr == XFA_ATTRIBUTE_Value) {
+      pDocView->AddCalculateNodeNotify(pSender);
+    }
+  }
+}
+void CXFA_FFNotify::OnChildAdded(CXFA_Node* pSender,
+                                 void* pParam,
+                                 void* pParam2) {
+  if (!pSender->IsFormContainer()) {
+    return;
+  }
+  CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+  if (!pDocView) {
+    return;
+  }
+  FX_BOOL bLayoutReady =
+      !(pDocView->m_bInLayoutStatus) &&
+      (pDocView->GetLayoutStatus() == XFA_DOCVIEW_LAYOUTSTATUS_End);
+  if (bLayoutReady) {
+    m_pDoc->GetDocProvider()->SetChangeMark(m_pDoc);
+  }
+}
+void CXFA_FFNotify::OnChildRemoved(CXFA_Node* pSender,
+                                   void* pParam,
+                                   void* pParam2) {
+  if (CXFA_FFDocView* pDocView = m_pDoc->GetDocView()) {
+    FX_BOOL bLayoutReady =
+        !(pDocView->m_bInLayoutStatus) &&
+        (pDocView->GetLayoutStatus() == XFA_DOCVIEW_LAYOUTSTATUS_End);
+    if (bLayoutReady) {
+      m_pDoc->GetDocProvider()->SetChangeMark(m_pDoc);
+    }
+  }
+}
+void CXFA_FFNotify::OnLayoutItemAdd(CXFA_FFDocView* pDocView,
+                                    IXFA_DocLayout* pLayout,
+                                    CXFA_LayoutItem* pSender,
+                                    void* pParam,
+                                    void* pParam2) {
+  CXFA_FFWidget* pWidget = static_cast<CXFA_FFWidget*>(pSender);
+  int32_t iPageIdx = (int32_t)(uintptr_t)pParam;
+  IXFA_PageView* pNewPageView = pDocView->GetPageView(iPageIdx);
+  FX_DWORD dwStatus = (FX_DWORD)(uintptr_t)pParam2;
+  FX_DWORD dwFilter = XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable |
+                      XFA_WIDGETSTATUS_Printable;
+  pWidget->ModifyStatus(dwStatus, dwFilter);
+  IXFA_PageView* pPrePageView = pWidget->GetPageView();
+  if (pPrePageView != pNewPageView ||
+      (dwStatus & (XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable)) ==
+          (XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable)) {
+    pWidget->SetPageView(pNewPageView);
+    m_pDoc->GetDocProvider()->WidgetEvent(pWidget, pWidget->GetDataAcc(),
+                                          XFA_WIDGETEVENT_PostAdded,
+                                          pNewPageView, pPrePageView);
+  }
+  if (pDocView->GetLayoutStatus() != XFA_DOCVIEW_LAYOUTSTATUS_End ||
+      !(dwStatus & XFA_WIDGETSTATUS_Visible)) {
+    return;
+  }
+  if (pWidget->IsLoaded()) {
+    CFX_RectF rtOld;
+    pWidget->GetWidgetRect(rtOld);
+    if (rtOld != pWidget->ReCacheWidgetRect())
+      pWidget->PerformLayout();
+  } else {
+    pWidget->LoadWidget();
+  }
+  pWidget->AddInvalidateRect(nullptr);
+}
+void CXFA_FFNotify::OnLayoutItemRemoving(CXFA_FFDocView* pDocView,
+                                         IXFA_DocLayout* pLayout,
+                                         CXFA_LayoutItem* pSender,
+                                         void* pParam,
+                                         void* pParam2) {
+  CXFA_FFWidget* pWidget = static_cast<CXFA_FFWidget*>(pSender);
+  pDocView->DeleteLayoutItem(pWidget);
+  m_pDoc->GetDocProvider()->WidgetEvent(pWidget, pWidget->GetDataAcc(),
+                                        XFA_WIDGETEVENT_PreRemoved, nullptr,
+                                        pWidget->GetPageView());
+  pWidget->AddInvalidateRect(nullptr);
+}
+void CXFA_FFNotify::OnLayoutItemRectChanged(CXFA_FFDocView* pDocView,
+                                            IXFA_DocLayout* pLayout,
+                                            CXFA_LayoutItem* pSender,
+                                            void* pParam,
+                                            void* pParam2) {}
+void CXFA_FFNotify::OnLayoutItemStatustChanged(CXFA_FFDocView* pDocView,
+                                               IXFA_DocLayout* pLayout,
+                                               CXFA_LayoutItem* pSender,
+                                               void* pParam,
+                                               void* pParam2) {
+  CXFA_FFWidget* pWidget = static_cast<CXFA_FFWidget*>(pSender);
+  if (!pWidget) {
+    return;
+  }
+  FX_DWORD dwStatus = (FX_DWORD)(uintptr_t)pParam;
+  if (dwStatus == 0) {
+    CXFA_LayoutItem* pPreItem = pSender->GetPrev();
+    if (pPreItem) {
+      CXFA_FFWidget* pPreWidget = static_cast<CXFA_FFWidget*>(pPreItem);
+      if (pPreWidget) {
+        dwStatus = pPreWidget->GetStatus();
+      }
+    }
+  }
+  FX_DWORD dwOldStatus = pWidget->GetStatus();
+  FX_DWORD dwFilter = XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable |
+                      XFA_WIDGETSTATUS_Printable;
+  if ((dwOldStatus & dwFilter) == dwStatus) {
+    return;
+  }
+  pWidget->ModifyStatus(dwStatus, dwFilter);
+}
diff --git a/xfa/fxfa/app/xfa_ffnotify.h b/xfa/fxfa/app/xfa_ffnotify.h
new file mode 100644
index 0000000..e61c079
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffnotify.h
@@ -0,0 +1,99 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFNOTIFY_H_
+#define XFA_FXFA_APP_XFA_FFNOTIFY_H_
+
+#include "xfa/fxfa/parser/xfa_document.h"
+
+class CXFA_FFNotify : public IXFA_Notify {
+ public:
+  CXFA_FFNotify(CXFA_FFDoc* pDoc);
+  ~CXFA_FFNotify();
+
+  virtual void OnPageEvent(IXFA_LayoutPage* pSender,
+                           XFA_PAGEEVENT eEvent,
+                           void* pParam = NULL);
+
+  virtual void OnNodeEvent(CXFA_Node* pSender,
+                           XFA_NODEEVENT eEvent,
+                           void* pParam = NULL,
+                           void* pParam2 = NULL,
+                           void* pParam3 = NULL,
+                           void* pParam4 = NULL);
+  virtual void OnWidgetDataEvent(CXFA_WidgetData* pSender,
+                                 FX_DWORD dwEvent,
+                                 void* pParam = NULL,
+                                 void* pAdditional = NULL,
+                                 void* pAdditional2 = NULL);
+  virtual CXFA_LayoutItem* OnCreateLayoutItem(CXFA_Node* pNode);
+  virtual void OnLayoutEvent(IXFA_DocLayout* pLayout,
+                             CXFA_LayoutItem* pSender,
+                             XFA_LAYOUTEVENT eEvent,
+                             void* pParam = NULL,
+                             void* pParam2 = NULL);
+
+  virtual void StartFieldDrawLayout(CXFA_Node* pItem,
+                                    FX_FLOAT& fCalcWidth,
+                                    FX_FLOAT& fCalcHeight);
+  virtual FX_BOOL FindSplitPos(CXFA_Node* pItem,
+                               int32_t iBlockIndex,
+                               FX_FLOAT& fCalcHeightPos);
+  virtual FX_BOOL RunScript(CXFA_Node* pScript, CXFA_Node* pFormItem);
+  virtual int32_t ExecEventByDeepFirst(CXFA_Node* pFormNode,
+                                       XFA_EVENTTYPE eEventType,
+                                       FX_BOOL bIsFormReady = FALSE,
+                                       FX_BOOL bRecursive = TRUE,
+                                       CXFA_WidgetAcc* pExclude = NULL);
+  virtual void AddCalcValidate(CXFA_Node* pNode);
+  virtual IXFA_Doc* GetHDOC();
+  virtual IXFA_DocProvider* GetDocProvider();
+  virtual IXFA_AppProvider* GetAppProvider();
+  virtual IXFA_WidgetHandler* GetWidgetHandler();
+  virtual IXFA_Widget* GetHWidget(CXFA_LayoutItem* pLayoutItem);
+  virtual void OpenDropDownList(IXFA_Widget* hWidget);
+  virtual CFX_WideString GetCurrentDateTime();
+  virtual void ResetData(CXFA_WidgetData* pWidgetData = NULL);
+  virtual int32_t GetLayoutStatus();
+  virtual void RunNodeInitialize(CXFA_Node* pNode);
+  virtual void RunSubformIndexChange(CXFA_Node* pSubformNode);
+  virtual CXFA_Node* GetFocusWidgetNode();
+  virtual void SetFocusWidgetNode(CXFA_Node* pNode);
+
+ protected:
+  void OnNodeReady(CXFA_Node* pNode);
+  void OnValueChanging(CXFA_Node* pSender, void* pParam, void* pParam2);
+  void OnValueChanged(CXFA_Node* pSender,
+                      void* pParam,
+                      void* pParam2,
+                      void* pParam3,
+                      void* pParam4);
+  void OnChildAdded(CXFA_Node* pSender, void* pParam, void* pParam2);
+  void OnChildRemoved(CXFA_Node* pSender, void* pParam, void* pParam2);
+  void OnLayoutItemAdd(CXFA_FFDocView* pDocView,
+                       IXFA_DocLayout* pLayout,
+                       CXFA_LayoutItem* pSender,
+                       void* pParam,
+                       void* pParam2);
+  void OnLayoutItemRemoving(CXFA_FFDocView* pDocView,
+                            IXFA_DocLayout* pLayout,
+                            CXFA_LayoutItem* pSender,
+                            void* pParam,
+                            void* pParam2);
+  void OnLayoutItemRectChanged(CXFA_FFDocView* pDocView,
+                               IXFA_DocLayout* pLayout,
+                               CXFA_LayoutItem* pSender,
+                               void* pParam,
+                               void* pParam2);
+  void OnLayoutItemStatustChanged(CXFA_FFDocView* pDocView,
+                                  IXFA_DocLayout* pLayout,
+                                  CXFA_LayoutItem* pSender,
+                                  void* pParam,
+                                  void* pParam2);
+  CXFA_FFDoc* m_pDoc;
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFNOTIFY_H_
diff --git a/xfa/fxfa/app/xfa_ffpageview.cpp b/xfa/fxfa/app/xfa_ffpageview.cpp
new file mode 100644
index 0000000..1bc1681
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffpageview.cpp
@@ -0,0 +1,424 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+
+#include "xfa/fde/fde_render.h"
+#include "xfa/fxfa/app/xfa_ffcheckbutton.h"
+#include "xfa/fxfa/app/xfa_ffchoicelist.h"
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_ffdocview.h"
+#include "xfa/fxfa/app/xfa_fffield.h"
+#include "xfa/fxfa/app/xfa_ffimageedit.h"
+#include "xfa/fxfa/app/xfa_ffpushbutton.h"
+#include "xfa/fxfa/app/xfa_fftextedit.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+#include "xfa/fxfa/app/xfa_fwladapter.h"
+
+CXFA_FFPageView::CXFA_FFPageView(CXFA_FFDocView* pDocView, CXFA_Node* pPageArea)
+    : CXFA_ContainerLayoutItem(pPageArea),
+      m_pDocView(pDocView),
+      m_bLoaded(FALSE) {}
+CXFA_FFPageView::~CXFA_FFPageView() {}
+IXFA_DocView* CXFA_FFPageView::GetDocView() {
+  return m_pDocView;
+}
+int32_t CXFA_FFPageView::GetPageViewIndex() {
+  return GetPageIndex();
+}
+void CXFA_FFPageView::GetPageViewRect(CFX_RectF& rtPage) {
+  CFX_SizeF sz;
+  GetPageSize(sz);
+  rtPage.Set(0, 0, sz);
+}
+void CXFA_FFPageView::GetDisplayMatrix(CFX_Matrix& mt,
+                                       const CFX_Rect& rtDisp,
+                                       int32_t iRotate) {
+  CFX_SizeF sz;
+  GetPageSize(sz);
+  CFX_RectF fdePage;
+  fdePage.Set(0, 0, sz.x, sz.y);
+  FDE_GetPageMatrix(mt, fdePage, rtDisp, iRotate, 0);
+}
+int32_t CXFA_FFPageView::LoadPageView(IFX_Pause* pPause) {
+  if (m_bLoaded) {
+    return 100;
+  }
+  m_bLoaded = TRUE;
+  return 100;
+}
+void CXFA_FFPageView::UnloadPageView() {
+  if (!m_bLoaded) {
+    return;
+  }
+}
+FX_BOOL CXFA_FFPageView::IsPageViewLoaded() {
+  return m_bLoaded;
+}
+IXFA_Widget* CXFA_FFPageView::GetWidgetByPos(FX_FLOAT fx, FX_FLOAT fy) {
+  if (!m_bLoaded) {
+    return nullptr;
+  }
+  IXFA_WidgetIterator* pIterator = CreateWidgetIterator();
+  CXFA_FFWidget* pWidget = nullptr;
+  while ((pWidget = static_cast<CXFA_FFWidget*>(pIterator->MoveToNext()))) {
+    if (!(pWidget->GetStatus() & XFA_WIDGETSTATUS_Visible)) {
+      continue;
+    }
+    CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
+    int32_t type = pAcc->GetClassID();
+    if (type != XFA_ELEMENT_Field && type != XFA_ELEMENT_Draw) {
+      continue;
+    }
+    FX_FLOAT fWidgetx = fx;
+    FX_FLOAT fWidgety = fy;
+    pWidget->Rotate2Normal(fWidgetx, fWidgety);
+    FX_DWORD dwFlag = pWidget->OnHitTest(fWidgetx, fWidgety);
+    if ((FWL_WGTHITTEST_Client == dwFlag ||
+         FWL_WGTHITTEST_HyperLink == dwFlag)) {
+      break;
+    }
+  }
+  pIterator->Release();
+  return pWidget;
+}
+IXFA_WidgetIterator* CXFA_FFPageView::CreateWidgetIterator(
+    FX_DWORD dwTraverseWay,
+    FX_DWORD dwWidgetFilter) {
+  switch (dwTraverseWay) {
+    case XFA_TRAVERSEWAY_Tranvalse:
+      return new CXFA_FFTabOrderPageWidgetIterator(this, dwWidgetFilter);
+    case XFA_TRAVERSEWAY_Form:
+      return new CXFA_FFPageWidgetIterator(this, dwWidgetFilter);
+  }
+  return NULL;
+}
+static FX_BOOL XFA_PageWidgetFilter(CXFA_FFWidget* pWidget,
+                                    FX_DWORD dwFilter,
+                                    FX_BOOL bTraversal,
+                                    FX_BOOL bIgnorerelevant) {
+  CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc();
+  FX_DWORD dwType = dwFilter & XFA_WIDGETFILTER_AllType;
+  if ((dwType == XFA_WIDGETFILTER_Field) &&
+      (pWidgetAcc->GetClassID() != XFA_ELEMENT_Field)) {
+    return FALSE;
+  }
+  FX_DWORD dwStatus = pWidget->GetStatus();
+  if (bTraversal && (dwStatus & XFA_WIDGETSTATUS_Disabled)) {
+    return FALSE;
+  }
+  if (bIgnorerelevant) {
+    return (dwStatus & XFA_WIDGETFILTER_Visible) != 0;
+  }
+  dwFilter &= (XFA_WIDGETFILTER_Visible | XFA_WIDGETFILTER_Viewable |
+               XFA_WIDGETFILTER_Printable);
+  return (dwFilter & dwStatus) == dwFilter;
+}
+CXFA_FFPageWidgetIterator::CXFA_FFPageWidgetIterator(CXFA_FFPageView* pPageView,
+                                                     FX_DWORD dwFilter) {
+  m_pPageView = pPageView;
+  m_dwFilter = dwFilter;
+  m_sIterator.Init(pPageView);
+  m_bIgnorerelevant = ((CXFA_FFDoc*)m_pPageView->GetDocView()->GetDoc())
+                          ->GetXFADoc()
+                          ->GetCurVersionMode() < XFA_VERSION_205;
+}
+CXFA_FFPageWidgetIterator::~CXFA_FFPageWidgetIterator() {}
+void CXFA_FFPageWidgetIterator::Reset() {
+  m_sIterator.Reset();
+}
+IXFA_Widget* CXFA_FFPageWidgetIterator::MoveToFirst() {
+  m_sIterator.Reset();
+  for (CXFA_LayoutItem* pLayoutItem = m_sIterator.GetCurrent(); pLayoutItem;
+       pLayoutItem = m_sIterator.MoveToNext()) {
+    if (IXFA_Widget* hWidget = GetWidget(pLayoutItem)) {
+      return hWidget;
+    }
+  }
+  return NULL;
+}
+IXFA_Widget* CXFA_FFPageWidgetIterator::MoveToLast() {
+  m_sIterator.SetCurrent(NULL);
+  return MoveToPrevious();
+}
+IXFA_Widget* CXFA_FFPageWidgetIterator::MoveToNext() {
+  for (CXFA_LayoutItem* pLayoutItem = m_sIterator.MoveToNext(); pLayoutItem;
+       pLayoutItem = m_sIterator.MoveToNext()) {
+    if (IXFA_Widget* hWidget = GetWidget(pLayoutItem)) {
+      return hWidget;
+    }
+  }
+  return NULL;
+}
+IXFA_Widget* CXFA_FFPageWidgetIterator::MoveToPrevious() {
+  for (CXFA_LayoutItem* pLayoutItem = m_sIterator.MoveToPrev(); pLayoutItem;
+       pLayoutItem = m_sIterator.MoveToPrev()) {
+    if (IXFA_Widget* hWidget = GetWidget(pLayoutItem)) {
+      return hWidget;
+    }
+  }
+  return NULL;
+}
+IXFA_Widget* CXFA_FFPageWidgetIterator::GetCurrentWidget() {
+  CXFA_LayoutItem* pLayoutItem = m_sIterator.GetCurrent();
+  return pLayoutItem ? XFA_GetWidgetFromLayoutItem(pLayoutItem) : NULL;
+}
+FX_BOOL CXFA_FFPageWidgetIterator::SetCurrentWidget(IXFA_Widget* hWidget) {
+  CXFA_FFWidget* pWidget = static_cast<CXFA_FFWidget*>(hWidget);
+  return pWidget && m_sIterator.SetCurrent(pWidget);
+}
+IXFA_Widget* CXFA_FFPageWidgetIterator::GetWidget(
+    CXFA_LayoutItem* pLayoutItem) {
+  if (CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pLayoutItem)) {
+    if (!XFA_PageWidgetFilter(pWidget, m_dwFilter, FALSE, m_bIgnorerelevant)) {
+      return NULL;
+    }
+    if (!pWidget->IsLoaded() &&
+        (pWidget->GetStatus() & XFA_WIDGETSTATUS_Visible) != 0) {
+      pWidget->LoadWidget();
+    }
+    return pWidget;
+  }
+  return NULL;
+}
+CXFA_FFTabOrderPageWidgetIterator::CXFA_FFTabOrderPageWidgetIterator(
+    CXFA_FFPageView* pPageView,
+    FX_DWORD dwFilter)
+    : m_pPageView(pPageView), m_dwFilter(dwFilter), m_iCurWidget(-1) {
+  m_bIgnorerelevant = ((CXFA_FFDoc*)m_pPageView->GetDocView()->GetDoc())
+                          ->GetXFADoc()
+                          ->GetCurVersionMode() < XFA_VERSION_205;
+  Reset();
+}
+CXFA_FFTabOrderPageWidgetIterator::~CXFA_FFTabOrderPageWidgetIterator() {}
+void CXFA_FFTabOrderPageWidgetIterator::Release() {
+  delete this;
+}
+void CXFA_FFTabOrderPageWidgetIterator::Reset() {
+  CreateTabOrderWidgetArray();
+  m_iCurWidget = -1;
+}
+IXFA_Widget* CXFA_FFTabOrderPageWidgetIterator::MoveToFirst() {
+  if (m_TabOrderWidgetArray.GetSize() > 0) {
+    for (int32_t i = 0; i < m_TabOrderWidgetArray.GetSize(); i++) {
+      if (XFA_PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, TRUE,
+                               m_bIgnorerelevant)) {
+        m_iCurWidget = i;
+        return m_TabOrderWidgetArray[m_iCurWidget];
+      }
+    }
+  }
+  return NULL;
+}
+IXFA_Widget* CXFA_FFTabOrderPageWidgetIterator::MoveToLast() {
+  if (m_TabOrderWidgetArray.GetSize() > 0) {
+    for (int32_t i = m_TabOrderWidgetArray.GetSize() - 1; i >= 0; i--) {
+      if (XFA_PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, TRUE,
+                               m_bIgnorerelevant)) {
+        m_iCurWidget = i;
+        return m_TabOrderWidgetArray[m_iCurWidget];
+      }
+    }
+  }
+  return NULL;
+}
+IXFA_Widget* CXFA_FFTabOrderPageWidgetIterator::MoveToNext() {
+  for (int32_t i = m_iCurWidget + 1; i < m_TabOrderWidgetArray.GetSize(); i++) {
+    if (XFA_PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, TRUE,
+                             m_bIgnorerelevant)) {
+      m_iCurWidget = i;
+      return m_TabOrderWidgetArray[m_iCurWidget];
+    }
+  }
+  m_iCurWidget = -1;
+  return NULL;
+}
+IXFA_Widget* CXFA_FFTabOrderPageWidgetIterator::MoveToPrevious() {
+  for (int32_t i = m_iCurWidget - 1; i >= 0; i--) {
+    if (XFA_PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, TRUE,
+                             m_bIgnorerelevant)) {
+      m_iCurWidget = i;
+      return m_TabOrderWidgetArray[m_iCurWidget];
+    }
+  }
+  m_iCurWidget = -1;
+  return NULL;
+}
+IXFA_Widget* CXFA_FFTabOrderPageWidgetIterator::GetCurrentWidget() {
+  if (m_iCurWidget >= 0) {
+    return m_TabOrderWidgetArray[m_iCurWidget];
+  }
+  return NULL;
+}
+FX_BOOL CXFA_FFTabOrderPageWidgetIterator::SetCurrentWidget(
+    IXFA_Widget* hWidget) {
+  int32_t iWidgetIndex =
+      m_TabOrderWidgetArray.Find(static_cast<CXFA_FFWidget*>(hWidget));
+  if (iWidgetIndex >= 0) {
+    m_iCurWidget = iWidgetIndex;
+    return TRUE;
+  }
+  return FALSE;
+}
+CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::GetTraverseWidget(
+    CXFA_FFWidget* pWidget) {
+  CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
+  CXFA_Node* pTraversal = pAcc->GetNode()->GetChild(0, XFA_ELEMENT_Traversal);
+  if (pTraversal) {
+    CXFA_Node* pTraverse = pTraversal->GetChild(0, XFA_ELEMENT_Traverse);
+    if (pTraverse) {
+      CFX_WideString wsTraverseWidgetName;
+      if (pTraverse->GetAttribute(XFA_ATTRIBUTE_Ref, wsTraverseWidgetName)) {
+        return FindWidgetByName(wsTraverseWidgetName, pWidget);
+      }
+    }
+  }
+  return NULL;
+}
+CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::FindWidgetByName(
+    const CFX_WideStringC& wsWidgetName,
+    CXFA_FFWidget* pRefWidget) {
+  return pRefWidget->GetDocView()->GetWidgetByName(wsWidgetName, pRefWidget);
+}
+void CXFA_FFTabOrderPageWidgetIterator::CreateTabOrderWidgetArray() {
+  m_TabOrderWidgetArray.RemoveAll();
+  CXFA_WidgetArray SpaceOrderWidgetArray;
+  CreateSpaceOrderWidgetArray(SpaceOrderWidgetArray);
+  int32_t nWidgetCount = SpaceOrderWidgetArray.GetSize();
+  if (nWidgetCount < 1) {
+    return;
+  }
+  CXFA_FFWidget* hWidget = SpaceOrderWidgetArray[0];
+  for (; m_TabOrderWidgetArray.GetSize() < nWidgetCount;) {
+    if (m_TabOrderWidgetArray.Find(hWidget) < 0) {
+      m_TabOrderWidgetArray.Add(hWidget);
+      CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc();
+      if (pWidgetAcc->GetUIType() == XFA_ELEMENT_ExclGroup) {
+        int32_t iWidgetIndex = SpaceOrderWidgetArray.Find(hWidget) + 1;
+        while (TRUE) {
+          CXFA_FFWidget* pRadio =
+              SpaceOrderWidgetArray[(iWidgetIndex) % nWidgetCount];
+          if (pRadio->GetDataAcc()->GetExclGroup() != pWidgetAcc) {
+            break;
+          }
+          if (m_TabOrderWidgetArray.Find(hWidget) < 0) {
+            m_TabOrderWidgetArray.Add(pRadio);
+          }
+          iWidgetIndex++;
+        }
+      }
+      if (CXFA_FFWidget* hTraverseWidget = GetTraverseWidget(hWidget)) {
+        hWidget = hTraverseWidget;
+        continue;
+      }
+    }
+    int32_t iWidgetIndex = SpaceOrderWidgetArray.Find(hWidget);
+    hWidget = SpaceOrderWidgetArray[(iWidgetIndex + 1) % nWidgetCount];
+  }
+}
+static int32_t XFA_TabOrderWidgetComparator(const void* phWidget1,
+                                            const void* phWidget2) {
+  CXFA_FFWidget* pWidget1 = (*(CXFA_TabParam**)phWidget1)->m_pWidget;
+  CXFA_FFWidget* pWidget2 = (*(CXFA_TabParam**)phWidget2)->m_pWidget;
+  CFX_RectF rt1, rt2;
+  pWidget1->GetWidgetRect(rt1);
+  pWidget2->GetWidgetRect(rt2);
+  FX_FLOAT x1 = rt1.left, y1 = rt1.top, x2 = rt2.left, y2 = rt2.top;
+  if (y1 < y2 || (y1 - y2 < XFA_FLOAT_PERCISION && x1 < x2)) {
+    return -1;
+  }
+  return 1;
+}
+void CXFA_FFTabOrderPageWidgetIterator::OrderContainer(
+    CXFA_LayoutItemIterator* sIterator,
+    CXFA_LayoutItem* pContainerItem,
+    CXFA_TabParam* pContainer,
+    FX_BOOL& bCurrentItem,
+    FX_BOOL& bContentArea,
+    FX_BOOL bMarsterPage) {
+  CFX_PtrArray tabParams;
+  CXFA_LayoutItem* pSearchItem = sIterator->MoveToNext();
+  while (pSearchItem) {
+    if (!pSearchItem->IsContentLayoutItem()) {
+      bContentArea = TRUE;
+      pSearchItem = sIterator->MoveToNext();
+      continue;
+    }
+    if (bMarsterPage && bContentArea) {
+      break;
+    }
+    if (bMarsterPage || bContentArea) {
+      CXFA_FFWidget* hWidget = GetWidget(pSearchItem);
+      if (!hWidget) {
+        pSearchItem = sIterator->MoveToNext();
+        continue;
+      }
+      if (pContainerItem && (pSearchItem->GetParent() != pContainerItem)) {
+        bCurrentItem = TRUE;
+        break;
+      }
+      CXFA_TabParam* pParam = new CXFA_TabParam;
+      pParam->m_pWidget = hWidget;
+      tabParams.Add(pParam);
+      if (XFA_IsLayoutElement(pSearchItem->GetFormNode()->GetClassID(), TRUE)) {
+        OrderContainer(sIterator, pSearchItem, pParam, bCurrentItem,
+                       bContentArea, bMarsterPage);
+      }
+    }
+    if (bCurrentItem) {
+      pSearchItem = sIterator->GetCurrent();
+      bCurrentItem = FALSE;
+    } else {
+      pSearchItem = sIterator->MoveToNext();
+    }
+  }
+  int32_t iChildren = tabParams.GetSize();
+  if (iChildren > 1) {
+    FXSYS_qsort(tabParams.GetData(), iChildren, sizeof(void*),
+                XFA_TabOrderWidgetComparator);
+  }
+  for (int32_t iStart = 0; iStart < iChildren; iStart++) {
+    CXFA_TabParam* pParam = (CXFA_TabParam*)tabParams[iStart];
+    pContainer->m_Children.Add(pParam->m_pWidget);
+    if (pParam->m_Children.GetSize() > 0) {
+      pContainer->m_Children.Append(pParam->m_Children);
+    }
+    delete pParam;
+  }
+  tabParams.RemoveAll();
+}
+void CXFA_FFTabOrderPageWidgetIterator::CreateSpaceOrderWidgetArray(
+    CXFA_WidgetArray& WidgetArray) {
+  CXFA_LayoutItemIterator sIterator;
+  sIterator.Init(m_pPageView);
+  CXFA_TabParam* pParam = new CXFA_TabParam;
+  FX_BOOL bCurrentItem = FALSE;
+  FX_BOOL bContentArea = FALSE;
+  OrderContainer(&sIterator, NULL, pParam, bCurrentItem, bContentArea);
+  if (pParam->m_Children.GetSize() > 0) {
+    WidgetArray.Append(pParam->m_Children);
+  }
+  sIterator.Reset();
+  bCurrentItem = FALSE;
+  bContentArea = FALSE;
+  pParam->m_Children.RemoveAll();
+  OrderContainer(&sIterator, NULL, pParam, bCurrentItem, bContentArea, TRUE);
+  if (pParam->m_Children.GetSize() > 0) {
+    WidgetArray.Append(pParam->m_Children);
+  }
+  delete pParam;
+}
+CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::GetWidget(
+    CXFA_LayoutItem* pLayoutItem) {
+  if (CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pLayoutItem)) {
+    if (!pWidget->IsLoaded() &&
+        (pWidget->GetStatus() & XFA_WIDGETSTATUS_Visible)) {
+      pWidget->LoadWidget();
+    }
+    return pWidget;
+  }
+  return NULL;
+}
diff --git a/xfa/fxfa/app/xfa_ffpageview.h b/xfa/fxfa/app/xfa_ffpageview.h
new file mode 100644
index 0000000..b68e828
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffpageview.h
@@ -0,0 +1,111 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFPAGEVIEW_H_
+#define XFA_FXFA_APP_XFA_FFPAGEVIEW_H_
+
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+
+class CXFA_FFWidget;
+class CXFA_FFDocView;
+class CXFA_FFPageView : public CXFA_ContainerLayoutItem, public IXFA_PageView {
+ public:
+  CXFA_FFPageView(CXFA_FFDocView* pDocView, CXFA_Node* pPageArea);
+  ~CXFA_FFPageView() override;
+
+  // IFXA_PageView:
+  IXFA_DocView* GetDocView() override;
+  int32_t GetPageViewIndex() override;
+  void GetPageViewRect(CFX_RectF& rtPage) override;
+  void GetDisplayMatrix(CFX_Matrix& mt,
+                        const CFX_Rect& rtDisp,
+                        int32_t iRotate) override;
+  int32_t LoadPageView(IFX_Pause* pPause = NULL) override;
+  void UnloadPageView() override;
+  IXFA_Widget* GetWidgetByPos(FX_FLOAT fx, FX_FLOAT fy) override;
+  IXFA_WidgetIterator* CreateWidgetIterator(
+      FX_DWORD dwTraverseWay = XFA_TRAVERSEWAY_Form,
+      FX_DWORD dwWidgetFilter = XFA_WIDGETFILTER_Visible |
+                                XFA_WIDGETFILTER_Viewable |
+                                XFA_WIDGETFILTER_AllType) override;
+
+  FX_BOOL IsPageViewLoaded();
+
+ protected:
+  CXFA_FFDocView* m_pDocView;
+  FX_BOOL m_bLoaded;
+};
+typedef CXFA_NodeIteratorTemplate<CXFA_LayoutItem,
+                                  CXFA_TraverseStrategy_LayoutItem>
+    CXFA_LayoutItemIterator;
+class CXFA_FFPageWidgetIterator : public IXFA_WidgetIterator {
+ public:
+  CXFA_FFPageWidgetIterator(CXFA_FFPageView* pPageView, FX_DWORD dwFilter);
+  virtual ~CXFA_FFPageWidgetIterator();
+  virtual void Release() { delete this; }
+
+  virtual void Reset();
+  virtual IXFA_Widget* MoveToFirst();
+  virtual IXFA_Widget* MoveToLast();
+  virtual IXFA_Widget* MoveToNext();
+  virtual IXFA_Widget* MoveToPrevious();
+  virtual IXFA_Widget* GetCurrentWidget();
+  virtual FX_BOOL SetCurrentWidget(IXFA_Widget* hWidget);
+
+ protected:
+  IXFA_Widget* GetWidget(CXFA_LayoutItem* pLayoutItem);
+  CXFA_FFPageView* m_pPageView;
+  IXFA_Widget* m_hCurWidget;
+  FX_DWORD m_dwFilter;
+  FX_BOOL m_bIgnorerelevant;
+  CXFA_LayoutItemIterator m_sIterator;
+};
+typedef CFX_ArrayTemplate<CXFA_FFWidget*> CXFA_WidgetArray;
+class CXFA_TabParam {
+ public:
+  CXFA_TabParam() : m_pWidget(NULL) {}
+  ~CXFA_TabParam() {}
+
+  CXFA_FFWidget* m_pWidget;
+  CXFA_WidgetArray m_Children;
+};
+class CXFA_FFTabOrderPageWidgetIterator : public IXFA_WidgetIterator {
+ public:
+  CXFA_FFTabOrderPageWidgetIterator(CXFA_FFPageView* pPageView,
+                                    FX_DWORD dwFilter);
+  virtual ~CXFA_FFTabOrderPageWidgetIterator();
+
+  virtual void Release();
+
+  virtual void Reset();
+  virtual IXFA_Widget* MoveToFirst();
+  virtual IXFA_Widget* MoveToLast();
+  virtual IXFA_Widget* MoveToNext();
+  virtual IXFA_Widget* MoveToPrevious();
+  virtual IXFA_Widget* GetCurrentWidget();
+  virtual FX_BOOL SetCurrentWidget(IXFA_Widget* hWidget);
+
+ protected:
+  CXFA_WidgetArray m_TabOrderWidgetArray;
+  CXFA_FFPageView* m_pPageView;
+  FX_DWORD m_dwFilter;
+  int32_t m_iCurWidget;
+  FX_BOOL m_bIgnorerelevant;
+  CXFA_FFWidget* GetTraverseWidget(CXFA_FFWidget* pWidget);
+  CXFA_FFWidget* FindWidgetByName(const CFX_WideStringC& wsWidgetName,
+                                  CXFA_FFWidget* pRefWidget);
+  void CreateTabOrderWidgetArray();
+  void CreateSpaceOrderWidgetArray(CXFA_WidgetArray& WidgetArray);
+  CXFA_FFWidget* GetWidget(CXFA_LayoutItem* pLayoutItem);
+  void OrderContainer(CXFA_LayoutItemIterator* sIterator,
+                      CXFA_LayoutItem* pContainerItem,
+                      CXFA_TabParam* pContainer,
+                      FX_BOOL& bCurrentItem,
+                      FX_BOOL& bContentArea,
+                      FX_BOOL bMarsterPage = FALSE);
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFPAGEVIEW_H_
diff --git a/xfa/fxfa/app/xfa_ffpath.cpp b/xfa/fxfa/app/xfa_ffpath.cpp
new file mode 100644
index 0000000..f082232
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffpath.cpp
@@ -0,0 +1,159 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffpath.h"
+
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_ffdraw.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+#include "xfa/include/fxgraphics/fx_graphics.h"
+
+CXFA_FFLine::CXFA_FFLine(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFDraw(pPageView, pDataAcc) {}
+CXFA_FFLine::~CXFA_FFLine() {}
+void CXFA_FFLine::GetRectFromHand(CFX_RectF& rect,
+                                  int32_t iHand,
+                                  FX_FLOAT fLineWidth) {
+  FX_FLOAT fHalfWidth = fLineWidth / 2.0f;
+  if (rect.height < 1.0f) {
+    switch (iHand) {
+      case XFA_ATTRIBUTEENUM_Left:
+        rect.top -= fHalfWidth;
+        break;
+      case XFA_ATTRIBUTEENUM_Right:
+        rect.top += fHalfWidth;
+    }
+  } else if (rect.width < 1.0f) {
+    switch (iHand) {
+      case XFA_ATTRIBUTEENUM_Left:
+        rect.left += fHalfWidth;
+        break;
+      case XFA_ATTRIBUTEENUM_Right:
+        rect.left += fHalfWidth;
+        break;
+    }
+  } else {
+    switch (iHand) {
+      case XFA_ATTRIBUTEENUM_Left:
+        rect.Inflate(fHalfWidth, fHalfWidth);
+        break;
+      case XFA_ATTRIBUTEENUM_Right:
+        rect.Deflate(fHalfWidth, fHalfWidth);
+        break;
+    }
+  }
+}
+void CXFA_FFLine::RenderWidget(CFX_Graphics* pGS,
+                               CFX_Matrix* pMatrix,
+                               FX_DWORD dwStatus,
+                               int32_t iRotate) {
+  if (!IsMatchVisibleStatus(dwStatus)) {
+    return;
+  }
+  CXFA_Value value = m_pDataAcc->GetFormValue();
+  if (!value) {
+    return;
+  }
+  CXFA_Line lineObj = value.GetLine();
+  FX_ARGB lineColor = 0xFF000000;
+  int32_t iStrokeType = 0;
+  FX_FLOAT fLineWidth = 1.0f;
+  FX_BOOL bSlope = lineObj.GetSlop();
+  int32_t iCap = 0;
+  CXFA_Edge edge = lineObj.GetEdge();
+  if (edge) {
+    if (edge.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
+      return;
+    }
+    lineColor = edge.GetColor();
+    iStrokeType = edge.GetStrokeType();
+    fLineWidth = edge.GetThickness();
+    iCap = edge.GetCapType();
+  }
+  CFX_Matrix mtRotate;
+  GetRotateMatrix(mtRotate);
+  if (pMatrix) {
+    mtRotate.Concat(*pMatrix);
+  }
+  CFX_RectF rtLine;
+  GetRectWithoutRotate(rtLine);
+  if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
+    XFA_RectWidthoutMargin(rtLine, mgWidget);
+  }
+  GetRectFromHand(rtLine, lineObj.GetHand(), fLineWidth);
+  CFX_Path linePath;
+  linePath.Create();
+  if (bSlope && rtLine.right() > 0.0f && rtLine.bottom() > 0.0f) {
+    linePath.AddLine(rtLine.right(), rtLine.top, rtLine.left, rtLine.bottom());
+  } else {
+    linePath.AddLine(rtLine.left, rtLine.top, rtLine.right(), rtLine.bottom());
+  }
+  CFX_Color color(lineColor);
+  pGS->SaveGraphState();
+  pGS->SetLineWidth(fLineWidth, TRUE);
+  XFA_StrokeTypeSetLineDash(pGS, iStrokeType, iCap);
+  pGS->SetStrokeColor(&color);
+  pGS->SetLineCap(XFA_LineCapToFXGE(iCap));
+  pGS->StrokePath(&linePath, &mtRotate);
+  pGS->RestoreGraphState();
+}
+CXFA_FFArc::CXFA_FFArc(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFDraw(pPageView, pDataAcc) {}
+CXFA_FFArc::~CXFA_FFArc() {}
+void CXFA_FFArc::RenderWidget(CFX_Graphics* pGS,
+                              CFX_Matrix* pMatrix,
+                              FX_DWORD dwStatus,
+                              int32_t iRotate) {
+  if (!IsMatchVisibleStatus(dwStatus)) {
+    return;
+  }
+  CXFA_Value value = m_pDataAcc->GetFormValue();
+  if (!value) {
+    return;
+  }
+  CXFA_Arc arcObj = value.GetArc();
+  CFX_Matrix mtRotate;
+  GetRotateMatrix(mtRotate);
+  if (pMatrix) {
+    mtRotate.Concat(*pMatrix);
+  }
+  CFX_RectF rtArc;
+  GetRectWithoutRotate(rtArc);
+  if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
+    XFA_RectWidthoutMargin(rtArc, mgWidget);
+  }
+  DrawBorder(pGS, arcObj, rtArc, &mtRotate);
+}
+CXFA_FFRectangle::CXFA_FFRectangle(CXFA_FFPageView* pPageView,
+                                   CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFDraw(pPageView, pDataAcc) {}
+CXFA_FFRectangle::~CXFA_FFRectangle() {}
+void CXFA_FFRectangle::RenderWidget(CFX_Graphics* pGS,
+                                    CFX_Matrix* pMatrix,
+                                    FX_DWORD dwStatus,
+                                    int32_t iRotate) {
+  if (!IsMatchVisibleStatus(dwStatus)) {
+    return;
+  }
+  CXFA_Value value = m_pDataAcc->GetFormValue();
+  if (!value) {
+    return;
+  }
+  CXFA_Rectangle rtObj = value.GetRectangle();
+  CFX_RectF rect;
+  GetRectWithoutRotate(rect);
+  if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
+    XFA_RectWidthoutMargin(rect, mgWidget);
+  }
+  CFX_Matrix mtRotate;
+  GetRotateMatrix(mtRotate);
+  if (pMatrix) {
+    mtRotate.Concat(*pMatrix);
+  }
+  DrawBorder(pGS, rtObj, rect, &mtRotate);
+}
diff --git a/xfa/fxfa/app/xfa_ffpath.h b/xfa/fxfa/app/xfa_ffpath.h
new file mode 100644
index 0000000..2b2c40d
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffpath.h
@@ -0,0 +1,43 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFPATH_H_
+#define XFA_FXFA_APP_XFA_FFPATH_H_
+
+#include "xfa/fxfa/app/xfa_ffdraw.h"
+
+class CXFA_FFLine : public CXFA_FFDraw {
+ public:
+  CXFA_FFLine(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFLine();
+  virtual void RenderWidget(CFX_Graphics* pGS,
+                            CFX_Matrix* pMatrix = NULL,
+                            FX_DWORD dwStatus = 0,
+                            int32_t iRotate = 0);
+
+ private:
+  void GetRectFromHand(CFX_RectF& rect, int32_t iHand, FX_FLOAT fLineWidth);
+};
+class CXFA_FFArc : public CXFA_FFDraw {
+ public:
+  CXFA_FFArc(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFArc();
+  virtual void RenderWidget(CFX_Graphics* pGS,
+                            CFX_Matrix* pMatrix = NULL,
+                            FX_DWORD dwStatus = 0,
+                            int32_t iRotate = 0);
+};
+class CXFA_FFRectangle : public CXFA_FFDraw {
+ public:
+  CXFA_FFRectangle(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFRectangle();
+  virtual void RenderWidget(CFX_Graphics* pGS,
+                            CFX_Matrix* pMatrix = NULL,
+                            FX_DWORD dwStatus = 0,
+                            int32_t iRotate = 0);
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFPATH_H_
diff --git a/xfa/fxfa/app/xfa_ffpushbutton.cpp b/xfa/fxfa/app/xfa_ffpushbutton.cpp
new file mode 100644
index 0000000..718853e
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffpushbutton.cpp
@@ -0,0 +1,249 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffpushbutton.h"
+
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/fxfa/app/xfa_fffield.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+#include "xfa/fxfa/app/xfa_ffwidgetacc.h"
+#include "xfa/fxfa/app/xfa_textlayout.h"
+#include "xfa/include/fwl/core/fwl_widgetmgr.h"
+#include "xfa/include/fwl/lightwidget/pushbutton.h"
+
+CXFA_FFPushButton::CXFA_FFPushButton(CXFA_FFPageView* pPageView,
+                                     CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFField(pPageView, pDataAcc),
+      m_pRolloverTextLayout(NULL),
+      m_pDownTextLayout(NULL),
+      m_pDownProvider(NULL),
+      m_pRollProvider(NULL),
+      m_pOldDelegate(NULL) {}
+CXFA_FFPushButton::~CXFA_FFPushButton() {
+  CXFA_FFPushButton::UnloadWidget();
+}
+void CXFA_FFPushButton::RenderWidget(CFX_Graphics* pGS,
+                                     CFX_Matrix* pMatrix,
+                                     FX_DWORD dwStatus,
+                                     int32_t iRotate) {
+  if (!IsMatchVisibleStatus(dwStatus)) {
+    return;
+  }
+  CFX_Matrix mtRotate;
+  GetRotateMatrix(mtRotate);
+  if (pMatrix) {
+    mtRotate.Concat(*pMatrix);
+  }
+  CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+  RenderHighlightCaption(pGS, &mtRotate);
+  CFX_RectF rtWidget;
+  GetRectWithoutRotate(rtWidget);
+  CFX_Matrix mt;
+  mt.Set(1, 0, 0, 1, rtWidget.left, rtWidget.top);
+  mt.Concat(mtRotate);
+  GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget->GetWidget(),
+                                                 pGS, &mt);
+}
+FX_BOOL CXFA_FFPushButton::LoadWidget() {
+  FXSYS_assert(m_pNormalWidget == NULL);
+  CFWL_PushButton* pPushButton = CFWL_PushButton::Create();
+  if (pPushButton) {
+    pPushButton->Initialize();
+  }
+  m_pOldDelegate = pPushButton->SetDelegate(this);
+  m_pNormalWidget = (CFWL_Widget*)pPushButton;
+  IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
+  m_pNormalWidget->SetPrivateData(pWidget, this, NULL);
+  IFWL_NoteDriver* pNoteDriver = FWL_GetApp()->GetNoteDriver();
+  pNoteDriver->RegisterEventTarget(pWidget, pWidget);
+  m_pNormalWidget->LockUpdate();
+  UpdateWidgetProperty();
+  LoadHighlightCaption();
+  m_pNormalWidget->UnlockUpdate();
+  return CXFA_FFField::LoadWidget();
+}
+void CXFA_FFPushButton::UpdateWidgetProperty() {
+  FX_DWORD dwStyleEx = 0;
+  switch (m_pDataAcc->GetButtonHighlight()) {
+    case XFA_ATTRIBUTEENUM_Inverted:
+      dwStyleEx = XFA_FWL_PSBSTYLEEXT_HiliteInverted;
+      break;
+    case XFA_ATTRIBUTEENUM_Outline:
+      dwStyleEx = XFA_FWL_PSBSTYLEEXT_HiliteOutLine;
+      break;
+    case XFA_ATTRIBUTEENUM_Push:
+      dwStyleEx = XFA_FWL_PSBSTYLEEXT_HilitePush;
+      break;
+    default:
+      break;
+  }
+  m_pNormalWidget->ModifyStylesEx(dwStyleEx, 0xFFFFFFFF);
+}
+void CXFA_FFPushButton::UnloadWidget() {
+  if (m_pRolloverTextLayout) {
+    delete m_pRolloverTextLayout;
+    m_pRolloverTextLayout = NULL;
+  }
+  if (m_pDownTextLayout) {
+    delete m_pDownTextLayout;
+    m_pDownTextLayout = NULL;
+  }
+  if (m_pDownProvider) {
+    delete m_pDownProvider;
+    m_pDownProvider = NULL;
+  }
+  if (m_pRollProvider) {
+    delete m_pRollProvider;
+    m_pRollProvider = NULL;
+  }
+  CXFA_FFField::UnloadWidget();
+}
+FX_BOOL CXFA_FFPushButton::PerformLayout() {
+  CXFA_FFWidget::PerformLayout();
+  CFX_RectF rtWidget;
+  GetRectWithoutRotate(rtWidget);
+  m_rtUI = rtWidget;
+  if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
+    XFA_RectWidthoutMargin(rtWidget, mgWidget);
+  }
+  CXFA_Caption caption = m_pDataAcc->GetCaption();
+  m_rtCaption.Set(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height);
+  if (CXFA_Margin mgCap = caption.GetMargin()) {
+    XFA_RectWidthoutMargin(m_rtCaption, mgCap);
+  }
+  LayoutHighlightCaption();
+  SetFWLRect();
+  if (m_pNormalWidget) {
+    m_pNormalWidget->Update();
+  }
+  return TRUE;
+}
+FX_FLOAT CXFA_FFPushButton::GetLineWidth() {
+  CXFA_Border border = m_pDataAcc->GetBorder();
+  if (border && border.GetPresence() == XFA_ATTRIBUTEENUM_Visible) {
+    CXFA_Edge edge = border.GetEdge(0);
+    return edge.GetThickness();
+  }
+  return 0;
+}
+FX_ARGB CXFA_FFPushButton::GetLineColor() {
+  return 0xFF000000;
+}
+FX_ARGB CXFA_FFPushButton::GetFillColor() {
+  return 0xFFFFFFFF;
+}
+void CXFA_FFPushButton::LoadHighlightCaption() {
+  CXFA_Caption caption = m_pDataAcc->GetCaption();
+  if (caption && caption.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) {
+    {
+      CFX_WideString wsRollover;
+      FX_BOOL bRichText;
+      if (m_pDataAcc->GetButtonRollover(wsRollover, bRichText)) {
+        if (m_pRollProvider == NULL) {
+          m_pRollProvider =
+              new CXFA_TextProvider(m_pDataAcc, XFA_TEXTPROVIDERTYPE_Rollover);
+        }
+        m_pRolloverTextLayout = new CXFA_TextLayout(m_pRollProvider);
+      }
+      CFX_WideString wsDown;
+      if (m_pDataAcc->GetButtonDown(wsDown, bRichText)) {
+        if (m_pDownProvider == NULL) {
+          m_pDownProvider =
+              new CXFA_TextProvider(m_pDataAcc, XFA_TEXTPROVIDERTYPE_Down);
+        }
+        m_pDownTextLayout = new CXFA_TextLayout(m_pDownProvider);
+      }
+    }
+  }
+}
+void CXFA_FFPushButton::LayoutHighlightCaption() {
+  CFX_SizeF sz(m_rtCaption.width, m_rtCaption.height);
+  LayoutCaption();
+  if (m_pRolloverTextLayout) {
+    m_pRolloverTextLayout->Layout(sz);
+  }
+  if (m_pDownTextLayout) {
+    m_pDownTextLayout->Layout(sz);
+  }
+}
+void CXFA_FFPushButton::RenderHighlightCaption(CFX_Graphics* pGS,
+                                               CFX_Matrix* pMatrix) {
+  CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout();
+  CXFA_Caption caption = m_pDataAcc->GetCaption();
+  if (caption && caption.GetPresence() == XFA_ATTRIBUTEENUM_Visible) {
+    CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
+    CFX_RectF rtWidget;
+    GetRectWithoutRotate(rtWidget);
+    CFX_RectF rtClip = m_rtCaption;
+    rtClip.Intersect(rtWidget);
+    CFX_Matrix mt;
+    mt.Set(1, 0, 0, 1, m_rtCaption.left, m_rtCaption.top);
+    if (pMatrix) {
+      pMatrix->TransformRect(rtClip);
+      mt.Concat(*pMatrix);
+    }
+    {
+      FX_DWORD dwState = m_pNormalWidget->GetStates();
+      if (m_pDownTextLayout && (dwState & FWL_STATE_PSB_Pressed) &&
+          (dwState & FWL_STATE_PSB_Hovered)) {
+        if (m_pDownTextLayout->DrawString(pRenderDevice, mt, rtClip)) {
+          return;
+        }
+      } else if (m_pRolloverTextLayout && (dwState & FWL_STATE_PSB_Hovered)) {
+        if (m_pRolloverTextLayout->DrawString(pRenderDevice, mt, rtClip)) {
+          return;
+        }
+      }
+    }
+    if (pCapTextLayout) {
+      pCapTextLayout->DrawString(pRenderDevice, mt, rtClip);
+    }
+  }
+}
+int32_t CXFA_FFPushButton::OnProcessMessage(CFWL_Message* pMessage) {
+  return m_pOldDelegate->OnProcessMessage(pMessage);
+}
+FWL_ERR CXFA_FFPushButton::OnProcessEvent(CFWL_Event* pEvent) {
+  m_pOldDelegate->OnProcessEvent(pEvent);
+  return CXFA_FFField::OnProcessEvent(pEvent);
+}
+FWL_ERR CXFA_FFPushButton::OnDrawWidget(CFX_Graphics* pGraphics,
+                                        const CFX_Matrix* pMatrix) {
+  if (m_pNormalWidget->GetStylesEx() & XFA_FWL_PSBSTYLEEXT_HiliteInverted) {
+    if ((m_pNormalWidget->GetStates() & FWL_STATE_PSB_Pressed) &&
+        (m_pNormalWidget->GetStates() & FWL_STATE_PSB_Hovered)) {
+      CFX_RectF rtFill;
+      m_pNormalWidget->GetWidgetRect(rtFill);
+      rtFill.left = rtFill.top = 0;
+      FX_FLOAT fLineWith = GetLineWidth();
+      rtFill.Deflate(fLineWith, fLineWith);
+      CFX_Color cr(FXARGB_MAKE(128, 128, 255, 255));
+      pGraphics->SetFillColor(&cr);
+      CFX_Path path;
+      path.Create();
+      path.AddRectangle(rtFill.left, rtFill.top, rtFill.width, rtFill.height);
+      pGraphics->FillPath(&path, FXFILL_WINDING, (CFX_Matrix*)pMatrix);
+    }
+  } else if (m_pNormalWidget->GetStylesEx() &
+             XFA_FWL_PSBSTYLEEXT_HiliteOutLine) {
+    if ((m_pNormalWidget->GetStates() & FWL_STATE_PSB_Pressed) &&
+        (m_pNormalWidget->GetStates() & FWL_STATE_PSB_Hovered)) {
+      FX_FLOAT fLineWidth = GetLineWidth();
+      CFX_Color cr(FXARGB_MAKE(255, 128, 255, 255));
+      pGraphics->SetStrokeColor(&cr);
+      pGraphics->SetLineWidth(fLineWidth);
+      CFX_Path path;
+      path.Create();
+      CFX_RectF rect;
+      m_pNormalWidget->GetWidgetRect(rect);
+      path.AddRectangle(0, 0, rect.width, rect.height);
+      pGraphics->StrokePath(&path, (CFX_Matrix*)pMatrix);
+    }
+  } else if (m_pNormalWidget->GetStylesEx() & XFA_FWL_PSBSTYLEEXT_HilitePush) {
+  }
+  return FWL_ERR_Succeeded;
+}
diff --git a/xfa/fxfa/app/xfa_ffpushbutton.h b/xfa/fxfa/app/xfa_ffpushbutton.h
new file mode 100644
index 0000000..39f6bd4
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffpushbutton.h
@@ -0,0 +1,50 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFPUSHBUTTON_H_
+#define XFA_FXFA_APP_XFA_FFPUSHBUTTON_H_
+
+#include "xfa/fxfa/app/xfa_fffield.h"
+
+#define XFA_FWL_PSBSTYLEEXT_HiliteNone (0L << 0)
+#define XFA_FWL_PSBSTYLEEXT_HiliteInverted (1L << 0)
+#define XFA_FWL_PSBSTYLEEXT_HilitePush (2L << 0)
+#define XFA_FWL_PSBSTYLEEXT_HiliteOutLine (4L << 0)
+
+class CXFA_TextProvider;
+
+class CXFA_FFPushButton : public CXFA_FFField {
+ public:
+  CXFA_FFPushButton(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFPushButton();
+  virtual void RenderWidget(CFX_Graphics* pGS,
+                            CFX_Matrix* pMatrix = NULL,
+                            FX_DWORD dwStatus = 0,
+                            int32_t iRotate = 0);
+  virtual FX_BOOL LoadWidget();
+  virtual void UnloadWidget();
+  virtual FX_BOOL PerformLayout();
+  virtual void UpdateWidgetProperty();
+  virtual int32_t OnProcessMessage(CFWL_Message* pMessage);
+  virtual FWL_ERR OnProcessEvent(CFWL_Event* pEvent);
+  virtual FWL_ERR OnDrawWidget(CFX_Graphics* pGraphics,
+                               const CFX_Matrix* pMatrix = NULL);
+
+ protected:
+  void LoadHighlightCaption();
+  void LayoutHighlightCaption();
+  void RenderHighlightCaption(CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL);
+  FX_FLOAT GetLineWidth();
+  FX_ARGB GetLineColor();
+  FX_ARGB GetFillColor();
+  CXFA_TextLayout* m_pRolloverTextLayout;
+  CXFA_TextLayout* m_pDownTextLayout;
+  CXFA_TextProvider* m_pDownProvider;
+  CXFA_TextProvider* m_pRollProvider;
+  IFWL_WidgetDelegate* m_pOldDelegate;
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFPUSHBUTTON_H_
diff --git a/xfa/fxfa/app/xfa_ffsignature.cpp b/xfa/fxfa/app/xfa_ffsignature.cpp
new file mode 100644
index 0000000..96907c5
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffsignature.cpp
@@ -0,0 +1,120 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffsignature.h"
+
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_fffield.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+
+CXFA_FFSignature::CXFA_FFSignature(CXFA_FFPageView* pPageView,
+                                   CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFField(pPageView, pDataAcc) {}
+CXFA_FFSignature::~CXFA_FFSignature() {}
+FX_BOOL CXFA_FFSignature::LoadWidget() {
+  return CXFA_FFField::LoadWidget();
+}
+void CXFA_FFSignature::RenderWidget(CFX_Graphics* pGS,
+                                    CFX_Matrix* pMatrix,
+                                    FX_DWORD dwStatus,
+                                    int32_t iRotate) {
+  if (!IsMatchVisibleStatus(dwStatus)) {
+    return;
+  }
+  CFX_Matrix mtRotate;
+  GetRotateMatrix(mtRotate);
+  if (pMatrix) {
+    mtRotate.Concat(*pMatrix);
+  }
+  CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+  CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
+  DrawBorder(pGS, borderUI, m_rtUI, &mtRotate);
+  RenderCaption(pGS, &mtRotate);
+  DrawHighlight(pGS, &mtRotate, dwStatus, FALSE);
+  CFX_RectF rtWidget = m_rtUI;
+  IXFA_DocProvider* pDocProvider = m_pDataAcc->GetDoc()->GetDocProvider();
+  FXSYS_assert(pDocProvider);
+  pDocProvider->RenderCustomWidget(this, pGS, &mtRotate, rtWidget);
+}
+FX_BOOL CXFA_FFSignature::OnMouseEnter() {
+  return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnMouseExit() {
+  return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnLButtonDown(FX_DWORD dwFlags,
+                                        FX_FLOAT fx,
+                                        FX_FLOAT fy) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnLButtonUp(FX_DWORD dwFlags,
+                                      FX_FLOAT fx,
+                                      FX_FLOAT fy) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnLButtonDblClk(FX_DWORD dwFlags,
+                                          FX_FLOAT fx,
+                                          FX_FLOAT fy) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnMouseMove(FX_DWORD dwFlags,
+                                      FX_FLOAT fx,
+                                      FX_FLOAT fy) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnMouseWheel(FX_DWORD dwFlags,
+                                       int16_t zDelta,
+                                       FX_FLOAT fx,
+                                       FX_FLOAT fy) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnRButtonDown(FX_DWORD dwFlags,
+                                        FX_FLOAT fx,
+                                        FX_FLOAT fy) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnRButtonUp(FX_DWORD dwFlags,
+                                      FX_FLOAT fx,
+                                      FX_FLOAT fy) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnRButtonDblClk(FX_DWORD dwFlags,
+                                          FX_FLOAT fx,
+                                          FX_FLOAT fy) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnKeyDown(FX_DWORD dwKeyCode, FX_DWORD dwFlags) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnKeyUp(FX_DWORD dwKeyCode, FX_DWORD dwFlags) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnChar(FX_DWORD dwChar, FX_DWORD dwFlags) {
+  return FALSE;
+}
+FX_DWORD CXFA_FFSignature::OnHitTest(FX_FLOAT fx, FX_FLOAT fy) {
+  if (m_pNormalWidget) {
+    FX_FLOAT ffx = fx, ffy = fy;
+    FWLToClient(ffx, ffy);
+    FX_DWORD dwWidgetHit = m_pNormalWidget->HitTest(ffx, ffy);
+    if (dwWidgetHit != FWL_WGTHITTEST_Unknown) {
+      return FWL_WGTHITTEST_Client;
+    }
+  }
+  CFX_RectF rtBox;
+  GetRectWithoutRotate(rtBox);
+  if (!rtBox.Contains(fx, fy)) {
+    return FWL_WGTHITTEST_Unknown;
+  }
+  if (m_rtCaption.Contains(fx, fy)) {
+    return FWL_WGTHITTEST_Titlebar;
+  }
+  return FWL_WGTHITTEST_Client;
+}
+FX_BOOL CXFA_FFSignature::OnSetCursor(FX_FLOAT fx, FX_FLOAT fy) {
+  return FALSE;
+}
diff --git a/xfa/fxfa/app/xfa_ffsignature.h b/xfa/fxfa/app/xfa_ffsignature.h
new file mode 100644
index 0000000..f976fed
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffsignature.h
@@ -0,0 +1,43 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFSIGNATURE_H_
+#define XFA_FXFA_APP_XFA_FFSIGNATURE_H_
+
+#include "xfa/fxfa/app/xfa_fffield.h"
+
+class CXFA_FFSignature final : public CXFA_FFField {
+ public:
+  CXFA_FFSignature(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFSignature();
+
+  virtual void RenderWidget(CFX_Graphics* pGS,
+                            CFX_Matrix* pMatrix = NULL,
+                            FX_DWORD dwStatus = 0,
+                            int32_t iRotate = 0);
+  virtual FX_BOOL LoadWidget();
+  virtual FX_BOOL OnMouseEnter();
+  virtual FX_BOOL OnMouseExit();
+  virtual FX_BOOL OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnLButtonDblClk(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnMouseWheel(FX_DWORD dwFlags,
+                               int16_t zDelta,
+                               FX_FLOAT fx,
+                               FX_FLOAT fy);
+  virtual FX_BOOL OnRButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnRButtonDblClk(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+
+  virtual FX_BOOL OnKeyDown(FX_DWORD dwKeyCode, FX_DWORD dwFlags);
+  virtual FX_BOOL OnKeyUp(FX_DWORD dwKeyCode, FX_DWORD dwFlags);
+  virtual FX_BOOL OnChar(FX_DWORD dwChar, FX_DWORD dwFlags);
+  virtual FX_DWORD OnHitTest(FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnSetCursor(FX_FLOAT fx, FX_FLOAT fy);
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFSIGNATURE_H_
diff --git a/xfa/fxfa/app/xfa_ffsubform.cpp b/xfa/fxfa/app/xfa_ffsubform.cpp
new file mode 100644
index 0000000..aebbb08
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffsubform.cpp
@@ -0,0 +1,17 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffsubform.h"
+
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+
+CXFA_FFSubForm::CXFA_FFSubForm(CXFA_FFPageView* pPageView,
+                               CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFWidget(pPageView, pDataAcc) {}
+CXFA_FFSubForm::~CXFA_FFSubForm() {}
diff --git a/xfa/fxfa/app/xfa_ffsubform.h b/xfa/fxfa/app/xfa_ffsubform.h
new file mode 100644
index 0000000..e436911
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffsubform.h
@@ -0,0 +1,19 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFSUBFORM_H_
+#define XFA_FXFA_APP_XFA_FFSUBFORM_H_
+
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+
+class CXFA_FFSubForm : public CXFA_FFWidget {
+ public:
+  CXFA_FFSubForm(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFSubForm();
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFSUBFORM_H_
diff --git a/xfa/fxfa/app/xfa_fftext.cpp b/xfa/fxfa/app/xfa_fftext.cpp
new file mode 100644
index 0000000..aba8d16
--- /dev/null
+++ b/xfa/fxfa/app/xfa_fftext.cpp
@@ -0,0 +1,179 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_fftext.h"
+
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_ffdraw.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+#include "xfa/fxfa/app/xfa_textlayout.h"
+#include "xfa/include/fwl/core/fwl_widgetdef.h"
+#include "xfa/include/fxgraphics/fx_graphics.h"
+
+CXFA_FFText::CXFA_FFText(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFDraw(pPageView, pDataAcc) {}
+CXFA_FFText::~CXFA_FFText() {}
+void CXFA_FFText::RenderWidget(CFX_Graphics* pGS,
+                               CFX_Matrix* pMatrix,
+                               FX_DWORD dwStatus,
+                               int32_t iRotate) {
+  if (!IsMatchVisibleStatus(dwStatus)) {
+    return;
+  }
+  {
+    CFX_Matrix mtRotate;
+    GetRotateMatrix(mtRotate);
+    if (pMatrix) {
+      mtRotate.Concat(*pMatrix);
+    }
+    CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+    CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
+    if (pTextLayout) {
+      CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
+      CFX_RectF rtText;
+      GetRectWithoutRotate(rtText);
+      if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
+        CXFA_LayoutItem* pItem = this;
+        if (pItem->GetPrev() == NULL && pItem->GetNext() == NULL) {
+          XFA_RectWidthoutMargin(rtText, mgWidget);
+        } else {
+          FX_FLOAT fLeftInset, fRightInset, fTopInset = 0, fBottomInset = 0;
+          mgWidget.GetLeftInset(fLeftInset);
+          mgWidget.GetRightInset(fRightInset);
+          if (pItem->GetPrev() == NULL) {
+            mgWidget.GetTopInset(fTopInset);
+          } else if (pItem->GetNext() == NULL) {
+            mgWidget.GetBottomInset(fBottomInset);
+          }
+          rtText.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset);
+        }
+      }
+      CFX_Matrix mt;
+      mt.Set(1, 0, 0, 1, rtText.left, rtText.top);
+      CFX_RectF rtClip = rtText;
+      mtRotate.TransformRect(rtClip);
+      mt.Concat(mtRotate);
+      pTextLayout->DrawString(pRenderDevice, mt, rtClip, GetIndex());
+    }
+  }
+}
+FX_BOOL CXFA_FFText::IsLoaded() {
+  CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
+  return pTextLayout && !pTextLayout->m_bHasBlock;
+}
+FX_BOOL CXFA_FFText::PerformLayout() {
+  CXFA_FFDraw::PerformLayout();
+  CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
+  if (!pTextLayout) {
+    return FALSE;
+  }
+  if (!pTextLayout->m_bHasBlock) {
+    return TRUE;
+  }
+  pTextLayout->m_Blocks.RemoveAll();
+  CXFA_LayoutItem* pItem = this;
+  if (pItem->GetPrev() == NULL && pItem->GetNext() == NULL) {
+    return TRUE;
+  }
+  pItem = pItem->GetFirst();
+  while (pItem) {
+    CFX_RectF rtText;
+    pItem->GetRect(rtText);
+    if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
+      if (pItem->GetPrev() == NULL) {
+        FX_FLOAT fTopInset;
+        mgWidget.GetTopInset(fTopInset);
+        rtText.height -= fTopInset;
+      } else if (pItem->GetNext() == NULL) {
+        FX_FLOAT fBottomInset;
+        mgWidget.GetBottomInset(fBottomInset);
+        rtText.height -= fBottomInset;
+      }
+    }
+    pTextLayout->ItemBlocks(rtText, pItem->GetIndex());
+    pItem = pItem->GetNext();
+  }
+  pTextLayout->m_bHasBlock = FALSE;
+  return TRUE;
+}
+FX_BOOL CXFA_FFText::OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
+  CFX_RectF rtBox;
+  GetRectWithoutRotate(rtBox);
+  if (!rtBox.Contains(fx, fy)) {
+    return FALSE;
+  }
+  const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(fx, fy);
+  if (NULL == wsURLContent) {
+    return FALSE;
+  }
+  SetButtonDown(TRUE);
+  return TRUE;
+}
+FX_BOOL CXFA_FFText::OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
+  CFX_RectF rtBox;
+  GetRectWithoutRotate(rtBox);
+  if (!rtBox.Contains(fx, fy)) {
+    return FALSE;
+  }
+  const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(fx, fy);
+  if (NULL == wsURLContent) {
+    return FALSE;
+  }
+  return TRUE;
+}
+FX_BOOL CXFA_FFText::OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
+  if (!IsButtonDown()) {
+    return FALSE;
+  }
+  SetButtonDown(FALSE);
+  const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(fx, fy);
+  if (NULL == wsURLContent) {
+    return FALSE;
+  }
+  CXFA_FFDoc* pDoc = GetDoc();
+  pDoc->GetDocProvider()->GotoURL(pDoc, CFX_WideStringC(wsURLContent), FALSE);
+  return TRUE;
+}
+FX_DWORD CXFA_FFText::OnHitTest(FX_FLOAT fx, FX_FLOAT fy) {
+  CFX_RectF rtBox;
+  GetRectWithoutRotate(rtBox);
+  if (!rtBox.Contains(fx, fy)) {
+    return FWL_WGTHITTEST_Unknown;
+  }
+  if (!GetLinkURLAtPoint(fx, fy)) {
+    return FWL_WGTHITTEST_Unknown;
+  }
+  return FWL_WGTHITTEST_HyperLink;
+}
+const FX_WCHAR* CXFA_FFText::GetLinkURLAtPoint(FX_FLOAT fx, FX_FLOAT fy) {
+  CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
+  if (NULL == pTextLayout) {
+    return NULL;
+  }
+  FX_FLOAT x(fx), y(fy);
+  FWLToClient(x, y);
+  const CXFA_PieceLineArray* pPieceLines = pTextLayout->GetPieceLines();
+  int32_t iCount = pPieceLines->GetSize();
+  for (int32_t i = 0; i < iCount; i++) {
+    CXFA_PieceLine* pPieceLine = pPieceLines->GetAt(i);
+    int32_t iPieces = pPieceLine->m_textPieces.GetSize();
+    for (int32_t j = 0; j < iPieces; j++) {
+      XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(j);
+      if (pPiece->pLinkData && pPiece->rtPiece.Contains(x, y)) {
+        return pPiece->pLinkData->GetLinkURL();
+      }
+    }
+  }
+  return NULL;
+}
+void CXFA_FFText::FWLToClient(FX_FLOAT& fx, FX_FLOAT& fy) {
+  CFX_RectF rtWidget;
+  GetRectWithoutRotate(rtWidget);
+  fx -= rtWidget.left;
+  fy -= rtWidget.top;
+}
diff --git a/xfa/fxfa/app/xfa_fftext.h b/xfa/fxfa/app/xfa_fftext.h
new file mode 100644
index 0000000..edf12f5
--- /dev/null
+++ b/xfa/fxfa/app/xfa_fftext.h
@@ -0,0 +1,32 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFTEXT_H_
+#define XFA_FXFA_APP_XFA_FFTEXT_H_
+
+#include "xfa/fxfa/app/xfa_ffdraw.h"
+
+class CXFA_FFText : public CXFA_FFDraw {
+ public:
+  CXFA_FFText(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFText();
+  virtual FX_BOOL OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_DWORD OnHitTest(FX_FLOAT fx, FX_FLOAT fy);
+  virtual void RenderWidget(CFX_Graphics* pGS,
+                            CFX_Matrix* pMatrix = NULL,
+                            FX_DWORD dwStatus = 0,
+                            int32_t iRotate = 0);
+  virtual FX_BOOL IsLoaded();
+  virtual FX_BOOL PerformLayout();
+
+ private:
+  virtual const FX_WCHAR* GetLinkURLAtPoint(FX_FLOAT fx, FX_FLOAT fy);
+  void FWLToClient(FX_FLOAT& fx, FX_FLOAT& fy);
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFTEXT_H_
diff --git a/xfa/fxfa/app/xfa_fftextedit.cpp b/xfa/fxfa/app/xfa_fftextedit.cpp
new file mode 100644
index 0000000..c35fe58
--- /dev/null
+++ b/xfa/fxfa/app/xfa_fftextedit.cpp
@@ -0,0 +1,796 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_fftextedit.h"
+
+#include <vector>
+
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_ffdocview.h"
+#include "xfa/fxfa/app/xfa_fffield.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+#include "xfa/fxfa/app/xfa_fwladapter.h"
+#include "xfa/fxfa/app/xfa_textlayout.h"
+#include "xfa/fxfa/parser/xfa_localevalue.h"
+#include "xfa/include/fwl/basewidget/fwl_datetimepicker.h"
+#include "xfa/include/fwl/basewidget/fwl_edit.h"
+#include "xfa/include/fwl/lightwidget/datetimepicker.h"
+#include "xfa/include/fwl/lightwidget/edit.h"
+
+CXFA_FFTextEdit::CXFA_FFTextEdit(CXFA_FFPageView* pPageView,
+                                 CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFField(pPageView, pDataAcc), m_pOldDelegate(NULL) {}
+CXFA_FFTextEdit::~CXFA_FFTextEdit() {
+  if (m_pNormalWidget) {
+    IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
+    IFWL_NoteDriver* pNoteDriver = FWL_GetApp()->GetNoteDriver();
+    pNoteDriver->UnregisterEventTarget(pWidget);
+  }
+}
+FX_BOOL CXFA_FFTextEdit::LoadWidget() {
+  CFWL_Edit* pFWLEdit = CFWL_Edit::Create();
+  pFWLEdit->Initialize();
+  m_pNormalWidget = pFWLEdit;
+  IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
+  m_pNormalWidget->SetPrivateData(pWidget, this, NULL);
+  IFWL_NoteDriver* pNoteDriver = FWL_GetApp()->GetNoteDriver();
+  pNoteDriver->RegisterEventTarget(pWidget, pWidget);
+  m_pOldDelegate = m_pNormalWidget->SetDelegate(this);
+  m_pNormalWidget->LockUpdate();
+  UpdateWidgetProperty();
+  CFX_WideString wsText;
+  m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display);
+  pFWLEdit->SetText(wsText);
+  m_pNormalWidget->UnlockUpdate();
+  return CXFA_FFField::LoadWidget();
+}
+void CXFA_FFTextEdit::UpdateWidgetProperty() {
+  CFWL_Edit* pWidget = (CFWL_Edit*)m_pNormalWidget;
+  if (!pWidget) {
+    return;
+  }
+  FX_DWORD dwStyle = 0;
+  FX_DWORD dwExtendedStyle = FWL_STYLEEXT_EDT_ShowScrollbarFocus |
+                             FWL_STYLEEXT_EDT_OuterScrollbar |
+                             FWL_STYLEEXT_EDT_LastLineHeight;
+  dwExtendedStyle |= UpdateUIProperty();
+  if (m_pDataAcc->IsMultiLine()) {
+    dwExtendedStyle |= FWL_STYLEEXT_EDT_MultiLine | FWL_STYLEEXT_EDT_WantReturn;
+    if (m_pDataAcc->GetVerticalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
+      dwStyle |= FWL_WGTSTYLE_VScroll;
+      dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoVScroll;
+    }
+  } else if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
+    dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoHScroll;
+  }
+  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
+      !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+    dwExtendedStyle |= FWL_STYLEEXT_EDT_ReadOnly;
+    dwExtendedStyle |= FWL_STYLEEXT_EDT_MultiLine;
+  }
+  XFA_ELEMENT eType = XFA_ELEMENT_UNKNOWN;
+  int32_t iMaxChars = m_pDataAcc->GetMaxChars(eType);
+  if (eType == XFA_ELEMENT_ExData) {
+    iMaxChars = 0;
+  }
+  int32_t iNumCells = m_pDataAcc->GetNumberOfCells();
+  if (iNumCells == 0) {
+    dwExtendedStyle |= FWL_STYLEEXT_EDT_CombText;
+    pWidget->SetLimit(iMaxChars > 0 ? iMaxChars : 1);
+  } else if (iNumCells > 0) {
+    dwExtendedStyle |= FWL_STYLEEXT_EDT_CombText;
+    pWidget->SetLimit(iNumCells);
+  } else {
+    pWidget->SetLimit(iMaxChars);
+  }
+  dwExtendedStyle |= GetAlignment();
+  m_pNormalWidget->ModifyStyles(dwStyle, 0xFFFFFFFF);
+  m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
+}
+FX_BOOL CXFA_FFTextEdit::OnLButtonDown(FX_DWORD dwFlags,
+                                       FX_FLOAT fx,
+                                       FX_FLOAT fy) {
+  if (!PtInActiveRect(fx, fy)) {
+    return FALSE;
+  }
+  if (!IsFocused()) {
+    m_dwStatus |= XFA_WIDGETSTATUS_Focused;
+    UpdateFWLData();
+    AddInvalidateRect();
+  }
+  SetButtonDown(TRUE);
+  CFWL_MsgMouse ms;
+  ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonDown;
+  ms.m_dwFlags = dwFlags;
+  ms.m_fx = fx;
+  ms.m_fy = fy;
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  FWLToClient(ms.m_fx, ms.m_fy);
+  TranslateFWLMessage(&ms);
+  return TRUE;
+}
+FX_BOOL CXFA_FFTextEdit::OnRButtonDown(FX_DWORD dwFlags,
+                                       FX_FLOAT fx,
+                                       FX_FLOAT fy) {
+  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
+    return FALSE;
+  }
+  if (!PtInActiveRect(fx, fy)) {
+    return FALSE;
+  }
+  if (!IsFocused()) {
+    m_dwStatus |= XFA_WIDGETSTATUS_Focused;
+    UpdateFWLData();
+    AddInvalidateRect();
+  }
+  SetButtonDown(TRUE);
+  CFWL_MsgMouse ms;
+  ms.m_dwCmd = FWL_MSGMOUSECMD_RButtonDown;
+  ms.m_dwFlags = dwFlags;
+  ms.m_fx = fx;
+  ms.m_fy = fy;
+  FWLToClient(ms.m_fx, ms.m_fy);
+  TranslateFWLMessage(&ms);
+  return TRUE;
+}
+FX_BOOL CXFA_FFTextEdit::OnRButtonUp(FX_DWORD dwFlags,
+                                     FX_FLOAT fx,
+                                     FX_FLOAT fy) {
+  if (!CXFA_FFField::OnRButtonUp(dwFlags, fx, fy))
+    return FALSE;
+
+  GetDoc()->GetDocProvider()->PopupMenu(this, CFX_PointF(fx, fy), nullptr);
+  return TRUE;
+}
+FX_BOOL CXFA_FFTextEdit::OnSetFocus(CXFA_FFWidget* pOldWidget) {
+  m_dwStatus &= ~XFA_WIDGETSTATUS_TextEditValueChanged;
+  if (!IsFocused()) {
+    m_dwStatus |= XFA_WIDGETSTATUS_Focused;
+    UpdateFWLData();
+    AddInvalidateRect();
+  }
+  CXFA_FFWidget::OnSetFocus(pOldWidget);
+  CFWL_MsgSetFocus ms;
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  ms.m_pSrcTarget = NULL;
+  TranslateFWLMessage(&ms);
+  return TRUE;
+}
+FX_BOOL CXFA_FFTextEdit::OnKillFocus(CXFA_FFWidget* pNewWidget) {
+  CFWL_MsgKillFocus ms;
+  ms.m_pDstTarget = m_pNormalWidget->m_pIface;
+  ms.m_pSrcTarget = NULL;
+  TranslateFWLMessage(&ms);
+  m_dwStatus &= ~XFA_WIDGETSTATUS_Focused;
+  SetEditScrollOffset();
+  ProcessCommittedData();
+  UpdateFWLData();
+  AddInvalidateRect();
+  CXFA_FFWidget::OnKillFocus(pNewWidget);
+  m_dwStatus &= ~XFA_WIDGETSTATUS_TextEditValueChanged;
+  return TRUE;
+}
+FX_BOOL CXFA_FFTextEdit::CommitData() {
+  CFX_WideString wsText;
+  ((CFWL_Edit*)m_pNormalWidget)->GetText(wsText);
+  if (m_pDataAcc->SetValue(wsText, XFA_VALUEPICTURE_Edit)) {
+    m_pDataAcc->UpdateUIDisplay(this);
+    return TRUE;
+  }
+  ValidateNumberField(wsText);
+  return FALSE;
+}
+void CXFA_FFTextEdit::ValidateNumberField(const CFX_WideString& wsText) {
+  CXFA_WidgetAcc* pAcc = GetDataAcc();
+  if (pAcc && pAcc->GetUIType() == XFA_ELEMENT_NumericEdit) {
+    IXFA_AppProvider* pAppProvider = GetApp()->GetAppProvider();
+    if (pAppProvider) {
+      CFX_WideString wsTitle;
+      pAppProvider->LoadString(XFA_IDS_AppName, wsTitle);
+      CFX_WideString wsMessage;
+      CFX_WideString wsError;
+      pAppProvider->LoadString(XFA_IDS_ValidateNumberError, wsError);
+      CFX_WideString wsSomField;
+      pAcc->GetNode()->GetSOMExpression(wsSomField);
+      wsMessage.Format(wsError, (const FX_WCHAR*)wsText,
+                       (const FX_WCHAR*)wsSomField);
+      pAppProvider->MsgBox(wsMessage, wsTitle, XFA_MBICON_Error, XFA_MB_OK);
+    }
+  }
+}
+FX_BOOL CXFA_FFTextEdit::IsDataChanged() {
+  return (m_dwStatus & XFA_WIDGETSTATUS_TextEditValueChanged) != 0;
+}
+FX_DWORD CXFA_FFTextEdit::GetAlignment() {
+  FX_DWORD dwExtendedStyle = 0;
+  if (CXFA_Para para = m_pDataAcc->GetPara()) {
+    int32_t iHorz = para.GetHorizontalAlign();
+    switch (iHorz) {
+      case XFA_ATTRIBUTEENUM_Center:
+        dwExtendedStyle |= FWL_STYLEEXT_EDT_HCenter;
+        break;
+      case XFA_ATTRIBUTEENUM_Justify:
+        dwExtendedStyle |= FWL_STYLEEXT_EDT_Justified;
+        break;
+      case XFA_ATTRIBUTEENUM_JustifyAll:
+        break;
+      case XFA_ATTRIBUTEENUM_Radix:
+        break;
+      case XFA_ATTRIBUTEENUM_Right:
+        dwExtendedStyle |= FWL_STYLEEXT_EDT_HFar;
+        break;
+      default:
+        dwExtendedStyle |= FWL_STYLEEXT_EDT_HNear;
+        break;
+    }
+    int32_t iVert = para.GetVerticalAlign();
+    switch (iVert) {
+      case XFA_ATTRIBUTEENUM_Middle:
+        dwExtendedStyle |= FWL_STYLEEXT_EDT_VCenter;
+        break;
+      case XFA_ATTRIBUTEENUM_Bottom:
+        dwExtendedStyle |= FWL_STYLEEXT_EDT_VFar;
+        break;
+      default:
+        dwExtendedStyle |= FWL_STYLEEXT_EDT_VNear;
+        break;
+    }
+  }
+  return dwExtendedStyle;
+}
+FX_BOOL CXFA_FFTextEdit::UpdateFWLData() {
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  XFA_VALUEPICTURE eType = XFA_VALUEPICTURE_Display;
+  if (IsFocused()) {
+    eType = XFA_VALUEPICTURE_Edit;
+  }
+  FX_BOOL bUpdate = FALSE;
+  if (m_pDataAcc->GetUIType() == XFA_ELEMENT_TextEdit &&
+      m_pDataAcc->GetNumberOfCells() < 0) {
+    XFA_ELEMENT elementType = XFA_ELEMENT_UNKNOWN;
+    int32_t iMaxChars = m_pDataAcc->GetMaxChars(elementType);
+    if (elementType == XFA_ELEMENT_ExData) {
+      iMaxChars = eType == XFA_VALUEPICTURE_Edit ? iMaxChars : 0;
+    }
+    if (((CFWL_Edit*)m_pNormalWidget)->GetLimit() != iMaxChars) {
+      ((CFWL_Edit*)m_pNormalWidget)->SetLimit(iMaxChars);
+      bUpdate = TRUE;
+    }
+  }
+  if (m_pDataAcc->GetUIType() == XFA_ELEMENT_Barcode) {
+    int32_t nDataLen = 0;
+    if (eType == XFA_VALUEPICTURE_Edit)
+      m_pDataAcc->GetBarcodeAttribute_DataLength(nDataLen);
+    static_cast<CFWL_Edit*>(m_pNormalWidget)->SetLimit(nDataLen);
+    bUpdate = TRUE;
+  }
+  CFX_WideString wsText;
+  m_pDataAcc->GetValue(wsText, eType);
+  CFX_WideString wsOldText;
+  ((CFWL_Edit*)m_pNormalWidget)->GetText(wsOldText);
+  if (wsText != wsOldText || (eType == XFA_VALUEPICTURE_Edit && bUpdate)) {
+    ((CFWL_Edit*)m_pNormalWidget)->SetText(wsText);
+    bUpdate = TRUE;
+  }
+  if (bUpdate) {
+    m_pNormalWidget->Update();
+  }
+  return TRUE;
+}
+FX_BOOL CXFA_FFTextEdit::CanUndo() {
+  return ((CFWL_Edit*)m_pNormalWidget)->CanUndo();
+}
+FX_BOOL CXFA_FFTextEdit::CanRedo() {
+  return ((CFWL_Edit*)m_pNormalWidget)->CanRedo();
+}
+FX_BOOL CXFA_FFTextEdit::Undo() {
+  return ((CFWL_Edit*)m_pNormalWidget)->Undo();
+}
+FX_BOOL CXFA_FFTextEdit::Redo() {
+  return ((CFWL_Edit*)m_pNormalWidget)->Redo();
+}
+FX_BOOL CXFA_FFTextEdit::CanCopy() {
+  int32_t nCount = ((CFWL_Edit*)m_pNormalWidget)->CountSelRanges();
+  return nCount > 0;
+}
+FX_BOOL CXFA_FFTextEdit::CanCut() {
+  if (m_pNormalWidget->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly) {
+    return FALSE;
+  }
+  int32_t nCount = ((CFWL_Edit*)m_pNormalWidget)->CountSelRanges();
+  return nCount > 0;
+}
+FX_BOOL CXFA_FFTextEdit::CanPaste() {
+  return m_pDataAcc->GetAccess() == XFA_ATTRIBUTEENUM_Open;
+}
+FX_BOOL CXFA_FFTextEdit::CanSelectAll() {
+  return ((CFWL_Edit*)m_pNormalWidget)->GetTextLength() > 0;
+}
+FX_BOOL CXFA_FFTextEdit::Copy(CFX_WideString& wsCopy) {
+  return ((CFWL_Edit*)m_pNormalWidget)->Copy(wsCopy);
+}
+FX_BOOL CXFA_FFTextEdit::Cut(CFX_WideString& wsCut) {
+  return ((CFWL_Edit*)m_pNormalWidget)->Cut(wsCut);
+}
+FX_BOOL CXFA_FFTextEdit::Paste(const CFX_WideString& wsPaste) {
+  return ((CFWL_Edit*)m_pNormalWidget)->Paste(wsPaste);
+}
+FX_BOOL CXFA_FFTextEdit::SelectAll() {
+  int32_t nCount = ((CFWL_Edit*)m_pNormalWidget)->GetTextLength();
+  return ((CFWL_Edit*)m_pNormalWidget)->AddSelRange(0, nCount);
+}
+FX_BOOL CXFA_FFTextEdit::Delete() {
+  return ((CFWL_Edit*)m_pNormalWidget)->Delete();
+}
+FX_BOOL CXFA_FFTextEdit::DeSelect() {
+  return ((CFWL_Edit*)m_pNormalWidget)->ClearSelections();
+}
+FX_BOOL CXFA_FFTextEdit::GetSuggestWords(
+    CFX_PointF pointf,
+    std::vector<CFX_ByteString>& sSuggest) {
+  if (m_pDataAcc->GetUIType() != XFA_ELEMENT_TextEdit) {
+    return FALSE;
+  }
+  FWLToClient(pointf.x, pointf.y);
+  return ((CFWL_Edit*)m_pNormalWidget)->GetSuggestWords(pointf, sSuggest);
+}
+FX_BOOL CXFA_FFTextEdit::ReplaceSpellCheckWord(
+    CFX_PointF pointf,
+    const CFX_ByteStringC& bsReplace) {
+  if (m_pDataAcc->GetUIType() != XFA_ELEMENT_TextEdit) {
+    return FALSE;
+  }
+  FWLToClient(pointf.x, pointf.y);
+  return ((CFWL_Edit*)m_pNormalWidget)
+      ->ReplaceSpellCheckWord(pointf, bsReplace);
+}
+void CXFA_FFTextEdit::OnTextChanged(IFWL_Widget* pWidget,
+                                    const CFX_WideString& wsChanged,
+                                    const CFX_WideString& wsPrevText) {
+  m_dwStatus |= XFA_WIDGETSTATUS_TextEditValueChanged;
+  CXFA_EventParam eParam;
+  eParam.m_eType = XFA_EVENT_Change;
+  eParam.m_wsChange = wsChanged;
+  eParam.m_pTarget = m_pDataAcc;
+  eParam.m_wsPrevText = wsPrevText;
+  CFWL_Edit* pEdit = ((CFWL_Edit*)m_pNormalWidget);
+  if (m_pDataAcc->GetUIType() == XFA_ELEMENT_DateTimeEdit) {
+    CFWL_DateTimePicker* pDateTime = (CFWL_DateTimePicker*)pEdit;
+    pDateTime->GetEditText(eParam.m_wsNewText);
+    int32_t iSels = pDateTime->CountSelRanges();
+    if (iSels) {
+      eParam.m_iSelEnd = pDateTime->GetSelRange(0, eParam.m_iSelStart);
+    }
+  } else {
+    pEdit->GetText(eParam.m_wsNewText);
+    int32_t iSels = pEdit->CountSelRanges();
+    if (iSels) {
+      eParam.m_iSelEnd = pEdit->GetSelRange(0, eParam.m_iSelStart);
+    }
+  }
+  m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
+}
+void CXFA_FFTextEdit::OnTextFull(IFWL_Widget* pWidget) {
+  CXFA_EventParam eParam;
+  eParam.m_eType = XFA_EVENT_Full;
+  eParam.m_pTarget = m_pDataAcc;
+  m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Full, &eParam);
+}
+
+FX_BOOL CXFA_FFTextEdit::CheckWord(const CFX_ByteStringC& sWord) {
+  if (sWord.IsEmpty() || m_pDataAcc->GetUIType() != XFA_ELEMENT_TextEdit) {
+    return TRUE;
+  }
+  return GetDoc()->GetDocProvider()->CheckWord(GetDoc(), sWord);
+}
+FX_BOOL CXFA_FFTextEdit::GetSuggestWords(
+    const CFX_ByteStringC& sWord,
+    std::vector<CFX_ByteString>& sSuggest) {
+  if (m_pDataAcc->GetUIType() != XFA_ELEMENT_TextEdit) {
+    return FALSE;
+  }
+  return GetDoc()->GetDocProvider()->GetSuggestWords(GetDoc(), sWord, sSuggest);
+}
+int32_t CXFA_FFTextEdit::OnProcessMessage(CFWL_Message* pMessage) {
+  return m_pOldDelegate->OnProcessMessage(pMessage);
+}
+FWL_ERR CXFA_FFTextEdit::OnProcessEvent(CFWL_Event* pEvent) {
+  CXFA_FFField::OnProcessEvent(pEvent);
+  FX_DWORD dwEventID = pEvent->GetClassID();
+  switch (dwEventID) {
+    case FWL_EVTHASH_EDT_TextChanged: {
+      CFWL_EvtEdtTextChanged* event = (CFWL_EvtEdtTextChanged*)pEvent;
+      CFX_WideString wsChange;
+      OnTextChanged(m_pNormalWidget->GetWidget(), wsChange, event->wsPrevText);
+      break;
+    }
+    case FWL_EVTHASH_EDT_TextFull: {
+      OnTextFull(m_pNormalWidget->GetWidget());
+      break;
+    }
+    case FWL_EVTHASH_EDT_CheckWord: {
+      CFX_WideString wstr(L"FWL_EVENT_DTP_SelectChanged");
+      CFWL_EvtEdtCheckWord* event = (CFWL_EvtEdtCheckWord*)pEvent;
+      event->bCheckWord = CheckWord(event->bsWord);
+      break;
+    }
+    case FWL_EVTHASH_EDT_GetSuggestWords: {
+      CFWL_EvtEdtGetSuggestWords* event = (CFWL_EvtEdtGetSuggestWords*)pEvent;
+      event->bSuggestWords =
+          GetSuggestWords(event->bsWord, event->bsArraySuggestWords);
+      break;
+    }
+    default: {}
+  }
+  return m_pOldDelegate->OnProcessEvent(pEvent);
+}
+FWL_ERR CXFA_FFTextEdit::OnDrawWidget(CFX_Graphics* pGraphics,
+                                      const CFX_Matrix* pMatrix) {
+  return m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix);
+}
+CXFA_FFNumericEdit::CXFA_FFNumericEdit(CXFA_FFPageView* pPageView,
+                                       CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFTextEdit(pPageView, pDataAcc) {}
+CXFA_FFNumericEdit::~CXFA_FFNumericEdit() {}
+FX_BOOL CXFA_FFNumericEdit::LoadWidget() {
+  CFWL_Edit* pWidget = CFWL_Edit::Create();
+  pWidget->Initialize();
+  m_pNormalWidget = (CFWL_Widget*)pWidget;
+  IFWL_Widget* pIWidget = m_pNormalWidget->GetWidget();
+  m_pNormalWidget->SetPrivateData(pIWidget, this, NULL);
+  IFWL_NoteDriver* pNoteDriver = FWL_GetApp()->GetNoteDriver();
+  pNoteDriver->RegisterEventTarget(pIWidget, pIWidget);
+  m_pOldDelegate = m_pNormalWidget->SetDelegate(this);
+  m_pNormalWidget->LockUpdate();
+  CFX_WideString wsText;
+  m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display);
+  pWidget->SetText(wsText);
+  UpdateWidgetProperty();
+  m_pNormalWidget->UnlockUpdate();
+  return CXFA_FFField::LoadWidget();
+}
+void CXFA_FFNumericEdit::UpdateWidgetProperty() {
+  CFWL_Edit* pWidget = (CFWL_Edit*)m_pNormalWidget;
+  if (!pWidget) {
+    return;
+  }
+  FX_DWORD dwExtendedStyle =
+      FWL_STYLEEXT_EDT_ShowScrollbarFocus | FWL_STYLEEXT_EDT_OuterScrollbar |
+      FWL_STYLEEXT_EDT_Validate | FWL_STYLEEXT_EDT_Number |
+      FWL_STYLEEXT_EDT_LastLineHeight;
+  dwExtendedStyle |= UpdateUIProperty();
+  if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
+    dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoHScroll;
+  }
+  int32_t iNumCells = m_pDataAcc->GetNumberOfCells();
+  if (iNumCells > 0) {
+    dwExtendedStyle |= FWL_STYLEEXT_EDT_CombText;
+    pWidget->SetLimit(iNumCells);
+  }
+  dwExtendedStyle |= GetAlignment();
+  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
+      !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+    dwExtendedStyle |= FWL_STYLEEXT_EDT_ReadOnly;
+  }
+  m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
+}
+FWL_ERR CXFA_FFNumericEdit::OnProcessEvent(CFWL_Event* pEvent) {
+  FX_DWORD dwEventID = pEvent->GetClassID();
+  if (dwEventID == FWL_EVTHASH_EDT_Validate) {
+    CFWL_EvtEdtValidate* event = (CFWL_EvtEdtValidate*)pEvent;
+    CFX_WideString wsChange = event->wsInsert;
+    event->bValidate = OnValidate(m_pNormalWidget->GetWidget(), wsChange);
+    return event->bValidate;
+  } else {
+    return CXFA_FFTextEdit::OnProcessEvent(pEvent);
+  }
+}
+FX_BOOL CXFA_FFNumericEdit::OnValidate(IFWL_Widget* pWidget,
+                                       CFX_WideString& wsText) {
+  CFX_WideString wsPattern;
+  m_pDataAcc->GetPictureContent(wsPattern, XFA_VALUEPICTURE_Edit);
+  if (!wsPattern.IsEmpty()) {
+    return TRUE;
+  }
+  int32_t iLeads = 0;
+  m_pDataAcc->GetLeadDigits(iLeads);
+  int32_t iFracs = 0;
+  m_pDataAcc->GetFracDigits(iFracs);
+  CFX_WideString wsFormat;
+  CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(m_pDataAcc);
+  widgetValue.GetNumbericFormat(wsFormat, iLeads, iFracs);
+  return widgetValue.ValidateNumericTemp(wsText, wsFormat,
+                                         m_pDataAcc->GetLocal());
+}
+CXFA_FFPasswordEdit::CXFA_FFPasswordEdit(CXFA_FFPageView* pPageView,
+                                         CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFTextEdit(pPageView, pDataAcc) {}
+CXFA_FFPasswordEdit::~CXFA_FFPasswordEdit() {}
+FX_BOOL CXFA_FFPasswordEdit::LoadWidget() {
+  CFWL_Edit* pWidget = CFWL_Edit::Create();
+  pWidget->Initialize();
+  m_pNormalWidget = (CFWL_Widget*)pWidget;
+  IFWL_Widget* pIWidget = m_pNormalWidget->GetWidget();
+  m_pNormalWidget->SetPrivateData(pIWidget, this, NULL);
+  IFWL_NoteDriver* pNoteDriver = FWL_GetApp()->GetNoteDriver();
+  pNoteDriver->RegisterEventTarget(pIWidget, pIWidget);
+  m_pOldDelegate = m_pNormalWidget->SetDelegate(this);
+  m_pNormalWidget->LockUpdate();
+  CFX_WideString wsText;
+  m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display);
+  pWidget->SetText(wsText);
+  UpdateWidgetProperty();
+  m_pNormalWidget->UnlockUpdate();
+  return CXFA_FFField::LoadWidget();
+}
+void CXFA_FFPasswordEdit::UpdateWidgetProperty() {
+  CFWL_Edit* pWidget = (CFWL_Edit*)m_pNormalWidget;
+  if (!pWidget) {
+    return;
+  }
+  FX_DWORD dwExtendedStyle =
+      FWL_STYLEEXT_EDT_ShowScrollbarFocus | FWL_STYLEEXT_EDT_OuterScrollbar |
+      FWL_STYLEEXT_EDT_Password | FWL_STYLEEXT_EDT_LastLineHeight;
+  dwExtendedStyle |= UpdateUIProperty();
+  CFX_WideString wsPassWord;
+  m_pDataAcc->GetPasswordChar(wsPassWord);
+  if (!wsPassWord.IsEmpty()) {
+    pWidget->SetAliasChar(wsPassWord.GetAt(0));
+  }
+  if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
+    dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoHScroll;
+  }
+  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
+      !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+    dwExtendedStyle |= FWL_STYLEEXT_EDT_ReadOnly;
+  }
+  dwExtendedStyle |= GetAlignment();
+  m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
+}
+CXFA_FFDateTimeEdit::CXFA_FFDateTimeEdit(CXFA_FFPageView* pPageView,
+                                         CXFA_WidgetAcc* pDataAcc)
+    : CXFA_FFTextEdit(pPageView, pDataAcc) {}
+
+CXFA_FFDateTimeEdit::~CXFA_FFDateTimeEdit() {}
+
+FX_BOOL CXFA_FFDateTimeEdit::GetBBox(CFX_RectF& rtBox,
+                                     FX_DWORD dwStatus,
+                                     FX_BOOL bDrawFocus) {
+  if (bDrawFocus)
+    return FALSE;
+  return CXFA_FFWidget::GetBBox(rtBox, dwStatus);
+}
+
+FX_BOOL CXFA_FFDateTimeEdit::PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy) {
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  CFX_RectF rtWidget;
+  ((CFWL_DateTimePicker*)m_pNormalWidget)->GetBBox(rtWidget);
+  if (rtWidget.Contains(fx, fy)) {
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_FFDateTimeEdit::LoadWidget() {
+  CFWL_DateTimePicker* pWidget = CFWL_DateTimePicker::Create();
+  pWidget->Initialize();
+  m_pNormalWidget = (CFWL_Widget*)pWidget;
+  IFWL_Widget* pIWidget = m_pNormalWidget->GetWidget();
+  m_pNormalWidget->SetPrivateData(pIWidget, this, NULL);
+  IFWL_NoteDriver* pNoteDriver = FWL_GetApp()->GetNoteDriver();
+  pNoteDriver->RegisterEventTarget(pIWidget, pIWidget);
+  m_pOldDelegate = m_pNormalWidget->SetDelegate(this);
+  m_pNormalWidget->LockUpdate();
+  CFX_WideString wsText;
+  m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display);
+  pWidget->SetEditText(wsText);
+  if (CXFA_Value value = m_pDataAcc->GetFormValue()) {
+    switch (value.GetChildValueClassID()) {
+      case XFA_ELEMENT_Date: {
+        if (!wsText.IsEmpty()) {
+          CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pDataAcc);
+          CFX_Unitime date = lcValue.GetDate();
+          if ((FX_UNITIME)date != 0) {
+            pWidget->SetCurSel(date.GetYear(), date.GetMonth(), date.GetDay());
+          }
+        }
+      } break;
+      default:
+        break;
+    }
+  }
+  UpdateWidgetProperty();
+  m_pNormalWidget->UnlockUpdate();
+  return CXFA_FFField::LoadWidget();
+}
+void CXFA_FFDateTimeEdit::UpdateWidgetProperty() {
+  CFWL_DateTimePicker* pWidget = (CFWL_DateTimePicker*)m_pNormalWidget;
+  if (!pWidget) {
+    return;
+  }
+  FX_DWORD dwExtendedStyle = FWL_STYLEEXT_DTP_ShortDateFormat;
+  dwExtendedStyle |= UpdateUIProperty();
+  dwExtendedStyle |= GetAlignment();
+  m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
+  FX_DWORD dwEditStyles = FWL_STYLEEXT_EDT_LastLineHeight;
+  int32_t iNumCells = m_pDataAcc->GetNumberOfCells();
+  if (iNumCells > 0) {
+    dwEditStyles |= FWL_STYLEEXT_EDT_CombText;
+    pWidget->SetEditLimit(iNumCells);
+  }
+  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open ||
+      !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+    dwEditStyles |= FWL_STYLEEXT_EDT_ReadOnly;
+  }
+  if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
+    dwEditStyles |= FWL_STYLEEXT_EDT_AutoHScroll;
+  }
+  pWidget->ModifyEditStylesEx(dwEditStyles, 0xFFFFFFFF);
+}
+FX_DWORD CXFA_FFDateTimeEdit::GetAlignment() {
+  FX_DWORD dwExtendedStyle = 0;
+  if (CXFA_Para para = m_pDataAcc->GetPara()) {
+    int32_t iHorz = para.GetHorizontalAlign();
+    switch (iHorz) {
+      case XFA_ATTRIBUTEENUM_Center:
+        dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHCenter;
+        break;
+      case XFA_ATTRIBUTEENUM_Justify:
+        dwExtendedStyle |= FWL_STYLEEXT_DTP_EditJustified;
+        break;
+      case XFA_ATTRIBUTEENUM_JustifyAll:
+        break;
+      case XFA_ATTRIBUTEENUM_Radix:
+        break;
+      case XFA_ATTRIBUTEENUM_Right:
+        dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHFar;
+        break;
+      default:
+        dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHNear;
+        break;
+    }
+    int32_t iVert = para.GetVerticalAlign();
+    switch (iVert) {
+      case XFA_ATTRIBUTEENUM_Middle:
+        dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVCenter;
+        break;
+      case XFA_ATTRIBUTEENUM_Bottom:
+        dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVFar;
+        break;
+      default:
+        dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVNear;
+        break;
+    }
+  }
+  return dwExtendedStyle;
+}
+FX_BOOL CXFA_FFDateTimeEdit::CommitData() {
+  CFX_WideString wsText;
+  ((CFWL_DateTimePicker*)m_pNormalWidget)->GetEditText(wsText);
+  if (m_pDataAcc->SetValue(wsText, XFA_VALUEPICTURE_Edit)) {
+    m_pDataAcc->UpdateUIDisplay(this);
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_FFDateTimeEdit::UpdateFWLData() {
+  if (!m_pNormalWidget) {
+    return FALSE;
+  }
+  XFA_VALUEPICTURE eType = XFA_VALUEPICTURE_Display;
+  if (IsFocused()) {
+    eType = XFA_VALUEPICTURE_Edit;
+  }
+  CFX_WideString wsText;
+  m_pDataAcc->GetValue(wsText, eType);
+  ((CFWL_DateTimePicker*)m_pNormalWidget)->SetEditText(wsText);
+  if (IsFocused() && !wsText.IsEmpty()) {
+    CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pDataAcc);
+    CFX_Unitime date = lcValue.GetDate();
+    if (lcValue.IsValid()) {
+      if ((FX_UNITIME)date != 0) {
+        ((CFWL_DateTimePicker*)m_pNormalWidget)
+            ->SetCurSel(date.GetYear(), date.GetMonth(), date.GetDay());
+      }
+    }
+  }
+  m_pNormalWidget->Update();
+  return TRUE;
+}
+FX_BOOL CXFA_FFDateTimeEdit::IsDataChanged() {
+  if (m_dwStatus & XFA_WIDGETSTATUS_TextEditValueChanged) {
+    return TRUE;
+  }
+  CFX_WideString wsText;
+  ((CFWL_DateTimePicker*)m_pNormalWidget)->GetEditText(wsText);
+  CFX_WideString wsOldValue;
+  m_pDataAcc->GetValue(wsOldValue, XFA_VALUEPICTURE_Edit);
+  return wsOldValue != wsText;
+}
+FX_BOOL CXFA_FFDateTimeEdit::CanUndo() {
+  return ((CFWL_DateTimePicker*)m_pNormalWidget)->CanUndo();
+}
+FX_BOOL CXFA_FFDateTimeEdit::CanRedo() {
+  return ((CFWL_DateTimePicker*)m_pNormalWidget)->CanRedo();
+}
+FX_BOOL CXFA_FFDateTimeEdit::Undo() {
+  return ((CFWL_DateTimePicker*)m_pNormalWidget)->Undo();
+}
+FX_BOOL CXFA_FFDateTimeEdit::Redo() {
+  return ((CFWL_DateTimePicker*)m_pNormalWidget)->Redo();
+}
+FX_BOOL CXFA_FFDateTimeEdit::CanCopy() {
+  return ((CFWL_DateTimePicker*)m_pNormalWidget)->CanCopy();
+}
+FX_BOOL CXFA_FFDateTimeEdit::CanCut() {
+  if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
+    return FALSE;
+  }
+  return ((CFWL_DateTimePicker*)m_pNormalWidget)->CanCut();
+}
+FX_BOOL CXFA_FFDateTimeEdit::CanPaste() {
+  return m_pDataAcc->GetAccess() == XFA_ATTRIBUTEENUM_Open;
+}
+FX_BOOL CXFA_FFDateTimeEdit::CanSelectAll() {
+  return ((CFWL_DateTimePicker*)m_pNormalWidget)->CanSelectAll();
+}
+FX_BOOL CXFA_FFDateTimeEdit::Copy(CFX_WideString& wsCopy) {
+  return ((CFWL_DateTimePicker*)m_pNormalWidget)->Copy(wsCopy);
+}
+FX_BOOL CXFA_FFDateTimeEdit::Cut(CFX_WideString& wsCut) {
+  return ((CFWL_DateTimePicker*)m_pNormalWidget)->Cut(wsCut);
+}
+FX_BOOL CXFA_FFDateTimeEdit::Paste(const CFX_WideString& wsPaste) {
+  return ((CFWL_DateTimePicker*)m_pNormalWidget)->Paste(wsPaste);
+}
+FX_BOOL CXFA_FFDateTimeEdit::SelectAll() {
+  return ((CFWL_DateTimePicker*)m_pNormalWidget)->SelectAll();
+}
+FX_BOOL CXFA_FFDateTimeEdit::Delete() {
+  return ((CFWL_DateTimePicker*)m_pNormalWidget)->Delete();
+}
+FX_BOOL CXFA_FFDateTimeEdit::DeSelect() {
+  return ((CFWL_DateTimePicker*)m_pNormalWidget)->DeSelect();
+}
+void CXFA_FFDateTimeEdit::OnSelectChanged(IFWL_Widget* pWidget,
+                                          int32_t iYear,
+                                          int32_t iMonth,
+                                          int32_t iDay) {
+  CFX_WideString wsPicture;
+  m_pDataAcc->GetPictureContent(wsPicture, XFA_VALUEPICTURE_Edit);
+  CXFA_LocaleValue date(XFA_VT_DATE, GetDoc()->GetXFADoc()->GetLocalMgr());
+  CFX_Unitime dt;
+  dt.Set(iYear, iMonth, iDay);
+  date.SetDate(dt);
+  CFX_WideString wsDate;
+  date.FormatPatterns(wsDate, wsPicture, m_pDataAcc->GetLocal(),
+                      XFA_VALUEPICTURE_Edit);
+  CFWL_DateTimePicker* pDateTime = (CFWL_DateTimePicker*)m_pNormalWidget;
+  pDateTime->SetEditText(wsDate);
+  pDateTime->Update();
+  GetDoc()->GetDocProvider()->SetFocusWidget(GetDoc(), NULL);
+  CXFA_EventParam eParam;
+  eParam.m_eType = XFA_EVENT_Change;
+  eParam.m_pTarget = m_pDataAcc;
+  m_pDataAcc->GetValue(eParam.m_wsNewText, XFA_VALUEPICTURE_Raw);
+  m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
+}
+FWL_ERR CXFA_FFDateTimeEdit::OnProcessEvent(CFWL_Event* pEvent) {
+  FX_DWORD dwEventID = pEvent->GetClassID();
+  if (dwEventID == FWL_EVTHASH_DTP_SelectChanged) {
+    CFWL_Event_DtpSelectChanged* event = (CFWL_Event_DtpSelectChanged*)pEvent;
+    OnSelectChanged(m_pNormalWidget->GetWidget(), event->iYear, event->iMonth,
+                    event->iDay);
+    return TRUE;
+  } else {
+    return CXFA_FFTextEdit::OnProcessEvent(pEvent);
+  }
+}
diff --git a/xfa/fxfa/app/xfa_fftextedit.h b/xfa/fxfa/app/xfa_fftextedit.h
new file mode 100644
index 0000000..d379ab1
--- /dev/null
+++ b/xfa/fxfa/app/xfa_fftextedit.h
@@ -0,0 +1,138 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFTEXTEDIT_H_
+#define XFA_FXFA_APP_XFA_FFTEXTEDIT_H_
+
+#include <vector>
+
+#include "xfa/fxfa/app/xfa_fffield.h"
+
+class CXFA_FFTextEdit : public CXFA_FFField {
+ public:
+  CXFA_FFTextEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  ~CXFA_FFTextEdit() override;
+
+  // CXFA_FFField:
+  FX_BOOL LoadWidget() override;
+  void UpdateWidgetProperty() override;
+  FX_BOOL OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) override;
+  FX_BOOL OnRButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) override;
+  FX_BOOL OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) override;
+  FX_BOOL OnSetFocus(CXFA_FFWidget* pOldWidget) override;
+  FX_BOOL OnKillFocus(CXFA_FFWidget* pNewWidget) override;
+  FX_BOOL CanUndo() override;
+  FX_BOOL CanRedo() override;
+  FX_BOOL Undo() override;
+  FX_BOOL Redo() override;
+  FX_BOOL CanCopy() override;
+  FX_BOOL CanCut() override;
+  FX_BOOL CanPaste() override;
+  FX_BOOL CanSelectAll() override;
+  FX_BOOL Copy(CFX_WideString& wsCopy) override;
+  FX_BOOL Cut(CFX_WideString& wsCut) override;
+  FX_BOOL Paste(const CFX_WideString& wsPaste) override;
+  FX_BOOL SelectAll() override;
+  FX_BOOL Delete() override;
+  FX_BOOL DeSelect() override;
+  FX_BOOL GetSuggestWords(CFX_PointF pointf,
+                          std::vector<CFX_ByteString>& sSuggest) override;
+  FX_BOOL ReplaceSpellCheckWord(CFX_PointF pointf,
+                                const CFX_ByteStringC& bsReplace) override;
+
+  // IFWL_WidgetDelegate:
+  int32_t OnProcessMessage(CFWL_Message* pMessage) override;
+  FWL_ERR OnProcessEvent(CFWL_Event* pEvent) override;
+  FWL_ERR OnDrawWidget(CFX_Graphics* pGraphics,
+                       const CFX_Matrix* pMatrix = NULL) override;
+
+  void OnTextChanged(IFWL_Widget* pWidget,
+                     const CFX_WideString& wsChanged,
+                     const CFX_WideString& wsPrevText);
+  void OnTextFull(IFWL_Widget* pWidget);
+  FX_BOOL CheckWord(const CFX_ByteStringC& sWord);
+  FX_BOOL GetSuggestWords(const CFX_ByteStringC& sWord,
+                          std::vector<CFX_ByteString>& sSuggest);
+
+ protected:
+  FX_DWORD GetAlignment();
+  FX_BOOL CommitData() override;
+  FX_BOOL UpdateFWLData() override;
+  FX_BOOL IsDataChanged() override;
+  void ValidateNumberField(const CFX_WideString& wsText);
+
+  IFWL_WidgetDelegate* m_pOldDelegate;
+};
+
+class CXFA_FFNumericEdit : public CXFA_FFTextEdit {
+ public:
+  CXFA_FFNumericEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFNumericEdit();
+  virtual FX_BOOL LoadWidget();
+  virtual void UpdateWidgetProperty();
+  virtual FWL_ERR OnProcessEvent(CFWL_Event* pEvent);
+
+ public:
+  FX_BOOL OnValidate(IFWL_Widget* pWidget, CFX_WideString& wsText);
+};
+class CXFA_FFPasswordEdit : public CXFA_FFTextEdit {
+ public:
+  CXFA_FFPasswordEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFPasswordEdit();
+  virtual FX_BOOL LoadWidget();
+  virtual void UpdateWidgetProperty();
+
+ protected:
+};
+enum XFA_DATETIMETYPE {
+  XFA_DATETIMETYPE_Date = 0,
+  XFA_DATETIMETYPE_Time,
+  XFA_DATETIMETYPE_DateAndTime
+};
+class CXFA_FFDateTimeEdit : public CXFA_FFTextEdit {
+ public:
+  CXFA_FFDateTimeEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFDateTimeEdit();
+
+  virtual FX_BOOL GetBBox(CFX_RectF& rtBox,
+                          FX_DWORD dwStatus,
+                          FX_BOOL bDrawFocus = FALSE);
+  virtual FX_BOOL LoadWidget();
+  virtual void UpdateWidgetProperty();
+
+  virtual FX_BOOL CanUndo();
+  virtual FX_BOOL CanRedo();
+  virtual FX_BOOL Undo();
+  virtual FX_BOOL Redo();
+
+  virtual FX_BOOL CanCopy();
+  virtual FX_BOOL CanCut();
+  virtual FX_BOOL CanPaste();
+  virtual FX_BOOL CanSelectAll();
+  virtual FX_BOOL Copy(CFX_WideString& wsCopy);
+  virtual FX_BOOL Cut(CFX_WideString& wsCut);
+  virtual FX_BOOL Paste(const CFX_WideString& wsPaste);
+  virtual FX_BOOL SelectAll();
+  virtual FX_BOOL Delete();
+  virtual FX_BOOL DeSelect();
+
+ protected:
+  FX_DWORD GetAlignment();
+
+  virtual FX_BOOL PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL CommitData();
+  virtual FX_BOOL UpdateFWLData();
+  virtual FX_BOOL IsDataChanged();
+
+ public:
+  void OnSelectChanged(IFWL_Widget* pWidget,
+                       int32_t iYear,
+                       int32_t iMonth,
+                       int32_t iDay);
+  virtual FWL_ERR OnProcessEvent(CFWL_Event* pEvent);
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFTEXTEDIT_H_
diff --git a/xfa/fxfa/app/xfa_ffwidget.cpp b/xfa/fxfa/app/xfa_ffwidget.cpp
new file mode 100644
index 0000000..3153946
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffwidget.cpp
@@ -0,0 +1,1961 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+
+#include <algorithm>
+
+#include "core/include/fpdfapi/fpdf_page.h"
+#include "core/include/fxcodec/fx_codec.h"
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_ffdocview.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_textlayout.h"
+#include "xfa/include/fxgraphics/fx_graphics.h"
+
+CXFA_FFWidget::CXFA_FFWidget(CXFA_FFPageView* pPageView,
+                             CXFA_WidgetAcc* pDataAcc)
+    : CXFA_ContentLayoutItem(pDataAcc->GetNode()),
+      m_pPageView(pPageView),
+      m_pDataAcc(pDataAcc) {
+  m_rtWidget.Set(0, 0, 0, 0);
+}
+CXFA_FFWidget::~CXFA_FFWidget() {}
+IXFA_PageView* CXFA_FFWidget::GetPageView() {
+  return m_pPageView;
+}
+void CXFA_FFWidget::SetPageView(IXFA_PageView* pPageView) {
+  m_pPageView = static_cast<CXFA_FFPageView*>(pPageView);
+}
+void CXFA_FFWidget::GetWidgetRect(CFX_RectF& rtWidget) {
+  if ((m_dwStatus & XFA_WIDGETSTATUS_RectCached) == 0) {
+    m_dwStatus |= XFA_WIDGETSTATUS_RectCached;
+    GetRect(m_rtWidget);
+  }
+  rtWidget = m_rtWidget;
+}
+CFX_RectF CXFA_FFWidget::ReCacheWidgetRect() {
+  m_dwStatus |= XFA_WIDGETSTATUS_RectCached;
+  GetRect(m_rtWidget);
+  return m_rtWidget;
+}
+void CXFA_FFWidget::GetRectWithoutRotate(CFX_RectF& rtWidget) {
+  GetWidgetRect(rtWidget);
+  FX_FLOAT fValue = 0;
+  switch (m_pDataAcc->GetRotate()) {
+    case 90:
+      rtWidget.top = rtWidget.bottom();
+      fValue = rtWidget.width;
+      rtWidget.width = rtWidget.height;
+      rtWidget.height = fValue;
+      break;
+    case 180:
+      rtWidget.left = rtWidget.right();
+      rtWidget.top = rtWidget.bottom();
+      break;
+    case 270:
+      rtWidget.left = rtWidget.right();
+      fValue = rtWidget.width;
+      rtWidget.width = rtWidget.height;
+      rtWidget.height = fValue;
+      break;
+  }
+}
+FX_DWORD CXFA_FFWidget::GetStatus() {
+  return m_dwStatus;
+}
+
+void CXFA_FFWidget::ModifyStatus(FX_DWORD dwAdded, FX_DWORD dwRemoved) {
+  m_dwStatus = (m_dwStatus & ~dwRemoved) | dwAdded;
+}
+
+FX_BOOL CXFA_FFWidget::GetBBox(CFX_RectF& rtBox,
+                               FX_DWORD dwStatus,
+                               FX_BOOL bDrawFocus) {
+  if (bDrawFocus)
+    return FALSE;
+  if (m_pPageView)
+    m_pPageView->GetPageViewRect(rtBox);
+  return TRUE;
+}
+
+CXFA_WidgetAcc* CXFA_FFWidget::GetDataAcc() {
+  return m_pDataAcc;
+}
+FX_BOOL CXFA_FFWidget::GetToolTip(CFX_WideString& wsToolTip) {
+  if (CXFA_Assist assist = m_pDataAcc->GetAssist()) {
+    if (CXFA_ToolTip toolTip = assist.GetToolTip()) {
+      return toolTip.GetTip(wsToolTip);
+    }
+  }
+  return GetCaptionText(wsToolTip);
+}
+void CXFA_FFWidget::RenderWidget(CFX_Graphics* pGS,
+                                 CFX_Matrix* pMatrix,
+                                 FX_DWORD dwStatus,
+                                 int32_t iRotate) {
+  if (!IsMatchVisibleStatus(dwStatus)) {
+    return;
+  }
+  CXFA_Border border = m_pDataAcc->GetBorder();
+  if (border) {
+    CFX_RectF rtBorder;
+    GetRectWithoutRotate(rtBorder);
+    CXFA_Margin margin = border.GetMargin();
+    if (margin) {
+      XFA_RectWidthoutMargin(rtBorder, margin);
+    }
+    rtBorder.Normalize();
+    DrawBorder(pGS, border, rtBorder, pMatrix);
+  }
+}
+FX_BOOL CXFA_FFWidget::IsLoaded() {
+  return m_pPageView != NULL;
+}
+FX_BOOL CXFA_FFWidget::LoadWidget() {
+  PerformLayout();
+  return TRUE;
+}
+void CXFA_FFWidget::UnloadWidget() {}
+FX_BOOL CXFA_FFWidget::PerformLayout() {
+  ReCacheWidgetRect();
+  return TRUE;
+}
+FX_BOOL CXFA_FFWidget::UpdateFWLData() {
+  return FALSE;
+}
+void CXFA_FFWidget::UpdateWidgetProperty() {}
+void CXFA_FFWidget::DrawBorder(CFX_Graphics* pGS,
+                               CXFA_Box box,
+                               const CFX_RectF& rtBorder,
+                               CFX_Matrix* pMatrix,
+                               FX_DWORD dwFlags) {
+  XFA_DrawBox(box, pGS, rtBorder, pMatrix, dwFlags);
+}
+void CXFA_FFWidget::InvalidateWidget(const CFX_RectF* pRect) {
+  if (!pRect) {
+    CFX_RectF rtWidget;
+    GetBBox(rtWidget, XFA_WIDGETSTATUS_Focused);
+    rtWidget.Inflate(2, 2);
+    GetDoc()->GetDocProvider()->InvalidateRect(m_pPageView, rtWidget,
+                                               XFA_INVALIDATE_CurrentPage);
+  } else {
+    GetDoc()->GetDocProvider()->InvalidateRect(m_pPageView, *pRect,
+                                               XFA_INVALIDATE_CurrentPage);
+  }
+}
+void CXFA_FFWidget::AddInvalidateRect(const CFX_RectF* pRect) {
+  CFX_RectF rtWidget;
+  if (pRect) {
+    rtWidget = *pRect;
+  } else {
+    GetBBox(rtWidget, XFA_WIDGETSTATUS_Focused);
+    rtWidget.Inflate(2, 2);
+  }
+  m_pDocView->AddInvalidateRect(m_pPageView, rtWidget);
+}
+FX_BOOL CXFA_FFWidget::GetCaptionText(CFX_WideString& wsCap) {
+  CXFA_TextLayout* pCapTextlayout = m_pDataAcc->GetCaptionTextLayout();
+  if (!pCapTextlayout) {
+    return FALSE;
+  }
+  pCapTextlayout->GetText(wsCap);
+  return TRUE;
+}
+FX_BOOL CXFA_FFWidget::IsFocused() {
+  return m_dwStatus & XFA_WIDGETSTATUS_Focused;
+}
+FX_BOOL CXFA_FFWidget::OnMouseEnter() {
+  return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnMouseExit() {
+  return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnLButtonDown(FX_DWORD dwFlags,
+                                     FX_FLOAT fx,
+                                     FX_FLOAT fy) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnLButtonDblClk(FX_DWORD dwFlags,
+                                       FX_FLOAT fx,
+                                       FX_FLOAT fy) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnMouseWheel(FX_DWORD dwFlags,
+                                    int16_t zDelta,
+                                    FX_FLOAT fx,
+                                    FX_FLOAT fy) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnRButtonDown(FX_DWORD dwFlags,
+                                     FX_FLOAT fx,
+                                     FX_FLOAT fy) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnRButtonDblClk(FX_DWORD dwFlags,
+                                       FX_FLOAT fx,
+                                       FX_FLOAT fy) {
+  return FALSE;
+}
+
+FX_BOOL CXFA_FFWidget::OnSetFocus(CXFA_FFWidget* pOldWidget) {
+  CXFA_FFWidget* pParent = GetParent();
+  if (pParent && !pParent->IsAncestorOf(pOldWidget)) {
+    pParent->OnSetFocus(pOldWidget);
+  }
+  m_dwStatus |= XFA_WIDGETSTATUS_Focused;
+  CXFA_EventParam eParam;
+  eParam.m_eType = XFA_EVENT_Enter;
+  eParam.m_pTarget = m_pDataAcc;
+  m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Enter, &eParam);
+  return TRUE;
+}
+FX_BOOL CXFA_FFWidget::OnKillFocus(CXFA_FFWidget* pNewWidget) {
+  m_dwStatus &= ~XFA_WIDGETSTATUS_Focused;
+  EventKillFocus();
+  if (pNewWidget) {
+    CXFA_FFWidget* pParent = GetParent();
+    if (pParent && !pParent->IsAncestorOf(pNewWidget)) {
+      pParent->OnKillFocus(pNewWidget);
+    }
+  }
+  return TRUE;
+}
+FX_BOOL CXFA_FFWidget::OnKeyDown(FX_DWORD dwKeyCode, FX_DWORD dwFlags) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnKeyUp(FX_DWORD dwKeyCode, FX_DWORD dwFlags) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnChar(FX_DWORD dwChar, FX_DWORD dwFlags) {
+  return FALSE;
+}
+FX_DWORD CXFA_FFWidget::OnHitTest(FX_FLOAT fx, FX_FLOAT fy) {
+  return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnSetCursor(FX_FLOAT fx, FX_FLOAT fy) {
+  return FALSE;
+}
+void CXFA_FFWidget::Rotate2Normal(FX_FLOAT& fx, FX_FLOAT& fy) {
+  CFX_Matrix mt;
+  GetRotateMatrix(mt);
+  if (mt.IsIdentity()) {
+    return;
+  }
+  CFX_Matrix mtReverse;
+  mtReverse.SetReverse(mt);
+  mtReverse.TransformPoint(fx, fy);
+}
+static void XFA_GetMatrix(CFX_Matrix& m,
+                          int32_t iRotate,
+                          int32_t at,
+                          const CFX_RectF& rt) {
+  if (!iRotate) {
+    return;
+  }
+  FX_FLOAT fAnchorX, fAnchorY;
+  switch (at) {
+    case XFA_ATTRIBUTEENUM_TopLeft:
+      fAnchorX = rt.left, fAnchorY = rt.top;
+      break;
+    case XFA_ATTRIBUTEENUM_TopCenter:
+      fAnchorX = (rt.left + rt.right()) / 2, fAnchorY = rt.top;
+      break;
+    case XFA_ATTRIBUTEENUM_TopRight:
+      fAnchorX = rt.right(), fAnchorY = rt.top;
+      break;
+    case XFA_ATTRIBUTEENUM_MiddleLeft:
+      fAnchorX = rt.left, fAnchorY = (rt.top + rt.bottom()) / 2;
+      break;
+    case XFA_ATTRIBUTEENUM_MiddleCenter:
+      fAnchorX = (rt.left + rt.right()) / 2,
+      fAnchorY = (rt.top + rt.bottom()) / 2;
+      break;
+    case XFA_ATTRIBUTEENUM_MiddleRight:
+      fAnchorX = rt.right(), fAnchorY = (rt.top + rt.bottom()) / 2;
+      break;
+    case XFA_ATTRIBUTEENUM_BottomLeft:
+      fAnchorX = rt.left, fAnchorY = rt.bottom();
+      break;
+    case XFA_ATTRIBUTEENUM_BottomCenter:
+      fAnchorX = (rt.left + rt.right()) / 2, fAnchorY = rt.bottom();
+      break;
+    case XFA_ATTRIBUTEENUM_BottomRight:
+      fAnchorX = rt.right(), fAnchorY = rt.bottom();
+      break;
+  }
+  switch (iRotate) {
+    case 90:
+      m.a = 0, m.b = -1, m.c = 1, m.d = 0, m.e = fAnchorX - fAnchorY,
+      m.f = fAnchorX + fAnchorY;
+      break;
+    case 180:
+      m.a = -1, m.b = 0, m.c = 0, m.d = -1, m.e = fAnchorX * 2,
+      m.f = fAnchorY * 2;
+      break;
+    case 270:
+      m.a = 0, m.b = 1, m.c = -1, m.d = 0, m.e = fAnchorX + fAnchorY,
+      m.f = fAnchorY - fAnchorX;
+      break;
+  }
+}
+void CXFA_FFWidget::GetRotateMatrix(CFX_Matrix& mt) {
+  mt.Set(1, 0, 0, 1, 0, 0);
+  int32_t iRotate = m_pDataAcc->GetRotate();
+  if (!iRotate) {
+    return;
+  }
+  CFX_RectF rcWidget;
+  GetRectWithoutRotate(rcWidget);
+  XFA_ATTRIBUTEENUM at = XFA_ATTRIBUTEENUM_TopLeft;
+  XFA_GetMatrix(mt, iRotate, at, rcWidget);
+}
+FX_BOOL CXFA_FFWidget::IsLayoutRectEmpty() {
+  CFX_RectF rtLayout;
+  GetRectWithoutRotate(rtLayout);
+  return rtLayout.width < 0.1f && rtLayout.height < 0.1f;
+}
+CXFA_FFWidget* CXFA_FFWidget::GetParent() {
+  CXFA_Node* pParentNode =
+      m_pDataAcc->GetNode()->GetNodeItem(XFA_NODEITEM_Parent);
+  if (pParentNode) {
+    CXFA_WidgetAcc* pParentWidgetAcc =
+        (CXFA_WidgetAcc*)pParentNode->GetWidgetData();
+    if (pParentWidgetAcc) {
+      return pParentWidgetAcc->GetNextWidget(NULL);
+    }
+  }
+  return NULL;
+}
+FX_BOOL CXFA_FFWidget::IsAncestorOf(CXFA_FFWidget* pWidget) {
+  if (!pWidget) {
+    return FALSE;
+  }
+  CXFA_Node* pNode = m_pDataAcc->GetNode();
+  CXFA_Node* pChildNode = pWidget->GetDataAcc()->GetNode();
+  while (pChildNode) {
+    if (pChildNode == pNode) {
+      return TRUE;
+    }
+    pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_Parent);
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_FFWidget::PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy) {
+  CFX_RectF rtWidget;
+  GetWidgetRect(rtWidget);
+  if (rtWidget.Contains(fx, fy)) {
+    return TRUE;
+  }
+  return FALSE;
+}
+CXFA_FFDocView* CXFA_FFWidget::GetDocView() {
+  return m_pDocView;
+}
+CXFA_FFDoc* CXFA_FFWidget::GetDoc() {
+  return (CXFA_FFDoc*)m_pDocView->GetDoc();
+}
+CXFA_FFApp* CXFA_FFWidget::GetApp() {
+  return GetDoc()->GetApp();
+}
+IXFA_AppProvider* CXFA_FFWidget::GetAppProvider() {
+  return GetApp()->GetAppProvider();
+}
+void CXFA_FFWidget::GetMinMaxWidth(FX_FLOAT fMinWidth, FX_FLOAT fMaxWidth) {
+  fMinWidth = fMaxWidth = 0;
+  FX_FLOAT fWidth = 0;
+  if (m_pDataAcc->GetWidth(fWidth)) {
+    fMinWidth = fMaxWidth = fWidth;
+  } else {
+    m_pDataAcc->GetMinWidth(fMinWidth);
+    m_pDataAcc->GetMaxWidth(fMaxWidth);
+  }
+}
+void CXFA_FFWidget::GetMinMaxHeight(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight) {
+  fMinHeight = fMaxHeight = 0;
+  FX_FLOAT fHeight = 0;
+  if (m_pDataAcc->GetHeight(fHeight)) {
+    fMinHeight = fMaxHeight = fHeight;
+  } else {
+    m_pDataAcc->GetMinHeight(fMinHeight);
+    m_pDataAcc->GetMaxHeight(fMaxHeight);
+  }
+}
+FX_BOOL CXFA_FFWidget::IsMatchVisibleStatus(FX_DWORD dwStatus) {
+  return m_dwStatus & XFA_WIDGETSTATUS_Visible;
+}
+void CXFA_FFWidget::EventKillFocus() {
+  if (m_dwStatus & XFA_WIDGETSTATUS_Access) {
+    m_dwStatus &= ~XFA_WIDGETSTATUS_Access;
+    return;
+  }
+  CXFA_EventParam eParam;
+  eParam.m_eType = XFA_EVENT_Exit;
+  eParam.m_pTarget = m_pDataAcc;
+  m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Exit, &eParam);
+}
+FX_BOOL CXFA_FFWidget::IsButtonDown() {
+  return (m_dwStatus & XFA_WIDGETSTATUS_ButtonDown) != 0;
+}
+void CXFA_FFWidget::SetButtonDown(FX_BOOL bSet) {
+  bSet ? m_dwStatus |= XFA_WIDGETSTATUS_ButtonDown
+       : m_dwStatus &= ~XFA_WIDGETSTATUS_ButtonDown;
+}
+int32_t XFA_StrokeTypeSetLineDash(CFX_Graphics* pGraphics,
+                                  int32_t iStrokeType,
+                                  int32_t iCapType) {
+  switch (iStrokeType) {
+    case XFA_ATTRIBUTEENUM_DashDot: {
+      FX_FLOAT dashArray[] = {4, 1, 2, 1};
+      if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
+        dashArray[1] = 2;
+        dashArray[3] = 2;
+      }
+      pGraphics->SetLineDash(0, dashArray, 4);
+      return FX_DASHSTYLE_DashDot;
+    }
+    case XFA_ATTRIBUTEENUM_DashDotDot: {
+      FX_FLOAT dashArray[] = {4, 1, 2, 1, 2, 1};
+      if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
+        dashArray[1] = 2;
+        dashArray[3] = 2;
+        dashArray[5] = 2;
+      }
+      pGraphics->SetLineDash(0, dashArray, 6);
+      return FX_DASHSTYLE_DashDotDot;
+    }
+    case XFA_ATTRIBUTEENUM_Dashed: {
+      FX_FLOAT dashArray[] = {5, 1};
+      if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
+        dashArray[1] = 2;
+      }
+      pGraphics->SetLineDash(0, dashArray, 2);
+      return FX_DASHSTYLE_Dash;
+    }
+    case XFA_ATTRIBUTEENUM_Dotted: {
+      FX_FLOAT dashArray[] = {2, 1};
+      if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
+        dashArray[1] = 2;
+      }
+      pGraphics->SetLineDash(0, dashArray, 2);
+      return FX_DASHSTYLE_Dot;
+    }
+    default:
+      break;
+  }
+  pGraphics->SetLineDash(FX_DASHSTYLE_Solid);
+  return FX_DASHSTYLE_Solid;
+}
+CFX_GraphStateData::LineCap XFA_LineCapToFXGE(int32_t iLineCap) {
+  switch (iLineCap) {
+    case XFA_ATTRIBUTEENUM_Round:
+      return CFX_GraphStateData::LineCapRound;
+    case XFA_ATTRIBUTEENUM_Butt:
+      return CFX_GraphStateData::LineCapButt;
+    default:
+      break;
+  }
+  return CFX_GraphStateData::LineCapSquare;
+}
+class CXFA_ImageRenderer {
+ public:
+  CXFA_ImageRenderer();
+  ~CXFA_ImageRenderer();
+  FX_BOOL Start(CFX_RenderDevice* pDevice,
+                CFX_DIBSource* pDIBSource,
+                FX_ARGB bitmap_argb,
+                int bitmap_alpha,
+                const CFX_Matrix* pImage2Device,
+                FX_DWORD flags,
+                int blendType = FXDIB_BLEND_NORMAL);
+  FX_BOOL Continue(IFX_Pause* pPause);
+
+ protected:
+  CFX_RenderDevice* m_pDevice;
+  int m_Status;
+  CFX_Matrix m_ImageMatrix;
+  CFX_DIBSource* m_pDIBSource;
+  CFX_DIBitmap* m_pCloneConvert;
+  int m_BitmapAlpha;
+  FX_ARGB m_FillArgb;
+  FX_DWORD m_Flags;
+  CFX_ImageTransformer* m_pTransformer;
+  void* m_DeviceHandle;
+  int32_t m_BlendType;
+  FX_BOOL m_Result;
+  FX_BOOL m_bPrint;
+  FX_BOOL StartDIBSource();
+  void CompositeDIBitmap(CFX_DIBitmap* pDIBitmap,
+                         int left,
+                         int top,
+                         FX_ARGB mask_argb,
+                         int bitmap_alpha,
+                         int blend_mode,
+                         int Transparency);
+};
+CXFA_ImageRenderer::CXFA_ImageRenderer() {
+  m_pDevice = NULL;
+  m_Status = 0;
+  m_pDIBSource = NULL;
+  m_pCloneConvert = NULL;
+  m_BitmapAlpha = 255;
+  m_FillArgb = 0;
+  m_Flags = 0;
+  m_pTransformer = NULL;
+  m_DeviceHandle = NULL;
+  m_BlendType = FXDIB_BLEND_NORMAL;
+  m_Result = TRUE;
+  m_bPrint = FALSE;
+}
+CXFA_ImageRenderer::~CXFA_ImageRenderer() {
+  if (m_pCloneConvert) {
+    delete m_pCloneConvert;
+  }
+  if (m_pTransformer) {
+    delete m_pTransformer;
+  }
+  if (m_DeviceHandle) {
+    m_pDevice->CancelDIBits(m_DeviceHandle);
+  }
+}
+FX_BOOL CXFA_ImageRenderer::Start(CFX_RenderDevice* pDevice,
+                                  CFX_DIBSource* pDIBSource,
+                                  FX_ARGB bitmap_argb,
+                                  int bitmap_alpha,
+                                  const CFX_Matrix* pImage2Device,
+                                  FX_DWORD flags,
+                                  int blendType) {
+  m_pDevice = pDevice;
+  m_pDIBSource = pDIBSource;
+  m_FillArgb = bitmap_argb;
+  m_BitmapAlpha = bitmap_alpha;
+  m_ImageMatrix = *pImage2Device;
+  m_Flags = flags;
+  m_BlendType = blendType;
+  return StartDIBSource();
+}
+FX_BOOL CXFA_ImageRenderer::StartDIBSource() {
+  if (m_pDevice->StartDIBits(m_pDIBSource, m_BitmapAlpha, m_FillArgb,
+                             &m_ImageMatrix, m_Flags, m_DeviceHandle, 0, NULL,
+                             m_BlendType)) {
+    if (m_DeviceHandle) {
+      m_Status = 3;
+      return TRUE;
+    }
+    return FALSE;
+  }
+  CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect();
+  FX_RECT image_rect = image_rect_f.GetOutterRect();
+  int dest_width = image_rect.Width();
+  int dest_height = image_rect.Height();
+  if ((FXSYS_fabs(m_ImageMatrix.b) >= 0.5f || m_ImageMatrix.a == 0) ||
+      (FXSYS_fabs(m_ImageMatrix.c) >= 0.5f || m_ImageMatrix.d == 0)) {
+    if (m_bPrint && !(m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
+      m_Result = FALSE;
+      return FALSE;
+    }
+    CFX_DIBSource* pDib = m_pDIBSource;
+    if (m_pDIBSource->HasAlpha() &&
+        !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_IMAGE) &&
+        !(m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) {
+      m_pCloneConvert = m_pDIBSource->CloneConvert(FXDIB_Rgb);
+      if (!m_pCloneConvert) {
+        m_Result = FALSE;
+        return FALSE;
+      }
+      pDib = m_pCloneConvert;
+    }
+    FX_RECT clip_box = m_pDevice->GetClipBox();
+    clip_box.Intersect(image_rect);
+    m_Status = 2;
+    m_pTransformer = new CFX_ImageTransformer;
+    m_pTransformer->Start(pDib, &m_ImageMatrix, m_Flags, &clip_box);
+    return TRUE;
+  }
+  if (m_ImageMatrix.a < 0) {
+    dest_width = -dest_width;
+  }
+  if (m_ImageMatrix.d > 0) {
+    dest_height = -dest_height;
+  }
+  int dest_left, dest_top;
+  dest_left = dest_width > 0 ? image_rect.left : image_rect.right;
+  dest_top = dest_height > 0 ? image_rect.top : image_rect.bottom;
+  if (m_pDIBSource->IsOpaqueImage() && m_BitmapAlpha == 255) {
+    if (m_pDevice->StretchDIBits(m_pDIBSource, dest_left, dest_top, dest_width,
+                                 dest_height, m_Flags, NULL, m_BlendType)) {
+      return FALSE;
+    }
+  }
+  if (m_pDIBSource->IsAlphaMask()) {
+    if (m_BitmapAlpha != 255) {
+      m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha);
+    }
+    if (m_pDevice->StretchBitMask(m_pDIBSource, dest_left, dest_top, dest_width,
+                                  dest_height, m_FillArgb, m_Flags)) {
+      return FALSE;
+    }
+  }
+  if (m_bPrint && !(m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
+    m_Result = FALSE;
+    return TRUE;
+  }
+  FX_RECT clip_box = m_pDevice->GetClipBox();
+  FX_RECT dest_rect = clip_box;
+  dest_rect.Intersect(image_rect);
+  FX_RECT dest_clip(
+      dest_rect.left - image_rect.left, dest_rect.top - image_rect.top,
+      dest_rect.right - image_rect.left, dest_rect.bottom - image_rect.top);
+  CFX_DIBitmap* pStretched =
+      m_pDIBSource->StretchTo(dest_width, dest_height, m_Flags, &dest_clip);
+  if (pStretched) {
+    CompositeDIBitmap(pStretched, dest_rect.left, dest_rect.top, m_FillArgb,
+                      m_BitmapAlpha, m_BlendType, FALSE);
+    delete pStretched;
+    pStretched = NULL;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_ImageRenderer::Continue(IFX_Pause* pPause) {
+  if (m_Status == 2) {
+    if (m_pTransformer->Continue(pPause)) {
+      return TRUE;
+    }
+    CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach();
+    if (pBitmap == NULL) {
+      return FALSE;
+    }
+    if (pBitmap->IsAlphaMask()) {
+      if (m_BitmapAlpha != 255) {
+        m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha);
+      }
+      m_Result = m_pDevice->SetBitMask(pBitmap, m_pTransformer->m_ResultLeft,
+                                       m_pTransformer->m_ResultTop, m_FillArgb);
+    } else {
+      if (m_BitmapAlpha != 255) {
+        pBitmap->MultiplyAlpha(m_BitmapAlpha);
+      }
+      m_Result = m_pDevice->SetDIBits(pBitmap, m_pTransformer->m_ResultLeft,
+                                      m_pTransformer->m_ResultTop, m_BlendType);
+    }
+    delete pBitmap;
+    return FALSE;
+  } else if (m_Status == 3) {
+    return m_pDevice->ContinueDIBits(m_DeviceHandle, pPause);
+  }
+  return FALSE;
+}
+void CXFA_ImageRenderer::CompositeDIBitmap(CFX_DIBitmap* pDIBitmap,
+                                           int left,
+                                           int top,
+                                           FX_ARGB mask_argb,
+                                           int bitmap_alpha,
+                                           int blend_mode,
+                                           int Transparency) {
+  if (pDIBitmap == NULL) {
+    return;
+  }
+  FX_BOOL bIsolated = Transparency & PDFTRANS_ISOLATED;
+  FX_BOOL bGroup = Transparency & PDFTRANS_GROUP;
+  if (blend_mode == FXDIB_BLEND_NORMAL) {
+    if (!pDIBitmap->IsAlphaMask()) {
+      if (bitmap_alpha < 255) {
+        pDIBitmap->MultiplyAlpha(bitmap_alpha);
+      }
+      if (m_pDevice->SetDIBits(pDIBitmap, left, top)) {
+        return;
+      }
+    } else {
+      FX_DWORD fill_argb = (mask_argb);
+      if (bitmap_alpha < 255) {
+        ((uint8_t*)&fill_argb)[3] =
+            ((uint8_t*)&fill_argb)[3] * bitmap_alpha / 255;
+      }
+      if (m_pDevice->SetBitMask(pDIBitmap, left, top, fill_argb)) {
+        return;
+      }
+    }
+  }
+  FX_BOOL bBackAlphaRequired = blend_mode && bIsolated;
+  FX_BOOL bGetBackGround =
+      ((m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT)) ||
+      (!(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT) &&
+       (m_pDevice->GetRenderCaps() & FXRC_GET_BITS) && !bBackAlphaRequired);
+  if (bGetBackGround) {
+    if (bIsolated || !bGroup) {
+      if (pDIBitmap->IsAlphaMask()) {
+        return;
+      }
+      m_pDevice->SetDIBits(pDIBitmap, left, top, blend_mode);
+    } else {
+      FX_RECT rect(left, top, left + pDIBitmap->GetWidth(),
+                   top + pDIBitmap->GetHeight());
+      rect.Intersect(m_pDevice->GetClipBox());
+      CFX_DIBitmap* pClone = NULL;
+      FX_BOOL bClone = FALSE;
+      if (m_pDevice->GetBackDrop() && m_pDevice->GetBitmap()) {
+        bClone = TRUE;
+        pClone = m_pDevice->GetBackDrop()->Clone(&rect);
+        CFX_DIBitmap* pForeBitmap = m_pDevice->GetBitmap();
+        pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(),
+                                pForeBitmap, rect.left, rect.top);
+        left = left >= 0 ? 0 : left;
+        top = top >= 0 ? 0 : top;
+        if (!pDIBitmap->IsAlphaMask())
+          pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(),
+                                  pDIBitmap, left, top, blend_mode);
+        else
+          pClone->CompositeMask(0, 0, pClone->GetWidth(), pClone->GetHeight(),
+                                pDIBitmap, mask_argb, left, top, blend_mode);
+      } else {
+        pClone = pDIBitmap;
+      }
+      if (m_pDevice->GetBackDrop()) {
+        m_pDevice->SetDIBits(pClone, rect.left, rect.top);
+      } else {
+        if (pDIBitmap->IsAlphaMask()) {
+          return;
+        }
+        m_pDevice->SetDIBits(pDIBitmap, rect.left, rect.top, blend_mode);
+      }
+      if (bClone) {
+        delete pClone;
+      }
+    }
+    return;
+  }
+  if (pDIBitmap->HasAlpha() &&
+      !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_IMAGE)) {
+    CFX_DIBitmap* pCloneConvert = pDIBitmap->CloneConvert(FXDIB_Rgb);
+    if (!pCloneConvert) {
+      return;
+    }
+    CXFA_ImageRenderer imageRender;
+    FX_BOOL bRet = imageRender.Start(m_pDevice, pCloneConvert, m_FillArgb,
+                                     m_BitmapAlpha, &m_ImageMatrix, m_Flags);
+    while (bRet) {
+      bRet = imageRender.Continue(NULL);
+    }
+    delete pCloneConvert;
+    return;
+  }
+}
+void XFA_DrawImage(CFX_Graphics* pGS,
+                   const CFX_RectF& rtImage,
+                   CFX_Matrix* pMatrix,
+                   CFX_DIBitmap* pDIBitmap,
+                   int32_t iAspect,
+                   int32_t iImageXDpi,
+                   int32_t iImageYDpi,
+                   int32_t iHorzAlign,
+                   int32_t iVertAlign) {
+  if (rtImage.IsEmpty()) {
+    return;
+  }
+  if (!pDIBitmap || !pDIBitmap->GetBuffer()) {
+    return;
+  }
+  FX_FLOAT fWidth =
+      XFA_UnitPx2Pt((FX_FLOAT)pDIBitmap->GetWidth(), (FX_FLOAT)iImageXDpi);
+  FX_FLOAT fHeight =
+      XFA_UnitPx2Pt((FX_FLOAT)pDIBitmap->GetHeight(), (FX_FLOAT)iImageYDpi);
+  CFX_RectF rtFit;
+  rtFit.Set(rtImage.left, rtImage.top, fWidth, fHeight);
+  switch (iAspect) {
+    case XFA_ATTRIBUTEENUM_Fit: {
+      FX_FLOAT f1 = rtImage.height / rtFit.height;
+      FX_FLOAT f2 = rtImage.width / rtFit.width;
+      f1 = std::min(f1, f2);
+      rtFit.height = rtFit.height * f1;
+      rtFit.width = rtFit.width * f1;
+    } break;
+    case XFA_ATTRIBUTEENUM_Actual:
+      break;
+    case XFA_ATTRIBUTEENUM_Height: {
+      FX_FLOAT f1 = rtImage.height / rtFit.height;
+      rtFit.height = rtImage.height;
+      rtFit.width = f1 * rtFit.width;
+    } break;
+    case XFA_ATTRIBUTEENUM_None:
+      rtFit.height = rtImage.height;
+      rtFit.width = rtImage.width;
+      break;
+    case XFA_ATTRIBUTEENUM_Width: {
+      FX_FLOAT f1 = rtImage.width / rtFit.width;
+      rtFit.width = rtImage.width;
+      rtFit.height = rtFit.height * f1;
+    } break;
+  }
+  if (iHorzAlign == XFA_ATTRIBUTEENUM_Center) {
+    rtFit.left += (rtImage.width - rtFit.width) / 2;
+  } else if (iHorzAlign == XFA_ATTRIBUTEENUM_Right) {
+    rtFit.left = rtImage.right() - rtFit.width;
+  }
+  if (iVertAlign == XFA_ATTRIBUTEENUM_Middle) {
+    rtFit.top += (rtImage.height - rtFit.height) / 2;
+  } else if (iVertAlign == XFA_ATTRIBUTEENUM_Bottom) {
+    rtFit.top = rtImage.bottom() - rtImage.height;
+  }
+  CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
+  pRenderDevice->SaveState();
+  CFX_PathData path;
+  path.AppendRect(rtImage.left, rtImage.bottom(), rtImage.right(), rtImage.top);
+  pRenderDevice->SetClip_PathFill(&path, pMatrix, FXFILL_WINDING);
+  CFX_Matrix mtImage(1, 0, 0, -1, 0, 1);
+  mtImage.Concat(rtFit.width, 0, 0, rtFit.height, rtFit.left, rtFit.top);
+  mtImage.Concat(*pMatrix);
+  CXFA_ImageRenderer imageRender;
+  FX_BOOL bRet = imageRender.Start(pRenderDevice, pDIBitmap, 0, 255, &mtImage,
+                                   FXDIB_INTERPOL);
+  while (bRet) {
+    bRet = imageRender.Continue(NULL);
+  }
+  pRenderDevice->RestoreState();
+}
+
+static const uint8_t g_inv_base64[128] = {
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62,  255,
+    255, 255, 63,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  255, 255,
+    255, 255, 255, 255, 255, 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
+    10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,
+    25,  255, 255, 255, 255, 255, 255, 26,  27,  28,  29,  30,  31,  32,  33,
+    34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
+    49,  50,  51,  255, 255, 255, 255, 255,
+};
+
+static uint8_t* XFA_RemoveBase64Whitespace(const uint8_t* pStr, int32_t iLen) {
+  uint8_t* pCP;
+  int32_t i = 0, j = 0;
+  if (iLen == 0) {
+    iLen = FXSYS_strlen((FX_CHAR*)pStr);
+  }
+  pCP = FX_Alloc(uint8_t, iLen + 1);
+  for (; i < iLen; i++) {
+    if ((pStr[i] & 128) == 0) {
+      if (g_inv_base64[pStr[i]] != 0xFF || pStr[i] == '=') {
+        pCP[j++] = pStr[i];
+      }
+    }
+  }
+  pCP[j] = '\0';
+  return pCP;
+}
+static int32_t XFA_Base64Decode(const FX_CHAR* pStr, uint8_t* pOutBuffer) {
+  if (pStr == NULL) {
+    return 0;
+  }
+  uint8_t* pBuffer =
+      XFA_RemoveBase64Whitespace((uint8_t*)pStr, FXSYS_strlen((FX_CHAR*)pStr));
+  if (pBuffer == NULL) {
+    return 0;
+  }
+  int32_t iLen = FXSYS_strlen((FX_CHAR*)pBuffer);
+  int32_t i = 0, j = 0;
+  FX_DWORD dwLimb = 0;
+  for (; i + 3 < iLen; i += 4) {
+    if (pBuffer[i] == '=' || pBuffer[i + 1] == '=' || pBuffer[i + 2] == '=' ||
+        pBuffer[i + 3] == '=') {
+      if (pBuffer[i] == '=' || pBuffer[i + 1] == '=') {
+        break;
+      }
+      if (pBuffer[i + 2] == '=') {
+        dwLimb = ((FX_DWORD)g_inv_base64[pBuffer[i]] << 6) |
+                 ((FX_DWORD)g_inv_base64[pBuffer[i + 1]]);
+        pOutBuffer[j] = (uint8_t)(dwLimb >> 4) & 0xFF;
+        j++;
+      } else {
+        dwLimb = ((FX_DWORD)g_inv_base64[pBuffer[i]] << 12) |
+                 ((FX_DWORD)g_inv_base64[pBuffer[i + 1]] << 6) |
+                 ((FX_DWORD)g_inv_base64[pBuffer[i + 2]]);
+        pOutBuffer[j] = (uint8_t)(dwLimb >> 10) & 0xFF;
+        pOutBuffer[j + 1] = (uint8_t)(dwLimb >> 2) & 0xFF;
+        j += 2;
+      }
+    } else {
+      dwLimb = ((FX_DWORD)g_inv_base64[pBuffer[i]] << 18) |
+               ((FX_DWORD)g_inv_base64[pBuffer[i + 1]] << 12) |
+               ((FX_DWORD)g_inv_base64[pBuffer[i + 2]] << 6) |
+               ((FX_DWORD)g_inv_base64[pBuffer[i + 3]]);
+      pOutBuffer[j] = (uint8_t)(dwLimb >> 16) & 0xff;
+      pOutBuffer[j + 1] = (uint8_t)(dwLimb >> 8) & 0xff;
+      pOutBuffer[j + 2] = (uint8_t)(dwLimb)&0xff;
+      j += 3;
+    }
+  }
+  FX_Free(pBuffer);
+  return j;
+}
+static FX_CHAR g_base64_chars[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+FX_CHAR* XFA_Base64Encode(const uint8_t* buf, int32_t buf_len) {
+  FX_CHAR* out = NULL;
+  int i, j;
+  FX_DWORD limb;
+  out = FX_Alloc(FX_CHAR, ((buf_len * 8 + 5) / 6) + 5);
+  for (i = 0, j = 0, limb = 0; i + 2 < buf_len; i += 3, j += 4) {
+    limb = ((FX_DWORD)buf[i] << 16) | ((FX_DWORD)buf[i + 1] << 8) |
+           ((FX_DWORD)buf[i + 2]);
+    out[j] = g_base64_chars[(limb >> 18) & 63];
+    out[j + 1] = g_base64_chars[(limb >> 12) & 63];
+    out[j + 2] = g_base64_chars[(limb >> 6) & 63];
+    out[j + 3] = g_base64_chars[(limb)&63];
+  }
+  switch (buf_len - i) {
+    case 0:
+      break;
+    case 1:
+      limb = ((FX_DWORD)buf[i]);
+      out[j++] = g_base64_chars[(limb >> 2) & 63];
+      out[j++] = g_base64_chars[(limb << 4) & 63];
+      out[j++] = '=';
+      out[j++] = '=';
+      break;
+    case 2:
+      limb = ((FX_DWORD)buf[i] << 8) | ((FX_DWORD)buf[i + 1]);
+      out[j++] = g_base64_chars[(limb >> 10) & 63];
+      out[j++] = g_base64_chars[(limb >> 4) & 63];
+      out[j++] = g_base64_chars[(limb << 2) & 63];
+      out[j++] = '=';
+      break;
+    default:
+      break;
+  }
+  out[j] = '\0';
+  return out;
+}
+FXCODEC_IMAGE_TYPE XFA_GetImageType(const CFX_WideStringC& wsType) {
+  CFX_WideString wsContentType(wsType);
+  wsContentType.MakeLower();
+  if (wsContentType == FX_WSTRC(L"image/jpg")) {
+    return FXCODEC_IMAGE_JPG;
+  }
+  if (wsContentType == FX_WSTRC(L"image/png")) {
+    return FXCODEC_IMAGE_PNG;
+  }
+  if (wsContentType == FX_WSTRC(L"image/gif")) {
+    return FXCODEC_IMAGE_GIF;
+  }
+  if (wsContentType == FX_WSTRC(L"image/bmp")) {
+    return FXCODEC_IMAGE_BMP;
+  }
+  if (wsContentType == FX_WSTRC(L"image/tif")) {
+    return FXCODEC_IMAGE_TIF;
+  }
+  return FXCODEC_IMAGE_UNKNOWN;
+}
+CFX_DIBitmap* XFA_LoadImageData(CXFA_FFDoc* pDoc,
+                                CXFA_Image* pImage,
+                                FX_BOOL& bNameImage,
+                                int32_t& iImageXDpi,
+                                int32_t& iImageYDpi) {
+  CFX_WideString wsHref;
+  pImage->GetHref(wsHref);
+  CFX_WideString wsImage;
+  pImage->GetContent(wsImage);
+  if (wsHref.IsEmpty() && wsImage.IsEmpty()) {
+    return NULL;
+  }
+  CFX_WideString wsContentType;
+  pImage->GetContentType(wsContentType);
+  FXCODEC_IMAGE_TYPE type = XFA_GetImageType(wsContentType);
+  CFX_ByteString bsContent;
+  uint8_t* pImageBuffer = NULL;
+  IFX_FileRead* pImageFileRead = NULL;
+  if (wsImage.GetLength() > 0) {
+    XFA_ATTRIBUTEENUM iEncoding =
+        (XFA_ATTRIBUTEENUM)pImage->GetTransferEncoding();
+    if (iEncoding == XFA_ATTRIBUTEENUM_Base64) {
+      CFX_ByteString bsData = wsImage.UTF8Encode();
+      int32_t iLength = bsData.GetLength();
+      pImageBuffer = FX_Alloc(uint8_t, iLength);
+      int32_t iRead = XFA_Base64Decode((const FX_CHAR*)bsData, pImageBuffer);
+      if (iRead > 0) {
+        pImageFileRead = FX_CreateMemoryStream(pImageBuffer, iRead);
+      }
+    } else {
+      bsContent = CFX_ByteString::FromUnicode(wsImage);
+      pImageFileRead = FX_CreateMemoryStream(
+          (uint8_t*)(const uint8_t*)bsContent, bsContent.GetLength());
+    }
+  } else {
+    CFX_WideString wsURL = wsHref;
+    if (wsURL.Left(7) != FX_WSTRC(L"http://") &&
+        wsURL.Left(6) != FX_WSTRC(L"ftp://")) {
+      CFX_DIBitmap* pBitmap =
+          pDoc->GetPDFNamedImage(wsURL, iImageXDpi, iImageYDpi);
+      if (pBitmap) {
+        bNameImage = TRUE;
+        return pBitmap;
+      }
+    }
+    pImageFileRead = pDoc->GetDocProvider()->OpenLinkedFile(pDoc, wsURL);
+  }
+  if (!pImageFileRead) {
+    FX_Free(pImageBuffer);
+    return NULL;
+  }
+  bNameImage = FALSE;
+  CFX_DIBitmap* pBitmap =
+      XFA_LoadImageFromBuffer(pImageFileRead, type, iImageXDpi, iImageYDpi);
+  FX_Free(pImageBuffer);
+  pImageFileRead->Release();
+  return pBitmap;
+}
+static FXDIB_Format XFA_GetDIBFormat(FXCODEC_IMAGE_TYPE type,
+                                     int32_t iComponents,
+                                     int32_t iBitsPerComponent) {
+  FXDIB_Format dibFormat = FXDIB_Argb;
+  switch (type) {
+    case FXCODEC_IMAGE_BMP:
+    case FXCODEC_IMAGE_JPG:
+    case FXCODEC_IMAGE_TIF: {
+      dibFormat = FXDIB_Rgb32;
+      int32_t bpp = iComponents * iBitsPerComponent;
+      if (bpp <= 24) {
+        dibFormat = FXDIB_Rgb;
+      }
+    } break;
+    case FXCODEC_IMAGE_PNG:
+    default:
+      break;
+  }
+  return dibFormat;
+}
+CFX_DIBitmap* XFA_LoadImageFromBuffer(IFX_FileRead* pImageFileRead,
+                                      FXCODEC_IMAGE_TYPE type,
+                                      int32_t& iImageXDpi,
+                                      int32_t& iImageYDpi) {
+  CFX_GEModule* pGeModule = CFX_GEModule::Get();
+  if (!pGeModule) {
+    return NULL;
+  }
+  CCodec_ModuleMgr* pCodecMgr = pGeModule->GetCodecModule();
+  if (!pCodecMgr) {
+    return NULL;
+  }
+  CFX_DIBAttribute dibAttr;
+  CFX_DIBitmap* pBitmap = NULL;
+  ICodec_ProgressiveDecoder* pProgressiveDecoder =
+      pCodecMgr->CreateProgressiveDecoder();
+  pProgressiveDecoder->LoadImageInfo(pImageFileRead, type, &dibAttr);
+  switch (dibAttr.m_wDPIUnit) {
+    case FXCODEC_RESUNIT_CENTIMETER:
+      dibAttr.m_nXDPI = (int32_t)(dibAttr.m_nXDPI * 2.54f);
+      dibAttr.m_nYDPI = (int32_t)(dibAttr.m_nYDPI * 2.54f);
+      break;
+    case FXCODEC_RESUNIT_METER:
+      dibAttr.m_nXDPI = (int32_t)(dibAttr.m_nXDPI / (FX_FLOAT)100 * 2.54f);
+      dibAttr.m_nYDPI = (int32_t)(dibAttr.m_nYDPI / (FX_FLOAT)100 * 2.54f);
+      break;
+    default:
+      break;
+  }
+  iImageXDpi = dibAttr.m_nXDPI > 1 ? dibAttr.m_nXDPI : (96);
+  iImageYDpi = dibAttr.m_nYDPI > 1 ? dibAttr.m_nYDPI : (96);
+  if (pProgressiveDecoder->GetWidth() > 0 &&
+      pProgressiveDecoder->GetHeight() > 0) {
+    type = pProgressiveDecoder->GetType();
+    int32_t iComponents = pProgressiveDecoder->GetNumComponents();
+    int32_t iBpc = pProgressiveDecoder->GetBPC();
+    FXDIB_Format dibFormat = XFA_GetDIBFormat(type, iComponents, iBpc);
+    pBitmap = new CFX_DIBitmap();
+    pBitmap->Create(pProgressiveDecoder->GetWidth(),
+                    pProgressiveDecoder->GetHeight(), dibFormat);
+    pBitmap->Clear(0xffffffff);
+    int32_t nFrames;
+    if ((pProgressiveDecoder->GetFrames(nFrames) ==
+         FXCODEC_STATUS_DECODE_READY) &&
+        (nFrames > 0)) {
+      pProgressiveDecoder->StartDecode(pBitmap, 0, 0, pBitmap->GetWidth(),
+                                       pBitmap->GetHeight());
+      pProgressiveDecoder->ContinueDecode();
+    }
+  }
+  delete pProgressiveDecoder;
+  return pBitmap;
+}
+void XFA_RectWidthoutMargin(CFX_RectF& rt, const CXFA_Margin& mg, FX_BOOL bUI) {
+  if (!mg) {
+    return;
+  }
+  FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
+  mg.GetLeftInset(fLeftInset);
+  mg.GetTopInset(fTopInset);
+  mg.GetRightInset(fRightInset);
+  mg.GetBottomInset(fBottomInset);
+  rt.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset);
+}
+CXFA_FFWidget* XFA_GetWidgetFromLayoutItem(CXFA_LayoutItem* pLayoutItem) {
+  XFA_ELEMENT iType = pLayoutItem->GetFormNode()->GetClassID();
+  if (XFA_IsCreateWidget(iType)) {
+    return static_cast<CXFA_FFWidget*>(pLayoutItem);
+  }
+  return nullptr;
+}
+FX_BOOL XFA_IsCreateWidget(XFA_ELEMENT iType) {
+  return iType == XFA_ELEMENT_Field || iType == XFA_ELEMENT_Draw ||
+         iType == XFA_ELEMENT_Subform || iType == XFA_ELEMENT_ExclGroup;
+}
+static void XFA_BOX_GetPath_Arc(CXFA_Box box,
+                                CFX_RectF rtDraw,
+                                CFX_Path& fillPath,
+                                FX_DWORD dwFlags) {
+  FX_FLOAT a, b;
+  a = rtDraw.width / 2.0f;
+  b = rtDraw.height / 2.0f;
+  if (box.IsCircular() || (dwFlags & XFA_DRAWBOX_ForceRound) != 0) {
+    a = b = std::min(a, b);
+  }
+  CFX_PointF center = rtDraw.Center();
+  rtDraw.left = center.x - a;
+  rtDraw.top = center.y - b;
+  rtDraw.width = a + a;
+  rtDraw.height = b + b;
+  FX_FLOAT startAngle = 0, sweepAngle = 360;
+  FX_BOOL bStart = box.GetStartAngle(startAngle);
+  FX_BOOL bEnd = box.GetSweepAngle(sweepAngle);
+  if (!bStart && !bEnd) {
+    fillPath.AddEllipse(rtDraw);
+    return;
+  }
+  startAngle = -startAngle * FX_PI / 180.0f;
+  sweepAngle = -sweepAngle * FX_PI / 180.0f;
+  fillPath.AddArc(rtDraw.left, rtDraw.top, rtDraw.width, rtDraw.height,
+                  startAngle, sweepAngle);
+}
+static void XFA_BOX_GetPath(CXFA_Box box,
+                            const CXFA_StrokeArray& strokes,
+                            CFX_RectF rtWidget,
+                            CFX_Path& path,
+                            int32_t nIndex,
+                            FX_BOOL bStart,
+                            FX_BOOL bCorner) {
+  FXSYS_assert(nIndex >= 0 && nIndex < 8);
+  FX_BOOL bInverted, bRound;
+  FX_FLOAT fRadius1, fRadius2, sx, sy, vx, vy, nx, ny, offsetY, offsetX,
+      offsetEX, offsetEY;
+  CFX_PointF cpStart, cp, cp1, cp2;
+  CFX_RectF rtRadius;
+  int32_t n = (nIndex & 1) ? nIndex - 1 : nIndex;
+  CXFA_Corner corner1(strokes[n].GetNode());
+  CXFA_Corner corner2(strokes[(n + 2) % 8].GetNode());
+  fRadius1 = bCorner ? corner1.GetRadius() : 0;
+  fRadius2 = bCorner ? corner2.GetRadius() : 0;
+  bInverted = corner1.IsInverted();
+  offsetY = 0.0f;
+  offsetX = 0.0f;
+  bRound = corner1.GetJoinType() == XFA_ATTRIBUTEENUM_Round;
+  FX_FLOAT halfAfter = 0.0f;
+  FX_FLOAT halfBefore = 0.0f;
+  CXFA_Stroke stroke = strokes[nIndex];
+  if (stroke.IsCorner()) {
+    CXFA_Stroke edgeBefore = strokes[(nIndex + 1 * 8 - 1) % 8];
+    CXFA_Stroke edgeAfter = strokes[nIndex + 1];
+    if (stroke.IsInverted()) {
+      if (!stroke.SameStyles(edgeBefore)) {
+        halfBefore = edgeBefore.GetThickness() / 2;
+      }
+      if (!stroke.SameStyles(edgeAfter)) {
+        halfAfter = edgeAfter.GetThickness() / 2;
+      }
+    }
+  } else {
+    CXFA_Stroke edgeBefore = strokes[(nIndex + 8 - 2) % 8];
+    CXFA_Stroke edgeAfter = strokes[(nIndex + 2) % 8];
+    if (!bRound && !bInverted) {
+      { halfBefore = edgeBefore.GetThickness() / 2; }
+      { halfAfter = edgeAfter.GetThickness() / 2; }
+    }
+  }
+  offsetEX = 0.0f;
+  offsetEY = 0.0f;
+  if (bRound) {
+    sy = FX_PI / 2;
+  }
+  switch (nIndex) {
+    case 0:
+    case 1:
+      cp1 = rtWidget.TopLeft();
+      cp2 = rtWidget.TopRight();
+      if (nIndex == 0) {
+        cpStart.x = cp1.x - halfBefore;
+        cpStart.y = cp1.y + fRadius1, offsetY = -halfAfter;
+      } else {
+        cpStart.x = cp1.x + fRadius1 - halfBefore, cpStart.y = cp1.y,
+        offsetEX = halfAfter;
+      }
+      vx = 1, vy = 1;
+      nx = -1, ny = 0;
+      if (bRound) {
+        sx = bInverted ? FX_PI / 2 : FX_PI;
+      } else {
+        sx = 1, sy = 0;
+      }
+      break;
+    case 2:
+    case 3:
+      cp1 = rtWidget.TopRight();
+      cp2 = rtWidget.BottomRight();
+      if (nIndex == 2) {
+        cpStart.x = cp1.x - fRadius1, cpStart.y = cp1.y - halfBefore,
+        offsetX = halfAfter;
+      } else {
+        cpStart.x = cp1.x, cpStart.y = cp1.y + fRadius1 - halfBefore,
+        offsetEY = halfAfter;
+      }
+      vx = -1, vy = 1;
+      nx = 0, ny = -1;
+      if (bRound) {
+        sx = bInverted ? FX_PI : FX_PI * 3 / 2;
+      } else {
+        sx = 0, sy = 1;
+      }
+      break;
+    case 4:
+    case 5:
+      cp1 = rtWidget.BottomRight();
+      cp2 = rtWidget.BottomLeft();
+      if (nIndex == 4) {
+        cpStart.x = cp1.x + halfBefore, cpStart.y = cp1.y - fRadius1,
+        offsetY = halfAfter;
+      } else {
+        cpStart.x = cp1.x - fRadius1 + halfBefore, cpStart.y = cp1.y,
+        offsetEX = -halfAfter;
+      }
+      vx = -1, vy = -1;
+      nx = 1, ny = 0;
+      if (bRound) {
+        sx = bInverted ? FX_PI * 3 / 2 : 0;
+      } else {
+        sx = -1, sy = 0;
+      }
+      break;
+    case 6:
+    case 7:
+      cp1 = rtWidget.BottomLeft();
+      cp2 = rtWidget.TopLeft();
+      if (nIndex == 6) {
+        cpStart.x = cp1.x + fRadius1, cpStart.y = cp1.y + halfBefore,
+        offsetX = -halfAfter;
+      } else {
+        cpStart.x = cp1.x, cpStart.y = cp1.y - fRadius1 + halfBefore,
+        offsetEY = -halfAfter;
+      }
+      vx = 1, vy = -1;
+      nx = 0, ny = 1;
+      if (bRound) {
+        sx = bInverted ? 0 : FX_PI / 2;
+      } else {
+        sx = 0, sy = -1;
+      }
+      break;
+  }
+  if (bStart) {
+    path.MoveTo(cpStart.x, cpStart.y);
+  }
+  if (nIndex & 1) {
+    path.LineTo(cp2.x + fRadius2 * nx + offsetEX,
+                cp2.y + fRadius2 * ny + offsetEY);
+    return;
+  }
+  if (bRound) {
+    if (fRadius1 < 0) {
+      sx -= FX_PI;
+    }
+    if (bInverted) {
+      sy *= -1;
+    }
+    rtRadius.Set(cp1.x + offsetX * 2, cp1.y + offsetY * 2,
+                 fRadius1 * 2 * vx - offsetX * 2,
+                 fRadius1 * 2 * vy - offsetY * 2);
+    rtRadius.Normalize();
+    if (bInverted) {
+      rtRadius.Offset(-fRadius1 * vx, -fRadius1 * vy);
+    }
+    path.ArcTo(rtRadius.left, rtRadius.top, rtRadius.width, rtRadius.height, sx,
+               sy);
+  } else {
+    if (bInverted) {
+      cp.x = cp1.x + fRadius1 * vx, cp.y = cp1.y + fRadius1 * vy;
+    } else {
+      cp = cp1;
+    }
+    path.LineTo(cp.x, cp.y);
+    path.LineTo(cp1.x + fRadius1 * sx + offsetX,
+                cp1.y + fRadius1 * sy + offsetY);
+  }
+}
+static void XFA_BOX_GetFillPath(CXFA_Box box,
+                                const CXFA_StrokeArray& strokes,
+                                CFX_RectF rtWidget,
+                                CFX_Path& fillPath,
+                                FX_WORD dwFlags) {
+  if (box.IsArc() || (dwFlags & XFA_DRAWBOX_ForceRound) != 0) {
+    CXFA_Edge edge = box.GetEdge(0);
+    FX_FLOAT fThickness = edge.GetThickness();
+    if (fThickness < 0) {
+      fThickness = 0;
+    }
+    FX_FLOAT fHalf = fThickness / 2;
+    int32_t iHand = box.GetHand();
+    if (iHand == XFA_ATTRIBUTEENUM_Left) {
+      rtWidget.Inflate(fHalf, fHalf);
+    } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
+      rtWidget.Deflate(fHalf, fHalf);
+    }
+    XFA_BOX_GetPath_Arc(box, rtWidget, fillPath, dwFlags);
+    return;
+  }
+  FX_BOOL bSameStyles = TRUE;
+  int32_t i;
+  CXFA_Stroke stroke1 = strokes[0];
+  for (i = 1; i < 8; i++) {
+    CXFA_Stroke stroke2 = strokes[i];
+    if (!stroke1.SameStyles(stroke2)) {
+      bSameStyles = FALSE;
+      break;
+    }
+    stroke1 = stroke2;
+  }
+  if (bSameStyles) {
+    stroke1 = strokes[0];
+    for (i = 2; i < 8; i += 2) {
+      CXFA_Stroke stroke2 = strokes[i];
+      if (!stroke1.SameStyles(stroke2, XFA_STROKE_SAMESTYLE_NoPresence |
+                                           XFA_STROKE_SAMESTYLE_Corner)) {
+        bSameStyles = FALSE;
+        break;
+      }
+      stroke1 = stroke2;
+    }
+    if (bSameStyles) {
+      stroke1 = strokes[0];
+      if (stroke1.IsInverted()) {
+        bSameStyles = FALSE;
+      }
+      if (stroke1.GetJoinType() != XFA_ATTRIBUTEENUM_Square) {
+        bSameStyles = FALSE;
+      }
+    }
+  }
+  if (bSameStyles) {
+    fillPath.AddRectangle(rtWidget.left, rtWidget.top, rtWidget.width,
+                          rtWidget.height);
+    return;
+  }
+  FX_BOOL bInverted, bRound;
+  FX_FLOAT fRadius1, fRadius2, sx, sy, vx, vy, nx, ny;
+  CFX_PointF cp, cp1, cp2;
+  CFX_RectF rtRadius;
+  for (int32_t i = 0; i < 8; i += 2) {
+    CXFA_Corner corner1(strokes[i].GetNode());
+    CXFA_Corner corner2(strokes[(i + 2) % 8].GetNode());
+    fRadius1 = corner1.GetRadius();
+    fRadius2 = corner2.GetRadius();
+    bInverted = corner1.IsInverted();
+    bRound = corner1.GetJoinType() == XFA_ATTRIBUTEENUM_Round;
+    if (bRound) {
+      sy = FX_PI / 2;
+    }
+    switch (i) {
+      case 0:
+        cp1 = rtWidget.TopLeft();
+        cp2 = rtWidget.TopRight();
+        vx = 1, vy = 1;
+        nx = -1, ny = 0;
+        if (bRound) {
+          sx = bInverted ? FX_PI / 2 : FX_PI;
+        } else {
+          sx = 1, sy = 0;
+        }
+        break;
+      case 2:
+        cp1 = rtWidget.TopRight();
+        cp2 = rtWidget.BottomRight();
+        vx = -1, vy = 1;
+        nx = 0, ny = -1;
+        if (bRound) {
+          sx = bInverted ? FX_PI : FX_PI * 3 / 2;
+        } else {
+          sx = 0, sy = 1;
+        }
+        break;
+      case 4:
+        cp1 = rtWidget.BottomRight();
+        cp2 = rtWidget.BottomLeft();
+        vx = -1, vy = -1;
+        nx = 1, ny = 0;
+        if (bRound) {
+          sx = bInverted ? FX_PI * 3 / 2 : 0;
+        } else {
+          sx = -1, sy = 0;
+        }
+        break;
+      case 6:
+        cp1 = rtWidget.BottomLeft();
+        cp2 = rtWidget.TopLeft();
+        vx = 1, vy = -1;
+        nx = 0, ny = 1;
+        if (bRound) {
+          sx = bInverted ? 0 : FX_PI / 2;
+        } else {
+          sx = 0, sy = -1;
+        }
+        break;
+    }
+    if (i == 0) {
+      fillPath.MoveTo(cp1.x, cp1.y + fRadius1);
+    }
+    if (bRound) {
+      if (fRadius1 < 0) {
+        sx -= FX_PI;
+      }
+      if (bInverted) {
+        sy *= -1;
+      }
+      rtRadius.Set(cp1.x, cp1.y, fRadius1 * 2 * vx, fRadius1 * 2 * vy);
+      rtRadius.Normalize();
+      if (bInverted) {
+        rtRadius.Offset(-fRadius1 * vx, -fRadius1 * vy);
+      }
+      fillPath.ArcTo(rtRadius.left, rtRadius.top, rtRadius.width,
+                     rtRadius.height, sx, sy);
+    } else {
+      if (bInverted) {
+        cp.x = cp1.x + fRadius1 * vx, cp.y = cp1.y + fRadius1 * vy;
+      } else {
+        cp = cp1;
+      }
+      fillPath.LineTo(cp.x, cp.y);
+      fillPath.LineTo(cp1.x + fRadius1 * sx, cp1.y + fRadius1 * sy);
+    }
+    fillPath.LineTo(cp2.x + fRadius2 * nx, cp2.y + fRadius2 * ny);
+  }
+}
+static void XFA_BOX_Fill_Radial(CXFA_Box box,
+                                CFX_Graphics* pGS,
+                                CFX_Path& fillPath,
+                                CFX_RectF rtFill,
+                                CFX_Matrix* pMatrix) {
+  CXFA_Fill fill = box.GetFill();
+  FX_ARGB crStart, crEnd;
+  crStart = fill.GetColor();
+  int32_t iType = fill.GetRadial(crEnd);
+  CFX_Shading shading;
+  if (iType != XFA_ATTRIBUTEENUM_ToEdge) {
+    FX_ARGB temp = crEnd;
+    crEnd = crStart;
+    crStart = temp;
+  }
+  shading.CreateRadial(rtFill.Center(), rtFill.Center(), 0,
+                       FXSYS_sqrt(rtFill.Width() * rtFill.Width() +
+                                  rtFill.Height() * rtFill.Height()) /
+                           2,
+                       TRUE, TRUE, crStart, crEnd);
+  CFX_Color cr(&shading);
+  pGS->SetFillColor(&cr);
+  pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
+}
+static void XFA_BOX_Fill_Pattern(CXFA_Box box,
+                                 CFX_Graphics* pGS,
+                                 CFX_Path& fillPath,
+                                 CFX_RectF rtFill,
+                                 CFX_Matrix* pMatrix) {
+  CXFA_Fill fill = box.GetFill();
+  FX_ARGB crStart, crEnd;
+  crStart = fill.GetColor();
+  int32_t iType = fill.GetPattern(crEnd);
+  int32_t iHatch = FX_HATCHSTYLE_Cross;
+  switch (iType) {
+    case XFA_ATTRIBUTEENUM_CrossDiagonal:
+      iHatch = FX_HATCHSTYLE_DiagonalCross;
+      break;
+    case XFA_ATTRIBUTEENUM_DiagonalLeft:
+      iHatch = FX_HATCHSTYLE_ForwardDiagonal;
+      break;
+    case XFA_ATTRIBUTEENUM_DiagonalRight:
+      iHatch = FX_HATCHSTYLE_BackwardDiagonal;
+      break;
+    case XFA_ATTRIBUTEENUM_Horizontal:
+      iHatch = FX_HATCHSTYLE_Horizontal;
+      break;
+    case XFA_ATTRIBUTEENUM_Vertical:
+      iHatch = FX_HATCHSTYLE_Vertical;
+      break;
+    default:
+      break;
+  }
+  CFX_Pattern pattern;
+  pattern.Create(iHatch, crEnd, crStart);
+  CFX_Color cr(&pattern);
+  pGS->SetFillColor(&cr);
+  pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
+}
+static void XFA_BOX_Fill_Linear(CXFA_Box box,
+                                CFX_Graphics* pGS,
+                                CFX_Path& fillPath,
+                                CFX_RectF rtFill,
+                                CFX_Matrix* pMatrix) {
+  CXFA_Fill fill = box.GetFill();
+  FX_ARGB crStart = fill.GetColor();
+  FX_ARGB crEnd;
+  int32_t iType = fill.GetLinear(crEnd);
+  CFX_PointF ptStart;
+  CFX_PointF ptEnd;
+  switch (iType) {
+    case XFA_ATTRIBUTEENUM_ToRight:
+      ptStart = CFX_PointF(rtFill.left, rtFill.top);
+      ptEnd = CFX_PointF(rtFill.right(), rtFill.top);
+      break;
+    case XFA_ATTRIBUTEENUM_ToBottom:
+      ptStart = CFX_PointF(rtFill.left, rtFill.top);
+      ptEnd = CFX_PointF(rtFill.left, rtFill.bottom());
+      break;
+    case XFA_ATTRIBUTEENUM_ToLeft:
+      ptStart = CFX_PointF(rtFill.right(), rtFill.top);
+      ptEnd = CFX_PointF(rtFill.left, rtFill.top);
+      break;
+    case XFA_ATTRIBUTEENUM_ToTop:
+      ptStart = CFX_PointF(rtFill.left, rtFill.bottom());
+      ptEnd = CFX_PointF(rtFill.left, rtFill.top);
+      break;
+    default:
+      break;
+  }
+  CFX_Shading shading;
+  shading.CreateAxial(ptStart, ptEnd, FALSE, FALSE, crStart, crEnd);
+  CFX_Color cr(&shading);
+  pGS->SetFillColor(&cr);
+  pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
+}
+static void XFA_BOX_Fill(CXFA_Box box,
+                         const CXFA_StrokeArray& strokes,
+                         CFX_Graphics* pGS,
+                         const CFX_RectF& rtWidget,
+                         CFX_Matrix* pMatrix,
+                         FX_DWORD dwFlags) {
+  CXFA_Fill fill = box.GetFill();
+  if (!fill || fill.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
+    return;
+  }
+  pGS->SaveGraphState();
+  CFX_Path fillPath;
+  fillPath.Create();
+  XFA_BOX_GetFillPath(box, strokes, rtWidget, fillPath,
+                      (dwFlags & XFA_DRAWBOX_ForceRound) != 0);
+  fillPath.Close();
+  int32_t eType = fill.GetFillType();
+  switch (eType) {
+    case XFA_ELEMENT_Radial:
+      XFA_BOX_Fill_Radial(box, pGS, fillPath, rtWidget, pMatrix);
+      break;
+    case XFA_ELEMENT_Pattern:
+      XFA_BOX_Fill_Pattern(box, pGS, fillPath, rtWidget, pMatrix);
+      break;
+    case XFA_ELEMENT_Linear:
+      XFA_BOX_Fill_Linear(box, pGS, fillPath, rtWidget, pMatrix);
+      break;
+    default: {
+      FX_ARGB cr;
+      if (eType == XFA_ELEMENT_Stipple) {
+        int32_t iRate = fill.GetStipple(cr);
+        if (iRate == 0) {
+          iRate = 100;
+        }
+        int32_t a = 0;
+        FX_COLORREF rgb;
+        ArgbDecode(cr, a, rgb);
+        cr = ArgbEncode(iRate * a / 100, rgb);
+      } else {
+        cr = fill.GetColor();
+      }
+      CFX_Color fillColor(cr);
+      pGS->SetFillColor(&fillColor);
+      pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
+    } break;
+  }
+  pGS->RestoreGraphState();
+}
+static void XFA_BOX_StrokePath(CXFA_Stroke stroke,
+                               CFX_Path* pPath,
+                               CFX_Graphics* pGS,
+                               CFX_Matrix* pMatrix) {
+  if (!stroke || !stroke.IsVisible()) {
+    return;
+  }
+  FX_FLOAT fThickness = stroke.GetThickness();
+  if (fThickness < 0.001f) {
+    return;
+  }
+  pGS->SaveGraphState();
+  if (stroke.IsCorner() && fThickness > 2 * stroke.GetRadius()) {
+    fThickness = 2 * stroke.GetRadius();
+  }
+  pGS->SetLineWidth(fThickness, TRUE);
+  pGS->SetLineCap(CFX_GraphStateData::LineCapButt);
+  XFA_StrokeTypeSetLineDash(pGS, stroke.GetStrokeType(),
+                            XFA_ATTRIBUTEENUM_Butt);
+  CFX_Color fxColor(stroke.GetColor());
+  pGS->SetStrokeColor(&fxColor);
+  pGS->StrokePath(pPath, pMatrix);
+  pGS->RestoreGraphState();
+}
+static void XFA_BOX_StrokeArc(CXFA_Box box,
+                              CFX_Graphics* pGS,
+                              CFX_RectF rtWidget,
+                              CFX_Matrix* pMatrix,
+                              FX_DWORD dwFlags) {
+  CXFA_Edge edge = box.GetEdge(0);
+  if (!edge || !edge.IsVisible()) {
+    return;
+  }
+  FX_BOOL bVisible = FALSE;
+  FX_FLOAT fThickness = 0;
+  int32_t i3DType = box.Get3DStyle(bVisible, fThickness);
+  if (i3DType) {
+    if (bVisible && fThickness >= 0.001f) {
+      dwFlags |= XFA_DRAWBOX_Lowered3D;
+    }
+  }
+  FX_FLOAT fHalf = edge.GetThickness() / 2;
+  if (fHalf < 0) {
+    fHalf = 0;
+  }
+  int32_t iHand = box.GetHand();
+  if (iHand == XFA_ATTRIBUTEENUM_Left) {
+    rtWidget.Inflate(fHalf, fHalf);
+  } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
+    rtWidget.Deflate(fHalf, fHalf);
+  }
+  if ((dwFlags & XFA_DRAWBOX_ForceRound) == 0 ||
+      (dwFlags & XFA_DRAWBOX_Lowered3D) == 0) {
+    if (fHalf < 0.001f) {
+      return;
+    }
+    CFX_Path arcPath;
+    arcPath.Create();
+    XFA_BOX_GetPath_Arc(box, rtWidget, arcPath, dwFlags);
+    XFA_BOX_StrokePath(edge, &arcPath, pGS, pMatrix);
+    return;
+  }
+  pGS->SaveGraphState();
+  pGS->SetLineWidth(fHalf);
+  FX_FLOAT a, b;
+  a = rtWidget.width / 2.0f;
+  b = rtWidget.height / 2.0f;
+  if (dwFlags & XFA_DRAWBOX_ForceRound) {
+    a = b = std::min(a, b);
+  }
+  CFX_PointF center = rtWidget.Center();
+  rtWidget.left = center.x - a;
+  rtWidget.top = center.y - b;
+  rtWidget.width = a + a;
+  rtWidget.height = b + b;
+  FX_FLOAT startAngle = 0, sweepAngle = 360;
+  startAngle = startAngle * FX_PI / 180.0f;
+  sweepAngle = -sweepAngle * FX_PI / 180.0f;
+  CFX_Path arcPath;
+  arcPath.Create();
+  arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
+                 3.0f * FX_PI / 4.0f, FX_PI);
+  CFX_Color cr(0xFF808080);
+  pGS->SetStrokeColor(&cr);
+  pGS->StrokePath(&arcPath, pMatrix);
+  arcPath.Clear();
+  arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
+                 -1.0f * FX_PI / 4.0f, FX_PI);
+  cr.Set(0xFFFFFFFF);
+  pGS->SetStrokeColor(&cr);
+  pGS->StrokePath(&arcPath, pMatrix);
+  rtWidget.Deflate(fHalf, fHalf);
+  arcPath.Clear();
+  arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
+                 3.0f * FX_PI / 4.0f, FX_PI);
+  cr.Set(0xFF404040);
+  pGS->SetStrokeColor(&cr);
+  pGS->StrokePath(&arcPath, pMatrix);
+  arcPath.Clear();
+  arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
+                 -1.0f * FX_PI / 4.0f, FX_PI);
+  cr.Set(0xFFC0C0C0);
+  pGS->SetStrokeColor(&cr);
+  pGS->StrokePath(&arcPath, pMatrix);
+  pGS->RestoreGraphState();
+}
+static void XFA_Draw3DRect(CFX_Graphics* pGraphic,
+                           const CFX_RectF& rt,
+                           FX_FLOAT fLineWidth,
+                           CFX_Matrix* pMatrix,
+                           FX_ARGB argbTopLeft,
+                           FX_ARGB argbBottomRight) {
+  CFX_Color crLT(argbTopLeft);
+  pGraphic->SetFillColor(&crLT);
+  FX_FLOAT fBottom = rt.bottom();
+  FX_FLOAT fRight = rt.right();
+  CFX_Path pathLT;
+  pathLT.Create();
+  pathLT.MoveTo(rt.left, fBottom);
+  pathLT.LineTo(rt.left, rt.top);
+  pathLT.LineTo(fRight, rt.top);
+  pathLT.LineTo(fRight - fLineWidth, rt.top + fLineWidth);
+  pathLT.LineTo(rt.left + fLineWidth, rt.top + fLineWidth);
+  pathLT.LineTo(rt.left + fLineWidth, fBottom - fLineWidth);
+  pathLT.LineTo(rt.left, fBottom);
+  pGraphic->FillPath(&pathLT, FXFILL_WINDING, pMatrix);
+  CFX_Color crRB(argbBottomRight);
+  pGraphic->SetFillColor(&crRB);
+  CFX_Path pathRB;
+  pathRB.Create();
+  pathRB.MoveTo(fRight, rt.top);
+  pathRB.LineTo(fRight, fBottom);
+  pathRB.LineTo(rt.left, fBottom);
+  pathRB.LineTo(rt.left + fLineWidth, fBottom - fLineWidth);
+  pathRB.LineTo(fRight - fLineWidth, fBottom - fLineWidth);
+  pathRB.LineTo(fRight - fLineWidth, rt.top + fLineWidth);
+  pathRB.LineTo(fRight, rt.top);
+  pGraphic->FillPath(&pathRB, FXFILL_WINDING, pMatrix);
+}
+static void XFA_BOX_Stroke_3DRect_Lowered(CFX_Graphics* pGS,
+                                          CFX_RectF rt,
+                                          FX_FLOAT fThickness,
+                                          CFX_Matrix* pMatrix) {
+  FX_FLOAT fHalfWidth = fThickness / 2.0f;
+  CFX_RectF rtInner(rt);
+  rtInner.Deflate(fHalfWidth, fHalfWidth);
+  CFX_Color cr(0xFF000000);
+  pGS->SetFillColor(&cr);
+  CFX_Path path;
+  path.Create();
+  path.AddRectangle(rt.left, rt.top, rt.width, rt.height);
+  path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height);
+  pGS->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
+  XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFF808080, 0xFFC0C0C0);
+}
+static void XFA_BOX_Stroke_3DRect_Raised(CFX_Graphics* pGS,
+                                         CFX_RectF rt,
+                                         FX_FLOAT fThickness,
+                                         CFX_Matrix* pMatrix) {
+  FX_FLOAT fHalfWidth = fThickness / 2.0f;
+  CFX_RectF rtInner(rt);
+  rtInner.Deflate(fHalfWidth, fHalfWidth);
+  CFX_Color cr(0xFF000000);
+  pGS->SetFillColor(&cr);
+  CFX_Path path;
+  path.Create();
+  path.AddRectangle(rt.left, rt.top, rt.width, rt.height);
+  path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height);
+  pGS->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
+  XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFFFFFFFF, 0xFF808080);
+}
+static void XFA_BOX_Stroke_3DRect_Etched(CFX_Graphics* pGS,
+                                         CFX_RectF rt,
+                                         FX_FLOAT fThickness,
+                                         CFX_Matrix* pMatrix) {
+  FX_FLOAT fHalfWidth = fThickness / 2.0f;
+  XFA_Draw3DRect(pGS, rt, fThickness, pMatrix, 0xFF808080, 0xFFFFFFFF);
+  CFX_RectF rtInner(rt);
+  rtInner.Deflate(fHalfWidth, fHalfWidth);
+  XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFFFFFFFF, 0xFF808080);
+}
+static void XFA_BOX_Stroke_3DRect_Embossed(CFX_Graphics* pGS,
+                                           CFX_RectF rt,
+                                           FX_FLOAT fThickness,
+                                           CFX_Matrix* pMatrix) {
+  FX_FLOAT fHalfWidth = fThickness / 2.0f;
+  XFA_Draw3DRect(pGS, rt, fThickness, pMatrix, 0xFF808080, 0xFF000000);
+  CFX_RectF rtInner(rt);
+  rtInner.Deflate(fHalfWidth, fHalfWidth);
+  XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFF000000, 0xFF808080);
+}
+static void XFA_BOX_Stroke_Rect(CXFA_Box box,
+                                const CXFA_StrokeArray& strokes,
+                                CFX_Graphics* pGS,
+                                CFX_RectF rtWidget,
+                                CFX_Matrix* pMatrix) {
+  FX_BOOL bVisible = FALSE;
+  FX_FLOAT fThickness = 0;
+  int32_t i3DType = box.Get3DStyle(bVisible, fThickness);
+  if (i3DType) {
+    if (!bVisible || fThickness < 0.001f) {
+      return;
+    }
+    switch (i3DType) {
+      case XFA_ATTRIBUTEENUM_Lowered:
+        XFA_BOX_Stroke_3DRect_Lowered(pGS, rtWidget, fThickness, pMatrix);
+        break;
+      case XFA_ATTRIBUTEENUM_Raised:
+        XFA_BOX_Stroke_3DRect_Raised(pGS, rtWidget, fThickness, pMatrix);
+        break;
+      case XFA_ATTRIBUTEENUM_Etched:
+        XFA_BOX_Stroke_3DRect_Etched(pGS, rtWidget, fThickness, pMatrix);
+        break;
+      case XFA_ATTRIBUTEENUM_Embossed:
+        XFA_BOX_Stroke_3DRect_Embossed(pGS, rtWidget, fThickness, pMatrix);
+        break;
+    }
+    return;
+  }
+  FX_BOOL bClose = FALSE;
+  FX_BOOL bSameStyles = TRUE;
+  int32_t i;
+  CXFA_Stroke stroke1 = strokes[0];
+  for (i = 1; i < 8; i++) {
+    CXFA_Stroke stroke2 = strokes[i];
+    if (!stroke1.SameStyles(stroke2)) {
+      bSameStyles = FALSE;
+      break;
+    }
+    stroke1 = stroke2;
+  }
+  if (bSameStyles) {
+    stroke1 = strokes[0];
+    bClose = TRUE;
+    for (i = 2; i < 8; i += 2) {
+      CXFA_Stroke stroke2 = strokes[i];
+      if (!stroke1.SameStyles(stroke2, XFA_STROKE_SAMESTYLE_NoPresence |
+                                           XFA_STROKE_SAMESTYLE_Corner)) {
+        bSameStyles = FALSE;
+        break;
+      }
+      stroke1 = stroke2;
+    }
+    if (bSameStyles) {
+      stroke1 = strokes[0];
+      if (stroke1.IsInverted()) {
+        bSameStyles = FALSE;
+      }
+      if (stroke1.GetJoinType() != XFA_ATTRIBUTEENUM_Square) {
+        bSameStyles = FALSE;
+      }
+    }
+  }
+  FX_BOOL bStart = TRUE;
+  CFX_Path path;
+  path.Create();
+  for (i = 0; i < 8; i++) {
+    CXFA_Stroke stroke1 = strokes[i];
+    if ((i % 1) == 0 && stroke1.GetRadius() < 0) {
+      FX_BOOL bEmpty = path.IsEmpty();
+      if (!bEmpty) {
+        XFA_BOX_StrokePath(stroke1, &path, pGS, pMatrix);
+        path.Clear();
+      }
+      bStart = TRUE;
+      continue;
+    }
+    XFA_BOX_GetPath(box, strokes, rtWidget, path, i, bStart, !bSameStyles);
+    CXFA_Stroke stroke2 = strokes[(i + 1) % 8];
+    bStart = !stroke1.SameStyles(stroke2);
+    if (bStart) {
+      XFA_BOX_StrokePath(stroke1, &path, pGS, pMatrix);
+      path.Clear();
+    }
+  }
+  FX_BOOL bEmpty = path.IsEmpty();
+  if (!bEmpty) {
+    if (bClose) {
+      path.Close();
+    }
+    XFA_BOX_StrokePath(strokes[7], &path, pGS, pMatrix);
+  }
+}
+static void XFA_BOX_Stroke(CXFA_Box box,
+                           const CXFA_StrokeArray& strokes,
+                           CFX_Graphics* pGS,
+                           CFX_RectF rtWidget,
+                           CFX_Matrix* pMatrix,
+                           FX_DWORD dwFlags) {
+  if (box.IsArc() || (dwFlags & XFA_DRAWBOX_ForceRound) != 0) {
+    XFA_BOX_StrokeArc(box, pGS, rtWidget, pMatrix, dwFlags);
+    return;
+  }
+  bool bVisible = false;
+  for (int32_t j = 0; j < 4; j++) {
+    if (strokes[j * 2 + 1].IsVisible()) {
+      bVisible = true;
+      break;
+    }
+  }
+  if (!bVisible) {
+    return;
+  }
+  for (int32_t i = 1; i < 8; i += 2) {
+    CXFA_Edge edge(strokes[i].GetNode());
+    FX_FLOAT fThickness = edge.GetThickness();
+    if (fThickness < 0) {
+      fThickness = 0;
+    }
+    FX_FLOAT fHalf = fThickness / 2;
+    int32_t iHand = box.GetHand();
+    switch (i) {
+      case 1:
+        if (iHand == XFA_ATTRIBUTEENUM_Left) {
+          rtWidget.top -= fHalf;
+          rtWidget.height += fHalf;
+        } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
+          rtWidget.top += fHalf;
+          rtWidget.height -= fHalf;
+        }
+        break;
+      case 3:
+        if (iHand == XFA_ATTRIBUTEENUM_Left) {
+          rtWidget.width += fHalf;
+        } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
+          rtWidget.width -= fHalf;
+        }
+        break;
+      case 5:
+        if (iHand == XFA_ATTRIBUTEENUM_Left) {
+          rtWidget.height += fHalf;
+        } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
+          rtWidget.height -= fHalf;
+        }
+        break;
+      case 7:
+        if (iHand == XFA_ATTRIBUTEENUM_Left) {
+          rtWidget.left -= fHalf;
+          rtWidget.width += fHalf;
+        } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
+          rtWidget.left += fHalf;
+          rtWidget.width -= fHalf;
+        }
+        break;
+    }
+  }
+  XFA_BOX_Stroke_Rect(box, strokes, pGS, rtWidget, pMatrix);
+}
+void XFA_DrawBox(CXFA_Box box,
+                 CFX_Graphics* pGS,
+                 const CFX_RectF& rtWidget,
+                 CFX_Matrix* pMatrix,
+                 FX_DWORD dwFlags) {
+  if (!box || box.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
+    return;
+  }
+  int32_t iType = box.GetClassID();
+  if (iType != XFA_ELEMENT_Arc && iType != XFA_ELEMENT_Border &&
+      iType != XFA_ELEMENT_Rectangle) {
+    return;
+  }
+  CXFA_StrokeArray strokes;
+  if (!(dwFlags & XFA_DRAWBOX_ForceRound) && iType != XFA_ELEMENT_Arc) {
+    box.GetStrokes(strokes);
+  }
+  XFA_BOX_Fill(box, strokes, pGS, rtWidget, pMatrix, dwFlags);
+  XFA_BOX_Stroke(box, strokes, pGS, rtWidget, pMatrix, dwFlags);
+}
diff --git a/xfa/fxfa/app/xfa_ffwidget.h b/xfa/fxfa/app/xfa_ffwidget.h
new file mode 100644
index 0000000..3782e3b
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffwidget.h
@@ -0,0 +1,187 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFWIDGET_H_
+#define XFA_FXFA_APP_XFA_FFWIDGET_H_
+
+#include <vector>
+
+#include "core/include/fxcodec/fx_codec_def.h"
+#include "core/include/fxge/fx_ge.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/include/fxfa/fxfa.h"
+
+class CXFA_FFPageView;
+class CXFA_FFDocView;
+class CXFA_FFDoc;
+class CXFA_FFApp;
+
+inline FX_FLOAT XFA_UnitPx2Pt(FX_FLOAT fPx, FX_FLOAT fDpi) {
+  return fPx * 72.0f / fDpi;
+}
+#define XFA_FLOAT_PERCISION 0.001f
+enum XFA_WIDGETITEM {
+  XFA_WIDGETITEM_Parent,
+  XFA_WIDGETITEM_FirstChild,
+  XFA_WIDGETITEM_NextSibling,
+  XFA_WIDGETITEM_PrevSibling,
+};
+class CXFA_CalcData {
+ public:
+  CXFA_CalcData() : m_iRefCount(0) {}
+  ~CXFA_CalcData() { m_Globals.RemoveAll(); }
+  CFX_PtrArray m_Globals;
+  int32_t m_iRefCount;
+};
+class CXFA_FFWidget : public IXFA_Widget,
+                      public CFX_PrivateData,
+                      public CXFA_ContentLayoutItem {
+ public:
+  CXFA_FFWidget(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+  virtual ~CXFA_FFWidget();
+  IXFA_PageView* GetPageView();
+  void SetPageView(IXFA_PageView* pPageView);
+  void GetWidgetRect(CFX_RectF& rtWidget);
+  CFX_RectF ReCacheWidgetRect();
+  FX_DWORD GetStatus();
+  void ModifyStatus(FX_DWORD dwAdded, FX_DWORD dwRemoved);
+  virtual FX_BOOL GetBBox(CFX_RectF& rtBox,
+                          FX_DWORD dwStatus,
+                          FX_BOOL bDrawFocus = FALSE);
+  CXFA_WidgetAcc* GetDataAcc();
+  FX_BOOL GetToolTip(CFX_WideString& wsToolTip);
+  virtual void RenderWidget(CFX_Graphics* pGS,
+                            CFX_Matrix* pMatrix = NULL,
+                            FX_DWORD dwStatus = 0,
+                            int32_t iRotate = 0);
+
+  virtual FX_BOOL IsLoaded();
+  virtual FX_BOOL LoadWidget();
+  virtual void UnloadWidget();
+  virtual FX_BOOL PerformLayout();
+  virtual FX_BOOL UpdateFWLData();
+  virtual void UpdateWidgetProperty();
+  virtual FX_BOOL OnMouseEnter();
+  virtual FX_BOOL OnMouseExit();
+  virtual FX_BOOL OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnLButtonDblClk(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnMouseWheel(FX_DWORD dwFlags,
+                               int16_t zDelta,
+                               FX_FLOAT fx,
+                               FX_FLOAT fy);
+  virtual FX_BOOL OnRButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnRButtonDblClk(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+
+  virtual FX_BOOL OnSetFocus(CXFA_FFWidget* pOldWidget);
+  virtual FX_BOOL OnKillFocus(CXFA_FFWidget* pNewWidget);
+  virtual FX_BOOL OnKeyDown(FX_DWORD dwKeyCode, FX_DWORD dwFlags);
+  virtual FX_BOOL OnKeyUp(FX_DWORD dwKeyCode, FX_DWORD dwFlags);
+  virtual FX_BOOL OnChar(FX_DWORD dwChar, FX_DWORD dwFlags);
+  virtual FX_DWORD OnHitTest(FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnSetCursor(FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL CanUndo() { return FALSE; }
+  virtual FX_BOOL CanRedo() { return FALSE; }
+  virtual FX_BOOL Undo() { return FALSE; }
+  virtual FX_BOOL Redo() { return FALSE; }
+  virtual FX_BOOL CanCopy() { return FALSE; }
+  virtual FX_BOOL CanCut() { return FALSE; }
+  virtual FX_BOOL CanPaste() { return FALSE; }
+  virtual FX_BOOL CanSelectAll() { return FALSE; }
+  virtual FX_BOOL CanDelete() { return CanCut(); }
+  virtual FX_BOOL CanDeSelect() { return CanCopy(); }
+  virtual FX_BOOL Copy(CFX_WideString& wsCopy) { return FALSE; }
+  virtual FX_BOOL Cut(CFX_WideString& wsCut) { return FALSE; }
+  virtual FX_BOOL Paste(const CFX_WideString& wsPaste) { return FALSE; }
+  virtual FX_BOOL SelectAll() { return FALSE; }
+  virtual FX_BOOL Delete() { return FALSE; }
+  virtual FX_BOOL DeSelect() { return FALSE; }
+  virtual FX_BOOL GetSuggestWords(CFX_PointF pointf,
+                                  std::vector<CFX_ByteString>& sSuggest) {
+    return FALSE;
+  }
+  virtual FX_BOOL ReplaceSpellCheckWord(CFX_PointF pointf,
+                                        const CFX_ByteStringC& bsReplace) {
+    return FALSE;
+  }
+  CXFA_FFDocView* GetDocView();
+  void SetDocView(CXFA_FFDocView* pDocView) { m_pDocView = pDocView; }
+  CXFA_FFDoc* GetDoc();
+  CXFA_FFApp* GetApp();
+  IXFA_AppProvider* GetAppProvider();
+  void InvalidateWidget(const CFX_RectF* pRect = NULL);
+  void AddInvalidateRect(const CFX_RectF* pRect = NULL);
+  FX_BOOL GetCaptionText(CFX_WideString& wsCap);
+  FX_BOOL IsFocused();
+  void Rotate2Normal(FX_FLOAT& fx, FX_FLOAT& fy);
+  void GetRotateMatrix(CFX_Matrix& mt);
+  FX_BOOL IsLayoutRectEmpty();
+  CXFA_FFWidget* GetParent();
+  FX_BOOL IsAncestorOf(CXFA_FFWidget* pWidget);
+
+ protected:
+  virtual FX_BOOL PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy);
+  void DrawBorder(CFX_Graphics* pGS,
+                  CXFA_Box box,
+                  const CFX_RectF& rtBorder,
+                  CFX_Matrix* pMatrix,
+                  FX_DWORD dwFlags = 0);
+  void GetMinMaxWidth(FX_FLOAT fMinWidth, FX_FLOAT fMaxWidth);
+  void GetMinMaxHeight(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight);
+  void GetRectWithoutRotate(CFX_RectF& rtWidget);
+  FX_BOOL IsMatchVisibleStatus(FX_DWORD dwStatus);
+
+  void EventKillFocus();
+  FX_BOOL IsButtonDown();
+  void SetButtonDown(FX_BOOL bSet);
+  CXFA_FFDocView* m_pDocView;
+  CXFA_FFPageView* m_pPageView;
+  CXFA_WidgetAcc* m_pDataAcc;
+  CFX_RectF m_rtWidget;
+};
+int32_t XFA_StrokeTypeSetLineDash(CFX_Graphics* pGraphics,
+                                  int32_t iStrokeType,
+                                  int32_t iCapType);
+CFX_GraphStateData::LineCap XFA_LineCapToFXGE(int32_t iLineCap);
+void XFA_DrawImage(CFX_Graphics* pGS,
+                   const CFX_RectF& rtImage,
+                   CFX_Matrix* pMatrix,
+                   CFX_DIBitmap* pDIBitmap,
+                   int32_t iAspect,
+                   int32_t iImageXDpi,
+                   int32_t iImageYDpi,
+                   int32_t iHorzAlign = XFA_ATTRIBUTEENUM_Left,
+                   int32_t iVertAlign = XFA_ATTRIBUTEENUM_Top);
+CFX_DIBitmap* XFA_LoadImageData(CXFA_FFDoc* pDoc,
+                                CXFA_Image* pImage,
+                                FX_BOOL& bNameImage,
+                                int32_t& iImageXDpi,
+                                int32_t& iImageYDpi);
+CFX_DIBitmap* XFA_LoadImageFromBuffer(IFX_FileRead* pImageFileRead,
+                                      FXCODEC_IMAGE_TYPE type,
+                                      int32_t& iImageXDpi,
+                                      int32_t& iImageYDpi);
+FXCODEC_IMAGE_TYPE XFA_GetImageType(const CFX_WideStringC& wsType);
+FX_CHAR* XFA_Base64Encode(const uint8_t* buf, int32_t buf_len);
+void XFA_RectWidthoutMargin(CFX_RectF& rt,
+                            const CXFA_Margin& mg,
+                            FX_BOOL bUI = FALSE);
+FX_FLOAT XFA_GetEdgeThickness(const CXFA_StrokeArray& strokes,
+                              FX_BOOL b3DStyle,
+                              int32_t nIndex);
+CXFA_FFWidget* XFA_GetWidgetFromLayoutItem(CXFA_LayoutItem* pLayoutItem);
+FX_BOOL XFA_IsCreateWidget(XFA_ELEMENT iType);
+#define XFA_DRAWBOX_ForceRound 1
+#define XFA_DRAWBOX_Lowered3D 2
+void XFA_DrawBox(CXFA_Box box,
+                 CFX_Graphics* pGS,
+                 const CFX_RectF& rtWidget,
+                 CFX_Matrix* pMatrix,
+                 FX_DWORD dwFlags = 0);
+
+#endif  // XFA_FXFA_APP_XFA_FFWIDGET_H_
diff --git a/xfa/fxfa/app/xfa_ffwidgetacc.cpp b/xfa/fxfa/app/xfa_ffwidgetacc.cpp
new file mode 100644
index 0000000..500235d
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffwidgetacc.cpp
@@ -0,0 +1,1714 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffwidgetacc.h"
+
+#include <algorithm>
+
+#include "xfa/fde/tto/fde_textout.h"
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/fxfa/app/xfa_ffcheckbutton.h"
+#include "xfa/fxfa/app/xfa_ffchoicelist.h"
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_ffdocview.h"
+#include "xfa/fxfa/app/xfa_fffield.h"
+#include "xfa/fxfa/app/xfa_ffpageview.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+#include "xfa/fxfa/app/xfa_fontmgr.h"
+#include "xfa/fxfa/app/xfa_fwladapter.h"
+#include "xfa/fxfa/app/xfa_textlayout.h"
+#include "xfa/fxfa/parser/xfa_localevalue.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+
+static void XFA_FFDeleteCalcData(void* pData) {
+  if (pData) {
+    delete ((CXFA_CalcData*)pData);
+  }
+}
+static XFA_MAPDATABLOCKCALLBACKINFO gs_XFADeleteCalcData = {
+    XFA_FFDeleteCalcData, NULL};
+class CXFA_WidgetLayoutData {
+ public:
+  CXFA_WidgetLayoutData() : m_fWidgetHeight(-1) {}
+  virtual ~CXFA_WidgetLayoutData() {}
+  virtual void Release() { delete this; }
+  FX_FLOAT m_fWidgetHeight;
+};
+class CXFA_TextLayoutData : public CXFA_WidgetLayoutData {
+ public:
+  CXFA_TextLayoutData() : m_pTextLayout(NULL), m_pTextProvider(NULL) {}
+  ~CXFA_TextLayoutData() {
+    if (m_pTextLayout) {
+      delete m_pTextLayout;
+    }
+    m_pTextLayout = NULL;
+    if (m_pTextProvider) {
+      delete m_pTextProvider;
+    }
+    m_pTextProvider = NULL;
+  }
+  void LoadText(CXFA_WidgetAcc* pAcc) {
+    if (m_pTextLayout)
+      return;
+
+    m_pTextProvider = new CXFA_TextProvider(pAcc, XFA_TEXTPROVIDERTYPE_Text);
+    m_pTextLayout = new CXFA_TextLayout(m_pTextProvider);
+  }
+  CXFA_TextLayout* m_pTextLayout;
+  CXFA_TextProvider* m_pTextProvider;
+};
+class CXFA_ImageLayoutData : public CXFA_WidgetLayoutData {
+ public:
+  CXFA_ImageLayoutData()
+      : m_pDIBitmap(NULL),
+        m_bNamedImage(FALSE),
+        m_iImageXDpi(0),
+        m_iImageYDpi(0) {}
+
+  ~CXFA_ImageLayoutData() {
+    if (m_pDIBitmap && !m_bNamedImage) {
+      delete m_pDIBitmap;
+    }
+    m_pDIBitmap = NULL;
+  }
+
+  FX_BOOL LoadImageData(CXFA_WidgetAcc* pAcc) {
+    if (m_pDIBitmap) {
+      return TRUE;
+    }
+    CXFA_Value value = pAcc->GetFormValue();
+    if (!value) {
+      return FALSE;
+    }
+    CXFA_Image imageObj = value.GetImage();
+    if (!imageObj) {
+      return FALSE;
+    }
+    CXFA_FFDoc* pFFDoc = pAcc->GetDoc();
+    pAcc->SetImageImage(XFA_LoadImageData(pFFDoc, &imageObj, m_bNamedImage,
+                                          m_iImageXDpi, m_iImageYDpi));
+    return m_pDIBitmap != NULL;
+  }
+
+  CFX_DIBitmap* m_pDIBitmap;
+  FX_BOOL m_bNamedImage;
+  int32_t m_iImageXDpi;
+  int32_t m_iImageYDpi;
+};
+class CXFA_FieldLayoutData : public CXFA_WidgetLayoutData {
+ public:
+  CXFA_FieldLayoutData()
+      : m_pCapTextLayout(NULL),
+        m_pCapTextProvider(NULL),
+        m_pTextOut(NULL),
+        m_pFieldSplitArray(NULL) {}
+  ~CXFA_FieldLayoutData() {
+    if (m_pCapTextLayout) {
+      delete m_pCapTextLayout;
+    }
+    m_pCapTextLayout = NULL;
+    if (m_pCapTextProvider) {
+      delete m_pCapTextProvider;
+    }
+    m_pCapTextProvider = NULL;
+    if (m_pTextOut) {
+      m_pTextOut->Release();
+    }
+    m_pTextOut = NULL;
+    if (m_pFieldSplitArray) {
+      m_pFieldSplitArray->RemoveAll();
+      delete m_pFieldSplitArray;
+      m_pFieldSplitArray = NULL;
+    }
+  }
+  FX_BOOL LoadCaption(CXFA_WidgetAcc* pAcc) {
+    if (m_pCapTextLayout) {
+      return TRUE;
+    }
+    CXFA_Caption caption = pAcc->GetCaption();
+    if (caption && caption.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) {
+      m_pCapTextProvider =
+          new CXFA_TextProvider(pAcc, XFA_TEXTPROVIDERTYPE_Caption);
+      m_pCapTextLayout = new CXFA_TextLayout(m_pCapTextProvider);
+      return TRUE;
+    }
+    return FALSE;
+  }
+  CXFA_TextLayout* m_pCapTextLayout;
+  CXFA_TextProvider* m_pCapTextProvider;
+  IFDE_TextOut* m_pTextOut;
+  CFX_FloatArray* m_pFieldSplitArray;
+};
+class CXFA_TextEditData : public CXFA_FieldLayoutData {
+ public:
+};
+class CXFA_ImageEditData : public CXFA_FieldLayoutData {
+ public:
+  CXFA_ImageEditData()
+      : m_pDIBitmap(NULL),
+        m_bNamedImage(FALSE),
+        m_iImageXDpi(0),
+        m_iImageYDpi(0) {}
+
+  ~CXFA_ImageEditData() {
+    if (m_pDIBitmap && !m_bNamedImage) {
+      delete m_pDIBitmap;
+    }
+    m_pDIBitmap = NULL;
+  }
+  FX_BOOL LoadImageData(CXFA_WidgetAcc* pAcc) {
+    if (m_pDIBitmap) {
+      return TRUE;
+    }
+    CXFA_Value value = pAcc->GetFormValue();
+    if (!value) {
+      return FALSE;
+    }
+    CXFA_Image imageObj = value.GetImage();
+    CXFA_FFDoc* pFFDoc = pAcc->GetDoc();
+    pAcc->SetImageEditImage(XFA_LoadImageData(pFFDoc, &imageObj, m_bNamedImage,
+                                              m_iImageXDpi, m_iImageYDpi));
+    return m_pDIBitmap != NULL;
+  }
+  CFX_DIBitmap* m_pDIBitmap;
+  FX_BOOL m_bNamedImage;
+  int32_t m_iImageXDpi;
+  int32_t m_iImageYDpi;
+};
+CXFA_WidgetAcc::CXFA_WidgetAcc(CXFA_FFDocView* pDocView, CXFA_Node* pNode)
+    : CXFA_WidgetData(pNode),
+      m_pDocView(pDocView),
+      m_pLayoutData(NULL),
+      m_nRecursionDepth(0) {}
+CXFA_WidgetAcc::~CXFA_WidgetAcc() {
+  if (m_pLayoutData) {
+    m_pLayoutData->Release();
+    m_pLayoutData = NULL;
+  }
+}
+FX_BOOL CXFA_WidgetAcc::GetName(CFX_WideString& wsName, int32_t iNameType) {
+  if (iNameType == 0) {
+    m_pNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
+    return !wsName.IsEmpty();
+  }
+  m_pNode->GetSOMExpression(wsName);
+  if (iNameType == 2 && wsName.GetLength() >= 15) {
+    CFX_WideStringC wsPre = FX_WSTRC(L"xfa[0].form[0].");
+    if (wsPre == CFX_WideStringC(wsName, wsPre.GetLength())) {
+      wsName.Delete(0, wsPre.GetLength());
+    }
+  }
+  return TRUE;
+}
+CXFA_Node* CXFA_WidgetAcc::GetDatasets() {
+  return m_pNode->GetBindData();
+}
+FX_BOOL CXFA_WidgetAcc::ProcessValueChanged() {
+  m_pDocView->AddValidateWidget(this);
+  m_pDocView->AddCalculateWidgetAcc(this);
+  m_pDocView->RunCalculateWidgets();
+  m_pDocView->RunValidate();
+  return TRUE;
+}
+void CXFA_WidgetAcc::ResetData() {
+  CFX_WideString wsValue;
+  XFA_ELEMENT eUIType = (XFA_ELEMENT)GetUIType();
+  switch (eUIType) {
+    case XFA_ELEMENT_ImageEdit: {
+      CXFA_Value imageValue = GetDefaultValue();
+      CXFA_Image image = imageValue.GetImage();
+      CFX_WideString wsContentType, wsHref;
+      if (image) {
+        image.GetContent(wsValue);
+        image.GetContentType(wsContentType);
+        image.GetHref(wsHref);
+      }
+      SetImageEdit(wsContentType, wsHref, wsValue);
+    } break;
+    case XFA_ELEMENT_ExclGroup: {
+      CXFA_Node* pNextChild = m_pNode->GetNodeItem(
+          XFA_NODEITEM_FirstChild, XFA_OBJECTTYPE_ContainerNode);
+      while (pNextChild) {
+        CXFA_Node* pChild = pNextChild;
+        CXFA_WidgetAcc* pAcc = (CXFA_WidgetAcc*)pChild->GetWidgetData();
+        if (!pAcc) {
+          continue;
+        }
+        CXFA_Value defValue(NULL);
+        if (wsValue.IsEmpty() && (defValue = pAcc->GetDefaultValue())) {
+          defValue.GetChildValueContent(wsValue);
+          SetValue(wsValue, XFA_VALUEPICTURE_Raw);
+          pAcc->SetValue(wsValue, XFA_VALUEPICTURE_Raw);
+        } else {
+          CXFA_Node* pItems = pChild->GetChild(0, XFA_ELEMENT_Items);
+          if (!pItems) {
+            continue;
+          }
+          CFX_WideString itemText;
+          if (pItems->CountChildren(XFA_ELEMENT_UNKNOWN) > 1) {
+            itemText = pItems->GetChild(1, XFA_ELEMENT_UNKNOWN)->GetContent();
+          }
+          pAcc->SetValue(itemText, XFA_VALUEPICTURE_Raw);
+        }
+        pNextChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling,
+                                         XFA_OBJECTTYPE_ContainerNode);
+      }
+    } break;
+    case XFA_ELEMENT_ChoiceList:
+      ClearAllSelections();
+    default:
+      if (CXFA_Value defValue = GetDefaultValue()) {
+        defValue.GetChildValueContent(wsValue);
+      }
+      SetValue(wsValue, XFA_VALUEPICTURE_Raw);
+      break;
+  }
+}
+void CXFA_WidgetAcc::SetImageEdit(const CFX_WideStringC& wsContentType,
+                                  const CFX_WideStringC& wsHref,
+                                  const CFX_WideStringC& wsData) {
+  CXFA_Image image = GetFormValue().GetImage();
+  if (image) {
+    image.SetContentType(wsContentType);
+    image.SetHref(wsHref);
+  }
+  CFX_WideString wsFormatValue(wsData);
+  GetFormatDataValue(wsData, wsFormatValue);
+  m_pNode->SetContent(wsData, wsFormatValue, TRUE);
+  CXFA_Node* pBind = GetDatasets();
+  if (!pBind) {
+    image.SetTransferEncoding(XFA_ATTRIBUTEENUM_Base64);
+    return;
+  }
+  pBind->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
+  CXFA_Node* pHrefNode = pBind->GetNodeItem(XFA_NODEITEM_FirstChild);
+  if (pHrefNode) {
+    pHrefNode->SetCData(XFA_ATTRIBUTE_Value, wsHref);
+  } else {
+    IFDE_XMLNode* pXMLNode = pBind->GetXMLMappingNode();
+    FXSYS_assert(pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element);
+    ((IFDE_XMLElement*)pXMLNode)->SetString(FX_WSTRC(L"href"), wsHref);
+  }
+}
+
+CXFA_WidgetAcc* CXFA_WidgetAcc::GetExclGroup() {
+  CXFA_Node* pExcl = m_pNode->GetNodeItem(XFA_NODEITEM_Parent);
+  if (!pExcl || pExcl->GetClassID() != XFA_ELEMENT_ExclGroup) {
+    return NULL;
+  }
+  return (CXFA_WidgetAcc*)pExcl->GetWidgetData();
+}
+CXFA_FFDocView* CXFA_WidgetAcc::GetDocView() {
+  return m_pDocView;
+}
+CXFA_FFDoc* CXFA_WidgetAcc::GetDoc() {
+  return (CXFA_FFDoc*)m_pDocView->GetDoc();
+}
+CXFA_FFApp* CXFA_WidgetAcc::GetApp() {
+  return GetDoc()->GetApp();
+}
+IXFA_AppProvider* CXFA_WidgetAcc::GetAppProvider() {
+  return GetApp()->GetAppProvider();
+}
+int32_t CXFA_WidgetAcc::ProcessEvent(int32_t iActivity,
+                                     CXFA_EventParam* pEventParam) {
+  if (GetClassID() == XFA_ELEMENT_Draw) {
+    return XFA_EVENTERROR_NotExist;
+  }
+  int32_t iRet = XFA_EVENTERROR_NotExist;
+  CXFA_NodeArray eventArray;
+  int32_t iCounts =
+      GetEventByActivity(iActivity, eventArray, pEventParam->m_bIsFormReady);
+  for (int32_t i = 0; i < iCounts; i++) {
+    CXFA_Event event(eventArray[i]);
+    int32_t result = ProcessEvent(event, pEventParam);
+    if (i == 0) {
+      iRet = result;
+    } else if (result == XFA_EVENTERROR_Sucess) {
+      iRet = result;
+    }
+  }
+  return iRet;
+}
+int32_t CXFA_WidgetAcc::ProcessEvent(CXFA_Event& event,
+                                     CXFA_EventParam* pEventParam) {
+  if (!event) {
+    return XFA_EVENTERROR_NotExist;
+  }
+  switch (event.GetEventType()) {
+    case XFA_ELEMENT_Execute:
+      break;
+    case XFA_ELEMENT_Script: {
+      CXFA_Script script = event.GetScript();
+      return ExecuteScript(script, pEventParam);
+    } break;
+    case XFA_ELEMENT_SignData:
+      break;
+    case XFA_ELEMENT_Submit: {
+      CXFA_Submit submit = event.GetSubmit();
+      return GetDoc()->GetDocProvider()->SubmitData(GetDoc(), submit);
+    }
+    default:
+      break;
+  }
+  return XFA_EVENTERROR_NotExist;
+}
+int32_t CXFA_WidgetAcc::ProcessCalculate() {
+  if (GetClassID() == XFA_ELEMENT_Draw) {
+    return XFA_EVENTERROR_NotExist;
+  }
+  CXFA_Calculate calc = GetCalculate();
+  if (!calc) {
+    return XFA_EVENTERROR_NotExist;
+  }
+  if (GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
+    return XFA_EVENTERROR_Disabled;
+  }
+  CXFA_EventParam EventParam;
+  EventParam.m_eType = XFA_EVENT_Calculate;
+  CXFA_Script script = calc.GetScript();
+  int32_t iRet = ExecuteScript(script, &EventParam);
+  if (iRet == XFA_EVENTERROR_Sucess) {
+    if (GetRawValue() != EventParam.m_wsResult) {
+      const bool bNotify = GetDoc()->GetDocType() == XFA_DOCTYPE_Static;
+      SetValue(EventParam.m_wsResult, XFA_VALUEPICTURE_Raw);
+      UpdateUIDisplay();
+      if (bNotify) {
+        NotifyEvent(XFA_WIDGETEVENT_PostContentChanged, NULL, NULL, NULL);
+      }
+      iRet = XFA_EVENTERROR_Sucess;
+    }
+  }
+  return iRet;
+}
+void CXFA_WidgetAcc::ProcessScriptTestValidate(CXFA_Validate validate,
+                                               int32_t iRet,
+                                               FXJSE_HVALUE pRetValue,
+                                               FX_BOOL bVersionFlag) {
+  if (iRet == XFA_EVENTERROR_Sucess && pRetValue) {
+    if (FXJSE_Value_IsBoolean(pRetValue) && !FXJSE_Value_ToBoolean(pRetValue)) {
+      IXFA_AppProvider* pAppProvider = GetAppProvider();
+      if (!pAppProvider) {
+        return;
+      }
+      CFX_WideString wsTitle;
+      pAppProvider->LoadString(XFA_IDS_AppName, wsTitle);
+      CFX_WideString wsScriptMsg;
+      validate.GetScriptMessageText(wsScriptMsg);
+      int32_t eScriptTest = validate.GetScriptTest();
+      if (eScriptTest == XFA_ATTRIBUTEENUM_Warning) {
+        if (GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
+          return;
+        }
+        if (wsScriptMsg.IsEmpty()) {
+          GetValidateMessage(pAppProvider, wsScriptMsg, FALSE, bVersionFlag);
+        }
+        if (bVersionFlag) {
+          pAppProvider->MsgBox(wsScriptMsg, wsTitle, XFA_MBICON_Warning,
+                               XFA_MB_OK);
+          return;
+        }
+        if (pAppProvider->MsgBox(wsScriptMsg, wsTitle, XFA_MBICON_Warning,
+                                 XFA_MB_YesNo) == XFA_IDYes) {
+          GetNode()->SetFlag(XFA_NODEFLAG_UserInteractive, TRUE, FALSE);
+        }
+      } else {
+        if (wsScriptMsg.IsEmpty()) {
+          GetValidateMessage(pAppProvider, wsScriptMsg, TRUE, bVersionFlag);
+        }
+        pAppProvider->MsgBox(wsScriptMsg, wsTitle, XFA_MBICON_Error, XFA_MB_OK);
+      }
+    }
+  }
+}
+int32_t CXFA_WidgetAcc::ProcessFormatTestValidate(CXFA_Validate validate,
+                                                  FX_BOOL bVersionFlag) {
+  CFX_WideString wsRawValue = GetRawValue();
+  if (!wsRawValue.IsEmpty()) {
+    CFX_WideString wsPicture;
+    validate.GetPicture(wsPicture);
+    if (wsPicture.IsEmpty()) {
+      return XFA_EVENTERROR_NotExist;
+    }
+    IFX_Locale* pLocale = GetLocal();
+    if (!pLocale) {
+      return XFA_EVENTERROR_NotExist;
+    }
+    CXFA_LocaleValue lcValue = XFA_GetLocaleValue(this);
+    if (!lcValue.ValidateValue(lcValue.GetValue(), wsPicture, pLocale)) {
+      IXFA_AppProvider* pAppProvider = GetAppProvider();
+      if (!pAppProvider) {
+        return XFA_EVENTERROR_NotExist;
+      }
+      CFX_WideString wsFormatMsg;
+      validate.GetFormatMessageText(wsFormatMsg);
+      CFX_WideString wsTitle;
+      pAppProvider->LoadString(XFA_IDS_AppName, wsTitle);
+      int32_t eFormatTest = validate.GetFormatTest();
+      if (eFormatTest == XFA_ATTRIBUTEENUM_Error) {
+        if (wsFormatMsg.IsEmpty()) {
+          GetValidateMessage(pAppProvider, wsFormatMsg, TRUE, bVersionFlag);
+        }
+        pAppProvider->MsgBox(wsFormatMsg, wsTitle, XFA_MBICON_Error, XFA_MB_OK);
+        return XFA_EVENTERROR_Sucess;
+      }
+      if (GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
+        return XFA_EVENTERROR_NotExist;
+      }
+      if (wsFormatMsg.IsEmpty()) {
+        GetValidateMessage(pAppProvider, wsFormatMsg, FALSE, bVersionFlag);
+      }
+      if (bVersionFlag) {
+        pAppProvider->MsgBox(wsFormatMsg, wsTitle, XFA_MBICON_Warning,
+                             XFA_MB_OK);
+        return XFA_EVENTERROR_Sucess;
+      }
+      if (pAppProvider->MsgBox(wsFormatMsg, wsTitle, XFA_MBICON_Warning,
+                               XFA_MB_YesNo) == XFA_IDYes) {
+        GetNode()->SetFlag(XFA_NODEFLAG_UserInteractive, TRUE, FALSE);
+      }
+      return XFA_EVENTERROR_Sucess;
+    }
+  }
+  return XFA_EVENTERROR_NotExist;
+}
+int32_t CXFA_WidgetAcc::ProcessNullTestValidate(CXFA_Validate validate,
+                                                int32_t iFlags,
+                                                FX_BOOL bVersionFlag) {
+  CFX_WideString wsValue;
+  GetValue(wsValue, XFA_VALUEPICTURE_Raw);
+  if (!wsValue.IsEmpty()) {
+    return XFA_EVENTERROR_Sucess;
+  }
+  if (m_bIsNull && (m_bPreNull == m_bIsNull)) {
+    return XFA_EVENTERROR_Sucess;
+  }
+  int32_t eNullTest = validate.GetNullTest();
+  CFX_WideString wsNullMsg;
+  validate.GetNullMessageText(wsNullMsg);
+  if (iFlags & 0x01) {
+    int32_t iRet = XFA_EVENTERROR_Sucess;
+    if (eNullTest != XFA_ATTRIBUTEENUM_Disabled) {
+      iRet = XFA_EVENTERROR_Error;
+    }
+    if (!wsNullMsg.IsEmpty()) {
+      if (eNullTest != XFA_ATTRIBUTEENUM_Disabled) {
+        m_pDocView->m_arrNullTestMsg.Add(wsNullMsg);
+        return XFA_EVENTERROR_Error;
+      }
+      return XFA_EVENTERROR_Sucess;
+    }
+    return iRet;
+  }
+  if (wsNullMsg.IsEmpty() && bVersionFlag &&
+      eNullTest != XFA_ATTRIBUTEENUM_Disabled) {
+    return XFA_EVENTERROR_Error;
+  }
+  IXFA_AppProvider* pAppProvider = GetAppProvider();
+  if (!pAppProvider) {
+    return XFA_EVENTERROR_NotExist;
+  }
+  CFX_WideString wsCaptionName;
+  CFX_WideString wsTitle;
+  pAppProvider->LoadString(XFA_IDS_AppName, wsTitle);
+  switch (eNullTest) {
+    case XFA_ATTRIBUTEENUM_Error: {
+      if (wsNullMsg.IsEmpty()) {
+        GetValidateCaptionName(wsCaptionName, bVersionFlag);
+        CFX_WideString wsError;
+        pAppProvider->LoadString(XFA_IDS_ValidateNullError, wsError);
+        wsNullMsg.Format(wsError, (const FX_WCHAR*)wsCaptionName);
+      }
+      pAppProvider->MsgBox(wsNullMsg, wsTitle, XFA_MBICON_Status, XFA_MB_OK);
+      return XFA_EVENTERROR_Error;
+    }
+    case XFA_ATTRIBUTEENUM_Warning: {
+      if (GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
+        return TRUE;
+      }
+      if (wsNullMsg.IsEmpty()) {
+        GetValidateCaptionName(wsCaptionName, bVersionFlag);
+        CFX_WideString wsWarning;
+        pAppProvider->LoadString(XFA_IDS_ValidateNullWarning, wsWarning);
+        wsNullMsg.Format(wsWarning, (const FX_WCHAR*)wsCaptionName,
+                         (const FX_WCHAR*)wsCaptionName);
+      }
+      if (pAppProvider->MsgBox(wsNullMsg, wsTitle, XFA_MBICON_Warning,
+                               XFA_MB_YesNo) == XFA_IDYes) {
+        GetNode()->SetFlag(XFA_NODEFLAG_UserInteractive, TRUE, FALSE);
+      }
+      return XFA_EVENTERROR_Error;
+    }
+    case XFA_ATTRIBUTEENUM_Disabled:
+    default:
+      break;
+  }
+  return XFA_EVENTERROR_Sucess;
+}
+void CXFA_WidgetAcc::GetValidateCaptionName(CFX_WideString& wsCaptionName,
+                                            FX_BOOL bVersionFlag) {
+  if (!bVersionFlag) {
+    CXFA_Caption caption = GetCaption();
+    if (caption) {
+      CXFA_Value capValue = caption.GetValue();
+      if (capValue) {
+        CXFA_Text capText = capValue.GetText();
+        if (capText) {
+          capText.GetContent(wsCaptionName);
+        }
+      }
+    }
+  }
+  if (wsCaptionName.IsEmpty()) {
+    GetName(wsCaptionName);
+  }
+}
+void CXFA_WidgetAcc::GetValidateMessage(IXFA_AppProvider* pAppProvider,
+                                        CFX_WideString& wsMessage,
+                                        FX_BOOL bError,
+                                        FX_BOOL bVersionFlag) {
+  CFX_WideString wsCaptionName;
+  GetValidateCaptionName(wsCaptionName, bVersionFlag);
+  CFX_WideString wsError;
+  if (bVersionFlag) {
+    pAppProvider->LoadString(XFA_IDS_ValidateFailed, wsError);
+    wsMessage.Format(wsError, (const FX_WCHAR*)wsCaptionName);
+    return;
+  }
+  if (bError) {
+    pAppProvider->LoadString(XFA_IDS_ValidateError, wsError);
+    wsMessage.Format(wsError, (const FX_WCHAR*)wsCaptionName);
+    return;
+  }
+  CFX_WideString wsWarning;
+  pAppProvider->LoadString(XFA_IDS_ValidateWarning, wsWarning);
+  wsMessage.Format(wsWarning, (const FX_WCHAR*)wsCaptionName,
+                   (const FX_WCHAR*)wsCaptionName);
+}
+int32_t CXFA_WidgetAcc::ProcessValidate(int32_t iFlags) {
+  if (GetClassID() == XFA_ELEMENT_Draw) {
+    return XFA_EVENTERROR_NotExist;
+  }
+  CXFA_Validate validate = GetValidate();
+  if (!validate) {
+    return XFA_EVENTERROR_NotExist;
+  }
+  FX_BOOL bInitDoc = validate.GetNode()->HasFlag(XFA_NODEFLAG_NeedsInitApp);
+  FX_BOOL bStatus =
+      m_pDocView->GetLayoutStatus() < XFA_DOCVIEW_LAYOUTSTATUS_End;
+  int32_t iFormat = 0;
+  FXJSE_HVALUE pRetValue = NULL;
+  int32_t iRet = XFA_EVENTERROR_NotExist;
+  CXFA_Script script = validate.GetScript();
+  if (script) {
+    CXFA_EventParam eParam;
+    eParam.m_eType = XFA_EVENT_Validate;
+    eParam.m_pTarget = this;
+    iRet = ExecuteScript(script, &eParam,
+                         ((bInitDoc || bStatus) && GetRawValue().IsEmpty())
+                             ? nullptr
+                             : &pRetValue);
+  }
+  XFA_VERSION version = GetDoc()->GetXFADoc()->GetCurVersionMode();
+  FX_BOOL bVersionFlag = FALSE;
+  if (version < XFA_VERSION_208) {
+    bVersionFlag = TRUE;
+  }
+  if (bInitDoc) {
+    validate.GetNode()->SetFlag(XFA_NODEFLAG_NeedsInitApp, FALSE, FALSE);
+  } else {
+    iFormat = ProcessFormatTestValidate(validate, bVersionFlag);
+    if (!bVersionFlag) {
+      bVersionFlag = GetDoc()->GetXFADoc()->HasFlag(XFA_DOCFLAG_Scripting);
+    }
+    iRet |= ProcessNullTestValidate(validate, iFlags, bVersionFlag);
+  }
+  if (iFormat != XFA_EVENTERROR_Sucess) {
+    ProcessScriptTestValidate(validate, iRet, pRetValue, bVersionFlag);
+  }
+  if (pRetValue) {
+    FXJSE_Value_Release(pRetValue);
+  }
+  return iRet | iFormat;
+}
+int32_t CXFA_WidgetAcc::ExecuteScript(CXFA_Script script,
+                                      CXFA_EventParam* pEventParam,
+                                      FXJSE_HVALUE* pRetValue) {
+  static const uint32_t MAX_RECURSION_DEPTH = 2;
+  if (m_nRecursionDepth > MAX_RECURSION_DEPTH)
+    return XFA_EVENTERROR_Sucess;
+  FXSYS_assert(pEventParam);
+  if (!script) {
+    return XFA_EVENTERROR_NotExist;
+  }
+  if (script.GetRunAt() == XFA_ATTRIBUTEENUM_Server) {
+    return XFA_EVENTERROR_Disabled;
+  }
+  CFX_WideString wsExpression;
+  script.GetExpression(wsExpression);
+  if (wsExpression.IsEmpty()) {
+    return XFA_EVENTERROR_NotExist;
+  }
+  XFA_SCRIPTTYPE eScriptType = script.GetContentType();
+  if (eScriptType == XFA_SCRIPTTYPE_Unkown) {
+    return XFA_EVENTERROR_Sucess;
+  }
+  CXFA_FFDoc* pDoc = GetDoc();
+  IXFA_ScriptContext* pContext = pDoc->GetXFADoc()->GetScriptContext();
+  pContext->SetEventParam(*pEventParam);
+  pContext->SetRunAtType((XFA_ATTRIBUTEENUM)script.GetRunAt());
+  CXFA_NodeArray refNodes;
+  if (pEventParam->m_eType == XFA_EVENT_InitCalculate ||
+      pEventParam->m_eType == XFA_EVENT_Calculate) {
+    pContext->SetNodesOfRunScript(&refNodes);
+  }
+  FXJSE_HVALUE hRetValue = FXJSE_Value_Create(pContext->GetRuntime());
+  ++m_nRecursionDepth;
+  FX_BOOL bRet = pContext->RunScript((XFA_SCRIPTLANGTYPE)eScriptType,
+                                     wsExpression, hRetValue, m_pNode);
+  --m_nRecursionDepth;
+  int32_t iRet = XFA_EVENTERROR_Error;
+  if (bRet) {
+    iRet = XFA_EVENTERROR_Sucess;
+    if (pEventParam->m_eType == XFA_EVENT_Calculate ||
+        pEventParam->m_eType == XFA_EVENT_InitCalculate) {
+      if (!FXJSE_Value_IsUndefined(hRetValue)) {
+        if (!FXJSE_Value_IsNull(hRetValue)) {
+          CFX_ByteString bsString;
+          FXJSE_Value_ToUTF8String(hRetValue, bsString);
+          pEventParam->m_wsResult =
+              CFX_WideString::FromUTF8(bsString, bsString.GetLength());
+        }
+        iRet = XFA_EVENTERROR_Sucess;
+      } else {
+        iRet = XFA_EVENTERROR_Error;
+      }
+      if (pEventParam->m_eType == XFA_EVENT_InitCalculate) {
+        if ((iRet == XFA_EVENTERROR_Sucess) &&
+            (GetRawValue() != pEventParam->m_wsResult)) {
+          SetValue(pEventParam->m_wsResult, XFA_VALUEPICTURE_Raw);
+          m_pDocView->AddValidateWidget(this);
+        }
+      }
+      int32_t iRefs = refNodes.GetSize();
+      for (int32_t r = 0; r < iRefs; r++) {
+        CXFA_WidgetAcc* pRefAcc = (CXFA_WidgetAcc*)refNodes[r]->GetWidgetData();
+        if (pRefAcc && pRefAcc == this) {
+          continue;
+        }
+        CXFA_Node* pRefNode = refNodes[r];
+        CXFA_CalcData* pGlobalData =
+            (CXFA_CalcData*)pRefNode->GetUserData(XFA_CalcData);
+        if (!pGlobalData) {
+          pGlobalData = new CXFA_CalcData;
+          pRefNode->SetUserData(XFA_CalcData, pGlobalData,
+                                &gs_XFADeleteCalcData);
+        }
+        if (pGlobalData->m_Globals.Find(this) < 0) {
+          pGlobalData->m_Globals.Add(this);
+        }
+      }
+    }
+  }
+  if (pRetValue) {
+    *pRetValue = hRetValue;
+  } else {
+    FXJSE_Value_Release(hRetValue);
+  }
+  pContext->SetNodesOfRunScript(NULL);
+  return iRet;
+}
+CXFA_FFWidget* CXFA_WidgetAcc::GetNextWidget(CXFA_FFWidget* pWidget) {
+  CXFA_LayoutItem* pLayout = nullptr;
+  if (pWidget) {
+    pLayout = pWidget->GetNext();
+  } else {
+    pLayout = m_pDocView->GetXFALayout()->GetLayoutItem(m_pNode);
+  }
+  return static_cast<CXFA_FFWidget*>(pLayout);
+}
+void CXFA_WidgetAcc::UpdateUIDisplay(CXFA_FFWidget* pExcept) {
+  CXFA_FFWidget* pWidget = NULL;
+  while ((pWidget = GetNextWidget(pWidget))) {
+    if (pWidget == pExcept || !pWidget->IsLoaded() ||
+        (GetUIType() != XFA_ELEMENT_CheckButton && pWidget->IsFocused())) {
+      continue;
+    }
+    pWidget->UpdateFWLData();
+    pWidget->AddInvalidateRect();
+  }
+}
+void CXFA_WidgetAcc::NotifyEvent(FX_DWORD dwEvent,
+                                 CXFA_FFWidget* pWidget,
+                                 void* pParam,
+                                 void* pAdditional) {
+  IXFA_DocProvider* pDocProvider = GetDoc()->GetDocProvider();
+  if (pWidget) {
+    pDocProvider->WidgetEvent(pWidget, this, dwEvent, pParam, pAdditional);
+  } else {
+    pWidget = GetNextWidget(pWidget);
+    if (pWidget == NULL) {
+      pDocProvider->WidgetEvent(NULL, this, dwEvent, pParam, pAdditional);
+      return;
+    }
+    while (pWidget) {
+      pDocProvider->WidgetEvent(pWidget, this, dwEvent, pParam, pAdditional);
+      pWidget = GetNextWidget(pWidget);
+    }
+  }
+}
+void CXFA_WidgetAcc::CalcCaptionSize(CFX_SizeF& szCap) {
+  CXFA_Caption caption = GetCaption();
+  if (!caption || caption.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
+    return;
+  }
+  LoadCaption();
+  XFA_ELEMENT eUIType = (XFA_ELEMENT)GetUIType();
+  int32_t iCapPlacement = caption.GetPlacementType();
+  FX_FLOAT fCapReserve = caption.GetReserve();
+  const bool bVert = iCapPlacement == XFA_ATTRIBUTEENUM_Top ||
+                     iCapPlacement == XFA_ATTRIBUTEENUM_Bottom;
+  const bool bReserveExit = fCapReserve > 0.01;
+  CXFA_TextLayout* pCapTextLayout =
+      ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pCapTextLayout;
+  if (pCapTextLayout) {
+    if (!bVert && eUIType != XFA_ELEMENT_Button) {
+      szCap.x = fCapReserve;
+    }
+    CFX_SizeF minSize;
+    pCapTextLayout->CalcSize(minSize, szCap, szCap);
+    if (bReserveExit) {
+      bVert ? szCap.y = fCapReserve : szCap.x = fCapReserve;
+    }
+  } else {
+    FX_FLOAT fFontSize = 10.0f;
+    if (CXFA_Font font = caption.GetFont()) {
+      fFontSize = font.GetFontSize();
+    } else if (CXFA_Font widgetfont = GetFont()) {
+      fFontSize = widgetfont.GetFontSize();
+    }
+    if (bVert) {
+      szCap.y = fCapReserve > 0 ? fCapReserve : fFontSize;
+    } else {
+      szCap.x = fCapReserve > 0 ? fCapReserve : 0;
+      szCap.y = fFontSize;
+    }
+  }
+  if (CXFA_Margin mgCap = caption.GetMargin()) {
+    FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
+    mgCap.GetLeftInset(fLeftInset);
+    mgCap.GetTopInset(fTopInset);
+    mgCap.GetRightInset(fRightInset);
+    mgCap.GetBottomInset(fBottomInset);
+    if (bReserveExit) {
+      bVert ? (szCap.x += fLeftInset + fRightInset)
+            : (szCap.y += fTopInset + fBottomInset);
+    } else {
+      szCap.x += fLeftInset + fRightInset;
+      szCap.y += fTopInset + fBottomInset;
+    }
+  }
+}
+FX_BOOL CXFA_WidgetAcc::CalculateFieldAutoSize(CFX_SizeF& size) {
+  CFX_SizeF szCap;
+  CalcCaptionSize(szCap);
+  CFX_RectF rtUIMargin;
+  GetUIMargin(rtUIMargin);
+  size.x += rtUIMargin.left + rtUIMargin.width;
+  size.y += rtUIMargin.top + rtUIMargin.height;
+  if (szCap.x > 0 && szCap.y > 0) {
+    int32_t iCapPlacement = GetCaption().GetPlacementType();
+    switch (iCapPlacement) {
+      case XFA_ATTRIBUTEENUM_Left:
+      case XFA_ATTRIBUTEENUM_Right:
+      case XFA_ATTRIBUTEENUM_Inline: {
+        size.x += szCap.x;
+        size.y = std::max(size.y, szCap.y);
+      } break;
+      case XFA_ATTRIBUTEENUM_Top:
+      case XFA_ATTRIBUTEENUM_Bottom: {
+        size.y += szCap.y;
+        size.x = std::max(size.x, szCap.x);
+      }
+      default:
+        break;
+    }
+  }
+  return CalculateWidgetAutoSize(size);
+}
+FX_BOOL CXFA_WidgetAcc::CalculateWidgetAutoSize(CFX_SizeF& size) {
+  CXFA_Margin mgWidget = GetMargin();
+  if (mgWidget) {
+    FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
+    mgWidget.GetLeftInset(fLeftInset);
+    mgWidget.GetTopInset(fTopInset);
+    mgWidget.GetRightInset(fRightInset);
+    mgWidget.GetBottomInset(fBottomInset);
+    size.x += fLeftInset + fRightInset;
+    size.y += fTopInset + fBottomInset;
+  }
+  CXFA_Para para = GetPara();
+  if (para) {
+    size.x += para.GetMarginLeft();
+    size.x += para.GetTextIndent();
+  }
+  FX_FLOAT fVal = 0, fMin = 0, fMax = 0;
+  if (GetWidth(fVal)) {
+    size.x = fVal;
+  } else {
+    if (GetMinWidth(fMin)) {
+      size.x = std::max(size.x, fMin);
+    }
+    if (GetMaxWidth(fMax) && fMax > 0) {
+      size.x = std::min(size.x, fMax);
+    }
+  }
+  fVal = 0, fMin = 0, fMax = 0;
+  if (GetHeight(fVal)) {
+    size.y = fVal;
+  } else {
+    if (GetMinHeight(fMin)) {
+      size.y = std::max(size.y, fMin);
+    }
+    if (GetMaxHeight(fMax) && fMax > 0) {
+      size.y = std::min(size.y, fMax);
+    }
+  }
+  return TRUE;
+}
+void CXFA_WidgetAcc::CalculateTextContentSize(CFX_SizeF& size) {
+  FX_FLOAT fFontSize = GetFontSize();
+  CFX_WideString wsText;
+  GetValue(wsText, XFA_VALUEPICTURE_Display);
+  if (wsText.IsEmpty()) {
+    size.y += fFontSize;
+    return;
+  }
+  FX_WCHAR wcEnter = '\n';
+  FX_WCHAR wsLast = wsText.GetAt(wsText.GetLength() - 1);
+  if (wsLast == wcEnter) {
+    wsText = wsText + wcEnter;
+  }
+  if (!((CXFA_FieldLayoutData*)m_pLayoutData)->m_pTextOut) {
+    ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pTextOut = IFDE_TextOut::Create();
+    IFDE_TextOut* pTextOut = ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pTextOut;
+    pTextOut->SetFont(GetFDEFont());
+    pTextOut->SetFontSize(fFontSize);
+    pTextOut->SetLineBreakTolerance(fFontSize * 0.2f);
+    pTextOut->SetLineSpace(GetLineHeight());
+    FX_DWORD dwStyles = FDE_TTOSTYLE_LastLineHeight;
+    if (GetUIType() == XFA_ELEMENT_TextEdit && IsMultiLine()) {
+      dwStyles |= FDE_TTOSTYLE_LineWrap;
+    }
+    pTextOut->SetStyles(dwStyles);
+  }
+  ((CXFA_FieldLayoutData*)m_pLayoutData)
+      ->m_pTextOut->CalcLogicSize(wsText, wsText.GetLength(), size);
+}
+FX_BOOL CXFA_WidgetAcc::CalculateTextEditAutoSize(CFX_SizeF& size) {
+  if (size.x > 0) {
+    CFX_SizeF szOrz = size;
+    CFX_SizeF szCap;
+    CalcCaptionSize(szCap);
+    FX_BOOL bCapExit = szCap.x > 0.01 && szCap.y > 0.01;
+    int32_t iCapPlacement = XFA_ATTRIBUTEENUM_Unknown;
+    if (bCapExit) {
+      iCapPlacement = GetCaption().GetPlacementType();
+      switch (iCapPlacement) {
+        case XFA_ATTRIBUTEENUM_Left:
+        case XFA_ATTRIBUTEENUM_Right:
+        case XFA_ATTRIBUTEENUM_Inline: {
+          size.x -= szCap.x;
+        }
+        default:
+          break;
+      }
+    }
+    CFX_RectF rtUIMargin;
+    GetUIMargin(rtUIMargin);
+    size.x -= rtUIMargin.left + rtUIMargin.width;
+    CXFA_Margin mgWidget = GetMargin();
+    if (mgWidget) {
+      FX_FLOAT fLeftInset, fRightInset;
+      mgWidget.GetLeftInset(fLeftInset);
+      mgWidget.GetRightInset(fRightInset);
+      size.x -= fLeftInset + fRightInset;
+    }
+    CalculateTextContentSize(size);
+    size.y += rtUIMargin.top + rtUIMargin.height;
+    if (bCapExit) {
+      switch (iCapPlacement) {
+        case XFA_ATTRIBUTEENUM_Left:
+        case XFA_ATTRIBUTEENUM_Right:
+        case XFA_ATTRIBUTEENUM_Inline: {
+          size.y = std::max(size.y, szCap.y);
+        } break;
+        case XFA_ATTRIBUTEENUM_Top:
+        case XFA_ATTRIBUTEENUM_Bottom: {
+          size.y += szCap.y;
+        }
+        default:
+          break;
+      }
+    }
+    size.x = szOrz.x;
+    return CalculateWidgetAutoSize(size);
+  }
+  CalculateTextContentSize(size);
+  return CalculateFieldAutoSize(size);
+}
+FX_BOOL CXFA_WidgetAcc::CalculateCheckButtonAutoSize(CFX_SizeF& size) {
+  FX_FLOAT fCheckSize = GetCheckButtonSize();
+  size.x = size.y = fCheckSize;
+  return CalculateFieldAutoSize(size);
+}
+FX_BOOL CXFA_WidgetAcc::CalculatePushButtonAutoSize(CFX_SizeF& size) {
+  CalcCaptionSize(size);
+  return CalculateWidgetAutoSize(size);
+}
+FX_BOOL CXFA_WidgetAcc::CalculateImageAutoSize(CFX_SizeF& size) {
+  if (!GetImageImage()) {
+    LoadImageImage();
+  }
+  size.clear();
+  if (CFX_DIBitmap* pBitmap = GetImageImage()) {
+    CFX_RectF rtImage, rtFit;
+    rtImage.Set(0, 0, 0, 0);
+    rtFit.Set(0, 0, 0, 0);
+    int32_t iImageXDpi = 0;
+    int32_t iImageYDpi = 0;
+    GetImageDpi(iImageXDpi, iImageYDpi);
+    rtImage.width =
+        XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetWidth(), (FX_FLOAT)iImageXDpi);
+    rtImage.height =
+        XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetHeight(), (FX_FLOAT)iImageYDpi);
+    if (GetWidth(rtFit.width)) {
+      GetWidthWithoutMargin(rtFit.width);
+    } else {
+      rtFit.width = rtImage.width;
+    }
+    if (GetHeight(rtFit.height)) {
+      GetHeightWithoutMargin(rtFit.height);
+    } else {
+      rtFit.height = rtImage.height;
+    }
+    size.x = rtFit.width;
+    size.y = rtFit.height;
+  }
+  return CalculateWidgetAutoSize(size);
+}
+FX_BOOL CXFA_WidgetAcc::CalculateImageEditAutoSize(CFX_SizeF& size) {
+  if (!GetImageEditImage()) {
+    LoadImageEditImage();
+  }
+  size.clear();
+  if (CFX_DIBitmap* pBitmap = GetImageEditImage()) {
+    CFX_RectF rtImage, rtFit;
+    rtImage.Set(0, 0, 0, 0);
+    rtFit.Set(0, 0, 0, 0);
+    int32_t iImageXDpi = 0;
+    int32_t iImageYDpi = 0;
+    GetImageEditDpi(iImageXDpi, iImageYDpi);
+    rtImage.width =
+        XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetWidth(), (FX_FLOAT)iImageXDpi);
+    rtImage.height =
+        XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetHeight(), (FX_FLOAT)iImageYDpi);
+    if (GetWidth(rtFit.width)) {
+      GetWidthWithoutMargin(rtFit.width);
+    } else {
+      rtFit.width = rtImage.width;
+    }
+    if (GetHeight(rtFit.height)) {
+      GetHeightWithoutMargin(rtFit.height);
+    } else {
+      rtFit.height = rtImage.height;
+    }
+    size.x = rtFit.width;
+    size.y = rtFit.height;
+  }
+  return CalculateFieldAutoSize(size);
+}
+FX_BOOL CXFA_WidgetAcc::LoadImageImage() {
+  InitLayoutData();
+  return ((CXFA_ImageLayoutData*)m_pLayoutData)->LoadImageData(this);
+}
+FX_BOOL CXFA_WidgetAcc::LoadImageEditImage() {
+  InitLayoutData();
+  return ((CXFA_ImageEditData*)m_pLayoutData)->LoadImageData(this);
+}
+void CXFA_WidgetAcc::GetImageDpi(int32_t& iImageXDpi, int32_t& iImageYDpi) {
+  iImageXDpi = ((CXFA_ImageLayoutData*)m_pLayoutData)->m_iImageXDpi;
+  iImageYDpi = ((CXFA_ImageLayoutData*)m_pLayoutData)->m_iImageYDpi;
+}
+void CXFA_WidgetAcc::GetImageEditDpi(int32_t& iImageXDpi, int32_t& iImageYDpi) {
+  iImageXDpi = ((CXFA_ImageEditData*)m_pLayoutData)->m_iImageXDpi;
+  iImageYDpi = ((CXFA_ImageEditData*)m_pLayoutData)->m_iImageYDpi;
+}
+FX_BOOL CXFA_WidgetAcc::CalculateTextAutoSize(CFX_SizeF& size) {
+  LoadText();
+  CXFA_TextLayout* pTextLayout =
+      ((CXFA_TextLayoutData*)m_pLayoutData)->m_pTextLayout;
+  if (pTextLayout) {
+    size.x = pTextLayout->StartLayout(size.x);
+    size.y = pTextLayout->GetLayoutHeight();
+  }
+  return CalculateWidgetAutoSize(size);
+}
+void CXFA_WidgetAcc::LoadText() {
+  InitLayoutData();
+  ((CXFA_TextLayoutData*)m_pLayoutData)->LoadText(this);
+}
+FX_FLOAT CXFA_WidgetAcc::CalculateWidgetAutoWidth(FX_FLOAT fWidthCalc) {
+  CXFA_Margin mgWidget = GetMargin();
+  if (mgWidget) {
+    FX_FLOAT fLeftInset, fRightInset;
+    mgWidget.GetLeftInset(fLeftInset);
+    mgWidget.GetRightInset(fRightInset);
+    fWidthCalc += fLeftInset + fRightInset;
+  }
+  FX_FLOAT fMin = 0, fMax = 0;
+  if (GetMinWidth(fMin)) {
+    fWidthCalc = std::max(fWidthCalc, fMin);
+  }
+  if (GetMaxWidth(fMax) && fMax > 0) {
+    fWidthCalc = std::min(fWidthCalc, fMax);
+  }
+  return fWidthCalc;
+}
+FX_FLOAT CXFA_WidgetAcc::GetWidthWithoutMargin(FX_FLOAT fWidthCalc) {
+  CXFA_Margin mgWidget = GetMargin();
+  if (mgWidget) {
+    FX_FLOAT fLeftInset, fRightInset;
+    mgWidget.GetLeftInset(fLeftInset);
+    mgWidget.GetRightInset(fRightInset);
+    fWidthCalc -= fLeftInset + fRightInset;
+  }
+  return fWidthCalc;
+}
+FX_FLOAT CXFA_WidgetAcc::CalculateWidgetAutoHeight(FX_FLOAT fHeightCalc) {
+  CXFA_Margin mgWidget = GetMargin();
+  if (mgWidget) {
+    FX_FLOAT fTopInset, fBottomInset;
+    mgWidget.GetTopInset(fTopInset);
+    mgWidget.GetBottomInset(fBottomInset);
+    fHeightCalc += fTopInset + fBottomInset;
+  }
+  FX_FLOAT fMin = 0, fMax = 0;
+  if (GetMinHeight(fMin)) {
+    fHeightCalc = std::max(fHeightCalc, fMin);
+  }
+  if (GetMaxHeight(fMax) && fMax > 0) {
+    fHeightCalc = std::min(fHeightCalc, fMax);
+  }
+  return fHeightCalc;
+}
+FX_FLOAT CXFA_WidgetAcc::GetHeightWithoutMargin(FX_FLOAT fHeightCalc) {
+  CXFA_Margin mgWidget = GetMargin();
+  if (mgWidget) {
+    FX_FLOAT fTopInset, fBottomInset;
+    mgWidget.GetTopInset(fTopInset);
+    mgWidget.GetBottomInset(fBottomInset);
+    fHeightCalc -= fTopInset + fBottomInset;
+  }
+  return fHeightCalc;
+}
+void CXFA_WidgetAcc::StartWidgetLayout(FX_FLOAT& fCalcWidth,
+                                       FX_FLOAT& fCalcHeight) {
+  InitLayoutData();
+  XFA_ELEMENT eUIType = GetUIType();
+  if (eUIType == XFA_ELEMENT_Text) {
+    m_pLayoutData->m_fWidgetHeight = -1;
+    GetHeight(m_pLayoutData->m_fWidgetHeight);
+    StartTextLayout(fCalcWidth, fCalcHeight);
+    return;
+  }
+  if (fCalcWidth > 0 && fCalcHeight > 0) {
+    return;
+  }
+  m_pLayoutData->m_fWidgetHeight = -1;
+  FX_FLOAT fWidth = 0;
+  if (fCalcWidth > 0 && fCalcHeight < 0) {
+    if (!GetHeight(fCalcHeight)) {
+      CalculateAccWidthAndHeight(eUIType, fCalcWidth, fCalcHeight);
+    }
+    m_pLayoutData->m_fWidgetHeight = fCalcHeight;
+    return;
+  }
+  if (fCalcWidth < 0 && fCalcHeight < 0) {
+    if (!GetWidth(fWidth) || !GetHeight(fCalcHeight)) {
+      CalculateAccWidthAndHeight(eUIType, fWidth, fCalcHeight);
+    }
+    fCalcWidth = fWidth;
+  }
+  m_pLayoutData->m_fWidgetHeight = fCalcHeight;
+}
+void CXFA_WidgetAcc::CalculateAccWidthAndHeight(XFA_ELEMENT eUIType,
+                                                FX_FLOAT& fWidth,
+                                                FX_FLOAT& fCalcHeight) {
+  CFX_SizeF sz(fWidth, m_pLayoutData->m_fWidgetHeight);
+  switch (eUIType) {
+    case XFA_ELEMENT_Barcode:
+    case XFA_ELEMENT_ChoiceList:
+    case XFA_ELEMENT_Signature:
+      CalculateFieldAutoSize(sz);
+      break;
+    case XFA_ELEMENT_ImageEdit:
+      CalculateImageEditAutoSize(sz);
+      break;
+    case XFA_ELEMENT_Button:
+      CalculatePushButtonAutoSize(sz);
+      break;
+    case XFA_ELEMENT_CheckButton:
+      CalculateCheckButtonAutoSize(sz);
+      break;
+    case XFA_ELEMENT_DateTimeEdit:
+    case XFA_ELEMENT_NumericEdit:
+    case XFA_ELEMENT_PasswordEdit:
+    case XFA_ELEMENT_TextEdit:
+      CalculateTextEditAutoSize(sz);
+      break;
+    case XFA_ELEMENT_Image:
+      CalculateImageAutoSize(sz);
+      break;
+    case XFA_ELEMENT_Arc:
+    case XFA_ELEMENT_Line:
+    case XFA_ELEMENT_Rectangle:
+    case XFA_ELEMENT_Subform:
+    case XFA_ELEMENT_ExclGroup:
+      CalculateWidgetAutoSize(sz);
+      break;
+    default:
+      break;
+  }
+  fWidth = sz.x;
+  m_pLayoutData->m_fWidgetHeight = sz.y;
+  fCalcHeight = sz.y;
+}
+FX_BOOL CXFA_WidgetAcc::FindSplitPos(int32_t iBlockIndex,
+                                     FX_FLOAT& fCalcHeight) {
+  XFA_ELEMENT eUIType = (XFA_ELEMENT)GetUIType();
+  if (eUIType == XFA_ELEMENT_Subform) {
+    return FALSE;
+  }
+  if (eUIType != XFA_ELEMENT_Text && eUIType != XFA_ELEMENT_TextEdit &&
+      eUIType != XFA_ELEMENT_NumericEdit &&
+      eUIType != XFA_ELEMENT_PasswordEdit) {
+    fCalcHeight = 0;
+    return TRUE;
+  }
+  FX_FLOAT fTopInset = 0;
+  FX_FLOAT fBottomInset = 0;
+  if (iBlockIndex == 0) {
+    CXFA_Margin mgWidget = GetMargin();
+    if (mgWidget) {
+      mgWidget.GetTopInset(fTopInset);
+      mgWidget.GetBottomInset(fBottomInset);
+    }
+    CFX_RectF rtUIMargin;
+    GetUIMargin(rtUIMargin);
+    fTopInset += rtUIMargin.top;
+    fBottomInset += rtUIMargin.width;
+  }
+  if (eUIType == XFA_ELEMENT_Text) {
+    FX_FLOAT fHeight = fCalcHeight;
+    if (iBlockIndex == 0) {
+      fCalcHeight = fCalcHeight - fTopInset;
+      if (fCalcHeight < 0) {
+        fCalcHeight = 0;
+      }
+    }
+    CXFA_TextLayout* pTextLayout =
+        ((CXFA_TextLayoutData*)m_pLayoutData)->m_pTextLayout;
+    pTextLayout->DoLayout(iBlockIndex, fCalcHeight, fCalcHeight,
+                          m_pLayoutData->m_fWidgetHeight - fTopInset);
+    if (fCalcHeight != 0) {
+      if (iBlockIndex == 0) {
+        fCalcHeight = fCalcHeight + fTopInset;
+      }
+      if (fabs(fHeight - fCalcHeight) < XFA_FLOAT_PERCISION) {
+        return FALSE;
+      }
+    }
+    return TRUE;
+  }
+  XFA_ATTRIBUTEENUM iCapPlacement = XFA_ATTRIBUTEENUM_Unknown;
+  FX_FLOAT fCapReserve = 0;
+  if (iBlockIndex == 0) {
+    CXFA_Caption caption = GetCaption();
+    if (caption && caption.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) {
+      iCapPlacement = (XFA_ATTRIBUTEENUM)caption.GetPlacementType();
+      fCapReserve = caption.GetReserve();
+    }
+    if (iCapPlacement == XFA_ATTRIBUTEENUM_Top &&
+        fCalcHeight < fCapReserve + fTopInset) {
+      fCalcHeight = 0;
+      return TRUE;
+    }
+    if (iCapPlacement == XFA_ATTRIBUTEENUM_Bottom &&
+        m_pLayoutData->m_fWidgetHeight - fCapReserve - fBottomInset) {
+      fCalcHeight = 0;
+      return TRUE;
+    }
+    if (iCapPlacement != XFA_ATTRIBUTEENUM_Top) {
+      fCapReserve = 0;
+    }
+  }
+  int32_t iLinesCount = 0;
+  FX_FLOAT fHeight = m_pLayoutData->m_fWidgetHeight;
+  CFX_WideString wsText;
+  GetValue(wsText, XFA_VALUEPICTURE_Display);
+  if (wsText.IsEmpty()) {
+    iLinesCount = 1;
+  } else {
+    if (!((CXFA_FieldLayoutData*)m_pLayoutData)->m_pTextOut) {
+      FX_FLOAT fWidth = 0;
+      GetWidth(fWidth);
+      CalculateAccWidthAndHeight(eUIType, fWidth, fHeight);
+    }
+    iLinesCount =
+        ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pTextOut->GetTotalLines();
+  }
+  if (!((CXFA_FieldLayoutData*)m_pLayoutData)->m_pFieldSplitArray) {
+    ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pFieldSplitArray =
+        new CFX_FloatArray;
+  }
+  CFX_FloatArray* pFieldArray =
+      ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pFieldSplitArray;
+  int32_t iFieldSplitCount = pFieldArray->GetSize();
+  for (int32_t i = 0; i < iBlockIndex * 3; i += 3) {
+    iLinesCount -= (int32_t)pFieldArray->GetAt(i + 1);
+    fHeight -= pFieldArray->GetAt(i + 2);
+  }
+  if (iLinesCount == 0) {
+    return FALSE;
+  }
+  FX_FLOAT fLineHeight = GetLineHeight();
+  FX_FLOAT fFontSize = GetFontSize();
+  FX_FLOAT fTextHeight = iLinesCount * fLineHeight - fLineHeight + fFontSize;
+  FX_FLOAT fSpaceAbove = 0;
+  FX_FLOAT fStartOffset = 0;
+  if (fHeight > 0.1f && iBlockIndex == 0) {
+    fStartOffset = fTopInset;
+    fHeight -= (fTopInset + fBottomInset);
+    if (CXFA_Para para = GetPara()) {
+      fSpaceAbove = para.GetSpaceAbove();
+      FX_FLOAT fSpaceBelow = para.GetSpaceBelow();
+      fHeight -= (fSpaceAbove + fSpaceBelow);
+      switch (para.GetVerticalAlign()) {
+        case XFA_ATTRIBUTEENUM_Top:
+          fStartOffset += fSpaceAbove;
+          break;
+        case XFA_ATTRIBUTEENUM_Middle:
+          fStartOffset += ((fHeight - fTextHeight) / 2 + fSpaceAbove);
+          break;
+        case XFA_ATTRIBUTEENUM_Bottom:
+          fStartOffset += (fHeight - fTextHeight + fSpaceAbove);
+          break;
+      }
+    }
+    if (fStartOffset < 0.1f) {
+      fStartOffset = 0;
+    }
+  }
+  for (int32_t i = iBlockIndex - 1; iBlockIndex > 0 && i < iBlockIndex; i++) {
+    fStartOffset = pFieldArray->GetAt(i * 3) - pFieldArray->GetAt(i * 3 + 2);
+    if (fStartOffset < 0.1f) {
+      fStartOffset = 0;
+    }
+  }
+  if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
+    pFieldArray->SetAt(0, fStartOffset);
+  } else {
+    pFieldArray->Add(fStartOffset);
+  }
+  XFA_VERSION version = GetDoc()->GetXFADoc()->GetCurVersionMode();
+  FX_BOOL bCanSplitNoContent = FALSE;
+  XFA_ATTRIBUTEENUM eLayoutMode;
+  GetNode()
+      ->GetNodeItem(XFA_NODEITEM_Parent)
+      ->TryEnum(XFA_ATTRIBUTE_Layout, eLayoutMode, TRUE);
+  if ((eLayoutMode == XFA_ATTRIBUTEENUM_Position ||
+       eLayoutMode == XFA_ATTRIBUTEENUM_Tb ||
+       eLayoutMode == XFA_ATTRIBUTEENUM_Row ||
+       eLayoutMode == XFA_ATTRIBUTEENUM_Table) &&
+      version > XFA_VERSION_208) {
+    bCanSplitNoContent = TRUE;
+  }
+  if ((eLayoutMode == XFA_ATTRIBUTEENUM_Tb ||
+       eLayoutMode == XFA_ATTRIBUTEENUM_Row ||
+       eLayoutMode == XFA_ATTRIBUTEENUM_Table) &&
+      version <= XFA_VERSION_208) {
+    if (fStartOffset < fCalcHeight) {
+      bCanSplitNoContent = TRUE;
+    } else {
+      fCalcHeight = 0;
+      return TRUE;
+    }
+  }
+  if (bCanSplitNoContent) {
+    if ((fCalcHeight - fTopInset - fSpaceAbove < fLineHeight)) {
+      fCalcHeight = 0;
+      return TRUE;
+    }
+    if (fStartOffset + XFA_FLOAT_PERCISION >= fCalcHeight) {
+      if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
+        pFieldArray->SetAt(iBlockIndex * 3 + 1, 0);
+        pFieldArray->SetAt(iBlockIndex * 3 + 2, fCalcHeight);
+      } else {
+        pFieldArray->Add(0);
+        pFieldArray->Add(fCalcHeight);
+      }
+      return FALSE;
+    }
+    if (fCalcHeight - fStartOffset < fLineHeight) {
+      fCalcHeight = fStartOffset;
+      if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
+        pFieldArray->SetAt(iBlockIndex * 3 + 1, 0);
+        pFieldArray->SetAt(iBlockIndex * 3 + 2, fCalcHeight);
+      } else {
+        pFieldArray->Add(0);
+        pFieldArray->Add(fCalcHeight);
+      }
+      return TRUE;
+    }
+    FX_FLOAT fTextNum =
+        fCalcHeight + XFA_FLOAT_PERCISION - fCapReserve - fStartOffset;
+    int32_t iLineNum =
+        (int32_t)((fTextNum + (fLineHeight - fFontSize)) / fLineHeight);
+    if (iLineNum >= iLinesCount) {
+      if (fCalcHeight - fStartOffset - fTextHeight >= fFontSize) {
+        if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
+          pFieldArray->SetAt(iBlockIndex * 3 + 1, (FX_FLOAT)iLinesCount);
+          pFieldArray->SetAt(iBlockIndex * 3 + 2, fCalcHeight);
+        } else {
+          pFieldArray->Add((FX_FLOAT)iLinesCount);
+          pFieldArray->Add(fCalcHeight);
+        }
+        return FALSE;
+      }
+      if (fHeight - fStartOffset - fTextHeight < fFontSize) {
+        iLineNum -= 1;
+        if (iLineNum == 0) {
+          fCalcHeight = 0;
+          return TRUE;
+        }
+      } else {
+        iLineNum = (int32_t)(fTextNum / fLineHeight);
+      }
+    }
+    if (iLineNum > 0) {
+      FX_FLOAT fSplitHeight =
+          iLineNum * fLineHeight + fCapReserve + fStartOffset;
+      if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
+        pFieldArray->SetAt(iBlockIndex * 3 + 1, (FX_FLOAT)iLineNum);
+        pFieldArray->SetAt(iBlockIndex * 3 + 2, fSplitHeight);
+      } else {
+        pFieldArray->Add((FX_FLOAT)iLineNum);
+        pFieldArray->Add(fSplitHeight);
+      }
+      if (fabs(fSplitHeight - fCalcHeight) < XFA_FLOAT_PERCISION) {
+        return FALSE;
+      }
+      fCalcHeight = fSplitHeight;
+      return TRUE;
+    }
+  }
+  fCalcHeight = 0;
+  return TRUE;
+}
+void CXFA_WidgetAcc::InitLayoutData() {
+  if (m_pLayoutData) {
+    return;
+  }
+  switch (GetUIType()) {
+    case XFA_ELEMENT_Text:
+      m_pLayoutData = new CXFA_TextLayoutData;
+      return;
+    case XFA_ELEMENT_TextEdit:
+      m_pLayoutData = new CXFA_TextEditData;
+      return;
+    case XFA_ELEMENT_Image:
+      m_pLayoutData = new CXFA_ImageLayoutData;
+      return;
+    case XFA_ELEMENT_ImageEdit:
+      m_pLayoutData = new CXFA_ImageEditData;
+      return;
+    default:
+      break;
+  }
+  if (GetClassID() == XFA_ELEMENT_Field) {
+    m_pLayoutData = new CXFA_FieldLayoutData;
+  } else {
+    m_pLayoutData = new CXFA_WidgetLayoutData;
+  }
+}
+void CXFA_WidgetAcc::StartTextLayout(FX_FLOAT& fCalcWidth,
+                                     FX_FLOAT& fCalcHeight) {
+  LoadText();
+  CXFA_TextLayout* pTextLayout =
+      ((CXFA_TextLayoutData*)m_pLayoutData)->m_pTextLayout;
+  FX_FLOAT fTextHeight = 0;
+  if (fCalcWidth > 0 && fCalcHeight > 0) {
+    FX_FLOAT fWidth = GetWidthWithoutMargin(fCalcWidth);
+    pTextLayout->StartLayout(fWidth);
+    fTextHeight = fCalcHeight;
+    fTextHeight = GetHeightWithoutMargin(fTextHeight);
+    pTextLayout->DoLayout(0, fTextHeight, -1, fTextHeight);
+    return;
+  }
+  if (fCalcWidth > 0 && fCalcHeight < 0) {
+    FX_FLOAT fWidth = GetWidthWithoutMargin(fCalcWidth);
+    pTextLayout->StartLayout(fWidth);
+  }
+  if (fCalcWidth < 0 && fCalcHeight < 0) {
+    FX_FLOAT fMaxWidth = -1;
+    FX_BOOL bRet = GetWidth(fMaxWidth);
+    if (bRet) {
+      FX_FLOAT fWidth = GetWidthWithoutMargin(fMaxWidth);
+      pTextLayout->StartLayout(fWidth);
+    } else {
+      FX_FLOAT fWidth = pTextLayout->StartLayout(fMaxWidth);
+      fMaxWidth = CalculateWidgetAutoWidth(fWidth);
+      fWidth = GetWidthWithoutMargin(fMaxWidth);
+      pTextLayout->StartLayout(fWidth);
+    }
+    fCalcWidth = fMaxWidth;
+  }
+  if (m_pLayoutData->m_fWidgetHeight < 0) {
+    m_pLayoutData->m_fWidgetHeight = pTextLayout->GetLayoutHeight();
+    m_pLayoutData->m_fWidgetHeight =
+        CalculateWidgetAutoHeight(m_pLayoutData->m_fWidgetHeight);
+  }
+  fTextHeight = m_pLayoutData->m_fWidgetHeight;
+  fTextHeight = GetHeightWithoutMargin(fTextHeight);
+  pTextLayout->DoLayout(0, fTextHeight, -1, fTextHeight);
+  fCalcHeight = m_pLayoutData->m_fWidgetHeight;
+}
+FX_BOOL CXFA_WidgetAcc::LoadCaption() {
+  InitLayoutData();
+  return ((CXFA_FieldLayoutData*)m_pLayoutData)->LoadCaption(this);
+}
+CXFA_TextLayout* CXFA_WidgetAcc::GetCaptionTextLayout() {
+  return m_pLayoutData
+             ? ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pCapTextLayout
+             : NULL;
+}
+CXFA_TextLayout* CXFA_WidgetAcc::GetTextLayout() {
+  return m_pLayoutData ? ((CXFA_TextLayoutData*)m_pLayoutData)->m_pTextLayout
+                       : NULL;
+}
+CFX_DIBitmap* CXFA_WidgetAcc::GetImageImage() {
+  return m_pLayoutData ? ((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap
+                       : NULL;
+}
+CFX_DIBitmap* CXFA_WidgetAcc::GetImageEditImage() {
+  return m_pLayoutData ? ((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap
+                       : NULL;
+}
+void CXFA_WidgetAcc::SetImageImage(CFX_DIBitmap* newImage) {
+  if (((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap == newImage) {
+    return;
+  }
+  if (((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap &&
+      !((CXFA_ImageLayoutData*)m_pLayoutData)->m_bNamedImage) {
+    delete ((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap;
+    ((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap = NULL;
+  }
+  ((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap = newImage;
+}
+void CXFA_WidgetAcc::SetImageEditImage(CFX_DIBitmap* newImage) {
+  if (((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap == newImage) {
+    return;
+  }
+  if (((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap &&
+      !((CXFA_ImageEditData*)m_pLayoutData)->m_bNamedImage) {
+    delete ((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap;
+    ((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap = NULL;
+  }
+  ((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap = newImage;
+}
+CXFA_WidgetLayoutData* CXFA_WidgetAcc::GetWidgetLayoutData() {
+  return m_pLayoutData;
+}
+IFX_Font* CXFA_WidgetAcc::GetFDEFont() {
+  CFX_WideStringC wsFontName = FX_WSTRC(L"Courier");
+  FX_DWORD dwFontStyle = 0;
+  if (CXFA_Font font = GetFont()) {
+    if (font.IsBold()) {
+      dwFontStyle |= FX_FONTSTYLE_Bold;
+    }
+    if (font.IsItalic()) {
+      dwFontStyle |= FX_FONTSTYLE_Italic;
+    }
+    font.GetTypeface(wsFontName);
+  }
+  CXFA_FFDoc* pDoc = GetDoc();
+  return pDoc->GetApp()->GetXFAFontMgr()->GetFont(pDoc, wsFontName,
+                                                  dwFontStyle);
+}
+FX_FLOAT CXFA_WidgetAcc::GetFontSize() {
+  FX_FLOAT fFontSize = 10.0f;
+  if (CXFA_Font font = GetFont()) {
+    fFontSize = font.GetFontSize();
+  }
+  return fFontSize < 0.1f ? 10.0f : fFontSize;
+}
+FX_FLOAT CXFA_WidgetAcc::GetLineHeight() {
+  FX_FLOAT fLineHeight = 0;
+  if (CXFA_Para para = GetPara()) {
+    fLineHeight = para.GetLineHeight();
+  }
+  if (fLineHeight < 1) {
+    fLineHeight = GetFontSize() * 1.2f;
+  }
+  return fLineHeight;
+}
+FX_ARGB CXFA_WidgetAcc::GetTextColor() {
+  if (CXFA_Font font = GetFont()) {
+    return font.GetColor();
+  }
+  return 0xFF000000;
+}
+CXFA_Node* CXFA_TextProvider::GetTextNode(FX_BOOL& bRichText) {
+  bRichText = FALSE;
+  if (m_pTextNode) {
+    if (m_pTextNode->GetClassID() == XFA_ELEMENT_ExData) {
+      CFX_WideString wsContentType;
+      m_pTextNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType,
+                                FALSE);
+      if (wsContentType.Equal(FX_WSTRC(L"text/html"))) {
+        bRichText = TRUE;
+      }
+    }
+    return m_pTextNode;
+  }
+  if (m_eType == XFA_TEXTPROVIDERTYPE_Text) {
+    CXFA_Node* pElementNode = m_pWidgetAcc->GetNode();
+    CXFA_Node* pValueNode = pElementNode->GetChild(0, XFA_ELEMENT_Value);
+    if (!pValueNode) {
+      return NULL;
+    }
+    CXFA_Node* pChildNode = pValueNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+    if (pChildNode && pChildNode->GetClassID() == XFA_ELEMENT_ExData) {
+      CFX_WideString wsContentType;
+      pChildNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);
+      if (wsContentType.Equal(FX_WSTRC(L"text/html"))) {
+        bRichText = TRUE;
+      }
+    }
+    return pChildNode;
+  } else if (m_eType == XFA_TEXTPROVIDERTYPE_Datasets) {
+    CXFA_Node* pBind = m_pWidgetAcc->GetDatasets();
+    IFDE_XMLNode* pXMLNode = pBind->GetXMLMappingNode();
+    FXSYS_assert(pXMLNode);
+    for (IFDE_XMLNode* pXMLChild =
+             pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild);
+         pXMLChild;
+         pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+      if (pXMLChild->GetType() == FDE_XMLNODE_Element) {
+        IFDE_XMLElement* pElement = (IFDE_XMLElement*)pXMLChild;
+        if (XFA_RecognizeRichText(pElement)) {
+          bRichText = TRUE;
+        }
+      }
+    }
+    return pBind;
+  } else if (m_eType == XFA_TEXTPROVIDERTYPE_Caption) {
+    CXFA_Node* pCaptionNode =
+        m_pWidgetAcc->GetNode()->GetChild(0, XFA_ELEMENT_Caption);
+    if (pCaptionNode == NULL) {
+      return NULL;
+    }
+    CXFA_Node* pValueNode = pCaptionNode->GetChild(0, XFA_ELEMENT_Value);
+    if (pValueNode == NULL) {
+      return NULL;
+    }
+    CXFA_Node* pChildNode = pValueNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+    if (pChildNode && pChildNode->GetClassID() == XFA_ELEMENT_ExData) {
+      CFX_WideString wsContentType;
+      pChildNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);
+      if (wsContentType.Equal(FX_WSTRC(L"text/html"))) {
+        bRichText = TRUE;
+      }
+    }
+    return pChildNode;
+  }
+  CXFA_Node* pItemNode =
+      m_pWidgetAcc->GetNode()->GetChild(0, XFA_ELEMENT_Items);
+  if (pItemNode == NULL) {
+    return NULL;
+  }
+  CXFA_Node* pNode = pItemNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+  while (pNode) {
+    CFX_WideStringC wsName;
+    pNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
+    if (m_eType == XFA_TEXTPROVIDERTYPE_Rollover &&
+        wsName == FX_WSTRC(L"rollover")) {
+      return pNode;
+    }
+    if (m_eType == XFA_TEXTPROVIDERTYPE_Down && wsName == FX_WSTRC(L"down")) {
+      return pNode;
+    }
+    pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+  }
+  return NULL;
+}
+CXFA_Para CXFA_TextProvider::GetParaNode() {
+  if (m_eType == XFA_TEXTPROVIDERTYPE_Text) {
+    return m_pWidgetAcc->GetPara();
+  }
+  CXFA_Node* pNode = m_pWidgetAcc->GetNode()->GetChild(0, XFA_ELEMENT_Caption);
+  return CXFA_Para(pNode->GetChild(0, XFA_ELEMENT_Para));
+}
+CXFA_Font CXFA_TextProvider::GetFontNode() {
+  if (m_eType == XFA_TEXTPROVIDERTYPE_Text) {
+    return m_pWidgetAcc->GetFont();
+  }
+  CXFA_Node* pNode = m_pWidgetAcc->GetNode()->GetChild(0, XFA_ELEMENT_Caption);
+  pNode = pNode->GetChild(0, XFA_ELEMENT_Font);
+  if (pNode) {
+    return CXFA_Font(pNode);
+  }
+  return m_pWidgetAcc->GetFont();
+}
+FX_BOOL CXFA_TextProvider::IsCheckButtonAndAutoWidth() {
+  XFA_ELEMENT eType = m_pWidgetAcc->GetUIType();
+  if (eType == XFA_ELEMENT_CheckButton) {
+    FX_FLOAT fWidth = 0;
+    return !m_pWidgetAcc->GetWidth(fWidth);
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_TextProvider::GetEmbbedObj(FX_BOOL bURI,
+                                        FX_BOOL bRaw,
+                                        const CFX_WideString& wsAttr,
+                                        CFX_WideString& wsValue) {
+  if (m_eType != XFA_TEXTPROVIDERTYPE_Text) {
+    return FALSE;
+  }
+  if (bURI) {
+    CXFA_Node* pWidgetNode = m_pWidgetAcc->GetNode();
+    CXFA_Node* pParent = pWidgetNode->GetNodeItem(XFA_NODEITEM_Parent);
+    CXFA_Document* pDocument = pWidgetNode->GetDocument();
+    CXFA_Node* pIDNode = NULL;
+    CXFA_WidgetAcc* pEmbAcc = NULL;
+    if (pParent) {
+      pIDNode = pDocument->GetNodeByID(pParent, wsAttr);
+    }
+    if (!pIDNode) {
+      pIDNode = pDocument->GetNodeByID(
+          ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Form)), wsAttr);
+    }
+    if (pIDNode) {
+      pEmbAcc = (CXFA_WidgetAcc*)pIDNode->GetWidgetData();
+    }
+    if (pEmbAcc) {
+      pEmbAcc->GetValue(wsValue, XFA_VALUEPICTURE_Display);
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
diff --git a/xfa/fxfa/app/xfa_ffwidgetacc.h b/xfa/fxfa/app/xfa_ffwidgetacc.h
new file mode 100644
index 0000000..722256a
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffwidgetacc.h
@@ -0,0 +1,44 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFWIDGETACC_H_
+#define XFA_FXFA_APP_XFA_FFWIDGETACC_H_
+
+#include "xfa/fxfa/app/xfa_textlayout.h"
+
+enum XFA_TEXTPROVIDERTYPE {
+  XFA_TEXTPROVIDERTYPE_Text,
+  XFA_TEXTPROVIDERTYPE_Datasets,
+  XFA_TEXTPROVIDERTYPE_Caption,
+  XFA_TEXTPROVIDERTYPE_Rollover,
+  XFA_TEXTPROVIDERTYPE_Down,
+};
+class CXFA_TextProvider : public IXFA_TextProvider {
+ public:
+  CXFA_TextProvider(CXFA_WidgetAcc* pWidgetAcc,
+                    XFA_TEXTPROVIDERTYPE eType,
+                    CXFA_Node* pTextNode = NULL)
+      : m_pWidgetAcc(pWidgetAcc), m_eType(eType), m_pTextNode(pTextNode) {
+    FXSYS_assert(m_pWidgetAcc);
+  }
+  virtual ~CXFA_TextProvider() {}
+  virtual CXFA_Node* GetTextNode(FX_BOOL& bRichText);
+  virtual CXFA_Para GetParaNode();
+  virtual CXFA_Font GetFontNode();
+  virtual FX_BOOL IsCheckButtonAndAutoWidth();
+  virtual CXFA_FFDoc* GetDocNode() { return m_pWidgetAcc->GetDoc(); }
+  virtual FX_BOOL GetEmbbedObj(FX_BOOL bURI,
+                               FX_BOOL bRaw,
+                               const CFX_WideString& wsAttr,
+                               CFX_WideString& wsValue);
+
+ protected:
+  CXFA_WidgetAcc* m_pWidgetAcc;
+  XFA_TEXTPROVIDERTYPE m_eType;
+  CXFA_Node* m_pTextNode;
+};
+
+#endif  // XFA_FXFA_APP_XFA_FFWIDGETACC_H_
diff --git a/xfa/fxfa/app/xfa_ffwidgethandler.cpp b/xfa/fxfa/app/xfa_ffwidgethandler.cpp
new file mode 100644
index 0000000..b775643
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffwidgethandler.cpp
@@ -0,0 +1,634 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_ffwidgethandler.h"
+
+#include <vector>
+
+#include "xfa/fxfa/app/xfa_ffchoicelist.h"
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_ffdocview.h"
+#include "xfa/fxfa/app/xfa_fffield.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+#include "xfa/fxfa/app/xfa_fwladapter.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+
+CXFA_FFWidgetHandler::CXFA_FFWidgetHandler(CXFA_FFDocView* pDocView)
+    : m_pDocView(pDocView) {}
+CXFA_FFWidgetHandler::~CXFA_FFWidgetHandler() {}
+IXFA_PageView* CXFA_FFWidgetHandler::GetPageView(IXFA_Widget* hWidget) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->GetPageView();
+}
+void CXFA_FFWidgetHandler::GetRect(IXFA_Widget* hWidget, CFX_RectF& rt) {
+  static_cast<CXFA_FFWidget*>(hWidget)->GetWidgetRect(rt);
+}
+FX_DWORD CXFA_FFWidgetHandler::GetStatus(IXFA_Widget* hWidget) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->GetStatus();
+}
+FX_BOOL CXFA_FFWidgetHandler::GetBBox(IXFA_Widget* hWidget,
+                                      CFX_RectF& rtBox,
+                                      FX_DWORD dwStatus,
+                                      FX_BOOL bDrawFocus) {
+  return static_cast<CXFA_FFWidget*>(hWidget)
+      ->GetBBox(rtBox, dwStatus, bDrawFocus);
+}
+CXFA_WidgetAcc* CXFA_FFWidgetHandler::GetDataAcc(IXFA_Widget* hWidget) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->GetDataAcc();
+}
+void CXFA_FFWidgetHandler::GetName(IXFA_Widget* hWidget,
+                                   CFX_WideString& wsName,
+                                   int32_t iNameType) {
+  static_cast<CXFA_FFWidget*>(hWidget)->GetDataAcc()->GetName(wsName,
+                                                              iNameType);
+}
+FX_BOOL CXFA_FFWidgetHandler::GetToolTip(IXFA_Widget* hWidget,
+                                         CFX_WideString& wsToolTip) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->GetToolTip(wsToolTip);
+}
+void CXFA_FFWidgetHandler::SetPrivateData(IXFA_Widget* hWidget,
+                                          void* module_id,
+                                          void* pData,
+                                          PD_CALLBACK_FREEDATA callback) {
+  static_cast<CXFA_FFWidget*>(hWidget)
+      ->SetPrivateData(module_id, pData, callback);
+}
+void* CXFA_FFWidgetHandler::GetPrivateData(IXFA_Widget* hWidget,
+                                           void* module_id) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->GetPrivateData(module_id);
+}
+FX_BOOL CXFA_FFWidgetHandler::OnMouseEnter(IXFA_Widget* hWidget) {
+  m_pDocView->LockUpdate();
+  FX_BOOL bRet = static_cast<CXFA_FFWidget*>(hWidget)->OnMouseEnter();
+  m_pDocView->UnlockUpdate();
+  m_pDocView->UpdateDocView();
+  return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnMouseExit(IXFA_Widget* hWidget) {
+  m_pDocView->LockUpdate();
+  FX_BOOL bRet = static_cast<CXFA_FFWidget*>(hWidget)->OnMouseExit();
+  m_pDocView->UnlockUpdate();
+  m_pDocView->UpdateDocView();
+  return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnLButtonDown(IXFA_Widget* hWidget,
+                                            FX_DWORD dwFlags,
+                                            FX_FLOAT fx,
+                                            FX_FLOAT fy) {
+  m_pDocView->LockUpdate();
+  static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
+  FX_BOOL bRet =
+      static_cast<CXFA_FFWidget*>(hWidget)->OnLButtonDown(dwFlags, fx, fy);
+  if (bRet && m_pDocView->SetFocus(hWidget)) {
+    ((CXFA_FFDoc*)m_pDocView->GetDoc())
+        ->GetDocProvider()
+        ->SetFocusWidget(m_pDocView->GetDoc(), (IXFA_Widget*)hWidget);
+  }
+  m_pDocView->UnlockUpdate();
+  m_pDocView->UpdateDocView();
+  return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnLButtonUp(IXFA_Widget* hWidget,
+                                          FX_DWORD dwFlags,
+                                          FX_FLOAT fx,
+                                          FX_FLOAT fy) {
+  m_pDocView->LockUpdate();
+  static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
+  m_pDocView->m_bLayoutEvent = TRUE;
+  FX_BOOL bRet =
+      static_cast<CXFA_FFWidget*>(hWidget)->OnLButtonUp(dwFlags, fx, fy);
+  m_pDocView->UnlockUpdate();
+  m_pDocView->UpdateDocView();
+  return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnLButtonDblClk(IXFA_Widget* hWidget,
+                                              FX_DWORD dwFlags,
+                                              FX_FLOAT fx,
+                                              FX_FLOAT fy) {
+  static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
+  FX_BOOL bRet =
+      static_cast<CXFA_FFWidget*>(hWidget)->OnLButtonDblClk(dwFlags, fx, fy);
+  m_pDocView->RunInvalidate();
+  return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnMouseMove(IXFA_Widget* hWidget,
+                                          FX_DWORD dwFlags,
+                                          FX_FLOAT fx,
+                                          FX_FLOAT fy) {
+  static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
+  FX_BOOL bRet =
+      static_cast<CXFA_FFWidget*>(hWidget)->OnMouseMove(dwFlags, fx, fy);
+  m_pDocView->RunInvalidate();
+  return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnMouseWheel(IXFA_Widget* hWidget,
+                                           FX_DWORD dwFlags,
+                                           int16_t zDelta,
+                                           FX_FLOAT fx,
+                                           FX_FLOAT fy) {
+  static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
+  FX_BOOL bRet = static_cast<CXFA_FFWidget*>(hWidget)
+                     ->OnMouseWheel(dwFlags, zDelta, fx, fy);
+  m_pDocView->RunInvalidate();
+  return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnRButtonDown(IXFA_Widget* hWidget,
+                                            FX_DWORD dwFlags,
+                                            FX_FLOAT fx,
+                                            FX_FLOAT fy) {
+  static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
+  FX_BOOL bRet =
+      static_cast<CXFA_FFWidget*>(hWidget)->OnRButtonDown(dwFlags, fx, fy);
+  if (bRet && m_pDocView->SetFocus(hWidget)) {
+    ((CXFA_FFDoc*)m_pDocView->GetDoc())
+        ->GetDocProvider()
+        ->SetFocusWidget(m_pDocView->GetDoc(), (IXFA_Widget*)hWidget);
+  }
+  m_pDocView->RunInvalidate();
+  return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnRButtonUp(IXFA_Widget* hWidget,
+                                          FX_DWORD dwFlags,
+                                          FX_FLOAT fx,
+                                          FX_FLOAT fy) {
+  static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
+  FX_BOOL bRet =
+      static_cast<CXFA_FFWidget*>(hWidget)->OnRButtonUp(dwFlags, fx, fy);
+  m_pDocView->RunInvalidate();
+  return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnRButtonDblClk(IXFA_Widget* hWidget,
+                                              FX_DWORD dwFlags,
+                                              FX_FLOAT fx,
+                                              FX_FLOAT fy) {
+  static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
+  FX_BOOL bRet =
+      static_cast<CXFA_FFWidget*>(hWidget)->OnRButtonDblClk(dwFlags, fx, fy);
+  m_pDocView->RunInvalidate();
+  return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnKeyDown(IXFA_Widget* hWidget,
+                                        FX_DWORD dwKeyCode,
+                                        FX_DWORD dwFlags) {
+  FX_BOOL bRet =
+      static_cast<CXFA_FFWidget*>(hWidget)->OnKeyDown(dwKeyCode, dwFlags);
+  m_pDocView->RunInvalidate();
+  m_pDocView->UpdateDocView();
+  return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnKeyUp(IXFA_Widget* hWidget,
+                                      FX_DWORD dwKeyCode,
+                                      FX_DWORD dwFlags) {
+  FX_BOOL bRet =
+      static_cast<CXFA_FFWidget*>(hWidget)->OnKeyUp(dwKeyCode, dwFlags);
+  m_pDocView->RunInvalidate();
+  return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnChar(IXFA_Widget* hWidget,
+                                     FX_DWORD dwChar,
+                                     FX_DWORD dwFlags) {
+  FX_BOOL bRet = static_cast<CXFA_FFWidget*>(hWidget)->OnChar(dwChar, dwFlags);
+  m_pDocView->RunInvalidate();
+  return bRet;
+}
+FX_DWORD CXFA_FFWidgetHandler::OnHitTest(IXFA_Widget* hWidget,
+                                         FX_FLOAT fx,
+                                         FX_FLOAT fy) {
+  if (!(static_cast<CXFA_FFWidget*>(hWidget)->GetStatus() &
+        XFA_WIDGETSTATUS_Visible)) {
+    return FWL_WGTHITTEST_Unknown;
+  }
+  static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
+  return static_cast<CXFA_FFWidget*>(hWidget)->OnHitTest(fx, fy);
+}
+FX_BOOL CXFA_FFWidgetHandler::OnSetCursor(IXFA_Widget* hWidget,
+                                          FX_FLOAT fx,
+                                          FX_FLOAT fy) {
+  static_cast<CXFA_FFWidget*>(hWidget)->Rotate2Normal(fx, fy);
+  return static_cast<CXFA_FFWidget*>(hWidget)->OnSetCursor(fx, fy);
+}
+void CXFA_FFWidgetHandler::RenderWidget(IXFA_Widget* hWidget,
+                                        CFX_Graphics* pGS,
+                                        CFX_Matrix* pMatrix,
+                                        FX_BOOL bHighlight) {
+  static_cast<CXFA_FFWidget*>(hWidget)->RenderWidget(
+      pGS, pMatrix, bHighlight ? XFA_WIDGETSTATUS_Highlight : 0, 0);
+}
+FX_BOOL CXFA_FFWidgetHandler::HasEvent(CXFA_WidgetAcc* pWidgetAcc,
+                                       XFA_EVENTTYPE eEventType) {
+  if (!pWidgetAcc || eEventType == XFA_EVENT_Unknown) {
+    return FALSE;
+  }
+  if (pWidgetAcc->GetClassID() == XFA_ELEMENT_Draw) {
+    return FALSE;
+  }
+  switch (eEventType) {
+    case XFA_EVENT_Calculate: {
+      CXFA_Calculate calc = pWidgetAcc->GetCalculate();
+      if (!calc) {
+        return FALSE;
+      }
+      if (calc.GetScript()) {
+        return TRUE;
+      }
+      return FALSE;
+    }
+    case XFA_EVENT_Validate: {
+      CXFA_Validate val = pWidgetAcc->GetValidate();
+      if (!val) {
+        return FALSE;
+      }
+      if (val.GetScript()) {
+        return TRUE;
+      }
+      return FALSE;
+    }
+    default:
+      break;
+  }
+  CXFA_NodeArray eventArray;
+  return pWidgetAcc->GetEventByActivity(gs_EventActivity[eEventType],
+                                        eventArray);
+}
+int32_t CXFA_FFWidgetHandler::ProcessEvent(CXFA_WidgetAcc* pWidgetAcc,
+                                           CXFA_EventParam* pParam) {
+  if (!pParam || pParam->m_eType == XFA_EVENT_Unknown) {
+    return XFA_EVENTERROR_NotExist;
+  }
+  if (!pWidgetAcc || pWidgetAcc->GetClassID() == XFA_ELEMENT_Draw) {
+    return XFA_EVENTERROR_NotExist;
+  }
+  switch (pParam->m_eType) {
+    case XFA_EVENT_Calculate:
+      return pWidgetAcc->ProcessCalculate();
+    case XFA_EVENT_Validate:
+      if (((CXFA_FFDoc*)m_pDocView->GetDoc())
+              ->GetDocProvider()
+              ->IsValidationsEnabled(m_pDocView->GetDoc())) {
+        return pWidgetAcc->ProcessValidate();
+      }
+      return XFA_EVENTERROR_Disabled;
+    case XFA_EVENT_InitCalculate: {
+      CXFA_Calculate calc = pWidgetAcc->GetCalculate();
+      if (!calc) {
+        return XFA_EVENTERROR_NotExist;
+      }
+      if (pWidgetAcc->GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
+        return XFA_EVENTERROR_Disabled;
+      }
+      CXFA_Script script = calc.GetScript();
+      return pWidgetAcc->ExecuteScript(script, pParam);
+    }
+    default:
+      break;
+  }
+  int32_t iRet =
+      pWidgetAcc->ProcessEvent(gs_EventActivity[pParam->m_eType], pParam);
+  return iRet;
+}
+IXFA_Widget* CXFA_FFWidgetHandler::CreateWidget(IXFA_Widget* hParent,
+                                                XFA_WIDGETTYPE eType,
+                                                IXFA_Widget* hBefore) {
+  CXFA_Node* pParentFormItem =
+      hParent ? static_cast<CXFA_FFWidget*>(hParent)->GetDataAcc()->GetNode()
+              : NULL;
+  CXFA_Node* pBeforeFormItem =
+      hBefore ? static_cast<CXFA_FFWidget*>(hBefore)->GetDataAcc()->GetNode()
+              : NULL;
+  CXFA_Node* pNewFormItem =
+      CreateWidgetFormItem(eType, pParentFormItem, pBeforeFormItem);
+  if (pNewFormItem == NULL) {
+    return NULL;
+  }
+  pNewFormItem->GetTemplateNode()->SetFlag(XFA_NODEFLAG_Initialized);
+  pNewFormItem->SetFlag(XFA_NODEFLAG_Initialized);
+  m_pDocView->RunLayout();
+  CXFA_LayoutItem* pLayout =
+      m_pDocView->GetXFALayout()->GetLayoutItem(pNewFormItem);
+  return (IXFA_Widget*)pLayout;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateWidgetFormItem(
+    XFA_WIDGETTYPE eType,
+    CXFA_Node* pParent,
+    CXFA_Node* pBefore) const {
+  switch (eType) {
+    case XFA_WIDGETTYPE_Barcode:
+      return NULL;
+    case XFA_WIDGETTYPE_PushButton:
+      return CreatePushButton(pParent, pBefore);
+    case XFA_WIDGETTYPE_CheckButton:
+      return CreateCheckButton(pParent, pBefore);
+    case XFA_WIDGETTYPE_ExcludeGroup:
+      return CreateExclGroup(pParent, pBefore);
+    case XFA_WIDGETTYPE_RadioButton:
+      return CreateRadioButton(pParent, pBefore);
+    case XFA_WIDGETTYPE_Arc:
+      return CreateArc(pParent, pBefore);
+    case XFA_WIDGETTYPE_Rectangle:
+      return CreateRectangle(pParent, pBefore);
+    case XFA_WIDGETTYPE_Image:
+      return CreateImage(pParent, pBefore);
+    case XFA_WIDGETTYPE_Line:
+      return CreateLine(pParent, pBefore);
+    case XFA_WIDGETTYPE_Text:
+      return CreateText(pParent, pBefore);
+    case XFA_WIDGETTYPE_DatetimeEdit:
+      return CreateDatetimeEdit(pParent, pBefore);
+    case XFA_WIDGETTYPE_DecimalField:
+      return CreateDecimalField(pParent, pBefore);
+    case XFA_WIDGETTYPE_NumericField:
+      return CreateNumericField(pParent, pBefore);
+    case XFA_WIDGETTYPE_Signature:
+      return CreateSignature(pParent, pBefore);
+    case XFA_WIDGETTYPE_TextEdit:
+      return CreateTextEdit(pParent, pBefore);
+    case XFA_WIDGETTYPE_DropdownList:
+      return CreateDropdownList(pParent, pBefore);
+    case XFA_WIDGETTYPE_ListBox:
+      return CreateListBox(pParent, pBefore);
+    case XFA_WIDGETTYPE_ImageField:
+      return CreateImageField(pParent, pBefore);
+    case XFA_WIDGETTYPE_PasswordEdit:
+      return CreatePasswordEdit(pParent, pBefore);
+    case XFA_WIDGETTYPE_Subform:
+      return CreateSubform(pParent, pBefore);
+    default:
+      break;
+  }
+  return NULL;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreatePushButton(CXFA_Node* pParent,
+                                                  CXFA_Node* pBefore) const {
+  CXFA_Node* pField = CreateField(XFA_ELEMENT_Button, pParent, pBefore);
+  CXFA_Node* pCaption = CreateCopyNode(XFA_ELEMENT_Caption, pField);
+  CXFA_Node* pValue = CreateCopyNode(XFA_ELEMENT_Value, pCaption);
+  CXFA_Node* pText = CreateCopyNode(XFA_ELEMENT_Text, pValue);
+  pText->SetContent(FX_WSTRC(L"Button"), FX_WSTRC(L"Button"), FALSE);
+  CXFA_Node* pPara = CreateCopyNode(XFA_ELEMENT_Para, pCaption);
+  pPara->SetEnum(XFA_ATTRIBUTE_VAlign, XFA_ATTRIBUTEENUM_Middle, FALSE);
+  pPara->SetEnum(XFA_ATTRIBUTE_HAlign, XFA_ATTRIBUTEENUM_Center, FALSE);
+  CreateFontNode(pCaption);
+  CXFA_Node* pBorder = CreateCopyNode(XFA_ELEMENT_Border, pField);
+  pBorder->SetEnum(XFA_ATTRIBUTE_Hand, XFA_ATTRIBUTEENUM_Right, FALSE);
+  CXFA_Node* pEdge = CreateCopyNode(XFA_ELEMENT_Edge, pBorder);
+  pEdge->SetEnum(XFA_ATTRIBUTE_Stroke, XFA_ATTRIBUTEENUM_Raised, FALSE);
+  CXFA_Node* pFill = CreateCopyNode(XFA_ELEMENT_Fill, pBorder);
+  CXFA_Node* pColor = CreateCopyNode(XFA_ELEMENT_Color, pFill);
+  pColor->SetCData(XFA_ATTRIBUTE_Value, FX_WSTRC(L"212, 208, 200"), FALSE);
+  CXFA_Node* pBind = CreateCopyNode(XFA_ELEMENT_Bind, pField);
+  pBind->SetEnum(XFA_ATTRIBUTE_Match, XFA_ATTRIBUTEENUM_None);
+  return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateCheckButton(CXFA_Node* pParent,
+                                                   CXFA_Node* pBefore) const {
+  CXFA_Node* pField = CreateField(XFA_ELEMENT_CheckButton, pParent, pBefore);
+  return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateExclGroup(CXFA_Node* pParent,
+                                                 CXFA_Node* pBefore) const {
+  return CreateFormItem(XFA_ELEMENT_ExclGroup, pParent, pBefore);
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateRadioButton(CXFA_Node* pParent,
+                                                   CXFA_Node* pBefore) const {
+  CXFA_Node* pField = CreateField(XFA_ELEMENT_CheckButton, pParent, pBefore);
+  CXFA_Node* pUi = pField->GetFirstChildByClass(XFA_ELEMENT_Ui);
+  CXFA_Node* pWidget = pUi->GetFirstChildByClass(XFA_ELEMENT_CheckButton);
+  pWidget->SetEnum(XFA_ATTRIBUTE_Shape, XFA_ATTRIBUTEENUM_Round);
+  return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateDatetimeEdit(CXFA_Node* pParent,
+                                                    CXFA_Node* pBefore) const {
+  CXFA_Node* pField = CreateField(XFA_ELEMENT_DateTimeEdit, pParent, pBefore);
+  CreateValueNode(XFA_ELEMENT_Date, pField);
+  return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateDecimalField(CXFA_Node* pParent,
+                                                    CXFA_Node* pBefore) const {
+  CXFA_Node* pField = CreateNumericField(pParent, pBefore);
+  CreateValueNode(XFA_ELEMENT_Decimal, pField);
+  return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateNumericField(CXFA_Node* pParent,
+                                                    CXFA_Node* pBefore) const {
+  CXFA_Node* pField = CreateField(XFA_ELEMENT_NumericEdit, pParent, pBefore);
+  return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateSignature(CXFA_Node* pParent,
+                                                 CXFA_Node* pBefore) const {
+  CXFA_Node* pField = CreateField(XFA_ELEMENT_Signature, pParent, pBefore);
+  return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateTextEdit(CXFA_Node* pParent,
+                                                CXFA_Node* pBefore) const {
+  CXFA_Node* pField = CreateField(XFA_ELEMENT_TextEdit, pParent, pBefore);
+  return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateDropdownList(CXFA_Node* pParent,
+                                                    CXFA_Node* pBefore) const {
+  CXFA_Node* pField = CreateField(XFA_ELEMENT_ChoiceList, pParent, pBefore);
+  return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateListBox(CXFA_Node* pParent,
+                                               CXFA_Node* pBefore) const {
+  CXFA_Node* pField = CreateDropdownList(pParent, pBefore);
+  CXFA_Node* pUi = pField->GetNodeItem(XFA_NODEITEM_FirstChild);
+  CXFA_Node* pListBox = pUi->GetNodeItem(XFA_NODEITEM_FirstChild);
+  pListBox->SetEnum(XFA_ATTRIBUTE_Open, XFA_ATTRIBUTEENUM_Always);
+  pListBox->SetEnum(XFA_ATTRIBUTE_CommitOn, XFA_ATTRIBUTEENUM_Exit);
+  return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateImageField(CXFA_Node* pParent,
+                                                  CXFA_Node* pBefore) const {
+  CXFA_Node* pField = CreateField(XFA_ELEMENT_ImageEdit, pParent, pBefore);
+  return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreatePasswordEdit(CXFA_Node* pParent,
+                                                    CXFA_Node* pBefore) const {
+  CXFA_Node* pField = CreateField(XFA_ELEMENT_PasswordEdit, pParent, pBefore);
+  CXFA_Node* pBind = CreateCopyNode(XFA_ELEMENT_Bind, pField);
+  pBind->SetEnum(XFA_ATTRIBUTE_Match, XFA_ATTRIBUTEENUM_None, FALSE);
+  return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateField(XFA_ELEMENT eElement,
+                                             CXFA_Node* pParent,
+                                             CXFA_Node* pBefore) const {
+  CXFA_Node* pField = CreateFormItem(XFA_ELEMENT_Field, pParent, pBefore);
+  CreateCopyNode(eElement, CreateCopyNode(XFA_ELEMENT_Ui, pField));
+  CreateFontNode(pField);
+  return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateArc(CXFA_Node* pParent,
+                                           CXFA_Node* pBefore) const {
+  return CreateDraw(XFA_ELEMENT_Arc, pParent, pBefore);
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateRectangle(CXFA_Node* pParent,
+                                                 CXFA_Node* pBefore) const {
+  return CreateDraw(XFA_ELEMENT_Rectangle, pParent, pBefore);
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateImage(CXFA_Node* pParent,
+                                             CXFA_Node* pBefore) const {
+  CXFA_Node* pField = CreateDraw(XFA_ELEMENT_Image, pParent, pBefore);
+  CreateCopyNode(XFA_ELEMENT_ImageEdit, CreateCopyNode(XFA_ELEMENT_Ui, pField));
+  return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateLine(CXFA_Node* pParent,
+                                            CXFA_Node* pBefore) const {
+  CXFA_Node* pField = CreateDraw(XFA_ELEMENT_Line, pParent, pBefore);
+  return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateText(CXFA_Node* pParent,
+                                            CXFA_Node* pBefore) const {
+  CXFA_Node* pField = CreateDraw(XFA_ELEMENT_Text, pParent, pBefore);
+  CreateCopyNode(XFA_ELEMENT_TextEdit, CreateCopyNode(XFA_ELEMENT_Ui, pField));
+  CreateFontNode(pField);
+  return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateDraw(XFA_ELEMENT eElement,
+                                            CXFA_Node* pParent,
+                                            CXFA_Node* pBefore) const {
+  CXFA_Node* pDraw = CreateFormItem(XFA_ELEMENT_Draw, pParent, pBefore);
+  CreateValueNode(eElement, pDraw);
+  return pDraw;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateSubform(CXFA_Node* pParent,
+                                               CXFA_Node* pBefore) const {
+  CXFA_Node* pSubform = CreateFormItem(XFA_ELEMENT_Subform, pParent, pBefore);
+  return pSubform;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateFormItem(XFA_ELEMENT eElement,
+                                                CXFA_Node* pParent,
+                                                CXFA_Node* pBefore) const {
+  CXFA_Node* pTemplateParent = pParent ? pParent->GetTemplateNode() : NULL;
+  CXFA_Node* pNewFormItem = pTemplateParent->CloneTemplateToForm(FALSE);
+  if (pParent)
+    pParent->InsertChild(pNewFormItem, pBefore);
+  return pNewFormItem;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateCopyNode(XFA_ELEMENT eElement,
+                                                CXFA_Node* pParent,
+                                                CXFA_Node* pBefore) const {
+  CXFA_Node* pTemplateParent = pParent ? pParent->GetTemplateNode() : NULL;
+  CXFA_Node* pNewNode =
+      CreateTemplateNode(eElement, pTemplateParent,
+                         pBefore ? pBefore->GetTemplateNode() : NULL)
+          ->Clone(FALSE);
+  if (pParent)
+    pParent->InsertChild(pNewNode, pBefore);
+  return pNewNode;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateTemplateNode(XFA_ELEMENT eElement,
+                                                    CXFA_Node* pParent,
+                                                    CXFA_Node* pBefore) const {
+  CXFA_Document* pXFADoc = GetXFADoc();
+  CXFA_Node* pNewTemplateNode = pXFADoc->GetParser()->GetFactory()->CreateNode(
+      XFA_XDPPACKET_Template, eElement);
+  if (pParent)
+    pParent->InsertChild(pNewTemplateNode, pBefore);
+  return pNewTemplateNode;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateFontNode(CXFA_Node* pParent) const {
+  CXFA_Node* pFont = CreateCopyNode(XFA_ELEMENT_Font, pParent);
+  pFont->SetCData(XFA_ATTRIBUTE_Typeface, FX_WSTRC(L"Myriad Pro"), FALSE);
+  return pFont;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateMarginNode(CXFA_Node* pParent,
+                                                  FX_DWORD dwFlags,
+                                                  FX_FLOAT fInsets[4]) const {
+  CXFA_Node* pMargin = CreateCopyNode(XFA_ELEMENT_Margin, pParent);
+  if (dwFlags & 0x01) {
+    pMargin->SetMeasure(XFA_ATTRIBUTE_LeftInset,
+                        CXFA_Measurement(fInsets[0], XFA_UNIT_Pt), FALSE);
+  }
+  if (dwFlags & 0x02) {
+    pMargin->SetMeasure(XFA_ATTRIBUTE_TopInset,
+                        CXFA_Measurement(fInsets[1], XFA_UNIT_Pt), FALSE);
+  }
+  if (dwFlags & 0x04) {
+    pMargin->SetMeasure(XFA_ATTRIBUTE_RightInset,
+                        CXFA_Measurement(fInsets[2], XFA_UNIT_Pt), FALSE);
+  }
+  if (dwFlags & 0x08) {
+    pMargin->SetMeasure(XFA_ATTRIBUTE_BottomInset,
+                        CXFA_Measurement(fInsets[3], XFA_UNIT_Pt), FALSE);
+  }
+  return pMargin;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateValueNode(XFA_ELEMENT eValue,
+                                                 CXFA_Node* pParent) const {
+  CXFA_Node* pValue = CreateCopyNode(XFA_ELEMENT_Value, pParent);
+  CreateCopyNode(eValue, pValue);
+  return pValue;
+}
+IXFA_ObjFactory* CXFA_FFWidgetHandler::GetObjFactory() const {
+  return GetXFADoc()->GetParser()->GetFactory();
+}
+CXFA_Document* CXFA_FFWidgetHandler::GetXFADoc() const {
+  return ((CXFA_FFDoc*)(m_pDocView->GetDoc()))->GetXFADoc();
+}
+CXFA_FFMenuHandler::CXFA_FFMenuHandler() {}
+CXFA_FFMenuHandler::~CXFA_FFMenuHandler() {}
+FX_BOOL CXFA_FFMenuHandler::CanCopy(IXFA_Widget* hWidget) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->CanCopy();
+}
+FX_BOOL CXFA_FFMenuHandler::CanCut(IXFA_Widget* hWidget) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->CanCut();
+}
+FX_BOOL CXFA_FFMenuHandler::CanPaste(IXFA_Widget* hWidget) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->CanPaste();
+}
+FX_BOOL CXFA_FFMenuHandler::CanSelectAll(IXFA_Widget* hWidget) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->CanSelectAll();
+}
+FX_BOOL CXFA_FFMenuHandler::CanDelete(IXFA_Widget* hWidget) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->CanDelete();
+}
+FX_BOOL CXFA_FFMenuHandler::CanDeSelect(IXFA_Widget* hWidget) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->CanDeSelect();
+}
+FX_BOOL CXFA_FFMenuHandler::Copy(IXFA_Widget* hWidget, CFX_WideString& wsText) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->Copy(wsText);
+}
+FX_BOOL CXFA_FFMenuHandler::Cut(IXFA_Widget* hWidget, CFX_WideString& wsText) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->Cut(wsText);
+}
+FX_BOOL CXFA_FFMenuHandler::Paste(IXFA_Widget* hWidget,
+                                  const CFX_WideString& wsText) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->Paste(wsText);
+}
+FX_BOOL CXFA_FFMenuHandler::SelectAll(IXFA_Widget* hWidget) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->SelectAll();
+}
+FX_BOOL CXFA_FFMenuHandler::Delete(IXFA_Widget* hWidget) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->Delete();
+}
+FX_BOOL CXFA_FFMenuHandler::DeSelect(IXFA_Widget* hWidget) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->DeSelect();
+}
+FX_BOOL CXFA_FFMenuHandler::CanUndo(IXFA_Widget* hWidget) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->CanUndo();
+}
+FX_BOOL CXFA_FFMenuHandler::CanRedo(IXFA_Widget* hWidget) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->CanRedo();
+}
+FX_BOOL CXFA_FFMenuHandler::Undo(IXFA_Widget* hWidget) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->Undo();
+}
+FX_BOOL CXFA_FFMenuHandler::Redo(IXFA_Widget* hWidget) {
+  return static_cast<CXFA_FFWidget*>(hWidget)->Redo();
+}
+FX_BOOL CXFA_FFMenuHandler::GetSuggestWords(
+    IXFA_Widget* hWidget,
+    CFX_PointF pointf,
+    std::vector<CFX_ByteString>& sSuggest) {
+  return static_cast<CXFA_FFWidget*>(hWidget)
+      ->GetSuggestWords(pointf, sSuggest);
+}
+FX_BOOL CXFA_FFMenuHandler::ReplaceSpellCheckWord(
+    IXFA_Widget* hWidget,
+    CFX_PointF pointf,
+    const CFX_ByteStringC& bsReplace) {
+  return static_cast<CXFA_FFWidget*>(hWidget)
+      ->ReplaceSpellCheckWord(pointf, bsReplace);
+}
diff --git a/xfa/fxfa/app/xfa_ffwidgethandler.h b/xfa/fxfa/app/xfa_ffwidgethandler.h
new file mode 100644
index 0000000..a9998b3
--- /dev/null
+++ b/xfa/fxfa/app/xfa_ffwidgethandler.h
@@ -0,0 +1,176 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FFWIDGETHANDLER_H_
+#define XFA_FXFA_APP_XFA_FFWIDGETHANDLER_H_
+
+#include <vector>
+
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/include/fxfa/fxfa.h"
+
+class CXFA_FFDocView;
+
+class CXFA_FFWidgetHandler : public IXFA_WidgetHandler {
+ public:
+  CXFA_FFWidgetHandler(CXFA_FFDocView* pDocView);
+  ~CXFA_FFWidgetHandler();
+  virtual IXFA_Widget* CreateWidget(IXFA_Widget* hParent,
+                                    XFA_WIDGETTYPE eType,
+                                    IXFA_Widget* hBefore = NULL);
+  virtual IXFA_PageView* GetPageView(IXFA_Widget* hWidget);
+  virtual void GetRect(IXFA_Widget* hWidget, CFX_RectF& rt);
+  virtual FX_DWORD GetStatus(IXFA_Widget* hWidget);
+  virtual FX_BOOL GetBBox(IXFA_Widget* hWidget,
+                          CFX_RectF& rtBox,
+                          FX_DWORD dwStatus,
+                          FX_BOOL bDrawFocus = FALSE);
+  virtual CXFA_WidgetAcc* GetDataAcc(IXFA_Widget* hWidget);
+  virtual void GetName(IXFA_Widget* hWidget,
+                       CFX_WideString& wsName,
+                       int32_t iNameType = 0);
+  virtual FX_BOOL GetToolTip(IXFA_Widget* hWidget, CFX_WideString& wsToolTip);
+  virtual void SetPrivateData(IXFA_Widget* hWidget,
+                              void* module_id,
+                              void* pData,
+                              PD_CALLBACK_FREEDATA callback);
+  virtual void* GetPrivateData(IXFA_Widget* hWidget, void* module_id);
+  virtual FX_BOOL OnMouseEnter(IXFA_Widget* hWidget);
+  virtual FX_BOOL OnMouseExit(IXFA_Widget* hWidget);
+  virtual FX_BOOL OnLButtonDown(IXFA_Widget* hWidget,
+                                FX_DWORD dwFlags,
+                                FX_FLOAT fx,
+                                FX_FLOAT fy);
+  virtual FX_BOOL OnLButtonUp(IXFA_Widget* hWidget,
+                              FX_DWORD dwFlags,
+                              FX_FLOAT fx,
+                              FX_FLOAT fy);
+  virtual FX_BOOL OnLButtonDblClk(IXFA_Widget* hWidget,
+                                  FX_DWORD dwFlags,
+                                  FX_FLOAT fx,
+                                  FX_FLOAT fy);
+  virtual FX_BOOL OnMouseMove(IXFA_Widget* hWidget,
+                              FX_DWORD dwFlags,
+                              FX_FLOAT fx,
+                              FX_FLOAT fy);
+  virtual FX_BOOL OnMouseWheel(IXFA_Widget* hWidget,
+                               FX_DWORD dwFlags,
+                               int16_t zDelta,
+                               FX_FLOAT fx,
+                               FX_FLOAT fy);
+  virtual FX_BOOL OnRButtonDown(IXFA_Widget* hWidget,
+                                FX_DWORD dwFlags,
+                                FX_FLOAT fx,
+                                FX_FLOAT fy);
+  virtual FX_BOOL OnRButtonUp(IXFA_Widget* hWidget,
+                              FX_DWORD dwFlags,
+                              FX_FLOAT fx,
+                              FX_FLOAT fy);
+  virtual FX_BOOL OnRButtonDblClk(IXFA_Widget* hWidget,
+                                  FX_DWORD dwFlags,
+                                  FX_FLOAT fx,
+                                  FX_FLOAT fy);
+
+  virtual FX_BOOL OnKeyDown(IXFA_Widget* hWidget,
+                            FX_DWORD dwKeyCode,
+                            FX_DWORD dwFlags);
+  virtual FX_BOOL OnKeyUp(IXFA_Widget* hWidget,
+                          FX_DWORD dwKeyCode,
+                          FX_DWORD dwFlags);
+  virtual FX_BOOL OnChar(IXFA_Widget* hWidget,
+                         FX_DWORD dwChar,
+                         FX_DWORD dwFlags);
+  virtual FX_DWORD OnHitTest(IXFA_Widget* hWidget, FX_FLOAT fx, FX_FLOAT fy);
+  virtual FX_BOOL OnSetCursor(IXFA_Widget* hWidget, FX_FLOAT fx, FX_FLOAT fy);
+  virtual void RenderWidget(IXFA_Widget* hWidget,
+                            CFX_Graphics* pGS,
+                            CFX_Matrix* pMatrix = NULL,
+                            FX_BOOL bHighlight = FALSE);
+  virtual FX_BOOL HasEvent(CXFA_WidgetAcc* pWidgetAcc,
+                           XFA_EVENTTYPE eEventType);
+  virtual int32_t ProcessEvent(CXFA_WidgetAcc* pWidgetAcc,
+                               CXFA_EventParam* pParam);
+
+ protected:
+  CXFA_Node* CreateWidgetFormItem(XFA_WIDGETTYPE eType,
+                                  CXFA_Node* pParent,
+                                  CXFA_Node* pBefore) const;
+
+  CXFA_Node* CreatePushButton(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreateCheckButton(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreateExclGroup(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreateRadioButton(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreateDatetimeEdit(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreateDecimalField(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreateNumericField(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreateSignature(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreateTextEdit(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreateDropdownList(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreateListBox(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreateImageField(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreatePasswordEdit(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreateField(XFA_ELEMENT eElement,
+                         CXFA_Node* pParent,
+                         CXFA_Node* pBefore) const;
+  CXFA_Node* CreateArc(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreateRectangle(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreateImage(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreateLine(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreateText(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreateDraw(XFA_ELEMENT eElement,
+                        CXFA_Node* pParent,
+                        CXFA_Node* pBefore) const;
+
+  CXFA_Node* CreateSubform(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+  CXFA_Node* CreateFormItem(XFA_ELEMENT eElement,
+                            CXFA_Node* pParent,
+                            CXFA_Node* pBefore) const;
+  CXFA_Node* CreateCopyNode(XFA_ELEMENT eElement,
+                            CXFA_Node* pParent,
+                            CXFA_Node* pBefore = NULL) const;
+  CXFA_Node* CreateTemplateNode(XFA_ELEMENT eElement,
+                                CXFA_Node* pParent,
+                                CXFA_Node* pBefore) const;
+  CXFA_Node* CreateFontNode(CXFA_Node* pParent) const;
+  CXFA_Node* CreateMarginNode(CXFA_Node* pParent,
+                              FX_DWORD dwFlags,
+                              FX_FLOAT fInsets[4]) const;
+  CXFA_Node* CreateValueNode(XFA_ELEMENT eValue, CXFA_Node* pParent) const;
+  IXFA_ObjFactory* GetObjFactory() const;
+  CXFA_Document* GetXFADoc() const;
+
+  CXFA_FFDocView* m_pDocView;
+};
+
+class CXFA_FFMenuHandler : public IXFA_MenuHandler {
+ public:
+  CXFA_FFMenuHandler();
+  ~CXFA_FFMenuHandler();
+  virtual FX_BOOL CanCopy(IXFA_Widget* hWidget);
+  virtual FX_BOOL CanCut(IXFA_Widget* hWidget);
+  virtual FX_BOOL CanPaste(IXFA_Widget* hWidget);
+  virtual FX_BOOL CanSelectAll(IXFA_Widget* hWidget);
+  virtual FX_BOOL CanDelete(IXFA_Widget* hWidget);
+  virtual FX_BOOL CanDeSelect(IXFA_Widget* hWidget);
+  virtual FX_BOOL Copy(IXFA_Widget* hWidget, CFX_WideString& wsText);
+  virtual FX_BOOL Cut(IXFA_Widget* hWidget, CFX_WideString& wsText);
+  virtual FX_BOOL Paste(IXFA_Widget* hWidget, const CFX_WideString& wsText);
+  virtual FX_BOOL SelectAll(IXFA_Widget* hWidget);
+  virtual FX_BOOL Delete(IXFA_Widget* hWidget);
+  virtual FX_BOOL DeSelect(IXFA_Widget* hWidget);
+  virtual FX_BOOL CanUndo(IXFA_Widget* hWidget);
+  virtual FX_BOOL CanRedo(IXFA_Widget* hWidget);
+  virtual FX_BOOL Undo(IXFA_Widget* hWidget);
+  virtual FX_BOOL Redo(IXFA_Widget* hWidget);
+  virtual FX_BOOL GetSuggestWords(IXFA_Widget* hWidget,
+                                  CFX_PointF pointf,
+                                  std::vector<CFX_ByteString>& sSuggest);
+  virtual FX_BOOL ReplaceSpellCheckWord(IXFA_Widget* hWidget,
+                                        CFX_PointF pointf,
+                                        const CFX_ByteStringC& bsReplace);
+};
+
+#endif  //  XFA_FXFA_APP_XFA_FFWIDGETHANDLER_H_
diff --git a/xfa/fxfa/app/xfa_fontmgr.cpp b/xfa/fxfa/app/xfa_fontmgr.cpp
new file mode 100644
index 0000000..dda8f5b
--- /dev/null
+++ b/xfa/fxfa/app/xfa_fontmgr.cpp
@@ -0,0 +1,2089 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_fontmgr.h"
+
+#include <algorithm>
+
+#include "core/include/fpdfapi/cpdf_dictionary.h"
+#include "core/include/fpdfapi/cpdf_document.h"
+#include "core/include/fpdfapi/fpdf_resource.h"
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+static const XFA_FONTINFO g_XFAFontsMap[] = {
+    {0x01d5d33e, L"SimSun", L"Arial", 0, 936},
+    {0x01e4f102, L"YouYuan", L"Arial", 1, 936},
+    {0x030549dc, L"LiSu", L"Arial", 1, 936},
+    {0x032edd44, L"Simhei", L"Arial", 1, 936},
+    {0x03eac6fc, L"PoorRichard-Regular", L"Arial", 2, 1252},
+    {0x03ed90e6, L"Nina", L"Arial", 0, 1252},
+    {0x077b56b3, L"KingsoftPhoneticPlain", L"Arial", 0, 1252},
+    {0x078ed524, L"MicrosoftSansSerif", L"Arial", 0, 1252},
+    {0x089b18a9, L"Arial", L"Arial", 0, 1252},
+    {0x0b2cad72, L"MonotypeCorsiva", L"Arial", 8, 1252},
+    {0x0bb003e7, L"Kartika", L"Arial", 2, 1252},
+    {0x0bb469df, L"VinerHandITC", L"Arial", 8, 1252},
+    {0x0bc1a851, L"SegoeUI", L"Arial", 0, 1252},
+    {0x0c112ebd, L"KozukaGothicPro-VIM", L"Arial", 0, 1252},
+    {0x0cfcb9c1, L"AdobeThai", L"Kokila,Arial Narrow", 0, 847},
+    {0x0e7de0f9, L"Playbill", L"Arial", 0, 1252},
+    {0x0eff47c3, L"STHupo", L"Arial", 0, 936},
+    {0x107ad374, L"Constantia", L"Arial", 2, 1252},
+    {0x12194c2d, L"KunstlerScript", L"Arial", 8, 1252},
+    {0x135ef6a1, L"MinionProSmBd",
+     L"Bell MT,Corbel,Times New Roman,Cambria,Berlin Sans FB", 0, 1252},
+    {0x158c4049, L"Garamond", L"Arial", 2, 1252},
+    {0x160ecb24, L"STZhongsong", L"Arial", 0, 936},
+    {0x161ed07e, L"MSGothic", L"Arial", 1, 1252},
+    {0x171d1ed1, L"SnapITC-Regular", L"Arial", 0, 1252},
+    {0x18d1188f, L"Cambria", L"Arial", 2, 1252},
+    {0x18eaf350, L"ArialUnicodeMS", L"Arial", 0, 936},
+    {0x1a92d115, L"MingLiU", L"Arial", 1, 1252},
+    {0x1cc217c6, L"TrebuchetMS", L"Arial", 0, 1252},
+    {0x1d649596, L"BasemicTimes", L"Arial", 0, 1252},
+    {0x1e34ee60, L"BellMT", L"Arial", 2, 1252},
+    {0x1eb36945, L"CooperBlack", L"Arial", 2, 1252},
+    {0x1ef7787d, L"BatangChe", L"Arial", 1, 1252},
+    {0x20b3bd3a, L"BrushScriptMT", L"Arial", 8, 1252},
+    {0x220877aa, L"Candara", L"Arial", 0, 1252},
+    {0x22135007, L"FreestyleScript-Regular", L"Arial", 8, 1252},
+    {0x251059c3, L"Chiller", L"Arial", 0, 1252},
+    {0x25bed6dd, L"MSReferenceSansSerif", L"Arial", 0, 1252},
+    {0x28154c81, L"Parchment-Regular", L"Arial", 8, 1252},
+    {0x29711eb9, L"STLiti", L"Arial", 0, 936},
+    {0x2b1993b4, L"Basemic", L"Arial", 0, 1252},
+    {0x2b316339, L"NiagaraSolid-Reg", L"Arial", 0, 1252},
+    {0x2c147529, L"FootlightMTLight", L"Arial", 0, 1252},
+    {0x2c198928, L"HarlowSolid", L"Arial", 0, 1252},
+    {0x2c6ac6b2, L"LucidaBright", L"Arial", 2, 1252},
+    {0x2c9f38e2, L"KozukaMinchoPro-VIR", L"Arial", 0, 1252},
+    {0x2d5a47b0, L"STCaiyun", L"Arial", 0, 936},
+    {0x2def26bf, L"BernardMT-Condensed", L"Arial", 0, 1252},
+    {0x2fd8930b, L"KozukaMinchoPr6NR", L"Arial", 0, 1252},
+    {0x3115525a, L"FangSong_GB2312", L"Arial", 0, 1252},
+    {0x31327817, L"MyriadPro",
+     L"Calibri,Corbel,Candara,Cambria Math,Franklin Gothic Medium,Arial "
+     L"Narrow,Times New Roman",
+     0, 1252},
+    {0x32244975, L"Helvetica", L"Arial", 0, 1252},
+    {0x32ac995c, L"Terminal", L"Arial", 0, 1252},
+    {0x338d648a, L"NiagaraEngraved-Reg", L"Arial", 0, 1252},
+    {0x33bb65f2, L"Sylfaen", L"Arial", 2, 1252},
+    {0x3402c30e, L"MSPMincho", L"Arial", 2, 1252},
+    {0x3412bf31, L"SimSun-PUA", L"Arial", 0, 936},
+    {0x36eb39b9, L"BerlinSansFB", L"Arial", 0, 1252},
+    {0x36f42055, L"UniversATT", L"Microsoft Sans Serif", 0, 1252},
+    {0x3864c4f6, L"HighTowerText", L"Arial", 2, 1252},
+    {0x3a257d03, L"FangSong_GB2312", L"Arial", 0, 1252},
+    {0x3cdae668, L"FreestyleScript", L"Arial", 8, 1252},
+    {0x3d55aed7, L"Jokerman", L"Arial", 0, 1252},
+    {0x3d5b4385, L"PMingLiU", L"Arial", 2, 1252},
+    {0x3d9b7669, L"EstrangeloEdessa", L"Arial", 0, 1252},
+    {0x3e532d74, L"FranklinGothicMedium", L"Arial", 0, 1252},
+    {0x3e6aa32d, L"NSimSun", L"Arial", 1, 936},
+    {0x3f6c36a8, L"Gautami", L"Arial", 0, 1252},
+    {0x3ff32662, L"Chiller-Regular", L"Arial", 0, 1252},
+    {0x409de312, L"ModernNo.20", L"Arial", 2, 1252},
+    {0x41443c5e, L"Georgia", L"Arial", 2, 1252},
+    {0x4160ade5, L"BellGothicStdBlack",
+     L"Arial,Arial Unicode MS,Book Antiqua,Dotum,Georgia", 0, 1252},
+    {0x421976c4, L"Modern-Regular", L"Arial", 2, 1252},
+    {0x422a7252, L"Stencil", L"Arial", 0, 1252},
+    {0x42c8554f, L"Fixedsys", L"Arial", 0, 1252},
+    {0x435cb41d, L"Roman", L"Arial", 0, 1252},
+    {0x47882383, L"CourierNew", L"Arial", 1, 1252},
+    {0x480a2338, L"BerlinSansFBDemi", L"Arial", 0, 1252},
+    {0x480bf7a4, L"CourierStd", L"Courier New,Verdana", 0, 1252},
+    {0x481ad6ed, L"VladimirScript", L"Arial", 8, 1252},
+    {0x4911577a, L"YouYuan", L"Arial", 1, 936},
+    {0x4a788d72, L"STXingkai", L"Arial", 0, 936},
+    {0x4bf88566, L"SegoeCondensed", L"Arial", 0, 1252},
+    {0x4ccf51a4, L"BerlinSansFB-Reg", L"Arial", 0, 1252},
+    {0x4ea967ce, L"GulimChe", L"Arial", 1, 1252},
+    {0x4f68bd79, L"LetterGothicStd", L"Courier New,Verdana", 0, 1252},
+    {0x51a0d0e6, L"KozukaGothicPr6NM", L"Arial", 0, 1252},
+    {0x531b3dea, L"BasemicSymbol", L"Arial", 0, 1252},
+    {0x5333fd39, L"CalifornianFB-Reg", L"Arial", 2, 1252},
+    {0x53561a54, L"FZYTK--GBK1-0", L"Arial", 0, 936},
+    {0x55e0dde6, L"LucidaSansTypewriter", L"Arial", 0, 1252},
+    {0x574d4d3d, L"AdobeArabic", L"Arial Narrow", 0, 1252},
+    {0x5792e759, L"STKaiti", L"Arial", 0, 936},
+    {0x5921978e, L"LucidaSansUnicode", L"Arial", 0, 1252},
+    {0x594e2da4, L"Vrinda", L"Arial", 0, 1252},
+    {0x59baa9a2, L"KaiTi_GB2312", L"Arial", 0, 1252},
+    {0x5cfedf4f, L"BaskOldFace", L"Arial", 0, 1252},
+    {0x5f97921c, L"AdobeMyungjoStdM",
+     L"Batang,Bookman Old Style,Consolas,STZhongsong", 0, 936},
+    {0x5fefbfad, L"Batang", L"Arial", 2, 1252},
+    {0x605342b9, L"DotumChe", L"Arial", 1, 1252},
+    {0x608c5f9a, L"KaiTi_GB2312", L"Arial", 0, 936},
+    {0x61efd0d1, L"MaturaMTScriptCapitals", L"Arial", 0, 1252},
+    {0x626608a9, L"MVBoli", L"Arial", 0, 1252},
+    {0x630501a3, L"SmallFonts", L"Arial", 0, 1252},
+    {0x65d0e2a9, L"FZYTK--GBK1-0", L"Arial", 0, 936},
+    {0x669f29e1, L"FZSTK--GBK1-0", L"Arial", 0, 936},
+    {0x673a9e5f, L"Tunga", L"Arial", 0, 1252},
+    {0x691aa4ce, L"NiagaraSolid", L"Arial", 0, 1252},
+    {0x696259b7, L"Corbel", L"Arial", 0, 1252},
+    {0x696ee9be, L"STXihei", L"Arial", 0, 936},
+    {0x6c59cf69, L"Dotum", L"Arial", 0, 1252},
+    {0x707fa561, L"Gungsuh", L"Arial", 2, 1252},
+    {0x71416bb2, L"ZWAdobeF", L"Arial", 0, 1252},
+    {0x71b41801, L"Verdana", L"Arial", 0, 1252},
+    {0x73f25e4c, L"PalatinoLinotype", L"Arial", 0, 1252},
+    {0x73f4d19f, L"NiagaraEngraved", L"Arial", 0, 1252},
+    {0x74001694, L"MyriadProBlack", L"Book Antiqua,Constantia,Dotum,Georgia", 0,
+     1252},
+    {0x74b14d8f, L"Haettenschweiler", L"Arial", 0, 1252},
+    {0x74cb44ee, L"NSimSun", L"Arial", 1, 936},
+    {0x76b4d7ff, L"Shruti", L"Arial", 0, 1252},
+    {0x788b3533, L"Webdings", L"Arial", 6, 42},
+    {0x797dde99, L"MSSerif", L"Arial", 0, 1252},
+    {0x7a0f9e9e, L"MSMincho", L"Arial", 1, 1252},
+    {0x7b439caf, L"OldEnglishTextMT", L"Arial", 0, 1252},
+    {0x8213a433, L"LucidaSans-Typewriter", L"Arial", 0, 1252},
+    {0x82fec929, L"AdobeSongStdL",
+     L"Centaur,Calibri,STSong,Bell MT,Garamond,Times New Roman", 0, 936},
+    {0x83581825, L"Modern", L"Arial", 0, 1252},
+    {0x835a2823, L"Algerian", L"Arial", 0, 1252},
+    {0x83dab9f5, L"Script", L"Arial", 0, 1252},
+    {0x847b56da, L"Tahoma", L"Arial", 0, 1252},
+    {0x8a783cb2, L"SimSun-PUA", L"Arial", 0, 1252},
+    {0x8b5cac0e, L"Onyx", L"Arial", 0, 1252},
+    {0x8c6a499e, L"Gulim", L"Arial", 0, 1252},
+    {0x8e0af790, L"JuiceITC", L"Arial", 0, 1252},
+    {0x8e8d43b2, L"Centaur", L"Arial", 2, 1252},
+    {0x8ee4dcca, L"BookshelfSymbol7", L"Arial", 0, 1252},
+    {0x90794800, L"BellGothicStdLight", L"Bell MT,Calibri,Times New Roman", 0,
+     1252},
+    {0x909b516a, L"Century", L"Arial", 2, 1252},
+    {0x92ae370d, L"MSOutlook", L"Arial", 4, 42},
+    {0x93c9fbf1, L"LucidaFax", L"Arial", 2, 1252},
+    {0x9565085e, L"BookAntiqua", L"Arial", 2, 1252},
+    {0x9856d95d, L"AdobeMingStdL", L"Arial,Arial Unicode MS,Cambria,BatangChe",
+     0, 949},
+    {0x9bbadd6b, L"ColonnaMT", L"Arial", 0, 1252},
+    {0x9cbd16a4, L"ShowcardGothic-Reg", L"Arial", 0, 1252},
+    {0x9d73008e, L"MSSansSerif", L"Arial", 0, 1252},
+    {0xa0607db1, L"GungsuhChe", L"Arial", 1, 1252},
+    {0xa0bcf6a1, L"LatinWide", L"Arial", 2, 1252},
+    {0xa1429b36, L"Symbol", L"Arial", 6, 42},
+    {0xa1fa5abc, L"Wingdings2", L"Arial", 6, 42},
+    {0xa1fa5abd, L"Wingdings3", L"Arial", 6, 42},
+    {0xa427bad4, L"InformalRoman-Regular", L"Arial", 8, 1252},
+    {0xa8b92ece, L"FZSTK--GBK1-0", L"Arial", 0, 936},
+    {0xa8d83ece, L"CalifornianFB", L"Arial", 2, 1252},
+    {0xaa3e082c, L"Kingsoft-Phonetic", L"Arial", 0, 1252},
+    {0xaa6bcabe, L"HarlowSolidItalic", L"Arial", 0, 1252},
+    {0xade5337c, L"MSUIGothic", L"Arial", 0, 1252},
+    {0xb08dd941, L"WideLatin", L"Arial", 2, 1252},
+    {0xb207f05d, L"PoorRichard", L"Arial", 2, 1252},
+    {0xb3bc492f, L"JuiceITC-Regular", L"Arial", 0, 1252},
+    {0xb5545399, L"Marlett", L"Arial", 4, 42},
+    {0xb5dd1ebb, L"BritannicBold", L"Arial", 0, 1252},
+    {0xb699c1c5, L"LucidaCalligraphy-Italic", L"Arial", 0, 1252},
+    {0xb725d629, L"TimesNewRoman", L"Arial", 2, 1252},
+    {0xb7eaebeb, L"AdobeHeitiStdR", L"Batang,Century,Dotum", 0, 936},
+    {0xbd29c486, L"BerlinSansFBDemi-Bold", L"Arial", 0, 1252},
+    {0xbe8a8db4, L"BookshelfSymbolSeven", L"Arial", 0, 1252},
+    {0xc16c0118, L"AdobeHebrew", L"Bell MT,Berlin Sans FB,Calibri", 0, 1252},
+    {0xc318b0af, L"MyriadProLight", L"Calibri,STFangsong,Times New Roman", 0,
+     1252},
+    {0xc65e5659, L"CambriaMath", L"Arial", 2, 1252},
+    {0xc75c8f05, L"LucidaConsole", L"Arial", 1, 1252},
+    {0xca7c35d6, L"Calibri", L"Arial", 0, 1252},
+    {0xcb053f53, L"MicrosoftYaHei", L"Arial", 0, 936},
+    {0xcb7190f9, L"Magneto-Bold", L"Arial", 0, 1252},
+    {0xcca00cc5, L"System", L"Arial", 0, 1252},
+    {0xccad6f76, L"Jokerman-Regular", L"Arial", 0, 1252},
+    {0xccc5818c, L"EuroSign", L"Arial", 0, 1252},
+    {0xcf3d7234, L"LucidaHandwriting-Italic", L"Arial", 0, 1252},
+    {0xcf7b8fdb, L"MinionPro",
+     L"Bell MT,Corbel,Times New Roman,Cambria,Berlin Sans FB", 0, 1252},
+    {0xcfe5755f, L"Simhei", L"Arial", 1, 936},
+    {0xd011f4ee, L"MSPGothic", L"Arial", 0, 1252},
+    {0xd060e7ef, L"Vivaldi", L"Arial", 8, 1252},
+    {0xd07edec1, L"FranklinGothic-Medium", L"Arial", 0, 1252},
+    {0xd107243f, L"SimSun", L"Arial", 0, 936},
+    {0xd1881562, L"ArialNarrow", L"Arial Narrow", 0, 1252},
+    {0xd22b7dce, L"BodoniMTPosterCompressed", L"Arial", 0, 1252},
+    {0xd22bfa60, L"ComicSansMS", L"Arial", 8, 1252},
+    {0xd3bd0e35, L"Bauhaus93", L"Arial", 0, 1252},
+    {0xd429ee7a, L"STFangsong", L"Arial", 0, 936},
+    {0xd6679c12, L"BernardMTCondensed", L"Arial", 0, 1252},
+    {0xd8e8a027, L"LucidaSans", L"Arial", 0, 1252},
+    {0xd9fe7761, L"HighTowerText-Reg", L"Arial", 2, 1252},
+    {0xda7e551e, L"STSong", L"Arial", 0, 936},
+    {0xdaa6842d, L"STZhongsong", L"Arial", 0, 936},
+    {0xdaaab93f, L"STFangsong", L"Arial", 0, 936},
+    {0xdaeb0713, L"STSong", L"Arial", 0, 936},
+    {0xdafedbef, L"STCaiyun", L"Arial", 0, 936},
+    {0xdb00a3d9, L"Broadway", L"Arial", 0, 1252},
+    {0xdb1f5ad4, L"STXinwei", L"Arial", 0, 936},
+    {0xdb326e7f, L"STKaiti", L"Arial", 0, 936},
+    {0xdb69595a, L"STHupo", L"Arial", 0, 936},
+    {0xdba0082c, L"STXihei", L"Arial", 0, 936},
+    {0xdbd0ab18, L"STXingkai", L"Arial", 0, 936},
+    {0xdc1a7db1, L"STLiti", L"Arial", 0, 936},
+    {0xdc33075f, L"KristenITC-Regular", L"Arial", 8, 1252},
+    {0xdcc7009c, L"Harrington", L"Arial", 0, 1252},
+    {0xdd712466, L"ArialBlack", L"Arial", 0, 1252},
+    {0xdde87b3e, L"Impact", L"Arial", 0, 1252},
+    {0xdf69fb32, L"SnapITC", L"Arial", 0, 1252},
+    {0xdf8b25e8, L"CenturyGothic", L"Arial", 0, 1252},
+    {0xe0f705c0, L"KristenITC", L"Arial", 8, 1252},
+    {0xe1427573, L"Raavi", L"Arial", 0, 1252},
+    {0xe2cea0cb, L"Magneto", L"Arial", 0, 1252},
+    {0xe36a9e17, L"Ravie", L"Arial", 0, 1252},
+    {0xe433f8e2, L"Parchment", L"Arial", 8, 1252},
+    {0xe43dff4a, L"Wingdings", L"Arial", 4, 42},
+    {0xe4e2c405, L"MTExtra", L"Arial", 6, 42},
+    {0xe618cc35, L"InformalRoman", L"Arial", 8, 1252},
+    {0xe6c27ffc, L"Mistral", L"Arial", 8, 1252},
+    {0xe7ebf4b9, L"Courier", L"Courier New", 0, 1252},
+    {0xe8bc4a9d, L"MSReferenceSpecialty", L"Arial", 0, 1252},
+    {0xe90fb013, L"TempusSansITC", L"Arial", 0, 1252},
+    {0xec637b42, L"Consolas", L"Verdana", 1, 1252},
+    {0xed3a683b, L"STXinwei", L"Arial", 0, 936},
+    {0xef264cd1, L"LucidaHandwriting", L"Arial", 0, 1252},
+    {0xf086bca2, L"BaskervilleOldFace", L"Arial", 0, 1252},
+    {0xf1028030, L"Mangal", L"Arial", 2, 1252},
+    {0xf1da7eb9, L"ShowcardGothic", L"Arial", 0, 1252},
+    {0xf210f06a, L"ArialMT", L"Arial", 0, 1252},
+    {0xf477f16a, L"Latha", L"Arial", 0, 1252},
+    {0xf616f3dd, L"LiSu", L"Arial", 1, 936},
+    {0xfa479aa6, L"MicrosoftYaHei", L"Arial", 0, 936},
+    {0xfcd19697, L"BookmanOldStyle", L"Arial", 0, 1252},
+    {0xfe209a82, L"LucidaCalligraphy", L"Arial", 0, 1252},
+    {0xfef135f8, L"AdobeHeitiStd-Regular", L"Batang,Century,Dotum", 0, 936},
+};
+#elif _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_
+static const XFA_FONTINFO g_XFAFontsMap[] = {
+    {0x01d5d33e, L"SimSun",
+     L"WenQuanYi Zen Hei Mono,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW,AR "
+     L"PL UMing TW MBE",
+     0, 936},
+    {0x01e4f102, L"YouYuan",
+     L"WenQuanYi Zen Hei Mono,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW,AR "
+     L"PL UMing TW MBE",
+     1, 936},
+    {0x030549dc, L"LiSu",
+     L"WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Zen Hei "
+     L"Mono,WenQuanYi Micro Hei",
+     1, 936},
+    {0x032edd44, L"Simhei",
+     L"WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Zen Hei "
+     L"Mono,WenQuanYi Micro Hei",
+     1, 936},
+    {0x03eac6fc, L"PoorRichard-Regular", L"Droid Sans Japanese,FreeSerif", 2,
+     1252},
+    {0x03ed90e6, L"Nina", L"FreeSerif", 0, 1252},
+    {0x077b56b3, L"KingsoftPhoneticPlain",
+     L"Tibetan Machine Uni,LKLUG,Samyak Gujarati,Droid Sans Thai,Droid Sans "
+     L"Armenian,Untitled1,utkal,Lohit Oriya",
+     0, 1252},
+    {0x078ed524, L"MicrosoftSansSerif",
+     L"Droid Sans Japanese,FreeSerif,WenQuanYi Micro Hei", 0, 1252},
+    {0x089b18a9, L"Arial",
+     L"Droid Sans Japanese,DejaVu Sans Condensed,FreeSerif,WenQuanYi Micro Hei",
+     0, 1252},
+    {0x0b2cad72, L"MonotypeCorsiva", L"Droid Sans Japanese,FreeSerif", 8, 1252},
+    {0x0bb003e7, L"Kartika",
+     L"FreeSans,Liberation Sans,Liberation Sans Narrow,Nimbus Sans "
+     L"L,Garuda,FreeSerif,WenQuanYi Micro Hei",
+     2, 1252},
+    {0x0bb469df, L"VinerHandITC",
+     L"Droid Sans Japanese,Ubuntu,Liberation Sans,Liberation Serif", 8, 1252},
+    {0x0bc1a851, L"SegoeUI", L"Droid Sans Japanese,DejaVu Sans", 0, 1252},
+    {0x0c112ebd, L"KozukaGothicPro-VIM", L"FreeSerif", 0, 1252},
+    {0x0cfcb9c1, L"AdobeThai", L"Droid Sans Japanese,Waree", 0, 847},
+    {0x0e7de0f9, L"Playbill",
+     L"KacstQurn,Droid Arabic Naskh,Droid Sans Ethiopic,mry_KacstQurn,Droid "
+     L"Sans Ethiopic,Droid Sans Japanese,FreeSerif",
+     0, 1252},
+    {0x0eff47c3, L"STHupo", L"AR PL UKai HK,AR PL UMing HK,AR PL UKai CN", 0,
+     936},
+    {0x107ad374, L"Constantia",
+     L"Droid Sans Japanese,FreeSerif,WenQuanYi Micro Hei,Ubuntu", 2, 1252},
+    {0x12194c2d, L"KunstlerScript", L"Droid Sans Japanese,Liberation Serif", 8,
+     1252},
+    {0x135ef6a1, L"MinionProSmBd", L"Liberation Serif", 0, 1252},
+    {0x158c4049, L"Garamond",
+     L"Droid Sans Japanese,Liberation Serif,Ubuntu,FreeSerif", 2, 1252},
+    {0x160ecb24, L"STZhongsong",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     0, 936},
+    {0x161ed07e, L"MSGothic",
+     L"WenQuanYi Micro Hei Mono,WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,AR PL "
+     L"UMing CN,AR PL UMing HK,AR PL UMing TW",
+     1, 1252},
+    {0x171d1ed1, L"SnapITC-Regular",
+     L"Liberation Sans Narrow,Ubuntu Condensed,Nimbus Sans L,DejaVu Sans", 0,
+     1252},
+    {0x18d1188f, L"Cambria", L"Droid Sans Japanese,FreeSerif,FreeMono", 2,
+     1252},
+    {0x18eaf350, L"ArialUnicodeMS",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     0, 936},
+    {0x1a92d115, L"MingLiU",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     1, 1252},
+    {0x1cc217c6, L"TrebuchetMS",
+     L"Droid Sans Japanese,Liberation Serif,FreeSerif,Ubuntu", 0, 1252},
+    {0x1d649596, L"BasemicTimes",
+     L"Liberation Serif,Times New Roman,Droid Sans Japanese,FreeSerif,Ubuntu",
+     0, 1252},
+    {0x1e34ee60, L"BellMT",
+     L"KacstQurn,Droid Sans Japanese,Ubuntu,Liberation Serif", 2, 1252},
+    {0x1eb36945, L"CooperBlack",
+     L"KacstQurn,Droid Sans Japanese,FreeMono,Liberation Mono, WenQuanYi Micro "
+     L"Hei Mono",
+     2, 1252},
+    {0x1ef7787d, L"BatangChe",
+     L"WenQuanYi Zen Hei Mono,AR PL UMing CN,AR PL UMing HK,AR PL UMing "
+     L"TW,WenQuanYi Zen Hei,WenQuanYi Micro Hei",
+     1, 1252},
+    {0x20b3bd3a, L"BrushScriptMT",
+     L"KacstQurn,Droid Arabic Naskh,Droid Sans Ethiopic,Droid Sans "
+     L"Japanese,URW Chancery L,Liberation Sans",
+     8, 1252},
+    {0x220877aa, L"Candara", L"Droid Sans Japanese,DejaVu Sans", 0, 1252},
+    {0x22135007, L"FreestyleScript-Regular",
+     L"KacstQurn,Droid Sans Japanese,Liberation Sans", 8, 1252},
+    {0x251059c3, L"Chiller",
+     L"KacstQurn,Droid Arabic Naskh,Droid Sans Ethiopic,Droid Sans "
+     L"Japanese,Liberation Sans",
+     0, 1252},
+    {0x25bed6dd, L"MSReferenceSansSerif",
+     L"DejaVu Sans Condensed,Ubuntu Condensed,Droid Sans Japanese,AR PL UKai "
+     L"HK",
+     0, 1252},
+    {0x28154c81, L"Parchment-Regular", L"Droid Sans Japanese,Liberation Sans",
+     8, 1252},
+    {0x29711eb9, L"STLiti", L"AR PL UKai HK", 0, 936},
+    {0x2b1993b4, L"Basemic",
+     L"Liberation Serif,Droid Sans Japanese,Liberation Sans", 0, 1252},
+    {0x2b316339, L"NiagaraSolid-Reg", L"Droid Sans Japanese,Liberation Sans", 0,
+     1252},
+    {0x2c147529, L"FootlightMTLight",
+     L"KacstQurn,Droid Sans Japanese,Liberation Sans", 0, 1252},
+    {0x2c198928, L"HarlowSolid",
+     L"KacstQurn,Droid Sans Japanese,Liberation Sans", 0, 1252},
+    {0x2c6ac6b2, L"LucidaBright",
+     L"KacstQurn,Droid Arabic Naskh,Droid Sans Ethiopic,mry_KacstQurn,Droid "
+     L"Sans Japanese,Liberation Sans",
+     2, 1252},
+    {0x2c9f38e2, L"KozukaMinchoPro-VIR", L"DejaVu Sans", 0, 1252},
+    {0x2d5a47b0, L"STCaiyun", L"AR PL UKai HK", 0, 936},
+    {0x2def26bf, L"BernardMT-Condensed",
+     L"KacstQurn,Droid Sans Japanese,DejaVu Serif", 0, 1252},
+    {0x2fd8930b, L"KozukaMinchoPr6NR", L"DejaVu Serif", 0, 1252},
+    {0x3115525a, L"FangSong_GB2312",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     0, 1252},
+    {0x31327817, L"MyriadPro",
+     L"Ubuntu Condensed,Droid Sans Japanese, FreeSerif", 0, 1252},
+    {0x32244975, L"Helvetica",
+     L"Ubuntu,DejaVu Sans Condensed,Liberation Sans,Liberation Sans "
+     L"Narrow,Nimbus Sans L",
+     0, 1252},
+    {0x32ac995c, L"Terminal", L"DejaVu Serif", 0, 1252},
+    {0x338d648a, L"NiagaraEngraved-Reg", L"Droid Sans Japanese,DejaVu Serif", 0,
+     1252},
+    {0x33bb65f2, L"Sylfaen", L"Droid Sans Japanese,DejaVu Sans", 2, 1252},
+    {0x3402c30e, L"MSPMincho",
+     L"WenQuanYi Zen Hei Mono,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW", 2,
+     1252},
+    {0x3412bf31, L"SimSun-PUA",
+     L"WenQuanYi Zen Hei Mono,AR PL UMing CN,AR PL UMing CN,AR PL UMing HK", 0,
+     936},
+    {0x36eb39b9, L"BerlinSansFB",
+     L"Droid Sans Japanese,Liberation Serif,Ubuntu,FreeSerif", 0, 1252},
+    {0x36f42055, L"UniversATT", L"Microsoft Sans Serif", 0, 1252},
+    {0x3864c4f6, L"HighTowerText", L"Droid Sans Japanese,DejaVu Serif", 2,
+     1252},
+    {0x3a257d03, L"FangSong_GB2312",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei", 0, 1252},
+    {0x3c7d1d07, L"Garamond3LTStd",
+     L"Droid Sans Japanese,Ubuntu Condensed,DejaVu Sans Condensed,Liberation "
+     L"Serif,Ubuntu,FreeSerif",
+     2, 1252},
+    {0x3cdae668, L"FreestyleScript",
+     L"KacstQurn,Droid Sans Japanese,DejaVu Sans", 8, 1252},
+    {0x3d55aed7, L"Jokerman", L"Droid Sans Japanese,DejaVu Sans", 0, 1252},
+    {0x3d5b4385, L"PMingLiU",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     2, 1252},
+    {0x3d9b7669, L"EstrangeloEdessa", L"Droid Sans Japanese,DejaVu Sans", 0,
+     1252},
+    {0x3e532d74, L"FranklinGothicMedium", L"Droid Sans Japanese,Ubuntu", 0,
+     1252},
+    {0x3e6aa32d, L"NSimSun",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     1, 936},
+    {0x3f6c36a8, L"Gautami",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic, mry_KacstQurn,Droid Sans "
+     L"Japanese,FreeSans",
+     0, 1252},
+    {0x3ff32662, L"Chiller-Regular",
+     L"KacstQurn,Droid Arabic Naskh,Droid Sans Ethiopic,FreeSans", 0, 1252},
+    {0x409de312, L"ModernNo.20",
+     L"KacstQurn,Droid Sans Japanese,Nimbus Sans L,Nimbus Sans L,FreeSans", 2,
+     1252},
+    {0x41443c5e, L"Georgia", L"Droid Sans Japanese,FreeSans", 2, 1252},
+    {0x4160ade5, L"BellGothicStdBlack", L"FreeSans", 0, 1252},
+    {0x421976c4, L"Modern-Regular", L"FreeSans", 2, 1252},
+    {0x422a7252, L"Stencil", L"Droid Sans Japanese,FreeSans,Liberation Sans", 0,
+     1252},
+    {0x42c8554f, L"Fixedsys", L"FreeSerif", 0, 1252},
+    {0x435cb41d, L"Roman", L"FreeSerif", 0, 1252},
+    {0x47882383, L"CourierNew",
+     L"FreeMono,WenQuanYi Micro Hei Mono,AR PL UKai CN,AR PL UKai HK,AR PL "
+     L"UKai TW,AR PL UKai TW MBE,DejaVu Sans",
+     1, 1252},
+    {0x480a2338, L"BerlinSansFBDemi", L"Droid Sans Japanese,Liberation Serif",
+     0, 1252},
+    {0x480bf7a4, L"CourierStd", L"DejaVu Sans", 0, 1252},
+    {0x481ad6ed, L"VladimirScript", L"Droid Sans Japanese,DejaVu Serif", 8,
+     1252},
+    {0x4911577a, L"YouYuan",
+     L"WenQuanYi Zen Hei Mono,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW", 1,
+     936},
+    {0x4a788d72, L"STXingkai", L"AR PL UKai HK,AR PL UMing HK,AR PL UKai CN", 0,
+     936},
+    {0x4bf88566, L"SegoeCondensed", L"FreeSerif", 0, 1252},
+    {0x4ccf51a4, L"BerlinSansFB-Reg", L"Droid Sans Japanese,Liberation Serif",
+     0, 1252},
+    {0x4ea967ce, L"GulimChe",
+     L"WenQuanYi Zen Hei Mono,AR PL UKai CN,AR PL UKai HK,AR PL UKai TW,AR PL "
+     L"UKai TW MBE",
+     1, 1252},
+    {0x4f68bd79, L"LetterGothicStd",
+     L"FreeMono,Liberation Mono,Andale Mono,WenQuanYi Micro Hei Mono", 0, 1252},
+    {0x51a0d0e6, L"KozukaGothicPr6NM", L"FreeSerif", 0, 1252},
+    {0x531b3dea, L"BasemicSymbol", L"FreeSerif", 0, 1252},
+    {0x5333fd39, L"CalifornianFB-Reg",
+     L"Droid Sans Japanese,URW Chancery L,FreeSerif", 2, 1252},
+    {0x53561a54, L"FZYTK--GBK1-0",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     0, 936},
+    {0x55e0dde6, L"LucidaSansTypewriter",
+     L"Ubuntu Mono,DejaVu Sans Mono,Nimbus Mono L,Liberation Mono,Courier 10 "
+     L"Pitch,FreeMono",
+     0, 1252},
+    {0x574d4d3d, L"AdobeArabic", L"Droid Sans Japanese,DejaVu Sans", 0, 1252},
+    {0x5792e759, L"STKaiti", L"WenQuanYi Micro Hei Mono", 0, 936},
+    {0x5921978e, L"LucidaSansUnicode", L"Droid Sans Japanese,DejaVu Sans", 0,
+     1252},
+    {0x594e2da4, L"Vrinda",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Arabic "
+     L"Naskh,mry_KacstQurn,Droid Sans Japanese,FreeSans,FreeSerif",
+     0, 1252},
+    {0x59baa9a2, L"KaiTi_GB2312",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     0, 1252},
+    {0x5cfedf4f, L"BaskOldFace",
+     L"KacstQurn,Droid Sans Japanese,Ubuntu,Liberation Serif", 0, 1252},
+    {0x5e16ac91, L"TrajanPro",
+     L"Nimbus Sans L,AR PL UMing HK,AR PL UKai HK,AR PL UMing TW,AR PL UMing "
+     L"TW MBE,DejaVu Sans,DejaVu Serif",
+     0, 1252},
+    {0x5f388196, L"ITCLegacySansStdMedium",
+     L"Liberation Serif,FreeSerif,FreeSans,Ubuntu", 0, 1252},
+    {0x5f97921c, L"AdobeMyungjoStdM",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     0, 936},
+    {0x5fefbfad, L"Batang",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     2, 1252},
+    {0x605342b9, L"DotumChe",
+     L"WenQuanYi Zen Hei Mono,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW", 1,
+     1252},
+    {0x608c5f9a, L"KaiTi_GB2312",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     0, 936},
+    {0x61efd0d1, L"MaturaMTScriptCapitals",
+     L"KacstQurn,Droid Arabic Naskh,Droid Sans Ethiopic,mry_KacstQurn,Droid "
+     L"Sans Japanese,DejaVu Serif,DejaVu Sans",
+     0, 1252},
+    {0x626608a9, L"MVBoli",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,mry_KacstQurn,Droid Sans "
+     L"Ethiopic,Droid Sans Japanese,DejaVu Sans",
+     0, 1252},
+    {0x630501a3, L"SmallFonts", L"DejaVu Serif", 0, 1252},
+    {0x65d0e2a9, L"FZYTK--GBK1-0",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     0, 936},
+    {0x669f29e1, L"FZSTK--GBK1-0",
+     L"AR PL UMing CN,AR PL UKai CN, AR PL UMing HK", 0, 936},
+    {0x673a9e5f, L"Tunga",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,mry_KacstQurn,Droid Sans "
+     L"Japanese,DejaVu Serif",
+     0, 1252},
+    {0x691aa4ce, L"NiagaraSolid", L"Droid Sans Japanese,DejaVu Serif", 0, 1252},
+    {0x696259b7, L"Corbel", L"Droid Sans Japanese,DejaVu Sans", 0, 1252},
+    {0x696ee9be, L"STXihei", L"WenQuanYi Micro Hei Mono", 0, 936},
+    {0x6c59cf69, L"Dotum", L"WenQuanYi Zen Hei Mono", 0, 1252},
+    {0x707fa561, L"Gungsuh", L"WenQuanYi Zen Hei Mono", 2, 1252},
+    {0x71416bb2, L"ZWAdobeF",
+     L"KacstArt,KacstBookm,KacstDecorative,KacstDigital,KacstFarsi,KacstLetter,"
+     L"KacstOffice,Dingbats,FreeSerif",
+     0, 1252},
+    {0x71b41801, L"Verdana",
+     L"DejaVu Sans Condensed,Ubuntu Condensed,Droid Sans Japanese,DejaVu Sans",
+     0, 1252},
+    {0x73f25e4c, L"PalatinoLinotype", L"Droid Sans Japanese,FreeSerif", 0,
+     1252},
+    {0x73f4d19f, L"NiagaraEngraved", L"Droid Sans Japanese,FreeSerif", 0, 1252},
+    {0x74001694, L"MyriadProBlack", L"Droid Sans Japanese,AR PL UKai HK", 0,
+     1252},
+    {0x74b14d8f, L"Haettenschweiler", L"Droid Sans Japanese,DejaVu Serif", 0,
+     1252},
+    {0x74cb44ee, L"NSimSun", L"WenQuanYi Zen Hei Mono", 1, 936},
+    {0x76b4d7ff, L"Shruti",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,mry_KacstQurn,Droid Sans "
+     L"Japanese,FreeSans",
+     0, 1252},
+    {0x788b3533, L"Webdings", L"FreeSans", 6, 42},
+    {0x797dde99, L"MSSerif", L"FreeSans", 0, 1252},
+    {0x7a0f9e9e, L"MSMincho",
+     L"WenQuanYi Micro Hei Mono,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW",
+     1, 1252},
+    {0x7b439caf, L"OldEnglishTextMT",
+     L"Droid Sans Japanese,Liberation Sans,Ubuntu", 0, 1252},
+    {0x8213a433, L"LucidaSans-Typewriter",
+     L"Ubuntu Mono,Liberation Mono,DejaVu Sans Mono", 0, 1252},
+    {0x82fec929, L"AdobeSongStdL",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     0, 936},
+    {0x83581825, L"Modern", L"FreeSans", 0, 1252},
+    {0x835a2823, L"Algerian",
+     L"KacstQurn,Droid Sans Japanese,FreeSans,Liberation Sans,Ubuntu", 0, 1252},
+    {0x83dab9f5, L"Script", L"FreeSans", 0, 1252},
+    {0x847b56da, L"Tahoma",
+     L"Droid Sans Japanese,DejaVu Sans Condensed,FreeSerif", 0, 1252},
+    {0x8a783cb2, L"SimSun-PUA",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     0, 1252},
+    {0x8b5cac0e, L"Onyx", L"Droid Sans Japanese,Liberation Sans", 0, 1252},
+    {0x8c6a499e, L"Gulim",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     0, 1252},
+    {0x8e0af790, L"JuiceITC", L"Droid Sans Japanese,Liberation Sans", 0, 1252},
+    {0x8e8d43b2, L"Centaur",
+     L"KacstQurn,Droid Sans Japanese,Khmer OS,Khmer OS System", 2, 1252},
+    {0x8ee4dcca, L"BookshelfSymbol7", L"Liberation Sans", 0, 1252},
+    {0x90794800, L"BellGothicStdLight", L"Liberation Sans", 0, 1252},
+    {0x909b516a, L"Century",
+     L"Droid Sans Japanese,Liberation Sans,Liberation Mono,Liberation Serif", 2,
+     1252},
+    {0x92ae370d, L"MSOutlook", L"Liberation Sans", 4, 42},
+    {0x93c9fbf1, L"LucidaFax",
+     L"KacstQurn,Droid Arabic Naskh,Droid Sans "
+     L"Ethiopic,mry_KacstQurn,Liberation Sans",
+     2, 1252},
+    {0x9565085e, L"BookAntiqua",
+     L"Droid Sans Japanese,Liberation Sans,Liberation Serif", 2, 1252},
+    {0x9856d95d, L"AdobeMingStdL", L"AR PL UMing HK", 0, 949},
+    {0x9bbadd6b, L"ColonnaMT",
+     L"KacstQurn,Droid Sans Japanese,Khmer OS,Khmer OS System", 0, 1252},
+    {0x9cbd16a4, L"ShowcardGothic-Reg",
+     L"Droid Sans Japanese,Liberation Sans,Ubuntu", 0, 1252},
+    {0x9d73008e, L"MSSansSerif", L"FreeSerif", 0, 1252},
+    {0xa0607db1, L"GungsuhChe",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     1, 1252},
+    {0xa0bcf6a1, L"LatinWide", L"FreeSerif", 2, 1252},
+    {0xa1429b36, L"Symbol", L"FreeSerif", 6, 42},
+    {0xa1fa5abc, L"Wingdings2", L"FreeSerif", 6, 42},
+    {0xa1fa5abd, L"Wingdings3", L"FreeSerif", 6, 42},
+    {0xa427bad4, L"InformalRoman-Regular",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,mry_KacstQurn,Droid Sans "
+     L"Japanese,FreeSerif",
+     8, 1252},
+    {0xa8b92ece, L"FZSTK--GBK1-0", L"AR PL UMing CN", 0, 936},
+    {0xa8d83ece, L"CalifornianFB", L"Droid Sans Japanese,FreeSerif", 2, 1252},
+    {0xaa3e082c, L"Kingsoft-Phonetic",
+     L"Tibetan Machine Uni,LKLUG,Samyak Gujarati,Droid Sans "
+     L"Thai,utkal,Kedage,Mallige,AR PL UKai CN",
+     0, 1252},
+    {0xaa6bcabe, L"HarlowSolidItalic",
+     L"KacstQurn,Droid Sans Japanese,Liberation Serif", 0, 1252},
+    {0xade5337c, L"MSUIGothic",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     0, 1252},
+    {0xb08dd941, L"WideLatin",
+     L"KacstQurn,Droid Arabic Naskh,Droid Sans Ethiopic,mry_KacstQurn,Droid "
+     L"Sans Japanese,Liberation Serif",
+     2, 1252},
+    {0xb12765e0, L"ITCLegacySansStdBook",
+     L"AR PL UMing HK,AR PL UKai HK,FreeSerif,Ubuntu,FreeSans", 0, 1252},
+    {0xb207f05d, L"PoorRichard", L"Droid Sans Japanese,Liberation Serif", 2,
+     1252},
+    {0xb3bc492f, L"JuiceITC-Regular", L"Droid Sans Japanese,Liberation Serif",
+     0, 1252},
+    {0xb5545399, L"Marlett", L"Liberation Serif", 4, 42},
+    {0xb5dd1ebb, L"BritannicBold",
+     L"KacstQurn,Droid Arabic Naskh,Droid Sans "
+     L"Ethiopic,mry_KacstQurn,Liberation Serif",
+     0, 1252},
+    {0xb699c1c5, L"LucidaCalligraphy-Italic",
+     L"KacstQurn,Droid Arabic Naskh,Droid Sans Ethiopic,mry_KacstQurn,Droid "
+     L"Sans Japanese,DejaVu Serif",
+     0, 1252},
+    {0xb725d629, L"TimesNewRoman", L"Droid Sans Japanese,Liberation Sans", 2,
+     1252},
+    {0xb7eaebeb, L"AdobeHeitiStdR",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     0, 936},
+    {0xbd29c486, L"BerlinSansFBDemi-Bold", L"Droid Sans Japanese,DejaVu Serif",
+     0, 1252},
+    {0xbe8a8db4, L"BookshelfSymbolSeven", L"DejaVu Sans", 0, 1252},
+    {0xc16c0118, L"AdobeHebrew", L"Droid Sans Japanese,Ubuntu,Liberation Serif",
+     0, 1252},
+    {0xc318b0af, L"MyriadProLight",
+     L"Droid Sans Japanese,AR PL UKai HK,AR PL UMing HK,AR PL UKai CN", 0,
+     1252},
+    {0xc65e5659, L"CambriaMath", L"Droid Sans Japanese,FreeSerif,FreeMono", 2,
+     1252},
+    {0xc75c8f05, L"LucidaConsole",
+     L"Liberation Mono,DejaVu Sans Mono,FreeMono,WenQuanYi Micro Hei Mono", 1,
+     1252},
+    {0xca7c35d6, L"Calibri", L"Droid Sans Japanese,DejaVu Sans", 0, 1252},
+    {0xcb053f53, L"MicrosoftYaHei",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     0, 936},
+    {0xcb7190f9, L"Magneto-Bold",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,mry_KacstQurn,Droid Sans "
+     L"Japanese,DejaVu Serif",
+     0, 1252},
+    {0xcca00cc5, L"System", L"DejaVu Sans", 0, 1252},
+    {0xccad6f76, L"Jokerman-Regular", L"Droid Sans Japanese,DejaVu Sans", 0,
+     1252},
+    {0xccc5818c, L"EuroSign", L"DejaVu Serif", 0, 1252},
+    {0xcf3d7234, L"LucidaHandwriting-Italic",
+     L"Liberation Sans Narrow,Ubuntu Condensed,Nimbus Sans L,DejaVu Serif", 0,
+     1252},
+    {0xcf7b8fdb, L"MinionPro", L"DejaVu Sans", 0, 1252},
+    {0xcfe5755f, L"Simhei",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     1, 936},
+    {0xd011f4ee, L"MSPGothic",
+     L"WenQuanYi Zen Hei Mono,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW", 0,
+     1252},
+    {0xd060e7ef, L"Vivaldi",
+     L"KacstQurn,Droid Sans Japanese,Liberation Sans,Ubuntu", 8, 1252},
+    {0xd07edec1, L"FranklinGothic-Medium", L"Droid Sans Japanese,Ubuntu", 0,
+     1252},
+    {0xd107243f, L"SimSun", L"WenQuanYi Zen Hei Mono", 0, 936},
+    {0xd1881562, L"ArialNarrow",
+     L"Liberation Sans Narrow,Droid Sans Japanese,FreeSerif", 0, 1252},
+    {0xd22b7dce, L"BodoniMTPosterCompressed",
+     L"Droid Sans Japanese,DejaVu Serif", 0, 1252},
+    {0xd22bfa60, L"ComicSansMS",
+     L"Droid Sans Japanese,FreeMono,Liberation Mono", 8, 1252},
+    {0xd3bd0e35, L"Bauhaus93",
+     L"KacstQurn,Droid Sans Japanese,Liberation Sans,Ubuntu", 0, 1252},
+    {0xd429ee7a, L"STFangsong", L"WenQuanYi Micro Hei Mono", 0, 936},
+    {0xd6679c12, L"BernardMTCondensed",
+     L"KacstQurn,Droid Sans Japanese,Nimbus Sans L,URW Chancery "
+     L"L,KacstOne,Liberation Sans",
+     0, 1252},
+    {0xd8e8a027, L"LucidaSans",
+     L"Liberation Sans Narrow,Nimbus Sans L,KacstQurn,Droid Arabic Naskh,Droid "
+     L"Sans Ethiopic,DejaVu Serif Condensed,Liberation Mono,Ubuntu",
+     0, 1252},
+    {0xd9fe7761, L"HighTowerText-Reg",
+     L"Droid Sans Japanese,Ubuntu,Liberation Serif", 2, 1252},
+    {0xda7e551e, L"STSong", L"WenQuanYi Micro Hei Mono", 0, 936},
+    {0xdaa6842d, L"STZhongsong",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     0, 936},
+    {0xdaaab93f, L"STFangsong",
+     L"WenQuanYi Micro Hei Mono,WenQuanYi Zen Hei Mono,WenQuanYi Zen "
+     L"Hei,WenQuanYi Zen Hei Sharp",
+     0, 936},
+    {0xdaeb0713, L"STSong",
+     L"WenQuanYi Micro Hei Mono,WenQuanYi Zen Hei Mono,WenQuanYi Zen "
+     L"Hei,WenQuanYi Zen Hei Sharp",
+     0, 936},
+    {0xdafedbef, L"STCaiyun", L"AR PL UKai HK,AR PL UMing HK,AR PL UKai CN", 0,
+     936},
+    {0xdb00a3d9, L"Broadway",
+     L"KacstQurn,Droid Sans Japanese,DejaVu Sans,FreeMono,Liberation Mono", 0,
+     1252},
+    {0xdb1f5ad4, L"STXinwei", L"AR PL UKai HK,AR PL UMing HK,AR PL UKai CN", 0,
+     936},
+    {0xdb326e7f, L"STKaiti",
+     L"WenQuanYi Micro Hei Mono,WenQuanYi Zen Hei Mono,WenQuanYi Zen "
+     L"Hei,WenQuanYi Zen Hei Sharp",
+     0, 936},
+    {0xdb69595a, L"STHupo",
+     L"WenQuanYi Micro Hei Mono,WenQuanYi Zen Hei Mono,WenQuanYi Zen "
+     L"Hei,WenQuanYi Zen Hei Sharp",
+     0, 936},
+    {0xdba0082c, L"STXihei",
+     L" WenQuanYi Micro Hei Mono,WenQuanYi Zen Hei Mono,WenQuanYi Zen "
+     L"Hei,WenQuanYi Zen Hei Sharp",
+     0, 936},
+    {0xdbd0ab18, L"STXingkai", L"AR PL UKai HK,AR PL UMing HK,AR PL UKai CN", 0,
+     936},
+    {0xdc1a7db1, L"STLiti", L"AR PL UKai HK,AR PL UMing HK,AR PL UKai CN", 0,
+     936},
+    {0xdc33075f, L"KristenITC-Regular",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,mry_KacstQurn,DejaVu Sans "
+     L"Condensed,Ubuntu,Liberation Sans",
+     8, 1252},
+    {0xdcc7009c, L"Harrington",
+     L"KacstQurn,Droid Sans Japanese,Liberation Serif,FreeSerif,Ubuntu", 0,
+     1252},
+    {0xdd712466, L"ArialBlack",
+     L"Droid Sans Japanese,DejaVu Sans,DejaVu Serif,FreeMono", 0, 1252},
+    {0xdde87b3e, L"Impact", L"Droid Sans Japanese,DejaVu Serif", 0, 1252},
+    {0xdf69fb32, L"SnapITC",
+     L"Liberation Sans Narrow,Ubuntu Condensed,DejaVu Sans,DejaVu "
+     L"Serif,FreeMono",
+     0, 1252},
+    {0xdf8b25e8, L"CenturyGothic",
+     L"Droid Sans Japanese,Liberation Mono,Liberation Sans,Liberation Serif", 0,
+     1252},
+    {0xe0f705c0, L"KristenITC",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,mry_KacstQurn,DejaVu Sans "
+     L"Condensed,Ubuntu,Liberation Sans",
+     8, 1252},
+    {0xe1427573, L"Raavi",
+     L"Droid Arabic Naskh,Droid Sans "
+     L"Ethiopic,mry_KacstQurn,FreeSerif,Liberation Serif,Khmer OS",
+     0, 1252},
+    {0xe2cea0cb, L"Magneto",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,mry_KacstQurn,DejaVu "
+     L"Serif,DejaVu Serif Condensed,DejaVu Sans",
+     0, 1252},
+    {0xe36a9e17, L"Ravie",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,mry_KacstQurn,DejaVu "
+     L"Serif,DejaVu Sans,FreeMono",
+     0, 1252},
+    {0xe433f8e2, L"Parchment", L"Droid Sans Japanese,DejaVu Serif", 8, 1252},
+    {0xe43dff4a, L"Wingdings", L"DejaVu Serif", 4, 42},
+    {0xe4e2c405, L"MTExtra", L"DejaVu Serif", 6, 42},
+    {0xe618cc35, L"InformalRoman",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,mry_KacstQurn,Droid Sans "
+     L"Japanese,Nimbus Sans L,DejaVu Sans Condensed,Ubuntu,Liberation Sans",
+     8, 1252},
+    {0xe6c27ffc, L"Mistral", L"Droid Sans Japanese,DejaVu Serif", 8, 1252},
+    {0xe7ebf4b9, L"Courier", L"DejaVu Sans,DejaVu Sans Condensed,FreeSerif", 0,
+     1252},
+    {0xe8bc4a9d, L"MSReferenceSpecialty", L"DejaVu Serif", 0, 1252},
+    {0xe90fb013, L"TempusSansITC",
+     L"Droid Sans Japanese,Ubuntu,Liberation Serif,FreeSerif", 0, 1252},
+    {0xec637b42, L"Consolas",
+     L"DejaVu Sans Condensed,AR PL UKai CN,AR PL UKai HK,AR PL UKai "
+     L"TW,FreeSerif,FreeSans",
+     1, 1252},
+    {0xed3a683b, L"STXinwei", L"AR PL UKai HK,AR PL UMing HK,AR PL UKai CN", 0,
+     936},
+    {0xef264cd1, L"LucidaHandwriting",
+     L"Liberation Sans Narrow,Ubuntu Condensed,Nimbus Sans "
+     L"L,KacstQurn,Liberation Mono",
+     0, 1252},
+    {0xf086bca2, L"BaskervilleOldFace",
+     L"KacstQurn,Droid Sans Japanese,Liberation Serif,Ubuntu,FreeSerif", 0,
+     1252},
+    {0xf1028030, L"Mangal",
+     L"FreeSans,TSCu_Paranar,Garuda,Liberation Sans,Liberation Sans "
+     L"Narrow,Nimbus Sans L",
+     2, 1252},
+    {0xf1da7eb9, L"ShowcardGothic",
+     L"Droid Sans Japanese,DejaVu Serif Condensed,DejaVu Sans "
+     L"Condensed,Liberation Sans,Ubuntu",
+     0, 1252},
+    {0xf210f06a, L"ArialMT",
+     L"Liberation Sans,Liberation Sans Narrow,FreeSans,Nimbus Sans L,Khmer OS "
+     L"System,Khmer OS",
+     0, 1252},
+    {0xf477f16a, L"Latha",
+     L"Liberation Sans Narrow,Nimbus Sans L,Droid Arabic "
+     L"Naskh,mry_KacstQurn,FreeSerif,Nimbus Sans L",
+     0, 1252},
+    {0xf616f3dd, L"LiSu",
+     L"WenQuanYi Zen Hei Mono,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW,AR "
+     L"PL UMing TW MBE",
+     1, 936},
+    {0xfa479aa6, L"MicrosoftYaHei",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     0, 936},
+    {0xfcd19697, L"BookmanOldStyle",
+     L"Droid Sans Japanese,Liberation Mono,Liberation Sans,Liberation Serif", 0,
+     1252},
+    {0xfe209a82, L"LucidaCalligraphy",
+     L"KacstQurn,Droid Arabic Naskh,Droid Sans Ethiopic,mry_KacstQurn,Droid "
+     L"Sans Japanese,DejaVu Serif,DejaVu Sans,FreeMono",
+     0, 1252},
+    {0xfef135f8, L"AdobeHeitiStd-Regular",
+     L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei "
+     L"Sharp,WenQuanYi Micro Hei",
+     0, 936},
+};
+#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+static const XFA_FONTINFO g_XFAFontsMap[] = {
+    {0x01d5d33e, L"SimSun", L"STHeiti,Heiti TC,STFangsong", 0, 936},
+    {0x01e4f102, L"YouYuan", L"STHeiti,Heiti TC,STFangsong", 1, 936},
+    {0x030549dc, L"LiSu", L"STHeiti,Heiti TC,STFangsong", 1, 936},
+    {0x032edd44, L"Simhei", L"STHeiti,Heiti TC,STFangsong", 1, 936},
+    {0x03eac6fc, L"PoorRichard-Regular",
+     L"Noteworthy,Avenir Next Condensed,Impact", 2, 1252},
+    {0x03ed90e6, L"Nina", L"Microsoft Sans Serif", 0, 1252},
+    {0x077b56b3, L"KingsoftPhoneticPlain",
+     L"LastResort,Apple "
+     L"Chancery,STIXVariants,STIXSizeOneSym,STIXSizeOneSym,Apple Braille",
+     0, 1252},
+    {0x078ed524, L"MicrosoftSansSerif", L"Songti SC,Apple Symbols", 0, 1252},
+    {0x089b18a9, L"Arial",
+     L"Arial Unicode MS,Microsoft Sans Serif,Apple Symbols", 0, 1252},
+    {0x0b2cad72, L"MonotypeCorsiva", L"Arial Narrow,Impact", 8, 1252},
+    {0x0bb003e7, L"Kartika",
+     L"Arial Unicode MS,Microsoft Sans Serif,Arial Narrow,Damascus", 2, 1252},
+    {0x0bb469df, L"VinerHandITC", L"Comic Sans MS,Songti SC,STSong", 8, 1252},
+    {0x0bc1a851, L"SegoeUI", L"Apple Symbols", 0, 1252},
+    {0x0c112ebd, L"KozukaGothicPro-VIM", L"Microsoft Sans Serif,Apple Symbols",
+     0, 1252},
+    {0x0cfcb9c1, L"AdobeThai", L"Avenir Next Condensed Ultra Light", 0, 847},
+    {0x0e7de0f9, L"Playbill", L"STIXNonUnicode", 0, 1252},
+    {0x0eff47c3, L"STHupo", L"Kaiti SC,Songti SC,STHeiti", 0, 936},
+    {0x107ad374, L"Constantia", L"Arial Unicode MS,Palatino,Baskerville", 2,
+     1252},
+    {0x12194c2d, L"KunstlerScript",
+     L"Avenir Next Condensed Demi Bold,Arial Narrow", 8, 1252},
+    {0x135ef6a1, L"MinionProSmBd", L"Microsoft Sans Serif,Apple Symbols", 0,
+     1252},
+    {0x158c4049, L"Garamond", L"Impact,Arial Narrow", 2, 1252},
+    {0x160ecb24, L"STZhongsong", L"STFangsong,Songti SC", 0, 936},
+    {0x161ed07e, L"MSGothic",
+     L"WenQuanYi Zen Hei Mono,AR PL UMing CN,AR PL UMing HK,AR PL UMing "
+     L"TW,Microsoft Sans Serif,Apple Symbols",
+     1, 1252},
+    {0x171d1ed1, L"SnapITC-Regular", L"STHeiti,Arial Black", 0, 1252},
+    {0x18d1188f, L"Cambria", L"Arial Unicode MS", 2, 1252},
+    {0x18eaf350, L"ArialUnicodeMS", L"Microsoft Sans Serif,Apple Symbols", 0,
+     936},
+    {0x1a92d115, L"MingLiU", L"Heiti SC,STHeiti", 1, 1252},
+    {0x1cc217c6, L"TrebuchetMS", L"Damascus,Impact,Arial Narrow", 0, 1252},
+    {0x1d649596, L"BasemicTimes", L"Liberation Serif,Impact,Arial Narrow", 0,
+     1252},
+    {0x1e34ee60, L"BellMT",
+     L"Papyrus,STIXNonUnicode,Microsoft Sans Serif,Avenir Light", 2, 1252},
+    {0x1eb36945, L"CooperBlack",
+     L"Marion,STIXNonUnicode,Arial Rounded MT Bold,Lucida Grande", 2, 1252},
+    {0x1ef7787d, L"BatangChe",
+     L"WenQuanYi Zen Hei Mono,AR PL UMing CN,,AR PL UMing HK,AR PL UMing TW,AR "
+     L"PL UMing TW MBE,Arial Unicode MS,Heiti TC",
+     1, 1252},
+    {0x20b3bd3a, L"BrushScriptMT",
+     L"STIXNonUnicode,Damascus,Arial Narrow,Avenir Next Condensed,Cochin", 8,
+     1252},
+    {0x220877aa, L"Candara", L"Cochin,Baskerville,Marion", 0, 1252},
+    {0x22135007, L"FreestyleScript-Regular",
+     L"STIXNonUnicode,Nadeem,Zapf Dingbats", 8, 1252},
+    {0x251059c3, L"Chiller",
+     L"Zapf Dingbats,Damascus,STIXNonUnicode,Papyrus,KufiStandardGK,Baghdad", 0,
+     1252},
+    {0x25bed6dd, L"MSReferenceSansSerif",
+     L"Tahoma,Apple Symbols,Apple LiGothic,Arial Unicode MS,Lucida "
+     L"Grande,Microsoft Sans Serif",
+     0, 1252},
+    {0x28154c81, L"Parchment-Regular", L"Microsoft Sans Serif,Apple Symbols", 8,
+     1252},
+    {0x29711eb9, L"STLiti", L"Kaiti SC,Songti SC", 0, 936},
+    {0x2b1993b4, L"Basemic", L"Impact,Arial Narrow", 0, 1252},
+    {0x2b316339, L"NiagaraSolid-Reg", L"Microsoft Sans Serif,Apple Symbols", 0,
+     1252},
+    {0x2c147529, L"FootlightMTLight",
+     L"STIXNonUnicode,Avenir Next Condensed Heavy,PT Sans,Noteworthy", 0, 1252},
+    {0x2c198928, L"HarlowSolid",
+     L"Avenir Medium,Avenir Next Medium,Arial Unicode MS", 0, 1252},
+    {0x2c6ac6b2, L"LucidaBright",
+     L"PT Sans Narrow,Papyrus,Damascus,STIXNonUnicode,Arial Rounded MT "
+     L"Bold,Comic Sans MS,Avenir Next",
+     2, 1252},
+    {0x2c9f38e2, L"KozukaMinchoPro-VIR", L"Microsoft Sans Serif,Apple Symbols",
+     0, 1252},
+    {0x2d5a47b0, L"STCaiyun", L"Kaiti SC,Songti SC", 0, 936},
+    {0x2def26bf, L"BernardMT-Condensed",
+     L"Impact,Avenir Next Condensed Demi Bold,American Typewriter", 0, 1252},
+    {0x2fd8930b, L"KozukaMinchoPr6NR", L"Microsoft Sans Serif,Apple Symbols", 0,
+     1252},
+    {0x3115525a, L"FangSong_GB2312", L"Hiragino Sans GB,STHeiti", 0, 1252},
+    {0x31327817, L"MyriadPro", L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+    {0x32244975, L"Helvetica",
+     L"Arial Narrow,Arial Unicode MS,Damascus,STIXNonUnicode", 0, 1252},
+    {0x32ac995c, L"Terminal", L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+    {0x338d648a, L"NiagaraEngraved-Reg", L"Microsoft Sans Serif,Apple Symbols",
+     0, 1252},
+    {0x33bb65f2, L"Sylfaen", L"Arial Unicode MS,Marion", 2, 1252},
+    {0x3402c30e, L"MSPMincho", L"Arial Unicode MS,Apple SD Gothic Neo", 2,
+     1252},
+    {0x3412bf31, L"SimSun-PUA", L"STHeiti,Heiti TC,STFangsong", 0, 936},
+    {0x36eb39b9, L"BerlinSansFB", L"American Typewriter,Impact", 0, 1252},
+    {0x36f42055, L"UniversATT", L"Microsoft Sans Serif", 0, 1252},
+    {0x3864c4f6, L"HighTowerText", L"STIXGeneral,.Helvetica Neue Desk UI", 2,
+     1252},
+    {0x3a257d03, L"FangSong_GB2312", L"Hiragino Sans GB,STHeiti", 0, 1252},
+    {0x3cdae668, L"FreestyleScript", L"Nadeem,Zapf Dingbats,STIXNonUnicode", 8,
+     1252},
+    {0x3d55aed7, L"Jokerman",
+     L"Papyrus,Lucida Grande,Heiti TC,American Typewriter", 0, 1252},
+    {0x3d5b4385, L"PMingLiU", L"Heiti SC,STHeiti", 2, 1252},
+    {0x3d9b7669, L"EstrangeloEdessa", L"American Typewriter,Marion", 0, 1252},
+    {0x3e532d74, L"FranklinGothicMedium", L"Impact,Arial Narrow", 0, 1252},
+    {0x3e6aa32d, L"NSimSun", L"STHeiti,STFangsong", 1, 936},
+    {0x3f6c36a8, L"Gautami",
+     L"Damascus,STIXNonUnicode,STIXGeneral,American Typewriter", 0, 1252},
+    {0x3ff32662, L"Chiller-Regular", L"Papyrus,KufiStandardGK,Baghdad", 0,
+     1252},
+    {0x409de312, L"ModernNo.20", L"Avenir Next Condensed,Impact", 2, 1252},
+    {0x41443c5e, L"Georgia", L".Helvetica Neue Desk UI,Arial Unicode MS", 2,
+     1252},
+    {0x4160ade5, L"BellGothicStdBlack", L"Microsoft Sans Serif,Apple Symbols",
+     0, 1252},
+    {0x421976c4, L"Modern-Regular", L"Impact", 2, 1252},
+    {0x422a7252, L"Stencil", L"STIXNonUnicode,Songti SC,Georgia,Baskerville", 0,
+     1252},
+    {0x42c8554f, L"Fixedsys", L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+    {0x435cb41d, L"Roman", L"Arial Narrow", 0, 1252},
+    {0x47882383, L"CourierNew", L"PCMyungjo,Osaka,Arial Unicode MS,Songti SC",
+     1, 1252},
+    {0x480a2338, L"BerlinSansFBDemi",
+     L"STIXNonUnicode,American Typewriter,Avenir Next Condensed Heavy", 0,
+     1252},
+    {0x480bf7a4, L"CourierStd", L"Courier New", 0, 1252},
+    {0x481ad6ed, L"VladimirScript",
+     L"STIXNonUnicode,Avenir Next Condensed,Impact", 8, 1252},
+    {0x4911577a, L"YouYuan", L"STHeiti,Heiti TC", 1, 936},
+    {0x4a788d72, L"STXingkai", L"Kaiti SC,Songti SC", 0, 936},
+    {0x4bf88566, L"SegoeCondensed", L"Microsoft Sans Serif,Apple Symbols", 0,
+     1252},
+    {0x4ccf51a4, L"BerlinSansFB-Reg",
+     L"STIXNonUnicode,American Typewriter,Impact", 0, 1252},
+    {0x4ea967ce, L"GulimChe", L"Arial Unicode MS,Heiti TC,STFangsong", 1, 1252},
+    {0x4f68bd79, L"LetterGothicStd",
+     L"Courier New,Andale Mono,Ayuthaya,PCMyungjo,Osaka", 0, 1252},
+    {0x51a0d0e6, L"KozukaGothicPr6NM", L"Microsoft Sans Serif,Apple Symbols", 0,
+     1252},
+    {0x531b3dea, L"BasemicSymbol", L"Microsoft Sans Serif,Apple Symbols", 0,
+     1252},
+    {0x5333fd39, L"CalifornianFB-Reg",
+     L"American Typewriter,Avenir Next Condensed,Impact", 2, 1252},
+    {0x53561a54, L"FZYTK--GBK1-0", L"STFangsong,Songti SC,STSong", 0, 936},
+    {0x55e0dde6, L"LucidaSansTypewriter", L"Menlo,Courier New,Andale Mono", 0,
+     1252},
+    {0x574d4d3d, L"AdobeArabic", L"Arial Narrow", 0, 1252},
+    {0x5792e759, L"STKaiti", L"Songti SC,Arial Unicode MS", 0, 936},
+    {0x5921978e, L"LucidaSansUnicode", L"Lucida Grande,Arial Unicode MS,Menlo",
+     0, 1252},
+    {0x594e2da4, L"Vrinda", L"Geeza Pro,Damascus,STIXGeneral,Gill Sans", 0,
+     1252},
+    {0x59baa9a2, L"KaiTi_GB2312", L"Hiragino Sans GB,STHeiti", 0, 1252},
+    {0x5cfedf4f, L"BaskOldFace",
+     L"Avenir Next Condensed Heavy,PT Sans,Avenir Next Condensed", 0, 1252},
+    {0x5e16ac91, L"TrajanPro", L"Arial Narrow,PT Sans Narrow,Damascus", 0,
+     1252},
+    {0x5f97921c, L"AdobeMyungjoStdM",
+     L"AppleMyungjo,AppleGothic,Arial Unicode MS", 0, 936},
+    {0x5fefbfad, L"Batang", L"Arial Unicode MS,Songti SC", 2, 1252},
+    {0x605342b9, L"DotumChe", L"Arial Unicode MS,Heiti TC", 1, 1252},
+    {0x608c5f9a, L"KaiTi_GB2312", L"Hiragino Sans GB,STHeiti,Heiti TC", 0, 936},
+    {0x61efd0d1, L"MaturaMTScriptCapitals",
+     L"Kokonor,Damascus,STIXNonUnicode,STHeiti,Arial Black,Avenir Next Heavy",
+     0, 1252},
+    {0x626608a9, L"MVBoli",
+     L"Apple Braille,Geeza Pro,Microsoft Sans Serif,Apple Symbols", 0, 1252},
+    {0x630501a3, L"SmallFonts", L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+    {0x65d0e2a9, L"FZYTK--GBK1-0", L"STFangsong,Songti SC,STSong", 0, 936},
+    {0x669f29e1, L"FZSTK--GBK1-0", L"STHeiti,Heiti TC", 0, 936},
+    {0x673a9e5f, L"Tunga",
+     L"Damascus,STIXNonUnicode,Avenir Next Condensed,Avenir Next Condensed "
+     L"Ultra Light,Futura",
+     0, 1252},
+    {0x691aa4ce, L"NiagaraSolid", L"Microsoft Sans Serif,Apple Symbols", 0,
+     1252},
+    {0x696259b7, L"Corbel", L"Cochin,Baskerville,Marion", 0, 1252},
+    {0x696ee9be, L"STXihei", L"STHeiti,Heiti TC,Songti SC,Arial Unicode MS", 0,
+     936},
+    {0x6c59cf69, L"Dotum", L"Arial Unicode MS,Songti SC", 0, 1252},
+    {0x707fa561, L"Gungsuh", L"Arial Unicode MS,Heiti TC", 2, 1252},
+    {0x71416bb2, L"ZWAdobeF",
+     L"STIXSizeFourSym,STIXSizeThreeSym,STIXSizeTwoSym,STIXSizeOneSym", 0,
+     1252},
+    {0x71b41801, L"Verdana",
+     L"Tahoma,Marion,Apple Symbols,.Helvetica Neue Desk UI,Lucida "
+     L"Grande,Courier New",
+     0, 1252},
+    {0x73f25e4c, L"PalatinoLinotype", L"Palatino,Arial Unicode MS", 0, 1252},
+    {0x73f4d19f, L"NiagaraEngraved", L"Microsoft Sans Serif,Apple Symbols", 0,
+     1252},
+    {0x74001694, L"MyriadProBlack", L"Palatino,Baskerville,Marion,Cochin", 0,
+     1252},
+    {0x74b14d8f, L"Haettenschweiler", L"Microsoft Sans Serif,Apple Symbols", 0,
+     1252},
+    {0x74cb44ee, L"NSimSun", L"STHeiti,Heiti TC,STFangsong", 1, 936},
+    {0x76b4d7ff, L"Shruti",
+     L"Damascus,STIXNonUnicode,Arial Unicode MS,American Typewriter", 0, 1252},
+    {0x788b3533, L"Webdings", L"Microsoft Sans Serif,Apple Symbols", 6, 42},
+    {0x797dde99, L"MSSerif", L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+    {0x7a0f9e9e, L"MSMincho",
+     L"WenQuanYi Zen Hei Mono,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW,AR "
+     L"PL UMing TW MBE,Arial Unicode MS,Apple SD Gothic Neo",
+     1, 1252},
+    {0x7b439caf, L"OldEnglishTextMT",
+     L"STIXNonUnicode,Arial Unicode MS,Baskerville,Avenir Next Medium", 0,
+     1252},
+    {0x8213a433, L"LucidaSans-Typewriter",
+     L"Comic Sans MS,Avenir Next,Arial Rounded MT Bold", 0, 1252},
+    {0x82fec929, L"AdobeSongStdL", L"Heiti TC,STHeiti", 0, 936},
+    {0x83581825, L"Modern", L"Avenir Next Condensed,Impact", 0, 1252},
+    {0x835a2823, L"Algerian",
+     L"STIXNonUnicode,Baskerville,Avenir Next Medium,American Typewriter", 0,
+     1252},
+    {0x83dab9f5, L"Script", L"Arial Narrow", 0, 1252},
+    {0x847b56da, L"Tahoma", L"Songti SC,Apple Symbols", 0, 1252},
+    {0x8a783cb2, L"SimSun-PUA", L"STHeiti,Heiti TC,STFangsong", 0, 1252},
+    {0x8b5cac0e, L"Onyx", L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+    {0x8c6a499e, L"Gulim", L"Arial Unicode MS,Songti SC", 0, 1252},
+    {0x8e0af790, L"JuiceITC", L"Nadeem,Al Bayan", 0, 1252},
+    {0x8e8d43b2, L"Centaur", L"Avenir Next Condensed,Noteworthy,Impact", 2,
+     1252},
+    {0x8ee4dcca, L"BookshelfSymbol7", L"Microsoft Sans Serif,Apple Symbols", 0,
+     1252},
+    {0x90794800, L"BellGothicStdLight", L"Microsoft Sans Serif,Apple Symbols",
+     0, 1252},
+    {0x909b516a, L"Century", L"Damascus,Andale Mono,Songti SC,Arial Unicode MS",
+     2, 1252},
+    {0x92ae370d, L"MSOutlook", L"Microsoft Sans Serif,Apple Symbols", 4, 42},
+    {0x93c9fbf1, L"LucidaFax",
+     L"PT Sans Narrow,Papyrus,Kokonor,Geeza Pro,Arial Rounded MT Bold,Lucida "
+     L"Grande,Futura",
+     2, 1252},
+    {0x9565085e, L"BookAntiqua", L"Palatino,Microsoft Sans Serif,Apple Symbols",
+     2, 1252},
+    {0x9856d95d, L"AdobeMingStdL", L"AHiragino Sans GB,Heiti TC,STHeiti", 0,
+     949},
+    {0x9bbadd6b, L"ColonnaMT", L"Noteworthy,Avenir Next Condensed,Impact", 0,
+     1252},
+    {0x9cbd16a4, L"ShowcardGothic-Reg",
+     L"Arial Unicode MS,Georgia,American Typewriter", 0, 1252},
+    {0x9d73008e, L"MSSansSerif", L"Songti SC,Apple Symbols", 0, 1252},
+    {0xa0607db1, L"GungsuhChe",
+     L"WenQuanYi Zen Hei Mono,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW,AR "
+     L"PL UMing TW MBE,Arial Unicode MS,Heiti TC,STFangsong",
+     1, 1252},
+    {0xa0bcf6a1, L"LatinWide", L"Zapfino,Arial Black,STHeiti", 2, 1252},
+    {0xa1429b36, L"Symbol", L"Microsoft Sans Serif,Apple Symbols", 6, 42},
+    {0xa1fa5abc, L"Wingdings2", L"Microsoft Sans Serif,Apple Symbols", 6, 42},
+    {0xa1fa5abd, L"Wingdings3", L"Microsoft Sans Serif,Apple Symbols", 6, 42},
+    {0xa427bad4, L"InformalRoman-Regular",
+     L"STIXNonUnicode,Arial Narrow,Avenir Next Condensed Demi Bold", 8, 1252},
+    {0xa8b92ece, L"FZSTK--GBK1-0", L"STHeiti,Heiti TC,STFangsong", 0, 936},
+    {0xa8d83ece, L"CalifornianFB",
+     L"American Typewriter,Avenir Next Condensed,Impact", 2, 1252},
+    {0xaa3e082c, L"Kingsoft-Phonetic",
+     L"STIXVariants,STIXSizeOneSym,Apple Braille", 0, 1252},
+    {0xaa6bcabe, L"HarlowSolidItalic",
+     L"STIXNonUnicode,Avenir Medium,Avenir Next Medium,Arial Unicode MS", 0,
+     1252},
+    {0xade5337c, L"MSUIGothic", L"Arial Unicode MS,Apple SD Gothic Neo", 0,
+     1252},
+    {0xb08dd941, L"WideLatin",
+     L"Marion,Papyrus,Nanum Pen Script,Zapf Dingbats,Damascus,Zapfino,Arial "
+     L"Black,STHeiti",
+     2, 1252},
+    {0xb12765e0, L"ITCLegacySansStdBook",
+     L"LastResort,.Helvetica Neue Desk UI,Arial Unicode MS,Palatino", 0, 1252},
+    {0xb207f05d, L"PoorRichard", L"Noteworthy,Avenir Next Condensed,Impact", 2,
+     1252},
+    {0xb3bc492f, L"JuiceITC-Regular", L"Nadeem,Al Bayan,STIXNonUnicode", 0,
+     1252},
+    {0xb5545399, L"Marlett", L"Microsoft Sans Serif,Apple Symbols", 4, 42},
+    {0xb5dd1ebb, L"BritannicBold",
+     L"Damascus,STIXNonUnicode,Avenir Next Condensed Heavy,PT Sans", 0, 1252},
+    {0xb699c1c5, L"LucidaCalligraphy-Italic", L"STHeiti,Arial Black", 0, 1252},
+    {0xb725d629, L"TimesNewRoman", L"Microsoft Sans Serif,Apple Symbols", 2,
+     1252},
+    {0xb7eaebeb, L"AdobeHeitiStdR", L"Heiti TC,STHeiti", 0, 936},
+    {0xbd29c486, L"BerlinSansFBDemi-Bold",
+     L"American Typewriter,Avenir Next Condensed Heavy", 0, 1252},
+    {0xbe8a8db4, L"BookshelfSymbolSeven", L"Microsoft Sans Serif,Apple Symbols",
+     0, 1252},
+    {0xc16c0118, L"AdobeHebrew",
+     L".Helvetica Neue Desk UI,Palatino,American Typewriter", 0, 1252},
+    {0xc318b0af, L"MyriadProLight", L"Palatino,Baskerville,Marion", 0, 1252},
+    {0xc65e5659, L"CambriaMath", L"Arial Unicode MS", 2, 1252},
+    {0xc75c8f05, L"LucidaConsole", L"Courier New,Menlo,Andale Mono", 1, 1252},
+    {0xca7c35d6, L"Calibri", L"Apple Symbols,HeadLineA", 0, 1252},
+    {0xcb053f53, L"MicrosoftYaHei", L"Arial Unicode MS", 0, 936},
+    {0xcb7190f9, L"Magneto-Bold", L"Lucida Grande", 0, 1252},
+    {0xcca00cc5, L"System", L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+    {0xccad6f76, L"Jokerman-Regular", L"Lucida Grande", 0, 1252},
+    {0xccc5818c, L"EuroSign", L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+    {0xcf3d7234, L"LucidaHandwriting-Italic",
+     L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+    {0xcf7b8fdb, L"MinionPro",
+     L"Bell MT,Corbel,Times New Roman,Cambria,Berlin Sans FB", 0, 1252},
+    {0xcfe5755f, L"Simhei", L"STHeiti,Heiti TC,STFangsong", 1, 936},
+    {0xd011f4ee, L"MSPGothic", L"Arial Unicode MS,Apple SD Gothic Neo", 0,
+     1252},
+    {0xd060e7ef, L"Vivaldi",
+     L"STIXNonUnicode,Arial Unicode MS,Avenir Medium,Avenir Next Medium", 8,
+     1252},
+    {0xd07edec1, L"FranklinGothic-Medium", L"Impact,Arial Narrow", 0, 1252},
+    {0xd107243f, L"SimSun", L"STHeiti,Heiti TC,STFangsong", 0, 936},
+    {0xd1881562, L"ArialNarrow", L"PT Sans Narrow,Apple Symbols", 0, 1252},
+    {0xd22b7dce, L"BodoniMTPosterCompressed",
+     L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+    {0xd22bfa60, L"ComicSansMS",
+     L"Damascus,Georgia,.Helvetica Neue Desk UI,Lucida Grande,Arial Unicode MS",
+     8, 1252},
+    {0xd3bd0e35, L"Bauhaus93",
+     L"STIXNonUnicode,Arial Unicode MS,Avenir Next,Avenir", 0, 1252},
+    {0xd429ee7a, L"STFangsong", L"Songti SC,Arial Unicode MS", 0, 936},
+    {0xd6679c12, L"BernardMTCondensed",
+     L"Impact,Avenir Next Condensed Demi Bold", 0, 1252},
+    {0xd8e8a027, L"LucidaSans",
+     L"Arial Narrow,Khmer MN,Kokonor,Damascus,Microsoft Sans Serif,Apple "
+     L"Symbols",
+     0, 1252},
+    {0xd9fe7761, L"HighTowerText-Reg",
+     L"STIXGeneral,.Helvetica Neue Desk UI,Trebuchet MS", 2, 1252},
+    {0xda7e551e, L"STSong", L"Arial Unicode MS", 0, 936},
+    {0xdaa6842d, L"STZhongsong", L"STFangsong,Songti SC,STSong", 0, 936},
+    {0xdaaab93f, L"STFangsong", L"Songti SC,Arial Unicode MS", 0, 936},
+    {0xdaeb0713, L"STSong", L"Songti SC,Arial Unicode MS", 0, 936},
+    {0xdafedbef, L"STCaiyun", L"Kaiti SC,Songti SC,STHeiti", 0, 936},
+    {0xdb00a3d9, L"Broadway",
+     L"Papyrus,STIXNonUnicode,Arial Black,Avenir Next Heavy,Heiti TC", 0, 1252},
+    {0xdb1f5ad4, L"STXinwei", L"Kaiti SC,Songti SC,STHeiti", 0, 936},
+    {0xdb326e7f, L"STKaiti", L"Songti SC,Arial Unicode MS", 0, 936},
+    {0xdb69595a, L"STHupo", L"Kaiti SC,Songti SC,STHeiti", 0, 936},
+    {0xdba0082c, L"STXihei", L"Songti SC,Arial Unicode MS", 0, 936},
+    {0xdbd0ab18, L"STXingkai", L"Kaiti SC,Songti SC", 0, 936},
+    {0xdc1a7db1, L"STLiti", L"Kaiti SC,Songti SC", 0, 936},
+    {0xdc33075f, L"KristenITC-Regular",
+     L"STIXNonUnicode,Damascus,Songti SC,STSong", 8, 1252},
+    {0xdcc7009c, L"Harrington",
+     L"STIXNonUnicode,Avenir Next Condensed Heavy,Noteworthy", 0, 1252},
+    {0xdd712466, L"ArialBlack", L"Geeza Pro,Damascus,Songti SC,STSong", 0,
+     1252},
+    {0xdde87b3e, L"Impact", L"Arial Narrow,Marion", 0, 1252},
+    {0xdf69fb32, L"SnapITC",
+     L"Arial Narrow,PT Sans Narrow,Marion,STHeiti,Arial Black", 0, 1252},
+    {0xdf8b25e8, L"CenturyGothic",
+     L"Damascus,Andale Mono,Songti SC,Arial Unicode MS", 0, 1252},
+    {0xe0f705c0, L"KristenITC", L"Songti SC,STSong", 8, 1252},
+    {0xe1427573, L"Raavi",
+     L"Damascus,STIXNonUnicode,Marion,Papyrus,Avenir Next Condensed "
+     L"Heavy,American Typewriter",
+     0, 1252},
+    {0xe2cea0cb, L"Magneto",
+     L"STIXNonUnicode,Damascus,Geeza Pro,Lucida Grande,Georgia,Heiti TC", 0,
+     1252},
+    {0xe36a9e17, L"Ravie", L"STHeiti,Arial Black", 0, 1252},
+    {0xe433f8e2, L"Parchment", L"Microsoft Sans Serif,Apple Symbols", 8, 1252},
+    {0xe43dff4a, L"Wingdings", L"Microsoft Sans Serif,Apple Symbols", 4, 42},
+    {0xe4e2c405, L"MTExtra", L"Microsoft Sans Serif,Apple Symbols", 6, 42},
+    {0xe618cc35, L"InformalRoman", L"Arial Narrow", 8, 1252},
+    {0xe6c27ffc, L"Mistral", L"Apple Symbols", 8, 1252},
+    {0xe7ebf4b9, L"Courier", L"Courier New", 0, 1252},
+    {0xe8bc4a9d, L"MSReferenceSpecialty", L"Microsoft Sans Serif,Apple Symbols",
+     0, 1252},
+    {0xe90fb013, L"TempusSansITC",
+     L"STIXNonUnicode,Microsoft Sans Serif,Avenir Light", 0, 1252},
+    {0xec637b42, L"Consolas",
+     L"AR PL UKai CN,AR PL UKai HK,AR PL UKai TW,AR PL UKai TW MBE,AR PL UMing "
+     L"CN,AR PL UMing HK,Microsoft Sans Serif,Tahoma",
+     1, 1252},
+    {0xed3a683b, L"STXinwei", L"Kaiti SC,Songti SC,", 0, 936},
+    {0xef264cd1, L"LucidaHandwriting",
+     L"Arial Narrow,Avenir Next Condensed Demi Bold,Avenir Next "
+     L"Condensed,Avenir Next Condensed Medium,STHeiti,Arial Black",
+     0, 1252},
+    {0xf086bca2, L"BaskervilleOldFace",
+     L"STIXNonUnicode,Avenir Next Condensed Heavy,PT Sans", 0, 1252},
+    {0xf1028030, L"Mangal",
+     L"Arial Unicode MS,Microsoft Sans Serif,Arial Narrow,Tahoma", 2, 1252},
+    {0xf1da7eb9, L"ShowcardGothic",
+     L"Papyrus,Arial Unicode MS,Georgia,American Typewriter", 0, 1252},
+    {0xf210f06a, L"ArialMT",
+     L"Arial Unicode MS,Arial Narrow,STIXNonUnicode,Damascus,Avenir Next "
+     L"Condensed Demi Bold,Avenir Next Condensed Medium,Avenir Next Condensed",
+     0, 1252},
+    {0xf477f16a, L"Latha",
+     L"Arial Narrow,Damascus,STIXNonUnicode,American Typewriter", 0, 1252},
+    {0xf616f3dd, L"LiSu", L"STHeiti,Heiti TC,STFangsong", 1, 936},
+    {0xfa479aa6, L"MicrosoftYaHei", L"Arial Unicode MS", 0, 936},
+    {0xfcd19697, L"BookmanOldStyle",
+     L"Geeza Pro,Damascus,Andale Mono,Songti SC,Arial Unicode MS", 0, 1252},
+    {0xfe209a82, L"LucidaCalligraphy",
+     L"Kokonor,Damascus,STIXNonUnicode,STHeiti,Arial Black", 0, 1252},
+    {0xfef135f8, L"AdobeHeitiStd-Regular", L"Heiti TC,STHeiti", 0, 936},
+};
+#elif _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_
+static const XFA_FONTINFO g_XFAFontsMap[] = {
+    {0x01d5d33e, L"SimSun", L"Droid Sans Fallback", 0, 936},
+    {0x01e4f102, L"YouYuan", L"Droid Sans Fallback", 1, 936},
+    {0x030549dc, L"LiSu", L"Droid Sans Fallback", 1, 936},
+    {0x032edd44, L"Simhei", L"Droid Sans Fallback", 1, 936},
+    {0x03eac6fc, L"PoorRichard-Regular",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback,Droid Arabic "
+     L"Naskh,Droid Sans Ethiopic",
+     2, 1252},
+    {0x03ed90e6, L"Nina",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x077b56b3, L"KingsoftPhoneticPlain",
+     L"Droid Sans Thai,Droid Sans Armenian,Droid Arabic Naskh,Droid Sans "
+     L"Ethiopic,Droid Sans Fallback",
+     0, 1252},
+    {0x078ed524, L"MicrosoftSansSerif", L"Droid Sans Fallback", 0, 1252},
+    {0x089b18a9, L"Arial", L"Droid Sans Fallback", 0, 1252},
+    {0x0b2cad72, L"MonotypeCorsiva",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+    {0x0bb003e7, L"Kartika",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif,Droid Sans "
+     L"Mono",
+     2, 1252},
+    {0x0bb469df, L"VinerHandITC",
+     L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+    {0x0bc1a851, L"SegoeUI", L"Droid Sans Fallback", 0, 1252},
+    {0x0c112ebd, L"KozukaGothicPro-VIM",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x0cfcb9c1, L"AdobeThai",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 847},
+    {0x0e7de0f9, L"Playbill",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif,Droid Sans "
+     L"Mono",
+     0, 1252},
+    {0x0eff47c3, L"STHupo", L"Droid Sans Fallback", 0, 936},
+    {0x107ad374, L"Constantia",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+    {0x12194c2d, L"KunstlerScript",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+    {0x135ef6a1, L"MinionProSmBd",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x158c4049, L"Garamond",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+    {0x160ecb24, L"STZhongsong", L"Droid Sans Fallback", 0, 936},
+    {0x161ed07e, L"MSGothic", L"Droid Sans Fallback", 1, 1252},
+    {0x171d1ed1, L"SnapITC-Regular",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x18d1188f, L"Cambria", L"Droid Sans Fallback", 2, 1252},
+    {0x18eaf350, L"ArialUnicodeMS", L"Droid Sans Fallback", 0, 936},
+    {0x1a92d115, L"MingLiU", L"Droid Sans Fallback", 1, 1252},
+    {0x1cc217c6, L"TrebuchetMS",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x1d649596, L"BasemicTimes",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x1e34ee60, L"BellMT",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+    {0x1eb36945, L"CooperBlack",
+     L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+    {0x1ef7787d, L"BatangChe", L"Droid Sans Fallback", 1, 1252},
+    {0x20b3bd3a, L"BrushScriptMT", L"Droid Arabic Naskh,Droid Sans Ethiopic", 8,
+     1252},
+    {0x220877aa, L"Candara",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x22135007, L"FreestyleScript-Regular",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+    {0x251059c3, L"Chiller",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif", 0, 1252},
+    {0x25bed6dd, L"MSReferenceSansSerif", L"Droid Sans Fallback", 0, 1252},
+    {0x28154c81, L"Parchment-Regular",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+    {0x29711eb9, L"STLiti", L"Droid Sans Fallback", 0, 936},
+    {0x2b1993b4, L"Basemic",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x2b316339, L"NiagaraSolid-Reg",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x2c147529, L"FootlightMTLight",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x2c198928, L"HarlowSolid",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x2c6ac6b2, L"LucidaBright",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto", 2, 1252},
+    {0x2c9f38e2, L"KozukaMinchoPro-VIR",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x2d5a47b0, L"STCaiyun", L"Droid Sans Fallback", 0, 936},
+    {0x2def26bf, L"BernardMT-Condensed",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x2fd8930b, L"KozukaMinchoPr6NR",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x3115525a, L"FangSong_GB2312", L"Droid Sans Fallback", 0, 1252},
+    {0x31327817, L"MyriadPro",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x32244975, L"Helvetica",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto", 0, 1252},
+    {0x32ac995c, L"Terminal",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x338d648a, L"NiagaraEngraved-Reg",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x33bb65f2, L"Sylfaen",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+    {0x3402c30e, L"MSPMincho", L"Droid Sans Fallback", 2, 1252},
+    {0x3412bf31, L"SimSun-PUA", L"Droid Sans Fallback", 0, 936},
+    {0x36eb39b9, L"BerlinSansFB",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x36f42055, L"UniversATT", L"Microsoft Sans Serif", 0, 1252},
+    {0x3864c4f6, L"HighTowerText",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+    {0x3a257d03, L"FangSong_GB2312", L"Droid Sans Fallback", 0, 1252},
+    {0x3cdae668, L"FreestyleScript",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+    {0x3d55aed7, L"Jokerman",
+     L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x3d5b4385, L"PMingLiU", L"Droid Sans Fallback", 2, 1252},
+    {0x3d9b7669, L"EstrangeloEdessa",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x3e532d74, L"FranklinGothicMedium",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x3e6aa32d, L"NSimSun", L"Droid Sans Fallback", 1, 936},
+    {0x3f6c36a8, L"Gautami",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif,Droid Sans "
+     L"Mono,Droid Sans Fallback",
+     0, 1252},
+    {0x3ff32662, L"Chiller-Regular",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x409de312, L"ModernNo.20",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+    {0x41443c5e, L"Georgia",
+     L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+    {0x4160ade5, L"BellGothicStdBlack",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x421976c4, L"Modern-Regular",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+    {0x422a7252, L"Stencil",
+     L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x42c8554f, L"Fixedsys",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x435cb41d, L"Roman",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x47882383, L"CourierNew", L"Droid Sans Fallback", 1, 1252},
+    {0x480a2338, L"BerlinSansFBDemi",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x480bf7a4, L"CourierStd", L"Droid Sans Fallback", 0, 1252},
+    {0x481ad6ed, L"VladimirScript",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+    {0x4911577a, L"YouYuan", L"Droid Sans Fallback", 1, 936},
+    {0x4a788d72, L"STXingkai", L"Droid Sans Fallback", 0, 936},
+    {0x4bf88566, L"SegoeCondensed",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x4ccf51a4, L"BerlinSansFB-Reg",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x4ea967ce, L"GulimChe", L"Droid Sans Fallback", 1, 1252},
+    {0x4f68bd79, L"LetterGothicStd",
+     L"Droid Sans Mono,Droid Arabic Naskh,Droid Sans Ethiopic,Droid Sans "
+     L"Mono,Droid Serif,Droid Sans Fallback",
+     0, 1252},
+    {0x51a0d0e6, L"KozukaGothicPr6NM",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x531b3dea, L"BasemicSymbol",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x5333fd39, L"CalifornianFB-Reg",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+    {0x53561a54, L"FZYTK--GBK1-0", L"Droid Sans Fallback", 0, 936},
+    {0x55e0dde6, L"LucidaSansTypewriter",
+     L"Droid Sans Mono,Droid Arabic Naskh,Droid Sans Ethiopic", 0, 1252},
+    {0x574d4d3d, L"AdobeArabic",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x5792e759, L"STKaiti", L"Droid Sans Fallback", 0, 936},
+    {0x5921978e, L"LucidaSansUnicode", L"Droid Sans Fallback", 0, 1252},
+    {0x594e2da4, L"Vrinda",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif,Droid Sans "
+     L"Mono",
+     0, 1252},
+    {0x59baa9a2, L"KaiTi_GB2312", L"Droid Sans Fallback", 0, 1252},
+    {0x5cfedf4f, L"BaskOldFace",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x5f97921c, L"AdobeMyungjoStdM", L"Droid Sans Fallback", 0, 936},
+    {0x5fefbfad, L"Batang", L"Droid Sans Fallback", 2, 1252},
+    {0x605342b9, L"DotumChe", L"Droid Sans Fallback", 1, 1252},
+    {0x608c5f9a, L"KaiTi_GB2312", L"Droid Sans Fallback", 0, 936},
+    {0x61efd0d1, L"MaturaMTScriptCapitals",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto,Droid Sans "
+     L"Mono",
+     0, 1252},
+    {0x626608a9, L"MVBoli",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto,Droid Sans "
+     L"Mono",
+     0, 1252},
+    {0x630501a3, L"SmallFonts",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x65d0e2a9, L"FZYTK--GBK1-0", L"Droid Sans Fallback", 0, 936},
+    {0x669f29e1, L"FZSTK--GBK1-0", L"Droid Sans Fallback", 0, 936},
+    {0x673a9e5f, L"Tunga",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif,Droid Sans "
+     L"Mono,Droid Sans Fallback",
+     0, 1252},
+    {0x691aa4ce, L"NiagaraSolid",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x696259b7, L"Corbel",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x696ee9be, L"STXihei", L"Droid Sans Fallback", 0, 936},
+    {0x6c59cf69, L"Dotum", L"Droid Sans Fallback", 0, 1252},
+    {0x707fa561, L"Gungsuh", L"Droid Sans Fallback", 2, 1252},
+    {0x71416bb2, L"ZWAdobeF",
+     L"Droid Arabic Naskh,Droid Sans Armenian,Droid Sans Ethiopic,Droid Sans "
+     L"Georgian,Droid Sans Hebrew,Droid Sans Thai",
+     0, 1252},
+    {0x71b41801, L"Verdana",
+     L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x73f25e4c, L"PalatinoLinotype", L"Droid Sans Fallback", 0, 1252},
+    {0x73f4d19f, L"NiagaraEngraved",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x74001694, L"MyriadProBlack", L"Book Antiqua,Constantia,Dotum,Georgia", 0,
+     1252},
+    {0x74b14d8f, L"Haettenschweiler",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x74cb44ee, L"NSimSun", L"Droid Sans Fallback", 1, 936},
+    {0x76b4d7ff, L"Shruti",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif,Droid Sans "
+     L"Mono",
+     0, 1252},
+    {0x788b3533, L"Webdings",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 6, 42},
+    {0x797dde99, L"MSSerif",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x7a0f9e9e, L"MSMincho", L"Droid Sans Fallback", 1, 1252},
+    {0x7b439caf, L"OldEnglishTextMT",
+     L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x8213a433, L"LucidaSans-Typewriter",
+     L"Droid Sans Mono,Droid Serif,Roboto,Droid Sans Fallback", 0, 1252},
+    {0x82fec929, L"AdobeSongStdL", L"Droid Sans Fallback", 0, 936},
+    {0x83581825, L"Modern",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x835a2823, L"Algerian",
+     L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x83dab9f5, L"Script",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x847b56da, L"Tahoma", L"Droid Sans Fallback", 0, 1252},
+    {0x8a783cb2, L"SimSun-PUA", L"Droid Sans Fallback", 0, 1252},
+    {0x8b5cac0e, L"Onyx",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x8c6a499e, L"Gulim", L"Droid Sans Fallback", 0, 1252},
+    {0x8e0af790, L"JuiceITC",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x8e8d43b2, L"Centaur",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+    {0x8ee4dcca, L"BookshelfSymbol7",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x90794800, L"BellGothicStdLight",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x909b516a, L"Century",
+     L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+    {0x92ae370d, L"MSOutlook",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 4, 42},
+    {0x93c9fbf1, L"LucidaFax",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto,Droid Sans "
+     L"Mono",
+     2, 1252},
+    {0x9565085e, L"BookAntiqua",
+     L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+    {0x9856d95d, L"AdobeMingStdL", L"Droid Sans Fallback", 0, 949},
+    {0x9bbadd6b, L"ColonnaMT",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0x9cbd16a4, L"ShowcardGothic-Reg",
+     L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallbac", 0, 1252},
+    {0x9d73008e, L"MSSansSerif",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xa0607db1, L"GungsuhChe", L"Droid Sans Fallback", 1, 1252},
+    {0xa0bcf6a1, L"LatinWide",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+    {0xa1429b36, L"Symbol",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 6, 42},
+    {0xa1fa5abc, L"Wingdings2",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 6, 42},
+    {0xa1fa5abd, L"Wingdings3",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 6, 42},
+    {0xa427bad4, L"InformalRoman-Regular",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic", 8, 1252},
+    {0xa8b92ece, L"FZSTK--GBK1-0", L"Droid Sans Fallback", 0, 936},
+    {0xa8d83ece, L"CalifornianFB",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+    {0xaa3e082c, L"Kingsoft-Phonetic",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xaa6bcabe, L"HarlowSolidItalic",
+     L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xade5337c, L"MSUIGothic",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xb08dd941, L"WideLatin",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto,Droid Sans "
+     L"Mono",
+     2, 1252},
+    {0xb207f05d, L"PoorRichard",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+    {0xb3bc492f, L"JuiceITC-Regular",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xb5545399, L"Marlett",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 4, 42},
+    {0xb5dd1ebb, L"BritannicBold", L"Droid Arabic Naskh,Droid Sans Ethiopic", 0,
+     1252},
+    {0xb699c1c5, L"LucidaCalligraphy-Italic",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xb725d629, L"TimesNewRoman", L"Droid Sans Fallback", 2, 1252},
+    {0xb7eaebeb, L"AdobeHeitiStdR", L"Droid Sans Fallback", 0, 936},
+    {0xbd29c486, L"BerlinSansFBDemi-Bold",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xbe8a8db4, L"BookshelfSymbolSeven",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xc16c0118, L"AdobeHebrew",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback,Droid Arabic "
+     L"Naskh,Droid Sans Ethiopic",
+     0, 1252},
+    {0xc318b0af, L"MyriadProLight",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xc65e5659, L"CambriaMath", L"Droid Sans Fallback", 2, 1252},
+    {0xc75c8f05, L"LucidaConsole",
+     L"Droid Sans Mono,Droid Serif,Roboto,Droid Sans Fallback", 1, 1252},
+    {0xca7c35d6, L"Calibri", L"Droid Sans Fallback", 0, 1252},
+    {0xcb053f53, L"MicrosoftYaHei", L"Droid Sans Fallback", 0, 936},
+    {0xcb7190f9, L"Magneto-Bold",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xcca00cc5, L"System",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xccad6f76, L"Jokerman-Regular",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xccc5818c, L"EuroSign",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xcf3d7234, L"LucidaHandwriting-Italic",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xcf7b8fdb, L"MinionPro",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xcfe5755f, L"Simhei", L"Droid Sans Fallback", 1, 936},
+    {0xd011f4ee, L"MSPGothic", L"Droid Sans Fallback", 0, 1252},
+    {0xd060e7ef, L"Vivaldi",
+     L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+    {0xd07edec1, L"FranklinGothic-Medium",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xd107243f, L"SimSun", L"Droid Sans Fallback", 0, 936},
+    {0xd1881562, L"ArialNarrow",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xd22b7dce, L"BodoniMTPosterCompressed",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xd22bfa60, L"ComicSansMS", L"Droid Serif,Roboto,Droid Sans Fallback", 8,
+     1252},
+    {0xd3bd0e35, L"Bauhaus93",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xd429ee7a, L"STFangsong", L"Droid Sans Fallback", 0, 936},
+    {0xd6679c12, L"BernardMTCondensed",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xd8e8a027, L"LucidaSans",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto", 0, 1252},
+    {0xd9fe7761, L"HighTowerText-Reg",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+    {0xda7e551e, L"STSong", L"Droid Sans Fallback", 0, 936},
+    {0xdaa6842d, L"STZhongsong", L"Droid Sans Fallback", 0, 936},
+    {0xdaaab93f, L"STFangsong", L"Droid Sans Fallback", 0, 936},
+    {0xdaeb0713, L"STSong",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 936},
+    {0xdafedbef, L"STCaiyun", L"Droid Sans Fallback", 0, 936},
+    {0xdb00a3d9, L"Broadway",
+     L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xdb1f5ad4, L"STXinwei", L"Droid Sans Fallback", 0, 936},
+    {0xdb326e7f, L"STKaiti", L"Droid Sans Fallback", 0, 936},
+    {0xdb69595a, L"STHupo", L"Droid Sans Fallback", 0, 936},
+    {0xdba0082c, L"STXihei", L"Droid Sans Fallback", 0, 936},
+    {0xdbd0ab18, L"STXingkai", L"Droid Sans Fallback", 0, 936},
+    {0xdc1a7db1, L"STLiti", L"Droid Sans Fallback", 0, 936},
+    {0xdc33075f, L"KristenITC-Regular",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto", 8, 1252},
+    {0xdcc7009c, L"Harrington",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xdd712466, L"ArialBlack",
+     L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xdde87b3e, L"Impact",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xdf69fb32, L"SnapITC",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto,Droid Sans "
+     L"Mono",
+     0, 1252},
+    {0xdf8b25e8, L"CenturyGothic",
+     L"Droid Serif,Roboto,Droid Serif,Droid Sans Mono", 0, 1252},
+    {0xe0f705c0, L"KristenITC",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto", 8, 1252},
+    {0xe1427573, L"Raavi",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif,Droid Sans "
+     L"Mono",
+     0, 1252},
+    {0xe2cea0cb, L"Magneto",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto,Droid Sans "
+     L"Mono",
+     0, 1252},
+    {0xe36a9e17, L"Ravie",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif,Droid Sans "
+     L"Mono",
+     0, 1252},
+    {0xe433f8e2, L"Parchment",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+    {0xe43dff4a, L"Wingdings",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 4, 42},
+    {0xe4e2c405, L"MTExtra",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 6, 42},
+    {0xe618cc35, L"InformalRoman",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif", 8, 1252},
+    {0xe6c27ffc, L"Mistral",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+    {0xe7ebf4b9, L"Courier", L"Droid Sans Fallback", 0, 1252},
+    {0xe8bc4a9d, L"MSReferenceSpecialty",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xe90fb013, L"TempusSansITC",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xec637b42, L"Consolas", L"Droid Sans Fallback", 1, 1252},
+    {0xed3a683b, L"STXinwei", L"Droid Sans Fallback", 0, 936},
+    {0xef264cd1, L"LucidaHandwriting",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto,Droid Sans "
+     L"Mono",
+     0, 1252},
+    {0xf086bca2, L"BaskervilleOldFace",
+     L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xf1028030, L"Mangal",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto,Droid Sans "
+     L"Mono",
+     2, 1252},
+    {0xf1da7eb9, L"ShowcardGothic",
+     L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallbac", 0, 1252},
+    {0xf210f06a, L"ArialMT",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif", 0, 1252},
+    {0xf477f16a, L"Latha",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif,Droid Sans "
+     L"Mono",
+     0, 1252},
+    {0xf616f3dd, L"LiSu", L"Droid Sans Fallback", 1, 936},
+    {0xfa479aa6, L"MicrosoftYaHei", L"Droid Sans Fallback", 0, 936},
+    {0xfcd19697, L"BookmanOldStyle",
+     L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+    {0xfe209a82, L"LucidaCalligraphy",
+     L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto,Droid Sans "
+     L"Mono",
+     0, 1252},
+    {0xfef135f8, L"AdobeHeitiStd-Regular", L"Droid Sans Fallback", 0, 936},
+};
+#endif
+void XFA_LocalFontNameToEnglishName(const CFX_WideStringC& wsLocalName,
+                                    CFX_WideString& wsEnglishName) {
+  wsEnglishName = wsLocalName;
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || \
+    _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ ||   \
+    _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ ||   \
+    _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_
+  FX_DWORD dwLocalNameHash = FX_HashCode_String_GetW(
+      wsLocalName.GetPtr(), wsLocalName.GetLength(), TRUE);
+  int32_t iStart = 0;
+  int32_t iEnd = sizeof(g_XFAFontsMap) / sizeof(XFA_FONTINFO) - 1;
+  int32_t iMid = 0;
+  do {
+    iMid = (iStart + iEnd) / 2;
+    FX_DWORD dwFontNameHash = g_XFAFontsMap[iMid].dwFontNameHash;
+    if (dwFontNameHash == dwLocalNameHash) {
+      wsEnglishName = g_XFAFontsMap[iMid].pPsName;
+      break;
+    } else if (dwFontNameHash < dwLocalNameHash) {
+      iStart = iMid + 1;
+    } else {
+      iEnd = iMid - 1;
+    }
+  } while (iEnd >= iStart);
+#endif
+}
+const XFA_FONTINFO* XFA_GetFontINFOByFontName(
+    const CFX_WideStringC& wsFontName) {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || \
+    _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ ||   \
+    _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ ||   \
+    _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_
+  CFX_WideString wsFontNameTemp = wsFontName;
+  wsFontNameTemp.Remove(L' ');
+  FX_DWORD dwCurFontNameHash =
+      FX_HashCode_String_GetW(wsFontNameTemp, wsFontNameTemp.GetLength(), TRUE);
+  int32_t iStart = 0;
+  int32_t iEnd = sizeof(g_XFAFontsMap) / sizeof(XFA_FONTINFO) - 1;
+  int32_t iMid = 0;
+  const XFA_FONTINFO* pFontInfo = NULL;
+  do {
+    iMid = (iStart + iEnd) / 2;
+    FX_DWORD dwFontNameHash = g_XFAFontsMap[iMid].dwFontNameHash;
+    if (dwFontNameHash == dwCurFontNameHash) {
+      pFontInfo = &g_XFAFontsMap[iMid];
+      break;
+    } else if (dwFontNameHash < dwCurFontNameHash) {
+      iStart = iMid + 1;
+    } else {
+      iEnd = iMid - 1;
+    }
+  } while (iEnd >= iStart);
+  return pFontInfo;
+#else
+  return NULL;
+#endif
+}
+// static
+IXFA_FontMgr* IXFA_FontMgr::CreateDefault() {
+  return new CXFA_DefFontMgr;
+}
+// virtual
+IXFA_FontMgr::~IXFA_FontMgr() {}
+CXFA_DefFontMgr::~CXFA_DefFontMgr() {
+  int32_t iCounts = m_CacheFonts.GetSize();
+  for (int32_t i = 0; i < iCounts; i++) {
+    ((IFX_Font*)m_CacheFonts[i])->Release();
+  }
+  m_CacheFonts.RemoveAll();
+}
+
+IFX_Font* CXFA_DefFontMgr::GetFont(IXFA_Doc* hDoc,
+                                   const CFX_WideStringC& wsFontFamily,
+                                   FX_DWORD dwFontStyles,
+                                   FX_WORD wCodePage) {
+  CFX_WideString wsFontName = wsFontFamily;
+  IFX_FontMgr* pFDEFontMgr =
+      static_cast<CXFA_FFDoc*>(hDoc)->GetApp()->GetFDEFontMgr();
+  IFX_Font* pFont = pFDEFontMgr->LoadFont(wsFontName, dwFontStyles, wCodePage);
+  if (!pFont) {
+    const XFA_FONTINFO* pCurFont = XFA_GetFontINFOByFontName(wsFontName);
+    if (pCurFont && pCurFont->pReplaceFont) {
+      FX_DWORD dwStyle = 0;
+      if (dwFontStyles & FX_FONTSTYLE_Bold) {
+        dwStyle |= FX_FONTSTYLE_Bold;
+      }
+      if (dwFontStyles & FX_FONTSTYLE_Italic) {
+        dwStyle |= FX_FONTSTYLE_Italic;
+      }
+      const FX_WCHAR* pReplace = pCurFont->pReplaceFont;
+      int32_t iLength = FXSYS_wcslen(pReplace);
+      while (iLength > 0) {
+        const FX_WCHAR* pNameText = pReplace;
+        while (*pNameText != L',' && iLength > 0) {
+          pNameText++;
+          iLength--;
+        }
+        CFX_WideString wsReplace =
+            CFX_WideString(pReplace, pNameText - pReplace);
+        pFont = pFDEFontMgr->LoadFont(wsReplace, dwStyle, wCodePage);
+        if (pFont) {
+          break;
+        }
+        iLength--;
+        pNameText++;
+        pReplace = pNameText;
+      }
+    }
+  }
+  if (pFont) {
+    m_CacheFonts.Add(pFont);
+  }
+  return pFont;
+}
+
+IFX_Font* CXFA_DefFontMgr::GetDefaultFont(IXFA_Doc* hDoc,
+                                          const CFX_WideStringC& wsFontFamily,
+                                          FX_DWORD dwFontStyles,
+                                          FX_WORD wCodePage) {
+  IFX_FontMgr* pFDEFontMgr = ((CXFA_FFDoc*)hDoc)->GetApp()->GetFDEFontMgr();
+  IFX_Font* pFont =
+      pFDEFontMgr->LoadFont(L"Arial Narrow", dwFontStyles, wCodePage);
+  if (!pFont)
+    pFont =
+        pFDEFontMgr->LoadFont((const FX_WCHAR*)NULL, dwFontStyles, wCodePage);
+  FXSYS_assert(pFont);
+  if (pFont) {
+    m_CacheFonts.Add(pFont);
+  }
+  return pFont;
+}
+struct XFA_PDFFONTNAME {
+  const FX_CHAR* lpPsName;
+  const FX_CHAR* lpNormal;
+  const FX_CHAR* lpBold;
+  const FX_CHAR* lpItalic;
+  const FX_CHAR* lpBoldItalic;
+};
+const XFA_PDFFONTNAME g_XFAPDFFontName[] = {
+    {"Adobe PI Std", "AdobePIStd", "AdobePIStd", "AdobePIStd", "AdobePIStd"},
+    {"Myriad Pro Light", "MyriadPro-Light", "MyriadPro-Semibold",
+     "MyriadPro-LightIt", "MyriadPro-SemiboldIt"},
+};
+CXFA_PDFFontMgr::CXFA_PDFFontMgr(CXFA_FFDoc* pDoc) {
+  m_pDoc = pDoc;
+}
+CXFA_PDFFontMgr::~CXFA_PDFFontMgr() {
+  m_FDE2PDFFont.RemoveAll();
+  for (const auto& pair : m_FontMap) {
+    if (pair.second)
+      pair.second->Release();
+  }
+}
+IFX_Font* CXFA_PDFFontMgr::FindFont(CFX_ByteString strPsName,
+                                    FX_BOOL bBold,
+                                    FX_BOOL bItalic,
+                                    CPDF_Font** pDstPDFFont,
+                                    FX_BOOL bStrictMatch) {
+  CPDF_Document* pDoc = m_pDoc->GetPDFDoc();
+  if (pDoc == NULL) {
+    return NULL;
+  }
+  CPDF_Dictionary* pFontSetDict =
+      pDoc->GetRoot()->GetDictBy("AcroForm")->GetDictBy("DR");
+  if (!pFontSetDict) {
+    return NULL;
+  }
+  pFontSetDict = (CPDF_Dictionary*)pFontSetDict->GetDictBy("Font");
+  if (!pFontSetDict) {
+    return NULL;
+  }
+  strPsName.Remove(' ');
+  IFX_FontMgr* pFDEFontMgr = m_pDoc->GetApp()->GetFDEFontMgr();
+  for (const auto& it : *pFontSetDict) {
+    const CFX_ByteString& key = it.first;
+    CPDF_Object* pObj = it.second;
+    if (!PsNameMatchDRFontName(strPsName, bBold, bItalic, key, bStrictMatch)) {
+      continue;
+    }
+    CPDF_Object* pDirect = pObj->GetDirect();
+    if (!pDirect || !pDirect->IsDictionary()) {
+      return NULL;
+    }
+    CPDF_Dictionary* pFontDict = (CPDF_Dictionary*)pDirect;
+    if (pFontDict->GetStringBy("Type") != "Font") {
+      return NULL;
+    }
+    CPDF_Font* pPDFFont = pDoc->LoadFont(pFontDict);
+    if (!pPDFFont) {
+      return NULL;
+    }
+    if (!pPDFFont->IsEmbedded()) {
+      *pDstPDFFont = pPDFFont;
+      return NULL;
+    }
+    return IFX_Font::LoadFont(&pPDFFont->m_Font, pFDEFontMgr);
+  }
+  return NULL;
+}
+IFX_Font* CXFA_PDFFontMgr::GetFont(const CFX_WideStringC& wsFontFamily,
+                                   FX_DWORD dwFontStyles,
+                                   CPDF_Font** pPDFFont,
+                                   FX_BOOL bStrictMatch) {
+  FX_DWORD dwHashCode =
+      FX_HashCode_String_GetW(wsFontFamily.GetPtr(), wsFontFamily.GetLength());
+  CFX_ByteString strKey;
+  strKey.Format("%u%u", dwHashCode, dwFontStyles);
+  auto it = m_FontMap.find(strKey);
+  if (it != m_FontMap.end())
+    return it->second;
+  CFX_ByteString bsPsName = CFX_ByteString::FromUnicode(wsFontFamily);
+  FX_BOOL bBold = (dwFontStyles & FX_FONTSTYLE_Bold) == FX_FONTSTYLE_Bold;
+  FX_BOOL bItalic = (dwFontStyles & FX_FONTSTYLE_Italic) == FX_FONTSTYLE_Italic;
+  CFX_ByteString strFontName = PsNameToFontName(bsPsName, bBold, bItalic);
+  IFX_Font* pFont =
+      FindFont(strFontName, bBold, bItalic, pPDFFont, bStrictMatch);
+  if (pFont)
+    m_FontMap[strKey] = pFont;
+  return pFont;
+}
+CFX_ByteString CXFA_PDFFontMgr::PsNameToFontName(
+    const CFX_ByteString& strPsName,
+    FX_BOOL bBold,
+    FX_BOOL bItalic) {
+  int32_t nCount = sizeof(g_XFAPDFFontName) / sizeof(XFA_PDFFONTNAME);
+  for (int32_t i = 0; i < nCount; i++) {
+    if (strPsName == g_XFAPDFFontName[i].lpPsName) {
+      int32_t index = 1 + ((bItalic << 1) | bBold);
+      return *(&g_XFAPDFFontName[i].lpPsName + index);
+    }
+  }
+  return strPsName;
+}
+FX_BOOL CXFA_PDFFontMgr::PsNameMatchDRFontName(
+    const CFX_ByteStringC& bsPsName,
+    FX_BOOL bBold,
+    FX_BOOL bItalic,
+    const CFX_ByteString& bsDRFontName,
+    FX_BOOL bStrictMatch) {
+  CFX_ByteString bsDRName = bsDRFontName;
+  bsDRName.Remove('-');
+  int32_t iPsLen = bsPsName.GetLength();
+  int32_t nIndex = bsDRName.Find(bsPsName);
+  if (nIndex != -1 && !bStrictMatch) {
+    return TRUE;
+  }
+  if (nIndex != 0) {
+    return FALSE;
+  }
+  int32_t iDifferLength = bsDRName.GetLength() - iPsLen;
+  if (iDifferLength > 1 || (bBold || bItalic)) {
+    int32_t iBoldIndex = bsDRName.Find("Bold");
+    FX_BOOL bBoldFont = iBoldIndex > 0;
+    if (bBold ^ bBoldFont) {
+      return FALSE;
+    }
+    if (bBoldFont) {
+      iDifferLength =
+          std::min(iDifferLength - 4, bsDRName.GetLength() - iBoldIndex - 4);
+    }
+    FX_BOOL bItalicFont = TRUE;
+    if (bsDRName.Find("Italic") > 0) {
+      iDifferLength -= 6;
+    } else if (bsDRName.Find("It") > 0) {
+      iDifferLength -= 2;
+    } else if (bsDRName.Find("Oblique") > 0) {
+      iDifferLength -= 7;
+    } else {
+      bItalicFont = FALSE;
+    }
+    if (bItalic ^ bItalicFont) {
+      return FALSE;
+    }
+    if (iDifferLength > 1) {
+      CFX_ByteString bsDRTailer = bsDRName.Right(iDifferLength);
+      if (bsDRTailer.Equal("MT") || bsDRTailer.Equal("PSMT") ||
+          bsDRTailer.Equal("Regular") || bsDRTailer.Equal("Reg")) {
+        return TRUE;
+      }
+      if (bBoldFont || bItalicFont) {
+        return FALSE;
+      }
+      FX_BOOL bMatch = FALSE;
+      switch (bsPsName.GetAt(iPsLen - 1)) {
+        case 'L': {
+          if (bsDRName.Right(5).Equal("Light")) {
+            bMatch = TRUE;
+          }
+        } break;
+        case 'R': {
+          if (bsDRName.Right(7).Equal("Regular") ||
+              bsDRName.Right(3).Equal("Reg")) {
+            bMatch = TRUE;
+          }
+        } break;
+        case 'M': {
+          if (bsDRName.Right(5).Equal("Medium")) {
+            bMatch = TRUE;
+          }
+        } break;
+        default:
+          break;
+      }
+      return bMatch;
+    }
+  }
+  return TRUE;
+}
+FX_BOOL CXFA_PDFFontMgr::GetCharWidth(IFX_Font* pFont,
+                                      FX_WCHAR wUnicode,
+                                      int32_t& iWidth,
+                                      FX_BOOL bCharCode) {
+  if (wUnicode != 0x20 || bCharCode) {
+    return FALSE;
+  }
+  CPDF_Font* pPDFFont = (CPDF_Font*)m_FDE2PDFFont.GetValueAt(pFont);
+  if (!pPDFFont) {
+    return FALSE;
+  }
+  wUnicode = (FX_WCHAR)pPDFFont->CharCodeFromUnicode(wUnicode);
+  iWidth = pPDFFont->GetCharWidthF(wUnicode);
+  return TRUE;
+}
+CXFA_FontMgr::CXFA_FontMgr() : m_pDefFontMgr(NULL) {}
+CXFA_FontMgr::~CXFA_FontMgr() {
+  DelAllMgrMap();
+}
+IFX_Font* CXFA_FontMgr::GetFont(IXFA_Doc* hDoc,
+                                const CFX_WideStringC& wsFontFamily,
+                                FX_DWORD dwFontStyles,
+                                FX_WORD wCodePage) {
+  FX_DWORD dwHash = FX_HashCode_String_GetW(wsFontFamily.GetPtr(),
+                                            wsFontFamily.GetLength(), FALSE);
+  CFX_ByteString bsKey;
+  bsKey.Format("%u%u%u", dwHash, dwFontStyles, wCodePage);
+  auto it = m_FontMap.find(bsKey);
+  if (it != m_FontMap.end())
+    return it->second;
+  CFX_WideString wsEnglishName;
+  XFA_LocalFontNameToEnglishName(wsFontFamily, wsEnglishName);
+  CXFA_PDFFontMgr* pMgr = (CXFA_PDFFontMgr*)m_PDFFontMgrArray.GetValueAt(hDoc);
+  CPDF_Font* pPDFFont = NULL;
+  IFX_Font* pFont = NULL;
+  if (pMgr) {
+    pFont = pMgr->GetFont(wsEnglishName, dwFontStyles, &pPDFFont);
+    if (pFont)
+      return pFont;
+  }
+  if (!pFont && m_pDefFontMgr) {
+    pFont = m_pDefFontMgr->GetFont(hDoc, wsFontFamily, dwFontStyles, wCodePage);
+  }
+  if (!pFont && pMgr) {
+    pPDFFont = NULL;
+    pFont = pMgr->GetFont(wsEnglishName, dwFontStyles, &pPDFFont, FALSE);
+    if (pFont)
+      return pFont;
+  }
+  if (!pFont && m_pDefFontMgr) {
+    pFont = m_pDefFontMgr->GetDefaultFont(hDoc, wsFontFamily, dwFontStyles,
+                                          wCodePage);
+  }
+  if (pFont) {
+    if (pPDFFont) {
+      pMgr->m_FDE2PDFFont.SetAt(pFont, pPDFFont);
+      pFont->SetFontProvider(pMgr);
+    }
+    m_FontMap[bsKey] = pFont;
+  }
+  return pFont;
+}
+void CXFA_FontMgr::LoadDocFonts(IXFA_Doc* hDoc) {
+  if (!m_PDFFontMgrArray.GetValueAt(hDoc)) {
+    m_PDFFontMgrArray.SetAt(hDoc, new CXFA_PDFFontMgr((CXFA_FFDoc*)hDoc));
+  }
+}
+void CXFA_FontMgr::ReleaseDocFonts(IXFA_Doc* hDoc) {
+  CXFA_PDFFontMgr* pMgr = NULL;
+  if (m_PDFFontMgrArray.Lookup(hDoc, (void*&)pMgr)) {
+    delete pMgr;
+    m_PDFFontMgrArray.RemoveKey(hDoc);
+  }
+}
+void CXFA_FontMgr::DelAllMgrMap() {
+  FX_POSITION ps = m_PDFFontMgrArray.GetStartPosition();
+  while (ps) {
+    IXFA_Doc* hDoc = NULL;
+    CXFA_PDFFontMgr* pMgr = NULL;
+    m_PDFFontMgrArray.GetNextAssoc(ps, (void*&)hDoc, (void*&)pMgr);
+    delete pMgr;
+  }
+  m_PDFFontMgrArray.RemoveAll();
+  m_FontMap.clear();
+}
+void CXFA_FontMgr::SetDefFontMgr(IXFA_FontMgr* pFontMgr) {
+  m_pDefFontMgr = pFontMgr;
+}
diff --git a/xfa/fxfa/app/xfa_fontmgr.h b/xfa/fxfa/app/xfa_fontmgr.h
new file mode 100644
index 0000000..4436079
--- /dev/null
+++ b/xfa/fxfa/app/xfa_fontmgr.h
@@ -0,0 +1,100 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FONTMGR_H_
+#define XFA_FXFA_APP_XFA_FONTMGR_H_
+
+#include <map>
+
+#include "core/include/fxcrt/fx_ext.h"
+#include "core/include/fxcrt/fx_system.h"
+#include "xfa/fgas/font/fgas_font.h"
+#include "xfa/include/fxfa/fxfa.h"
+
+class CPDF_Font;
+
+struct XFA_FONTINFO {
+  FX_DWORD dwFontNameHash;
+  const FX_WCHAR* pPsName;
+  const FX_WCHAR* pReplaceFont;
+  FX_WORD dwStyles;
+  FX_WORD wCodePage;
+};
+
+class CXFA_DefFontMgr : public IXFA_FontMgr {
+ public:
+  CXFA_DefFontMgr() {}
+  ~CXFA_DefFontMgr() override;
+
+  // IXFA_FontMgr:
+  IFX_Font* GetFont(IXFA_Doc* hDoc,
+                    const CFX_WideStringC& wsFontFamily,
+                    FX_DWORD dwFontStyles,
+                    FX_WORD wCodePage = 0xFFFF) override;
+  IFX_Font* GetDefaultFont(IXFA_Doc* hDoc,
+                           const CFX_WideStringC& wsFontFamily,
+                           FX_DWORD dwFontStyles,
+                           FX_WORD wCodePage = 0xFFFF) override;
+
+ protected:
+  CFX_PtrArray m_CacheFonts;
+};
+
+class CXFA_PDFFontMgr : public IFX_FontProvider {
+ public:
+  CXFA_PDFFontMgr(CXFA_FFDoc* pDoc);
+  ~CXFA_PDFFontMgr();
+  IFX_Font* GetFont(const CFX_WideStringC& wsFontFamily,
+                    FX_DWORD dwFontStyles,
+                    CPDF_Font** pPDFFont,
+                    FX_BOOL bStrictMatch = TRUE);
+  FX_BOOL GetCharWidth(IFX_Font* pFont,
+                       FX_WCHAR wUnicode,
+                       int32_t& iWidth,
+                       FX_BOOL bCharCode);
+  CFX_MapPtrToPtr m_FDE2PDFFont;
+
+ protected:
+  IFX_Font* FindFont(CFX_ByteString strFamilyName,
+                     FX_BOOL bBold,
+                     FX_BOOL bItalic,
+                     CPDF_Font** pPDFFont,
+                     FX_BOOL bStrictMatch = TRUE);
+  CFX_ByteString PsNameToFontName(const CFX_ByteString& strPsName,
+                                  FX_BOOL bBold,
+                                  FX_BOOL bItalic);
+  FX_BOOL PsNameMatchDRFontName(const CFX_ByteStringC& bsPsName,
+                                FX_BOOL bBold,
+                                FX_BOOL bItalic,
+                                const CFX_ByteString& bsDRFontName,
+                                FX_BOOL bStrictMatch = TRUE);
+
+  CXFA_FFDoc* m_pDoc;
+  std::map<CFX_ByteString, IFX_Font*> m_FontMap;
+};
+
+class CXFA_FontMgr {
+ public:
+  CXFA_FontMgr();
+  ~CXFA_FontMgr();
+  IFX_Font* GetFont(IXFA_Doc* hDoc,
+                    const CFX_WideStringC& wsFontFamily,
+                    FX_DWORD dwFontStyles,
+                    FX_WORD wCodePage = 0xFFFF);
+  void LoadDocFonts(IXFA_Doc* hDoc);
+  void ReleaseDocFonts(IXFA_Doc* hDoc);
+
+  void SetDefFontMgr(IXFA_FontMgr* pFontMgr);
+
+ protected:
+  void DelAllMgrMap();
+
+  CFX_MapPtrToPtr m_PDFFontMgrArray;
+  IXFA_FontMgr* m_pDefFontMgr;
+  std::map<CFX_ByteString, IFX_Font*> m_FontMap;
+};
+
+#endif  //  XFA_FXFA_APP_XFA_FONTMGR_H_
diff --git a/xfa/fxfa/app/xfa_fwladapter.cpp b/xfa/fxfa/app/xfa_fwladapter.cpp
new file mode 100644
index 0000000..1e6010e
--- /dev/null
+++ b/xfa/fxfa/app/xfa_fwladapter.cpp
@@ -0,0 +1,61 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_fwladapter.h"
+
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_fffield.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+
+void FWL_PostMessageToMainRoop(CFWL_Message* pMessage) {}
+FX_BOOL FWL_ShowCaret(IFWL_Widget* pWidget,
+                      FX_BOOL bVisible,
+                      const CFX_RectF* pRtAnchor) {
+  CXFA_FFWidget* pXFAWidget = (CXFA_FFWidget*)pWidget->GetPrivateData(pWidget);
+  if (!pXFAWidget) {
+    return FALSE;
+  }
+  IXFA_DocProvider* pDocProvider = pXFAWidget->GetDoc()->GetDocProvider();
+  if (!pDocProvider) {
+    return FALSE;
+  }
+  if (bVisible) {
+    CFX_Matrix mt;
+    pXFAWidget->GetRotateMatrix(mt);
+    CFX_RectF rt(*pRtAnchor);
+    mt.TransformRect(rt);
+    pDocProvider->DisplayCaret(pXFAWidget, bVisible, &rt);
+    return TRUE;
+  }
+  pDocProvider->DisplayCaret(pXFAWidget, bVisible, pRtAnchor);
+  return TRUE;
+}
+
+FWL_ERR CXFA_FWLAdapterWidgetMgr::RepaintWidget(IFWL_Widget* pWidget,
+                                                const CFX_RectF* pRect) {
+  if (!pWidget)
+    return FWL_ERR_Indefinite;
+  CXFA_FFField* pField = (CXFA_FFField*)pWidget->GetPrivateData(pWidget);
+  if (!pField)
+    return FWL_ERR_Indefinite;
+  pField->AddInvalidateRect(nullptr);
+  return FWL_ERR_Succeeded;
+}
+
+FX_BOOL CXFA_FWLAdapterWidgetMgr::GetPopupPos(IFWL_Widget* pWidget,
+                                              FX_FLOAT fMinHeight,
+                                              FX_FLOAT fMaxHeight,
+                                              const CFX_RectF& rtAnchor,
+                                              CFX_RectF& rtPopup) {
+  CXFA_FFWidget* pFFWidget = (CXFA_FFWidget*)(pWidget->GetPrivateData(pWidget));
+  CFX_Matrix mt;
+  pFFWidget->GetRotateMatrix(mt);
+  CFX_RectF rtRotateAnchor(rtAnchor);
+  mt.TransformRect(rtRotateAnchor);
+  pFFWidget->GetDoc()->GetDocProvider()->GetPopupPos(
+      pFFWidget, fMinHeight, fMaxHeight, rtRotateAnchor, rtPopup);
+  return TRUE;
+}
diff --git a/xfa/fxfa/app/xfa_fwladapter.h b/xfa/fxfa/app/xfa_fwladapter.h
new file mode 100644
index 0000000..bf9a3d6
--- /dev/null
+++ b/xfa/fxfa/app/xfa_fwladapter.h
@@ -0,0 +1,22 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FWLADAPTER_H_
+#define XFA_FXFA_APP_XFA_FWLADAPTER_H_
+
+#include "xfa/include/fwl/adapter/fwl_sdadapterimp.h"
+
+class CXFA_FWLAdapterWidgetMgr : public CFWL_SDAdapterWidgetMgr {
+ public:
+  virtual FWL_ERR RepaintWidget(IFWL_Widget* pWidget, const CFX_RectF* pRect);
+  virtual FX_BOOL GetPopupPos(IFWL_Widget* pWidget,
+                              FX_FLOAT fMinHeight,
+                              FX_FLOAT fMaxHeight,
+                              const CFX_RectF& rtAnchor,
+                              CFX_RectF& rtPopup);
+};
+
+#endif  // XFA_FXFA_APP_XFA_FWLADAPTER_H_
diff --git a/xfa/fxfa/app/xfa_fwltheme.cpp b/xfa/fxfa/app/xfa_fwltheme.cpp
new file mode 100644
index 0000000..b0657ee
--- /dev/null
+++ b/xfa/fxfa/app/xfa_fwltheme.cpp
@@ -0,0 +1,424 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_fwltheme.h"
+
+#include "xfa/fde/tto/fde_textout.h"
+#include "xfa/fgas/crt/fgas_codepage.h"
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+#include "xfa/include/fwl/basewidget/fwl_barcode.h"
+#include "xfa/include/fwl/basewidget/fwl_caret.h"
+#include "xfa/include/fwl/basewidget/fwl_checkbox.h"
+#include "xfa/include/fwl/basewidget/fwl_combobox.h"
+#include "xfa/include/fwl/basewidget/fwl_datetimepicker.h"
+#include "xfa/include/fwl/basewidget/fwl_edit.h"
+#include "xfa/include/fwl/basewidget/fwl_listbox.h"
+#include "xfa/include/fwl/basewidget/fwl_monthcalendar.h"
+#include "xfa/include/fwl/basewidget/fwl_picturebox.h"
+#include "xfa/include/fwl/basewidget/fwl_pushbutton.h"
+#include "xfa/include/fwl/basewidget/fwl_scrollbar.h"
+
+CXFA_FFWidget* XFA_ThemeGetOuterWidget(IFWL_Widget* pWidget) {
+  IFWL_Widget* pOuter = pWidget;
+  while (pOuter->GetOuter()) {
+    pOuter = pOuter->GetOuter();
+  }
+  if (pOuter) {
+    return (CXFA_FFWidget*)pOuter->GetPrivateData(pOuter);
+  }
+  return NULL;
+}
+CXFA_FWLTheme::CXFA_FWLTheme(CXFA_FFApp* pApp) : m_pApp(pApp) {
+  m_pTextOut = NULL;
+  m_dwCapacity = 0;
+  m_fCapacity = 0;
+  m_pCalendarFont = NULL;
+  m_Rect.Set(0, 0, 0, 0);
+  m_pCheckBoxTP = new CXFA_FWLCheckBoxTP;
+  m_pListBoxTP = new CFWL_ListBoxTP;
+  m_pPictureBoxTP = new CFWL_PictureBoxTP;
+  m_pSrollBarTP = new CFWL_ScrollBarTP;
+  m_pEditTP = new CXFA_FWLEditTP;
+  m_pComboBoxTP = new CFWL_ComboBoxTP;
+  m_pMonthCalendarTP = new CFWL_MonthCalendarTP;
+  m_pDateTimePickerTP = new CFWL_DateTimePickerTP;
+  m_pPushButtonTP = new CFWL_PushButtonTP;
+  m_pCaretTP = new CFWL_CaretTP;
+  m_pBarcodeTP = new CFWL_BarcodeTP;
+  Initialize();
+}
+CXFA_FWLTheme::~CXFA_FWLTheme() {
+  Finalize();
+  delete m_pCheckBoxTP;
+  delete m_pListBoxTP;
+  delete m_pPictureBoxTP;
+  delete m_pSrollBarTP;
+  delete m_pEditTP;
+  delete m_pComboBoxTP;
+  delete m_pMonthCalendarTP;
+  delete m_pDateTimePickerTP;
+  delete m_pPushButtonTP;
+  delete m_pCaretTP;
+  delete m_pBarcodeTP;
+}
+static const FX_WCHAR* g_FWLTheme_CalFonts[] = {
+    L"Arial", L"Courier New", L"DejaVu Sans",
+};
+FWL_ERR CXFA_FWLTheme::Initialize() {
+  m_pTextOut = IFDE_TextOut::Create();
+  for (size_t i = 0; !m_pCalendarFont && i < FX_ArraySize(g_FWLTheme_CalFonts);
+       ++i) {
+    m_pCalendarFont = IFX_Font::LoadFont(g_FWLTheme_CalFonts[i], 0, 0,
+                                         m_pApp->GetFDEFontMgr());
+  }
+  if (!m_pCalendarFont) {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+    m_pCalendarFont = m_pApp->GetFDEFontMgr()->GetDefFontByCodePage(
+        FX_CODEPAGE_MSWin_WesternEuropean, 0, NULL);
+#else
+    m_pCalendarFont = m_pApp->GetFDEFontMgr()->GetFontByCodePage(
+        FX_CODEPAGE_MSWin_WesternEuropean, 0, NULL);
+#endif
+  }
+
+  FXSYS_assert(NULL != m_pCalendarFont);
+  FWLTHEME_Init();
+  return FWL_ERR_Succeeded;
+}
+FWL_ERR CXFA_FWLTheme::Finalize() {
+  if (m_pTextOut) {
+    m_pTextOut->Release();
+    m_pTextOut = NULL;
+  }
+  if (m_pCalendarFont) {
+    m_pCalendarFont->Release();
+    m_pCalendarFont = NULL;
+  }
+  FWLTHEME_Release();
+  return FWL_ERR_Succeeded;
+}
+FX_BOOL CXFA_FWLTheme::IsValidWidget(IFWL_Widget* pWidget) {
+  return TRUE;
+}
+FX_DWORD CXFA_FWLTheme::GetThemeID(IFWL_Widget* pWidget) {
+  return 0;
+}
+FX_DWORD CXFA_FWLTheme::SetThemeID(IFWL_Widget* pWidget,
+                                   FX_DWORD dwThemeID,
+                                   FX_BOOL bChildren) {
+  return 0;
+}
+FX_BOOL CXFA_FWLTheme::DrawBackground(CFWL_ThemeBackground* pParams) {
+  return GetTheme(pParams->m_pWidget)->DrawBackground(pParams);
+}
+FX_BOOL CXFA_FWLTheme::DrawText(CFWL_ThemeText* pParams) {
+  if (pParams->m_wsText.IsEmpty()) {
+    return FWL_ERR_Indefinite;
+  }
+  if (pParams->m_pWidget->GetClassID() == FWL_CLASSHASH_MonthCalendar) {
+    CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
+    if (!pWidget) {
+      return FWL_ERR_Indefinite;
+    }
+    m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
+    m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
+    m_pTextOut->SetFont(m_pCalendarFont);
+    m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize);
+    m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor);
+    if ((pParams->m_iPart == FWL_PART_MCD_DatesIn) &&
+        !(pParams->m_dwStates & FWL_ITEMSTATE_MCD_Flag) &&
+        (pParams->m_dwStates &
+         (FWL_PARTSTATE_MCD_Hovered | FWL_PARTSTATE_MCD_Selected))) {
+      m_pTextOut->SetTextColor(0xFFFFFFFF);
+    }
+    if (pParams->m_iPart == FWL_PART_MCD_Caption) {
+      if (m_pMonthCalendarTP->GetThemeID(pParams->m_pWidget) == 0) {
+        m_pTextOut->SetTextColor(ArgbEncode(0xff, 0, 153, 255));
+      } else {
+        m_pTextOut->SetTextColor(ArgbEncode(0xff, 128, 128, 0));
+      }
+    }
+    CFX_Graphics* pGraphics = pParams->m_pGraphics;
+    CFX_RenderDevice* pRenderDevice = pGraphics->GetRenderDevice();
+    if (!pRenderDevice)
+      return FALSE;
+    m_pTextOut->SetRenderDevice(pRenderDevice);
+    CFX_Matrix mtPart = pParams->m_matrix;
+    CFX_Matrix* pMatrix = pGraphics->GetMatrix();
+    if (pMatrix) {
+      mtPart.Concat(*pMatrix);
+    }
+    m_pTextOut->SetMatrix(mtPart);
+    m_pTextOut->DrawLogicText(pParams->m_wsText, pParams->m_wsText.GetLength(),
+                              pParams->m_rtPart);
+    return TRUE;
+  }
+  CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
+  if (!pWidget) {
+    return FWL_ERR_Indefinite;
+  }
+  CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
+  CFX_Graphics* pGraphics = pParams->m_pGraphics;
+  CFX_RenderDevice* pRenderDevice = pGraphics->GetRenderDevice();
+  if (!pRenderDevice)
+    return FALSE;
+  m_pTextOut->SetRenderDevice(pRenderDevice);
+  m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
+  m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
+  m_pTextOut->SetFont(pAcc->GetFDEFont());
+  m_pTextOut->SetFontSize(pAcc->GetFontSize());
+  m_pTextOut->SetTextColor(pAcc->GetTextColor());
+  CFX_Matrix mtPart = pParams->m_matrix;
+  CFX_Matrix* pMatrix = pGraphics->GetMatrix();
+  if (pMatrix) {
+    mtPart.Concat(*pMatrix);
+  }
+  m_pTextOut->SetMatrix(mtPart);
+  m_pTextOut->DrawLogicText(pParams->m_wsText, pParams->m_wsText.GetLength(),
+                            pParams->m_rtPart);
+  return TRUE;
+}
+void* CXFA_FWLTheme::GetCapacity(CFWL_ThemePart* pThemePart,
+                                 FX_DWORD dwCapacity) {
+  switch (dwCapacity) {
+    case FWL_WGTCAPACITY_Font: {
+      if (CXFA_FFWidget* pWidget =
+              XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
+        return pWidget->GetDataAcc()->GetFDEFont();
+      }
+    } break;
+    case FWL_WGTCAPACITY_FontSize: {
+      if (CXFA_FFWidget* pWidget =
+              XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
+        m_fCapacity = pWidget->GetDataAcc()->GetFontSize();
+        return &m_fCapacity;
+      }
+    } break;
+    case FWL_WGTCAPACITY_TextColor: {
+      if (CXFA_FFWidget* pWidget =
+              XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
+        m_dwCapacity = pWidget->GetDataAcc()->GetTextColor();
+        return &m_dwCapacity;
+      }
+    } break;
+    case FWL_WGTCAPACITY_LineHeight: {
+      if (CXFA_FFWidget* pWidget =
+              XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
+        m_fCapacity = pWidget->GetDataAcc()->GetLineHeight();
+        return &m_fCapacity;
+      }
+    } break;
+    case FWL_WGTCAPACITY_ScrollBarWidth: {
+      m_fCapacity = 9;
+      return &m_fCapacity;
+    } break;
+    case FWL_WGTCAPACITY_UIMargin: {
+      CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget);
+      if (pWidget) {
+        CXFA_LayoutItem* pItem = pWidget;
+        CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc();
+        pWidgetAcc->GetUIMargin(m_Rect);
+        if (CXFA_Para para = pWidgetAcc->GetPara()) {
+          m_Rect.left += para.GetMarginLeft();
+          if (pWidgetAcc->IsMultiLine()) {
+            m_Rect.width += para.GetMarginRight();
+          }
+        }
+        if (pItem->GetPrev() == NULL) {
+          if (pItem->GetNext()) {
+            m_Rect.height = 0;
+          }
+        } else if (pItem->GetNext() == NULL) {
+          m_Rect.top = 0;
+        } else {
+          m_Rect.top = 0;
+          m_Rect.height = 0;
+        }
+      }
+      return &m_Rect;
+    } break;
+    case FWL_WGTCAPACITY_SpaceAboveBelow: {
+      CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget);
+      if (pWidget) {
+        CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc();
+        if (CXFA_Para para = pWidgetAcc->GetPara()) {
+          m_SizeAboveBelow.x = para.GetSpaceAbove();
+          m_SizeAboveBelow.y = para.GetSpaceBelow();
+        }
+      }
+      return &m_SizeAboveBelow;
+    } break;
+    default:
+      break;
+  }
+  if (pThemePart->m_pWidget->GetClassID() == FWL_CLASSHASH_MonthCalendar &&
+      dwCapacity >= FWL_MCCAPACITY_Sun && dwCapacity <= FWL_MCCAPACITY_Today) {
+    if (CXFA_FFWidget* pWidget =
+            XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
+      IXFA_AppProvider* pAppProvider = pWidget->GetAppProvider();
+      m_wsResource.Empty();
+      pAppProvider->LoadString(
+          XFA_IDS_StringWeekDay_Sun + dwCapacity - FWL_WGTCAPACITY_MAX - 5,
+          m_wsResource);
+      if (!m_wsResource.IsEmpty()) {
+        return &m_wsResource;
+      }
+    }
+  }
+  return GetTheme(pThemePart->m_pWidget)->GetCapacity(pThemePart, dwCapacity);
+}
+FX_BOOL CXFA_FWLTheme::IsCustomizedLayout(IFWL_Widget* pWidget) {
+  return GetTheme(pWidget)->IsCustomizedLayout(pWidget);
+}
+FWL_ERR CXFA_FWLTheme::GetPartRect(CFWL_ThemePart* pThemePart) {
+  CFX_RectF rect;
+  return GetTheme(pThemePart->m_pWidget)->GetPartRect(pThemePart, rect);
+}
+FX_BOOL CXFA_FWLTheme::IsInPart(CFWL_ThemePart* pThemePart,
+                                FX_FLOAT fx,
+                                FX_FLOAT fy) {
+  return GetTheme(pThemePart->m_pWidget)->IsInPart(pThemePart, fx, fy);
+}
+FX_BOOL CXFA_FWLTheme::CalcTextRect(CFWL_ThemeText* pParams, CFX_RectF& rect) {
+  if (pParams->m_pWidget->GetClassID() == FWL_CLASSHASH_MonthCalendar) {
+    CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
+    if (!pWidget) {
+      return FWL_ERR_Indefinite;
+    }
+    if (!pParams)
+      return FALSE;
+    if (!m_pTextOut)
+      return FALSE;
+    m_pTextOut->SetFont(m_pCalendarFont);
+    m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize);
+    m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor);
+    m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
+    m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
+    m_pTextOut->CalcLogicSize(pParams->m_wsText, pParams->m_wsText.GetLength(),
+                              rect);
+    return TRUE;
+  }
+  CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
+  if (!pWidget) {
+    return FWL_ERR_Indefinite;
+  }
+  CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
+  m_pTextOut->SetFont(pAcc->GetFDEFont());
+  m_pTextOut->SetFontSize(pAcc->GetFontSize());
+  m_pTextOut->SetTextColor(pAcc->GetTextColor());
+  if (!pParams)
+    return FALSE;
+  if (!m_pTextOut)
+    return FALSE;
+  m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
+  m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
+  m_pTextOut->CalcLogicSize(pParams->m_wsText, pParams->m_wsText.GetLength(),
+                            rect);
+  return TRUE;
+}
+CFWL_WidgetTP* CXFA_FWLTheme::GetTheme(IFWL_Widget* pWidget) {
+  switch (pWidget->GetClassID()) {
+    case FWL_CLASSHASH_CheckBox:
+      return m_pCheckBoxTP;
+    case FWL_CLASSHASH_ListBox:
+      return m_pListBoxTP;
+    case FWL_CLASSHASH_PictureBox:
+      return m_pPictureBoxTP;
+    case FWL_CLASSHASH_ScrollBar:
+      return m_pSrollBarTP;
+    case FWL_CLASSHASH_Edit:
+      return m_pEditTP;
+    case FWL_CLASSHASH_ComboBox:
+      return m_pComboBoxTP;
+    case FWL_CLASSHASH_MonthCalendar:
+      return m_pMonthCalendarTP;
+    case FWL_CLASSHASH_DateTimePicker:
+      return m_pDateTimePickerTP;
+    case FWL_CLASSHASH_PushButton:
+      return m_pPushButtonTP;
+    case FWL_CLASSHASH_Caret:
+      return m_pCaretTP;
+    case FWL_CLASSHASH_Barcode:
+      return m_pBarcodeTP;
+    default:
+      break;
+  }
+  return NULL;
+}
+CXFA_FWLCheckBoxTP::CXFA_FWLCheckBoxTP() {}
+FX_BOOL CXFA_FWLCheckBoxTP::DrawBackground(CFWL_ThemeBackground* pParams) {
+  if (pParams->m_iPart != FWL_PART_CKB_CheckBox) {
+    return TRUE;
+  }
+  if (((pParams->m_dwStates & FWL_PARTSTATE_CKB_Mask2) ==
+       FWL_PARTSTATE_CKB_Checked) ||
+      ((pParams->m_dwStates & FWL_PARTSTATE_CKB_Mask2) ==
+       FWL_PARTSTATE_CKB_Neutral)) {
+    DrawCheckSign(pParams->m_pWidget, pParams->m_pGraphics, &pParams->m_rtPart,
+                  pParams->m_dwStates, &pParams->m_matrix);
+  }
+  return TRUE;
+}
+void CXFA_FWLCheckBoxTP::DrawCheckSign(IFWL_Widget* pWidget,
+                                       CFX_Graphics* pGraphics,
+                                       const CFX_RectF* pRtBox,
+                                       int32_t iState,
+                                       CFX_Matrix* pMatrix) {
+  CFX_RectF rtSign(*pRtBox);
+  FX_DWORD dwColor = 0xFF000000;
+  if ((iState & FWL_PARTSTATE_CKB_Mask2) == FWL_PARTSTATE_CKB_Neutral) {
+    dwColor = 0xFFA9A9A9;
+  }
+  {
+    FX_DWORD dwStyle = pWidget->GetStylesEx();
+    rtSign.Deflate(rtSign.width / 4, rtSign.height / 4);
+    switch (dwStyle & FWL_STYLEEXT_CKB_SignShapeMask) {
+      case FWL_STYLEEXT_CKB_SignShapeCheck:
+        DrawSignCheck(pGraphics, &rtSign, dwColor, pMatrix);
+        break;
+      case FWL_STYLEEXT_CKB_SignShapeCircle:
+        DrawSignCircle(pGraphics, &rtSign, dwColor, pMatrix);
+        break;
+      case FWL_STYLEEXT_CKB_SignShapeCross:
+        DrawSignCross(pGraphics, &rtSign, dwColor, pMatrix);
+        break;
+      case FWL_STYLEEXT_CKB_SignShapeDiamond:
+        DrawSignDiamond(pGraphics, &rtSign, dwColor, pMatrix);
+        break;
+      case FWL_STYLEEXT_CKB_SignShapeSquare:
+        DrawSignSquare(pGraphics, &rtSign, dwColor, pMatrix);
+        break;
+      case FWL_STYLEEXT_CKB_SignShapeStar:
+        DrawSignStar(pGraphics, &rtSign, dwColor, pMatrix);
+        break;
+      default:
+        break;
+    }
+  }
+}
+CXFA_FWLEditTP::CXFA_FWLEditTP() {}
+CXFA_FWLEditTP::~CXFA_FWLEditTP() {}
+FX_BOOL CXFA_FWLEditTP::DrawBackground(CFWL_ThemeBackground* pParams) {
+  if (FWL_PART_EDT_CombTextLine == pParams->m_iPart) {
+    CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
+    FX_ARGB cr = 0xFF000000;
+    FX_FLOAT fWidth = 1.0f;
+    if (CXFA_Border borderUI = pWidget->GetDataAcc()->GetUIBorder()) {
+      CXFA_Edge edge = borderUI.GetEdge(0);
+      if (edge) {
+        cr = edge.GetColor();
+        fWidth = edge.GetThickness();
+      }
+    }
+    CFX_Color crLine(cr);
+    pParams->m_pGraphics->SetStrokeColor(&crLine);
+    pParams->m_pGraphics->SetLineWidth(fWidth);
+    pParams->m_pGraphics->StrokePath(pParams->m_pPath, &pParams->m_matrix);
+    return TRUE;
+  }
+  return CFWL_EditTP::DrawBackground(pParams);
+}
diff --git a/xfa/fxfa/app/xfa_fwltheme.h b/xfa/fxfa/app/xfa_fwltheme.h
new file mode 100644
index 0000000..aab8099
--- /dev/null
+++ b/xfa/fxfa/app/xfa_fwltheme.h
@@ -0,0 +1,110 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_FWLTHEME_H_
+#define XFA_FXFA_APP_XFA_FWLTHEME_H_
+
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/include/fwl/core/fwl_target.h"
+#include "xfa/include/fwl/core/fwl_theme.h"
+#include "xfa/include/fwl/theme/barcodetp.h"
+#include "xfa/include/fwl/theme/carettp.h"
+#include "xfa/include/fwl/theme/checkboxtp.h"
+#include "xfa/include/fwl/theme/comboboxtp.h"
+#include "xfa/include/fwl/theme/datetimepickertp.h"
+#include "xfa/include/fwl/theme/edittp.h"
+#include "xfa/include/fwl/theme/listboxtp.h"
+#include "xfa/include/fwl/theme/monthcalendartp.h"
+#include "xfa/include/fwl/theme/pictureboxtp.h"
+#include "xfa/include/fwl/theme/pushbuttontp.h"
+#include "xfa/include/fwl/theme/scrollbartp.h"
+#include "xfa/include/fwl/theme/widgettp.h"
+
+class CXFA_FWLTheme : public IFWL_ThemeProvider {
+ public:
+  CXFA_FWLTheme(CXFA_FFApp* pApp);
+  virtual ~CXFA_FWLTheme();
+  virtual FWL_ERR Release() {
+    delete this;
+    return FWL_ERR_Succeeded;
+  }
+  virtual IFWL_Target* Retain() { return NULL; }
+  virtual FWL_ERR GetClassName(CFX_WideString& wsClass) const {
+    return FWL_ERR_Succeeded;
+  }
+  virtual FX_DWORD GetHashCode() const { return 0; }
+  virtual FWL_ERR Initialize();
+  virtual FWL_ERR Finalize();
+  virtual FX_BOOL IsValidWidget(IFWL_Widget* pWidget);
+  virtual FX_DWORD GetThemeID(IFWL_Widget* pWidget);
+  virtual FX_DWORD SetThemeID(IFWL_Widget* pWidget,
+                              FX_DWORD dwThemeID,
+                              FX_BOOL bChildren = TRUE);
+  virtual FX_BOOL DrawBackground(CFWL_ThemeBackground* pParams);
+  virtual FX_BOOL DrawText(CFWL_ThemeText* pParams);
+  virtual void* GetCapacity(CFWL_ThemePart* pThemePart, FX_DWORD dwCapacity);
+  virtual FX_BOOL IsCustomizedLayout(IFWL_Widget* pWidget);
+  virtual FWL_ERR GetPartRect(CFWL_ThemePart* pThemePart);
+  virtual FX_BOOL IsInPart(CFWL_ThemePart* pThemePart,
+                           FX_FLOAT fx,
+                           FX_FLOAT fy);
+
+  virtual FX_BOOL CalcTextRect(CFWL_ThemeText* pParams, CFX_RectF& rect);
+  virtual FWL_ERR GetThemeMatrix(IFWL_Widget* pWidget, CFX_Matrix& matrix) {
+    return FWL_ERR_Succeeded;
+  }
+  virtual FWL_ERR SetThemeMatrix(IFWL_Widget* pWidget,
+                                 const CFX_Matrix& matrix) {
+    return FWL_ERR_Succeeded;
+  }
+  virtual FWL_ERR GetPartRect(CFWL_ThemePart* pThemePart, CFX_RectF& rtPart) {
+    return FWL_ERR_Succeeded;
+  }
+
+ protected:
+  CFWL_WidgetTP* GetTheme(IFWL_Widget* pWidget);
+  CFWL_CheckBoxTP* m_pCheckBoxTP;
+  CFWL_ListBoxTP* m_pListBoxTP;
+  CFWL_PictureBoxTP* m_pPictureBoxTP;
+  CFWL_ScrollBarTP* m_pSrollBarTP;
+  CFWL_EditTP* m_pEditTP;
+  CFWL_ComboBoxTP* m_pComboBoxTP;
+  CFWL_MonthCalendarTP* m_pMonthCalendarTP;
+  CFWL_DateTimePickerTP* m_pDateTimePickerTP;
+  CFWL_PushButtonTP* m_pPushButtonTP;
+  CFWL_CaretTP* m_pCaretTP;
+  CFWL_BarcodeTP* m_pBarcodeTP;
+  IFDE_TextOut* m_pTextOut;
+  FX_FLOAT m_fCapacity;
+  FX_DWORD m_dwCapacity;
+  IFX_Font* m_pCalendarFont;
+  CFX_WideString m_wsResource;
+  CXFA_FFApp* m_pApp;
+  CFX_RectF m_Rect;
+  CFX_SizeF m_SizeAboveBelow;
+};
+class CXFA_FWLCheckBoxTP : public CFWL_CheckBoxTP {
+ public:
+  CXFA_FWLCheckBoxTP();
+  virtual FX_BOOL DrawBackground(CFWL_ThemeBackground* pParams);
+
+ protected:
+  void DrawCheckSign(IFWL_Widget* pWidget,
+                     CFX_Graphics* pGraphics,
+                     const CFX_RectF* pRtBox,
+                     int32_t iState,
+                     CFX_Matrix* pMatrix);
+};
+class CXFA_FWLEditTP : public CFWL_EditTP {
+ public:
+  CXFA_FWLEditTP();
+  virtual ~CXFA_FWLEditTP();
+
+ public:
+  virtual FX_BOOL DrawBackground(CFWL_ThemeBackground* pParams);
+};
+
+#endif  // XFA_FXFA_APP_XFA_FWLTHEME_H_
diff --git a/xfa/fxfa/app/xfa_rendercontext.cpp b/xfa/fxfa/app/xfa_rendercontext.cpp
new file mode 100644
index 0000000..5b5cf48
--- /dev/null
+++ b/xfa/fxfa/app/xfa_rendercontext.cpp
@@ -0,0 +1,77 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_rendercontext.h"
+
+#include "xfa/fxfa/app/xfa_ffwidget.h"
+#include "xfa/include/fxgraphics/fx_graphics.h"
+
+#define XFA_RENDERCONTEXT_MaxCount 30
+
+IXFA_RenderContext* XFA_RenderContext_Create() {
+  return new CXFA_RenderContext;
+}
+CXFA_RenderContext::CXFA_RenderContext() {
+  m_pWidgetIterator = NULL;
+  m_pWidget = NULL;
+  m_pPageView = NULL;
+  m_pGS = NULL;
+  m_dwStatus = 0;
+  m_matrix.SetIdentity();
+  m_rtClipRect.Reset();
+}
+CXFA_RenderContext::~CXFA_RenderContext() {
+  StopRender();
+}
+int32_t CXFA_RenderContext::StartRender(IXFA_PageView* pPageView,
+                                        CFX_Graphics* pGS,
+                                        const CFX_Matrix& matrix,
+                                        const CXFA_RenderOptions& options) {
+  m_pPageView = pPageView;
+  m_pGS = pGS;
+  m_matrix = matrix;
+  m_options = options;
+  CFX_RectF rtPage;
+  pGS->GetClipRect(rtPage);
+  CFX_Matrix mtRes;
+  mtRes.SetReverse(matrix);
+  m_rtClipRect.Set(rtPage.left, rtPage.top, rtPage.width, rtPage.height);
+  mtRes.TransformRect(m_rtClipRect);
+  m_dwStatus = m_options.m_bHighlight ? XFA_WIDGETSTATUS_Highlight : 0;
+  FX_DWORD dwFilterType = XFA_WIDGETFILTER_Visible | XFA_WIDGETFILTER_AllType |
+                          (m_options.m_bPrint ? XFA_WIDGETSTATUS_Printable
+                                              : XFA_WIDGETSTATUS_Viewable);
+  m_pWidgetIterator =
+      m_pPageView->CreateWidgetIterator(XFA_TRAVERSEWAY_Form, dwFilterType);
+  m_pWidget = m_pWidgetIterator->MoveToNext();
+  return XFA_RENDERSTATUS_Ready;
+}
+int32_t CXFA_RenderContext::DoRender(IFX_Pause* pPause) {
+  int32_t iCount = 0;
+  while (m_pWidget) {
+    CXFA_FFWidget* pWidget = (CXFA_FFWidget*)m_pWidget;
+    CFX_RectF rtWidgetBox;
+    pWidget->GetBBox(rtWidgetBox, XFA_WIDGETSTATUS_Visible);
+    rtWidgetBox.width += 1;
+    rtWidgetBox.height += 1;
+    if (rtWidgetBox.IntersectWith(m_rtClipRect)) {
+      pWidget->RenderWidget(m_pGS, &m_matrix, m_dwStatus);
+    }
+    m_pWidget = m_pWidgetIterator->MoveToNext();
+    iCount++;
+    if (iCount > XFA_RENDERCONTEXT_MaxCount && pPause &&
+        pPause->NeedToPauseNow()) {
+      return XFA_RENDERSTATUS_ToBeContinued;
+    }
+  }
+  return XFA_RENDERSTATUS_Done;
+}
+void CXFA_RenderContext::StopRender() {
+  if (m_pWidgetIterator) {
+    m_pWidgetIterator->Release();
+    m_pWidgetIterator = NULL;
+  }
+}
diff --git a/xfa/fxfa/app/xfa_rendercontext.h b/xfa/fxfa/app/xfa_rendercontext.h
new file mode 100644
index 0000000..ef4b306
--- /dev/null
+++ b/xfa/fxfa/app/xfa_rendercontext.h
@@ -0,0 +1,35 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_RENDERCONTEXT_H_
+#define XFA_FXFA_APP_XFA_RENDERCONTEXT_H_
+
+#include "xfa/include/fxfa/fxfa.h"
+
+class CXFA_RenderContext : public IXFA_RenderContext {
+ public:
+  CXFA_RenderContext();
+  virtual ~CXFA_RenderContext();
+  virtual void Release() { delete this; }
+  virtual int32_t StartRender(IXFA_PageView* pPageView,
+                              CFX_Graphics* pGS,
+                              const CFX_Matrix& matrix,
+                              const CXFA_RenderOptions& options);
+  virtual int32_t DoRender(IFX_Pause* pPause = NULL);
+  virtual void StopRender();
+
+ protected:
+  IXFA_WidgetIterator* m_pWidgetIterator;
+  IXFA_Widget* m_pWidget;
+  IXFA_PageView* m_pPageView;
+  CFX_Graphics* m_pGS;
+  CFX_Matrix m_matrix;
+  CXFA_RenderOptions m_options;
+  FX_DWORD m_dwStatus;
+  CFX_RectF m_rtClipRect;
+};
+
+#endif  // XFA_FXFA_APP_XFA_RENDERCONTEXT_H_
diff --git a/xfa/fxfa/app/xfa_textlayout.cpp b/xfa/fxfa/app/xfa_textlayout.cpp
new file mode 100644
index 0000000..05316f8
--- /dev/null
+++ b/xfa/fxfa/app/xfa_textlayout.cpp
@@ -0,0 +1,2001 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/app/xfa_textlayout.h"
+
+#include <algorithm>
+
+#include "core/include/fxcrt/fx_ext.h"
+#include "xfa/fde/fde_pen.h"
+#include "xfa/fgas/crt/fgas_algorithm.h"
+#include "xfa/fgas/crt/fgas_codepage.h"
+#include "xfa/fxfa/app/xfa_ffapp.h"
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/app/xfa_fontmgr.h"
+
+CXFA_CSSTagProvider::~CXFA_CSSTagProvider() {
+  FX_POSITION pos = m_Attributes.GetStartPosition();
+  while (pos) {
+    CFX_WideString *pName = NULL, *pValue = NULL;
+    m_Attributes.GetNextAssoc(pos, (void*&)pName, (void*&)pValue);
+    delete pName;
+    delete pValue;
+  }
+}
+void CXFA_CSSTagProvider::GetNextAttribute(FX_POSITION& pos,
+                                           CFX_WideStringC& wsAttr,
+                                           CFX_WideStringC& wsValue) {
+  if (pos == NULL) {
+    return;
+  }
+  CFX_WideString* pName = NULL;
+  CFX_WideString* pValue = NULL;
+  m_Attributes.GetNextAssoc(pos, (void*&)pName, (void*&)pValue);
+  wsAttr = *pName;
+  wsValue = *pValue;
+}
+void CXFA_CSSTagProvider::SetAttribute(const CFX_WideString& wsAttr,
+                                       const CFX_WideString& wsValue) {
+  CFX_WideString* pName = new CFX_WideString();
+  CFX_WideString* pValue = new CFX_WideString();
+  *pName = wsAttr;
+  *pValue = wsValue;
+  m_Attributes.SetAt(pName, pValue);
+}
+void CXFA_TextParseContext::SetDecls(const IFDE_CSSDeclaration** ppDeclArray,
+                                     int32_t iDeclCount) {
+  if (iDeclCount <= 0 || ppDeclArray == NULL) {
+    return;
+  }
+  m_dwMatchedDecls = iDeclCount;
+  m_ppMatchedDecls = FX_Alloc(IFDE_CSSDeclaration*, iDeclCount);
+  FXSYS_memcpy(m_ppMatchedDecls, ppDeclArray,
+               iDeclCount * sizeof(IFDE_CSSDeclaration*));
+}
+CXFA_TextParser::~CXFA_TextParser() {
+  if (m_pUASheet)
+    m_pUASheet->Release();
+  if (m_pSelector)
+    m_pSelector->Release();
+  if (m_pAllocator)
+    m_pAllocator->Release();
+  FX_POSITION ps = m_mapXMLNodeToParseContext.GetStartPosition();
+  while (ps) {
+    IFDE_XMLNode* pXMLNode;
+    CXFA_TextParseContext* pParseContext;
+    m_mapXMLNodeToParseContext.GetNextAssoc(ps, pXMLNode, pParseContext);
+    if (pParseContext)
+      FXTARGET_DeleteWith(CXFA_TextParseContext, m_pAllocator, pParseContext);
+  }
+  m_mapXMLNodeToParseContext.RemoveAll();
+}
+void CXFA_TextParser::Reset() {
+  FX_POSITION ps = m_mapXMLNodeToParseContext.GetStartPosition();
+  while (ps) {
+    IFDE_XMLNode* pXMLNode;
+    CXFA_TextParseContext* pParseContext;
+    m_mapXMLNodeToParseContext.GetNextAssoc(ps, pXMLNode, pParseContext);
+    if (pParseContext)
+      FXTARGET_DeleteWith(CXFA_TextParseContext, m_pAllocator, pParseContext);
+  }
+  m_mapXMLNodeToParseContext.RemoveAll();
+  if (m_pAllocator) {
+    m_pAllocator->Release();
+    m_pAllocator = NULL;
+  }
+}
+void CXFA_TextParser::InitCSSData(IXFA_TextProvider* pTextProvider) {
+  if (pTextProvider == NULL) {
+    return;
+  }
+  if (m_pSelector == NULL) {
+    CXFA_FFDoc* pDoc = pTextProvider->GetDocNode();
+    IFX_FontMgr* pFontMgr = pDoc->GetApp()->GetFDEFontMgr();
+    FXSYS_assert(pFontMgr);
+    m_pSelector = IFDE_CSSStyleSelector::Create();
+    m_pSelector->SetFontMgr(pFontMgr);
+    FX_FLOAT fFontSize = 10;
+    CXFA_Font font = pTextProvider->GetFontNode();
+    if (font) {
+      fFontSize = font.GetFontSize();
+    }
+    m_pSelector->SetDefFontSize(fFontSize);
+  }
+  if (m_pUASheet == NULL) {
+    m_pUASheet = LoadDefaultSheetStyle();
+    m_pSelector->SetStyleSheet(FDE_CSSSTYLESHEETGROUP_UserAgent, m_pUASheet);
+    m_pSelector->UpdateStyleIndex(FDE_CSSMEDIATYPE_ALL);
+  }
+}
+IFDE_CSSStyleSheet* CXFA_TextParser::LoadDefaultSheetStyle() {
+  static const FX_WCHAR s_pStyle[] =
+      L"html,body,ol,p,ul{display:block}"
+      L"li{display:list-item}"
+      L"ol,ul{padding-left:33px}ol{list-style-type:decimal}ol,ul{margin-top:0;"
+      L"margin-bottom:0}ul,ol{margin:1.12em 0}"
+      L"a{color:#0000ff;text-decoration:underline}b{font-weight:bolder}i{font-"
+      L"style:italic}"
+      L"sup{vertical-align:+15em;font-size:.66em}sub{vertical-align:-15em;font-"
+      L"size:.66em}";
+  return IFDE_CSSStyleSheet::LoadFromBuffer(
+      CFX_WideString(), s_pStyle, FXSYS_wcslen(s_pStyle), FX_CODEPAGE_UTF8);
+}
+IFDE_CSSComputedStyle* CXFA_TextParser::CreateRootStyle(
+    IXFA_TextProvider* pTextProvider) {
+  CXFA_Font font = pTextProvider->GetFontNode();
+  CXFA_Para para = pTextProvider->GetParaNode();
+  IFDE_CSSComputedStyle* pStyle = m_pSelector->CreateComputedStyle(NULL);
+  IFDE_CSSFontStyle* pFontStyle = pStyle->GetFontStyles();
+  IFDE_CSSParagraphStyle* pParaStyle = pStyle->GetParagraphStyles();
+  FX_FLOAT fLineHeight = 0, fFontSize = 10;
+  if (para) {
+    fLineHeight = para.GetLineHeight();
+    FDE_CSSLENGTH indent;
+    indent.Set(FDE_CSSLENGTHUNIT_Point, para.GetTextIndent());
+    pParaStyle->SetTextIndent(indent);
+    FDE_CSSTEXTALIGN hAlgin = FDE_CSSTEXTALIGN_Left;
+    switch (para.GetHorizontalAlign()) {
+      case XFA_ATTRIBUTEENUM_Center:
+        hAlgin = FDE_CSSTEXTALIGN_Center;
+        break;
+      case XFA_ATTRIBUTEENUM_Right:
+        hAlgin = FDE_CSSTEXTALIGN_Right;
+        break;
+      case XFA_ATTRIBUTEENUM_Justify:
+        hAlgin = FDE_CSSTEXTALIGN_Justify;
+        break;
+      case XFA_ATTRIBUTEENUM_JustifyAll:
+        hAlgin = FDE_CSSTEXTALIGN_JustifyAll;
+        break;
+    }
+    pParaStyle->SetTextAlign(hAlgin);
+    FDE_CSSRECT rtMarginWidth;
+    rtMarginWidth.left.Set(FDE_CSSLENGTHUNIT_Point, para.GetMarginLeft());
+    rtMarginWidth.top.Set(FDE_CSSLENGTHUNIT_Point, para.GetSpaceAbove());
+    rtMarginWidth.right.Set(FDE_CSSLENGTHUNIT_Point, para.GetMarginRight());
+    rtMarginWidth.bottom.Set(FDE_CSSLENGTHUNIT_Point, para.GetSpaceBelow());
+    pStyle->GetBoundaryStyles()->SetMarginWidth(rtMarginWidth);
+  }
+  if (font) {
+    pFontStyle->SetColor(font.GetColor());
+    pFontStyle->SetFontStyle(font.IsItalic() ? FDE_CSSFONTSTYLE_Italic
+                                             : FDE_CSSFONTSTYLE_Normal);
+    pFontStyle->SetFontWeight(font.IsBold() ? FXFONT_FW_BOLD
+                                            : FXFONT_FW_NORMAL);
+    pParaStyle->SetNumberVerticalAlign(-font.GetBaselineShift());
+    fFontSize = font.GetFontSize();
+    FDE_CSSLENGTH letterSpacing;
+    letterSpacing.Set(FDE_CSSLENGTHUNIT_Point, font.GetLetterSpacing());
+    pParaStyle->SetLetterSpacing(letterSpacing);
+    FX_DWORD dwDecoration = 0;
+    if (font.GetLineThrough() > 0) {
+      dwDecoration |= FDE_CSSTEXTDECORATION_LineThrough;
+    }
+    if (font.GetUnderline() > 1) {
+      dwDecoration |= FDE_CSSTEXTDECORATION_Double;
+    } else if (font.GetUnderline() > 0) {
+      dwDecoration |= FDE_CSSTEXTDECORATION_Underline;
+    }
+    pParaStyle->SetTextDecoration(dwDecoration);
+  }
+  pParaStyle->SetLineHeight(fLineHeight);
+  pFontStyle->SetFontSize(fFontSize);
+  return pStyle;
+}
+IFDE_CSSComputedStyle* CXFA_TextParser::CreateStyle(
+    IFDE_CSSComputedStyle* pParentStyle) {
+  IFDE_CSSComputedStyle* pNewStyle =
+      m_pSelector->CreateComputedStyle(pParentStyle);
+  FXSYS_assert(pNewStyle);
+  if (pParentStyle) {
+    IFDE_CSSParagraphStyle* pParaStyle = pParentStyle->GetParagraphStyles();
+    FX_DWORD dwDecoration = pParaStyle->GetTextDecoration();
+    FX_FLOAT fBaseLine = 0;
+    if (pParaStyle->GetVerticalAlign() == FDE_CSSVERTICALALIGN_Number) {
+      fBaseLine = pParaStyle->GetNumberVerticalAlign();
+    }
+    pParaStyle = pNewStyle->GetParagraphStyles();
+    pParaStyle->SetTextDecoration(dwDecoration);
+    pParaStyle->SetNumberVerticalAlign(fBaseLine);
+    IFDE_CSSBoundaryStyle* pBoundarytyle = pParentStyle->GetBoundaryStyles();
+    const FDE_CSSRECT* pRect = pBoundarytyle->GetMarginWidth();
+    if (pRect) {
+      pBoundarytyle = pNewStyle->GetBoundaryStyles();
+      pBoundarytyle->SetMarginWidth(*pRect);
+    }
+  }
+  return pNewStyle;
+}
+IFDE_CSSComputedStyle* CXFA_TextParser::ComputeStyle(
+    IFDE_XMLNode* pXMLNode,
+    IFDE_CSSComputedStyle* pParentStyle) {
+  CXFA_TextParseContext* pContext = static_cast<CXFA_TextParseContext*>(
+      m_mapXMLNodeToParseContext.GetValueAt(pXMLNode));
+  if (!pContext)
+    return nullptr;
+  pContext->m_pParentStyle = pParentStyle;
+  pParentStyle->AddRef();
+  CXFA_CSSTagProvider tagProvider;
+  ParseTagInfo(pXMLNode, tagProvider);
+  if (tagProvider.m_bContent)
+    return nullptr;
+  IFDE_CSSComputedStyle* pStyle = CreateStyle(pParentStyle);
+  IFDE_CSSAccelerator* pCSSAccel = m_pSelector->InitAccelerator();
+  pCSSAccel->OnEnterTag(&tagProvider);
+  m_pSelector->ComputeStyle(&tagProvider, pContext->GetDecls(),
+                            pContext->CountDecls(), pStyle);
+  pCSSAccel->OnLeaveTag(&tagProvider);
+  return pStyle;
+}
+void CXFA_TextParser::DoParse(IFDE_XMLNode* pXMLContainer,
+                              IXFA_TextProvider* pTextProvider) {
+  if (pXMLContainer == NULL || pTextProvider == NULL || m_pAllocator) {
+    return;
+  }
+  m_pAllocator =
+      FX_CreateAllocator(FX_ALLOCTYPE_Fixed, 32, sizeof(CXFA_CSSTagProvider));
+  InitCSSData(pTextProvider);
+  IFDE_CSSComputedStyle* pRootStyle = CreateRootStyle(pTextProvider);
+  ParseRichText(pXMLContainer, pRootStyle);
+  pRootStyle->Release();
+}
+void CXFA_TextParser::ParseRichText(IFDE_XMLNode* pXMLNode,
+                                    IFDE_CSSComputedStyle* pParentStyle) {
+  if (pXMLNode == NULL) {
+    return;
+  }
+  CXFA_CSSTagProvider tagProvider;
+  ParseTagInfo(pXMLNode, tagProvider);
+  if (!tagProvider.m_bTagAviliable) {
+    return;
+  }
+  IFDE_CSSComputedStyle* pNewStyle = NULL;
+  if ((tagProvider.GetTagName() != FX_WSTRC(L"body")) ||
+      (tagProvider.GetTagName() != FX_WSTRC(L"html"))) {
+    CXFA_TextParseContext* pTextContext =
+        FXTARGET_NewWith(m_pAllocator) CXFA_TextParseContext;
+    FDE_CSSDISPLAY eDisplay = FDE_CSSDISPLAY_Inline;
+    if (!tagProvider.m_bContent) {
+      pNewStyle = CreateStyle(pParentStyle);
+      IFDE_CSSAccelerator* pCSSAccel = m_pSelector->InitAccelerator();
+      pCSSAccel->OnEnterTag(&tagProvider);
+      CFDE_CSSDeclarationArray DeclArray;
+      int32_t iMatchedDecls =
+          m_pSelector->MatchDeclarations(&tagProvider, DeclArray);
+      const IFDE_CSSDeclaration** ppMatchDecls =
+          (const IFDE_CSSDeclaration**)DeclArray.GetData();
+      m_pSelector->ComputeStyle(&tagProvider, ppMatchDecls, iMatchedDecls,
+                                pNewStyle);
+      pCSSAccel->OnLeaveTag(&tagProvider);
+      if (iMatchedDecls > 0) {
+        pTextContext->SetDecls(ppMatchDecls, iMatchedDecls);
+      }
+      eDisplay = pNewStyle->GetPositionStyles()->GetDisplay();
+    }
+    pTextContext->SetDisplay(eDisplay);
+    m_mapXMLNodeToParseContext.SetAt(pXMLNode, pTextContext);
+  }
+  for (IFDE_XMLNode* pXMLChild =
+           pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild);
+       pXMLChild;
+       pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+    ParseRichText(pXMLChild, pNewStyle);
+  }
+  if (pNewStyle)
+    pNewStyle->Release();
+}
+void CXFA_TextParser::ParseTagInfo(IFDE_XMLNode* pXMLNode,
+                                   CXFA_CSSTagProvider& tagProvider) {
+  static const FX_DWORD s_XFATagName[] = {
+      0x61,       0x62,       0x69,       0x70,       0x0001f714,
+      0x00022a55, 0x000239bb, 0x00025881, 0x0bd37faa, 0x0bd37fb8,
+      0xa73e3af2, 0xb182eaae, 0xdb8ac455,
+  };
+  CFX_WideString wsName;
+  if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
+    IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLNode;
+    pXMLElement->GetLocalTagName(wsName);
+    tagProvider.SetTagNameObj(wsName);
+    FX_DWORD dwHashCode =
+        FX_HashCode_String_GetW(wsName, wsName.GetLength(), TRUE);
+    static const int32_t s_iCount = sizeof(s_XFATagName) / sizeof(FX_DWORD);
+    CFX_DSPATemplate<FX_DWORD> lookup;
+    tagProvider.m_bTagAviliable =
+        lookup.Lookup(dwHashCode, s_XFATagName, s_iCount) > -1;
+    CFX_WideString wsValue;
+    pXMLElement->GetString(FX_WSTRC(L"style").GetPtr(), wsValue);
+    if (!wsValue.IsEmpty()) {
+      tagProvider.SetAttribute(FX_WSTRC(L"style"), wsValue);
+    }
+  } else if (pXMLNode->GetType() == FDE_XMLNODE_Text) {
+    tagProvider.m_bTagAviliable = TRUE;
+    tagProvider.m_bContent = TRUE;
+  }
+}
+int32_t CXFA_TextParser::GetVAlgin(IXFA_TextProvider* pTextProvider) const {
+  int32_t iAlign = XFA_ATTRIBUTEENUM_Top;
+  CXFA_Para para = pTextProvider->GetParaNode();
+  if (para) {
+    iAlign = para.GetVerticalAlign();
+  }
+  return iAlign;
+}
+FX_FLOAT CXFA_TextParser::GetTabInterval(IFDE_CSSComputedStyle* pStyle) const {
+  CFX_WideString wsValue;
+  if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"tab-interval"), wsValue)) {
+    CXFA_Measurement ms(wsValue);
+    return ms.ToUnit(XFA_UNIT_Pt);
+  }
+  return 36;
+}
+int32_t CXFA_TextParser::CountTabs(IFDE_CSSComputedStyle* pStyle) const {
+  CFX_WideString wsValue;
+  if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"xfa-tab-count"), wsValue)) {
+    return wsValue.GetInteger();
+  }
+  return 0;
+}
+FX_BOOL CXFA_TextParser::IsSpaceRun(IFDE_CSSComputedStyle* pStyle) const {
+  CFX_WideString wsValue;
+  if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"xfa-spacerun"), wsValue)) {
+    wsValue.MakeLower();
+    return wsValue == FX_WSTRC(L"yes");
+  }
+  return FALSE;
+}
+IFX_Font* CXFA_TextParser::GetFont(IXFA_TextProvider* pTextProvider,
+                                   IFDE_CSSComputedStyle* pStyle) const {
+  CFX_WideStringC wsFamily = FX_WSTRC(L"Courier");
+  FX_DWORD dwStyle = 0;
+  CXFA_Font font = pTextProvider->GetFontNode();
+  if (font) {
+    font.GetTypeface(wsFamily);
+    if (font.IsBold()) {
+      dwStyle |= FX_FONTSTYLE_Bold;
+    }
+    if (font.IsItalic()) {
+      dwStyle |= FX_FONTSTYLE_Italic;
+    }
+  }
+  if (pStyle) {
+    IFDE_CSSFontStyle* pFontStyle = pStyle->GetFontStyles();
+    int32_t iCount = pFontStyle->CountFontFamilies();
+    if (iCount > 0) {
+      wsFamily = pFontStyle->GetFontFamily(iCount - 1);
+    }
+    dwStyle = 0;
+    if (pFontStyle->GetFontWeight() > FXFONT_FW_NORMAL) {
+      dwStyle |= FX_FONTSTYLE_Bold;
+    }
+    if (pFontStyle->GetFontStyle() == FDE_CSSFONTSTYLE_Italic) {
+      dwStyle |= FX_FONTSTYLE_Italic;
+    }
+  }
+  CXFA_FFDoc* pDoc = pTextProvider->GetDocNode();
+  CXFA_FontMgr* pFontMgr = pDoc->GetApp()->GetXFAFontMgr();
+  return pFontMgr->GetFont(pDoc, wsFamily, dwStyle);
+}
+FX_FLOAT CXFA_TextParser::GetFontSize(IXFA_TextProvider* pTextProvider,
+                                      IFDE_CSSComputedStyle* pStyle) const {
+  if (pStyle)
+    return pStyle->GetFontStyles()->GetFontSize();
+
+  CXFA_Font font = pTextProvider->GetFontNode();
+  if (font) {
+    return font.GetFontSize();
+  }
+  return 10;
+}
+int32_t CXFA_TextParser::GetHorScale(IXFA_TextProvider* pTextProvider,
+                                     IFDE_CSSComputedStyle* pStyle,
+                                     IFDE_XMLNode* pXMLNode) const {
+  if (pStyle) {
+    CFX_WideString wsValue;
+    if (pStyle->GetCustomStyle(FX_WSTRC(L"xfa-font-horizontal-scale"),
+                               wsValue)) {
+      return wsValue.GetInteger();
+    }
+    while (pXMLNode) {
+      CXFA_TextParseContext* pContext = static_cast<CXFA_TextParseContext*>(
+          m_mapXMLNodeToParseContext.GetValueAt(pXMLNode));
+      if (pContext && pContext->m_pParentStyle &&
+          pContext->m_pParentStyle->GetCustomStyle(
+              FX_WSTRC(L"xfa-font-horizontal-scale"), wsValue)) {
+        return wsValue.GetInteger();
+      }
+      pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::Parent);
+    }
+  }
+  if (CXFA_Font font = pTextProvider->GetFontNode()) {
+    return static_cast<int32_t>(font.GetHorizontalScale());
+  }
+  return 100;
+}
+int32_t CXFA_TextParser::GetVerScale(IXFA_TextProvider* pTextProvider,
+                                     IFDE_CSSComputedStyle* pStyle) const {
+  if (pStyle) {
+    CFX_WideString wsValue;
+    if (pStyle->GetCustomStyle(FX_WSTRC(L"xfa-font-vertical-scale"), wsValue)) {
+      return wsValue.GetInteger();
+    }
+  }
+  if (CXFA_Font font = pTextProvider->GetFontNode()) {
+    return (int32_t)font.GetVerticalScale();
+  }
+  return 100;
+}
+void CXFA_TextParser::GetUnderline(IXFA_TextProvider* pTextProvider,
+                                   IFDE_CSSComputedStyle* pStyle,
+                                   int32_t& iUnderline,
+                                   int32_t& iPeriod) const {
+  iUnderline = 0;
+  iPeriod = XFA_ATTRIBUTEENUM_All;
+  if (pStyle) {
+    FX_DWORD dwDecoration = pStyle->GetParagraphStyles()->GetTextDecoration();
+    if (dwDecoration & FDE_CSSTEXTDECORATION_Double) {
+      iUnderline = 2;
+    } else if (dwDecoration & FDE_CSSTEXTDECORATION_Underline) {
+      iUnderline = 1;
+    }
+    CFX_WideString wsValue;
+    if (pStyle->GetCustomStyle(FX_WSTRC(L"underlinePeriod"), wsValue)) {
+      if (wsValue == FX_WSTRC(L"word")) {
+        iPeriod = XFA_ATTRIBUTEENUM_Word;
+      }
+    } else if (CXFA_Font font = pTextProvider->GetFontNode()) {
+      iPeriod = font.GetUnderlinePeriod();
+    }
+  } else {
+    CXFA_Font font = pTextProvider->GetFontNode();
+    if (font) {
+      iUnderline = font.GetUnderline();
+      iPeriod = font.GetUnderlinePeriod();
+    }
+  }
+}
+void CXFA_TextParser::GetLinethrough(IXFA_TextProvider* pTextProvider,
+                                     IFDE_CSSComputedStyle* pStyle,
+                                     int32_t& iLinethrough) const {
+  if (pStyle) {
+    FX_DWORD dwDecoration = pStyle->GetParagraphStyles()->GetTextDecoration();
+    iLinethrough = (dwDecoration & FDE_CSSTEXTDECORATION_LineThrough) ? 1 : 0;
+  } else {
+    CXFA_Font font = pTextProvider->GetFontNode();
+    if (font) {
+      iLinethrough = font.GetLineThrough();
+    }
+  }
+}
+FX_ARGB CXFA_TextParser::GetColor(IXFA_TextProvider* pTextProvider,
+                                  IFDE_CSSComputedStyle* pStyle) const {
+  if (pStyle)
+    return pStyle->GetFontStyles()->GetColor();
+
+  if (CXFA_Font font = pTextProvider->GetFontNode())
+    return font.GetColor();
+
+  return 0xFF000000;
+}
+FX_FLOAT CXFA_TextParser::GetBaseline(IXFA_TextProvider* pTextProvider,
+                                      IFDE_CSSComputedStyle* pStyle) const {
+  if (pStyle) {
+    IFDE_CSSParagraphStyle* pParaStyle = pStyle->GetParagraphStyles();
+    if (pParaStyle->GetVerticalAlign() == FDE_CSSVERTICALALIGN_Number) {
+      return pParaStyle->GetNumberVerticalAlign();
+    }
+  } else if (CXFA_Font font = pTextProvider->GetFontNode()) {
+    return font.GetBaselineShift();
+  }
+  return 0;
+}
+FX_FLOAT CXFA_TextParser::GetLineHeight(IXFA_TextProvider* pTextProvider,
+                                        IFDE_CSSComputedStyle* pStyle,
+                                        FX_BOOL bFirst,
+                                        FX_FLOAT fVerScale) const {
+  FX_FLOAT fLineHeight = 0;
+  if (pStyle) {
+    fLineHeight = pStyle->GetParagraphStyles()->GetLineHeight();
+  } else if (CXFA_Para para = pTextProvider->GetParaNode()) {
+    fLineHeight = para.GetLineHeight();
+  }
+  if (bFirst) {
+    FX_FLOAT fFontSize = GetFontSize(pTextProvider, pStyle);
+    if (fLineHeight < 0.1f) {
+      fLineHeight = fFontSize;
+    } else {
+      fLineHeight = std::min(fLineHeight, fFontSize);
+    }
+  } else if (fLineHeight < 0.1f) {
+    fLineHeight = GetFontSize(pTextProvider, pStyle) * 1.2f;
+  }
+  fLineHeight *= fVerScale;
+  return fLineHeight;
+}
+FX_BOOL CXFA_TextParser::GetEmbbedObj(IXFA_TextProvider* pTextProvider,
+                                      IFDE_XMLNode* pXMLNode,
+                                      CFX_WideString& wsValue) {
+  wsValue.Empty();
+  if (pXMLNode == NULL) {
+    return FALSE;
+  }
+  FX_BOOL bRet = FALSE;
+  if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
+    IFDE_XMLElement* pElement = (IFDE_XMLElement*)pXMLNode;
+    CFX_WideString wsAttr;
+    pElement->GetString(FX_WSTRC(L"xfa:embed").GetPtr(), wsAttr);
+    if (wsAttr.IsEmpty()) {
+      return FALSE;
+    }
+    if (wsAttr.GetAt(0) == L'#') {
+      wsAttr.Delete(0);
+    }
+    CFX_WideString ws;
+    pElement->GetString(FX_WSTRC(L"xfa:embedType").GetPtr(), ws);
+    if (ws.IsEmpty()) {
+      ws = L"som";
+    } else {
+      ws.MakeLower();
+    }
+    FX_BOOL bURI = (ws == FX_WSTRC(L"uri"));
+    if (!bURI && ws != FX_WSTRC(L"som")) {
+      return FALSE;
+    }
+    ws.Empty();
+    pElement->GetString(FX_WSTRC(L"xfa:embedMode").GetPtr(), ws);
+    if (ws.IsEmpty()) {
+      ws = L"formatted";
+    } else {
+      ws.MakeLower();
+    }
+    FX_BOOL bRaw = (ws == FX_WSTRC(L"raw"));
+    if (!bRaw && ws != FX_WSTRC(L"formatted")) {
+      return FALSE;
+    }
+    bRet = pTextProvider->GetEmbbedObj(bURI, bRaw, wsAttr, wsValue);
+  }
+  return bRet;
+}
+CXFA_TextParseContext* CXFA_TextParser::GetParseContextFromMap(
+    IFDE_XMLNode* pXMLNode) {
+  return (CXFA_TextParseContext*)m_mapXMLNodeToParseContext.GetValueAt(
+      pXMLNode);
+}
+enum XFA_TABSTOPSSTATUS {
+  XFA_TABSTOPSSTATUS_Error,
+  XFA_TABSTOPSSTATUS_EOS,
+  XFA_TABSTOPSSTATUS_None,
+  XFA_TABSTOPSSTATUS_Alignment,
+  XFA_TABSTOPSSTATUS_StartLeader,
+  XFA_TABSTOPSSTATUS_Leader,
+  XFA_TABSTOPSSTATUS_Location,
+};
+FX_BOOL CXFA_TextParser::GetTabstops(
+    IFDE_CSSComputedStyle* pStyle,
+    CXFA_TextTabstopsContext* pTabstopContext) {
+  if (pStyle == NULL || pTabstopContext == NULL) {
+    return FALSE;
+  }
+  CFX_WideString wsValue;
+  if (!pStyle->GetCustomStyle(FX_WSTRC(L"xfa-tab-stops"), wsValue) &&
+      !pStyle->GetCustomStyle(FX_WSTRC(L"tab-stops"), wsValue)) {
+    return FALSE;
+  }
+  int32_t iLength = wsValue.GetLength();
+  const FX_WCHAR* pTabStops = wsValue;
+  int32_t iCur = 0;
+  int32_t iLast = 0;
+  CFX_WideString wsAlign;
+  XFA_TABSTOPSSTATUS eStatus = XFA_TABSTOPSSTATUS_None;
+  FX_WCHAR ch;
+  while (iCur < iLength) {
+    ch = pTabStops[iCur];
+    switch (eStatus) {
+      case XFA_TABSTOPSSTATUS_None:
+        if (ch <= ' ') {
+          iCur++;
+        } else {
+          eStatus = XFA_TABSTOPSSTATUS_Alignment;
+          iLast = iCur;
+        }
+        break;
+      case XFA_TABSTOPSSTATUS_Alignment:
+        if (ch == ' ') {
+          wsAlign = CFX_WideStringC(pTabStops + iLast, iCur - iLast);
+          eStatus = XFA_TABSTOPSSTATUS_StartLeader;
+          iCur++;
+          while (iCur < iLength && pTabStops[iCur] <= ' ') {
+            iCur++;
+          }
+          iLast = iCur;
+        } else {
+          iCur++;
+        }
+        break;
+      case XFA_TABSTOPSSTATUS_StartLeader:
+        if (ch != 'l') {
+          eStatus = XFA_TABSTOPSSTATUS_Location;
+        } else {
+          int32_t iCount = 0;
+          while (iCur < iLength) {
+            ch = pTabStops[iCur];
+            iCur++;
+            if (ch == '(') {
+              iCount++;
+            } else if (ch == ')') {
+              iCount--;
+              if (iCount == 0) {
+                break;
+              }
+            }
+          }
+          while (iCur < iLength && pTabStops[iCur] <= ' ') {
+            iCur++;
+          }
+          iLast = iCur;
+          eStatus = XFA_TABSTOPSSTATUS_Location;
+        }
+        break;
+      case XFA_TABSTOPSSTATUS_Location:
+        if (ch == ' ') {
+          FX_DWORD dwHashCode =
+              FX_HashCode_String_GetW(wsAlign, wsAlign.GetLength(), TRUE);
+          CXFA_Measurement ms(CFX_WideStringC(pTabStops + iLast, iCur - iLast));
+          FX_FLOAT fPos = ms.ToUnit(XFA_UNIT_Pt);
+          pTabstopContext->Append(dwHashCode, fPos);
+          wsAlign.Empty();
+          eStatus = XFA_TABSTOPSSTATUS_None;
+        }
+        iCur++;
+        break;
+      default:
+        break;
+    }
+  }
+  if (!wsAlign.IsEmpty()) {
+    FX_DWORD dwHashCode =
+        FX_HashCode_String_GetW(wsAlign, wsAlign.GetLength(), TRUE);
+    CXFA_Measurement ms(CFX_WideStringC(pTabStops + iLast, iCur - iLast));
+    FX_FLOAT fPos = ms.ToUnit(XFA_UNIT_Pt);
+    pTabstopContext->Append(dwHashCode, fPos);
+  }
+  return TRUE;
+}
+CXFA_TextLayout::CXFA_TextLayout(IXFA_TextProvider* pTextProvider)
+    : m_bHasBlock(FALSE),
+      m_pTextProvider(pTextProvider),
+      m_pTextDataNode(nullptr),
+      m_bRichText(FALSE),
+      m_pAllocator(nullptr),
+      m_pBreak(nullptr),
+      m_pLoader(nullptr),
+      m_iLines(0),
+      m_fMaxWidth(0),
+      m_pTabstopContext(nullptr),
+      m_bBlockContinue(TRUE) {
+  FXSYS_assert(m_pTextProvider);
+}
+CXFA_TextLayout::~CXFA_TextLayout() {
+  m_textParser.Reset();
+  delete m_pLoader;
+  delete m_pTabstopContext;
+  Unload();
+}
+void CXFA_TextLayout::Unload() {
+  int32_t iCount = m_pieceLines.GetSize();
+  for (int32_t i = 0; i < iCount; i++) {
+    CXFA_PieceLine* pLine = m_pieceLines.GetAt(i);
+    FXTARGET_DeleteWith(CXFA_PieceLine, m_pAllocator, pLine);
+  }
+  m_pieceLines.RemoveAll();
+  if (m_pBreak) {
+    m_pBreak->Release();
+    m_pBreak = NULL;
+  }
+  if (m_pAllocator) {
+    m_pAllocator->Release();
+    m_pAllocator = NULL;
+  }
+}
+const CXFA_PieceLineArray* CXFA_TextLayout::GetPieceLines() {
+  return &m_pieceLines;
+}
+void CXFA_TextLayout::GetTextDataNode() {
+  if (m_pTextProvider == NULL) {
+    return;
+  }
+  CXFA_Node* pNode = m_pTextProvider->GetTextNode(m_bRichText);
+  if (pNode && m_bRichText) {
+    m_textParser.Reset();
+  }
+  m_pTextDataNode = pNode;
+}
+IFDE_XMLNode* CXFA_TextLayout::GetXMLContainerNode() {
+  IFDE_XMLNode* pXMLContainer = NULL;
+  if (m_bRichText) {
+    IFDE_XMLNode* pXMLRoot = m_pTextDataNode->GetXMLMappingNode();
+    if (!pXMLRoot) {
+      return pXMLContainer;
+    }
+    for (IFDE_XMLNode* pXMLChild =
+             pXMLRoot->GetNodeItem(IFDE_XMLNode::FirstChild);
+         pXMLChild;
+         pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+      if (pXMLChild->GetType() == FDE_XMLNODE_Element) {
+        IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLChild;
+        CFX_WideString wsTag;
+        pXMLElement->GetLocalTagName(wsTag);
+        if (wsTag.Equal(FX_WSTRC(L"body")) || wsTag.Equal(FX_WSTRC(L"html"))) {
+          pXMLContainer = pXMLChild;
+          break;
+        }
+      }
+    }
+  }
+  return pXMLContainer;
+}
+IFX_RTFBreak* CXFA_TextLayout::CreateBreak(FX_BOOL bDefault) {
+  FX_DWORD dwStyle = FX_RTFLAYOUTSTYLE_ExpandTab;
+  if (!bDefault) {
+    dwStyle |= FX_RTFLAYOUTSTYLE_Pagination;
+  }
+  IFX_RTFBreak* pBreak = IFX_RTFBreak::Create(0);
+  pBreak->SetLayoutStyles(dwStyle);
+  pBreak->SetLineBreakChar(L'\n');
+  pBreak->SetLineBreakTolerance(1);
+  pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, NULL));
+  pBreak->SetFontSize(m_textParser.GetFontSize(m_pTextProvider, NULL));
+  return pBreak;
+}
+void CXFA_TextLayout::InitBreak(FX_FLOAT fLineWidth) {
+  CXFA_Font font = m_pTextProvider->GetFontNode();
+  CXFA_Para para = m_pTextProvider->GetParaNode();
+  FX_FLOAT fStart = 0;
+  FX_FLOAT fStartPos = 0;
+  if (para) {
+    int32_t iAlign = FX_RTFLINEALIGNMENT_Left;
+    switch (para.GetHorizontalAlign()) {
+      case XFA_ATTRIBUTEENUM_Center:
+        iAlign = FX_RTFLINEALIGNMENT_Center;
+        break;
+      case XFA_ATTRIBUTEENUM_Right:
+        iAlign = FX_RTFLINEALIGNMENT_Right;
+        break;
+      case XFA_ATTRIBUTEENUM_Justify:
+        iAlign = FX_RTFLINEALIGNMENT_Justified;
+        break;
+      case XFA_ATTRIBUTEENUM_JustifyAll:
+        iAlign = FX_RTFLINEALIGNMENT_Distributed;
+        break;
+    }
+    m_pBreak->SetAlignment(iAlign);
+    fStart = para.GetMarginLeft();
+    if (m_pTextProvider->IsCheckButtonAndAutoWidth()) {
+      if (iAlign != FX_RTFLINEALIGNMENT_Left) {
+        fLineWidth -= para.GetMarginRight();
+      }
+    } else {
+      fLineWidth -= para.GetMarginRight();
+    }
+    if (fLineWidth < 0) {
+      fLineWidth = fStart;
+    }
+    fStartPos = fStart;
+    FX_FLOAT fIndent = para.GetTextIndent();
+    if (fIndent > 0) {
+      fStartPos += fIndent;
+    }
+  }
+  m_pBreak->SetLineBoundary(fStart, fLineWidth);
+  m_pBreak->SetLineStartPos(fStartPos);
+  if (font) {
+    m_pBreak->SetHorizontalScale((int32_t)font.GetHorizontalScale());
+    m_pBreak->SetVerticalScale((int32_t)font.GetVerticalScale());
+    m_pBreak->SetCharSpace(font.GetLetterSpacing());
+  }
+  FX_FLOAT fFontSize = m_textParser.GetFontSize(m_pTextProvider, NULL);
+  m_pBreak->SetFontSize(fFontSize);
+  m_pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, NULL));
+  m_pBreak->SetLineBreakTolerance(fFontSize * 0.2f);
+}
+void CXFA_TextLayout::InitBreak(IFDE_CSSComputedStyle* pStyle,
+                                FDE_CSSDISPLAY eDisplay,
+                                FX_FLOAT fLineWidth,
+                                IFDE_XMLNode* pXMLNode,
+                                IFDE_CSSComputedStyle* pParentStyle) {
+  if (pStyle == NULL) {
+    InitBreak(fLineWidth);
+    return;
+  }
+  IFDE_CSSParagraphStyle* pParaStyle = pStyle->GetParagraphStyles();
+  if (eDisplay == FDE_CSSDISPLAY_Block || eDisplay == FDE_CSSDISPLAY_ListItem) {
+    int32_t iAlign = FX_RTFLINEALIGNMENT_Left;
+    switch (pParaStyle->GetTextAlign()) {
+      case FDE_CSSTEXTALIGN_Right:
+        iAlign = FX_RTFLINEALIGNMENT_Right;
+        break;
+      case FDE_CSSTEXTALIGN_Center:
+        iAlign = FX_RTFLINEALIGNMENT_Center;
+        break;
+      case FDE_CSSTEXTALIGN_Justify:
+        iAlign = FX_RTFLINEALIGNMENT_Justified;
+        break;
+      case FDE_CSSTEXTALIGN_JustifyAll:
+        iAlign = FX_RTFLINEALIGNMENT_Distributed;
+        break;
+      default:
+        break;
+    }
+    m_pBreak->SetAlignment(iAlign);
+    FX_FLOAT fStart = 0;
+    const FDE_CSSRECT* pRect = pStyle->GetBoundaryStyles()->GetMarginWidth();
+    const FDE_CSSRECT* pPaddingRect =
+        pStyle->GetBoundaryStyles()->GetPaddingWidth();
+    if (pRect) {
+      fStart = pRect->left.GetValue();
+      fLineWidth -= pRect->right.GetValue();
+      if (pPaddingRect) {
+        fStart += pPaddingRect->left.GetValue();
+        fLineWidth -= pPaddingRect->right.GetValue();
+      }
+      if (eDisplay == FDE_CSSDISPLAY_ListItem) {
+        const FDE_CSSRECT* pParRect =
+            pParentStyle->GetBoundaryStyles()->GetMarginWidth();
+        const FDE_CSSRECT* pParPaddingRect =
+            pParentStyle->GetBoundaryStyles()->GetPaddingWidth();
+        if (pParRect) {
+          fStart += pParRect->left.GetValue();
+          fLineWidth -= pParRect->right.GetValue();
+          if (pParPaddingRect) {
+            fStart += pParPaddingRect->left.GetValue();
+            fLineWidth -= pParPaddingRect->right.GetValue();
+          }
+        }
+        FDE_CSSRECT pNewRect;
+        pNewRect.left.Set(FDE_CSSLENGTHUNIT_Point, fStart);
+        pNewRect.right.Set(FDE_CSSLENGTHUNIT_Point, pRect->right.GetValue());
+        pNewRect.top.Set(FDE_CSSLENGTHUNIT_Point, pRect->top.GetValue());
+        pNewRect.bottom.Set(FDE_CSSLENGTHUNIT_Point, pRect->bottom.GetValue());
+        pStyle->GetBoundaryStyles()->SetMarginWidth(pNewRect);
+      }
+    }
+    m_pBreak->SetLineBoundary(fStart, fLineWidth);
+    FX_FLOAT fIndent = pParaStyle->GetTextIndent().GetValue();
+    if (fIndent > 0) {
+      fStart += fIndent;
+    }
+    m_pBreak->SetLineStartPos(fStart);
+    m_pBreak->SetTabWidth(m_textParser.GetTabInterval(pStyle));
+    if (m_pTabstopContext == NULL) {
+      m_pTabstopContext = new CXFA_TextTabstopsContext;
+    }
+    m_textParser.GetTabstops(pStyle, m_pTabstopContext);
+    for (int32_t i = 0; i < m_pTabstopContext->m_iTabCount; i++) {
+      XFA_TABSTOPS* pTab = m_pTabstopContext->m_tabstops.GetDataPtr(i);
+      m_pBreak->AddPositionedTab(pTab->fTabstops);
+    }
+  }
+  FX_FLOAT fFontSize = m_textParser.GetFontSize(m_pTextProvider, pStyle);
+  m_pBreak->SetFontSize(fFontSize);
+  m_pBreak->SetLineBreakTolerance(fFontSize * 0.2f);
+  m_pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, pStyle));
+  m_pBreak->SetHorizontalScale(
+      m_textParser.GetHorScale(m_pTextProvider, pStyle, pXMLNode));
+  m_pBreak->SetVerticalScale(m_textParser.GetVerScale(m_pTextProvider, pStyle));
+  m_pBreak->SetCharSpace(pParaStyle->GetLetterSpacing().GetValue());
+}
+int32_t CXFA_TextLayout::GetText(CFX_WideString& wsText) {
+  GetTextDataNode();
+  wsText.Empty();
+  if (m_bRichText) {
+  } else {
+    wsText = m_pTextDataNode->GetContent();
+  }
+  return wsText.GetLength();
+}
+FX_FLOAT CXFA_TextLayout::GetLayoutHeight() {
+  if (m_pLoader == NULL) {
+    return 0;
+  }
+  int32_t iCount = m_pLoader->m_lineHeights.GetSize();
+  if (iCount == 0 && m_pLoader->m_fWidth > 0) {
+    CFX_SizeF szMax(m_pLoader->m_fWidth, m_pLoader->m_fHeight);
+    CFX_SizeF szDef;
+    m_pLoader->m_bSaveLineHeight = TRUE;
+    m_pLoader->m_fLastPos = 0;
+    CalcSize(szMax, szMax, szDef);
+    m_pLoader->m_bSaveLineHeight = FALSE;
+    return szDef.y;
+  }
+  FX_FLOAT fHeight = m_pLoader->m_fHeight;
+  if (fHeight < 0.1f) {
+    fHeight = 0;
+    for (int32_t i = 0; i < iCount; i++) {
+      fHeight += m_pLoader->m_lineHeights.ElementAt(i);
+    }
+  }
+  return fHeight;
+}
+FX_FLOAT CXFA_TextLayout::StartLayout(FX_FLOAT fWidth) {
+  if (m_pLoader == NULL) {
+    m_pLoader = new CXFA_LoaderContext;
+  }
+  if (fWidth < 0 || (m_pLoader->m_fWidth > -1 &&
+                     FXSYS_fabs(fWidth - m_pLoader->m_fWidth) > 0)) {
+    m_pLoader->m_lineHeights.RemoveAll();
+    m_Blocks.RemoveAll();
+    Unload();
+    m_pLoader->m_fStartLineOffset = 0;
+  }
+  m_pLoader->m_fWidth = fWidth;
+  if (fWidth < 0) {
+    CFX_SizeF szMax;
+    CFX_SizeF szDef;
+    m_pLoader->m_bSaveLineHeight = TRUE;
+    m_pLoader->m_fLastPos = 0;
+    CalcSize(szMax, szMax, szDef);
+    m_pLoader->m_bSaveLineHeight = FALSE;
+    fWidth = szDef.x;
+  }
+  return fWidth;
+}
+FX_BOOL CXFA_TextLayout::DoLayout(int32_t iBlockIndex,
+                                  FX_FLOAT& fCalcHeight,
+                                  FX_FLOAT fContentAreaHeight,
+                                  FX_FLOAT fTextHeight) {
+  if (m_pLoader == NULL) {
+    return FALSE;
+  }
+  int32_t iBlockCount = m_Blocks.GetSize();
+  FX_FLOAT fHeight = fTextHeight;
+  if (fHeight < 0) {
+    fHeight = GetLayoutHeight();
+  }
+  m_pLoader->m_fHeight = fHeight;
+  if (fContentAreaHeight < 0) {
+    return FALSE;
+  }
+  m_bHasBlock = TRUE;
+  if (iBlockCount == 0 && fHeight > 0) {
+    fHeight = fTextHeight - GetLayoutHeight();
+    if (fHeight > 0) {
+      int32_t iAlign = m_textParser.GetVAlgin(m_pTextProvider);
+      if (iAlign == XFA_ATTRIBUTEENUM_Middle) {
+        fHeight /= 2.0f;
+      } else if (iAlign != XFA_ATTRIBUTEENUM_Bottom) {
+        fHeight = 0;
+      }
+      m_pLoader->m_fStartLineOffset = fHeight;
+    }
+  }
+  FX_FLOAT fLinePos = m_pLoader->m_fStartLineOffset;
+  int32_t iLineIndex = 0;
+  if (iBlockCount > 1) {
+    if (iBlockCount >= (iBlockIndex + 1) * 2) {
+      iLineIndex = m_Blocks.ElementAt(iBlockIndex * 2);
+    } else {
+      iLineIndex = m_Blocks.ElementAt(iBlockCount - 1) +
+                   m_Blocks.ElementAt(iBlockCount - 2);
+    }
+    if (m_pLoader->m_BlocksHeight.GetSize() > 0) {
+      for (int32_t i = 0; i < iBlockIndex; i++) {
+        fLinePos -= m_pLoader->m_BlocksHeight.ElementAt(i * 2 + 1);
+      }
+    }
+  }
+  int32_t iCount = m_pLoader->m_lineHeights.GetSize();
+  int32_t i = 0;
+  for (i = iLineIndex; i < iCount; i++) {
+    FX_FLOAT fLineHeight = m_pLoader->m_lineHeights.ElementAt(i);
+    if ((i == iLineIndex) && (fLineHeight - fContentAreaHeight > 0.001)) {
+      fCalcHeight = 0;
+      return TRUE;
+    }
+    if (fLinePos + fLineHeight - fContentAreaHeight > 0.001) {
+      if (iBlockCount >= (iBlockIndex + 1) * 2) {
+        m_Blocks.SetAt(iBlockIndex * 2, iLineIndex);
+        m_Blocks.SetAt(iBlockIndex * 2 + 1, i - iLineIndex);
+      } else {
+        m_Blocks.Add(iLineIndex);
+        m_Blocks.Add(i - iLineIndex);
+      }
+      if (i == iLineIndex) {
+        if (fCalcHeight <= fLinePos) {
+          if (m_pLoader->m_BlocksHeight.GetSize() > iBlockIndex * 2 &&
+              (m_pLoader->m_BlocksHeight.GetAt(iBlockIndex * 2) ==
+               iBlockIndex)) {
+            m_pLoader->m_BlocksHeight.SetAt(iBlockIndex * 2 + 1, fCalcHeight);
+          } else {
+            m_pLoader->m_BlocksHeight.Add((FX_FLOAT)iBlockIndex);
+            m_pLoader->m_BlocksHeight.Add(fCalcHeight);
+          }
+        }
+        return TRUE;
+      }
+      fCalcHeight = fLinePos;
+      return TRUE;
+    }
+    fLinePos += fLineHeight;
+  }
+  return FALSE;
+}
+int32_t CXFA_TextLayout::CountBlocks() const {
+  int32_t iCount = m_Blocks.GetSize() / 2;
+  return iCount > 0 ? iCount : 1;
+}
+FX_BOOL CXFA_TextLayout::CalcSize(const CFX_SizeF& minSize,
+                                  const CFX_SizeF& maxSize,
+                                  CFX_SizeF& defaultSize) {
+  defaultSize.x = maxSize.x;
+  if (defaultSize.x < 1) {
+    defaultSize.x = 0xFFFF;
+  }
+  if (m_pBreak)
+    m_pBreak->Release();
+
+  m_pBreak = CreateBreak(FALSE);
+  FX_FLOAT fLinePos = 0;
+  m_iLines = 0;
+  m_fMaxWidth = 0;
+  Loader(defaultSize, fLinePos, FALSE);
+  if (fLinePos < 0.1f) {
+    fLinePos = m_textParser.GetFontSize(m_pTextProvider, NULL);
+  }
+  if (m_pTabstopContext) {
+    delete m_pTabstopContext;
+    m_pTabstopContext = NULL;
+  }
+  defaultSize = CFX_SizeF(m_fMaxWidth, fLinePos);
+  return TRUE;
+}
+FX_BOOL CXFA_TextLayout::Layout(const CFX_SizeF& size, FX_FLOAT* fHeight) {
+  if (size.x < 1) {
+    return FALSE;
+  }
+  Unload();
+  m_pBreak = CreateBreak(TRUE);
+  if (m_pLoader) {
+    m_pLoader->m_iTotalLines = -1;
+    m_pLoader->m_iChar = 0;
+  }
+  m_iLines = 0;
+  FX_FLOAT fLinePos = 0;
+  Loader(size, fLinePos, TRUE);
+  UpdateAlign(size.y, fLinePos);
+  if (m_pTabstopContext) {
+    delete m_pTabstopContext;
+    m_pTabstopContext = NULL;
+  }
+  if (fHeight) {
+    *fHeight = fLinePos;
+  }
+  return TRUE;
+}
+FX_BOOL CXFA_TextLayout::Layout(int32_t iBlock) {
+  if (m_pLoader == NULL || iBlock < 0 || iBlock >= CountBlocks()) {
+    return FALSE;
+  }
+  if (m_pLoader->m_fWidth < 1) {
+    return FALSE;
+  }
+  m_pLoader->m_iTotalLines = -1;
+  m_iLines = 0;
+  FX_FLOAT fLinePos = 0;
+  CXFA_Node* pNode = NULL;
+  CFX_SizeF szText(m_pLoader->m_fWidth, m_pLoader->m_fHeight);
+  int32_t iCount = m_Blocks.GetSize();
+  int32_t iBlocksHeightCount = m_pLoader->m_BlocksHeight.GetSize();
+  iBlocksHeightCount /= 2;
+  if (iBlock < iBlocksHeightCount) {
+    return TRUE;
+  }
+  if (iBlock == iBlocksHeightCount) {
+    Unload();
+    m_pBreak = CreateBreak(TRUE);
+    fLinePos = m_pLoader->m_fStartLineOffset;
+    for (int32_t i = 0; i < iBlocksHeightCount; i++) {
+      fLinePos -= m_pLoader->m_BlocksHeight.ElementAt(i * 2 + 1);
+    }
+    m_pLoader->m_iChar = 0;
+    if (iCount > 1) {
+      m_pLoader->m_iTotalLines = m_Blocks.ElementAt(iBlock * 2 + 1);
+    }
+    Loader(szText, fLinePos, TRUE);
+    if (iCount == 0 && m_pLoader->m_fStartLineOffset < 0.1f) {
+      UpdateAlign(szText.y, fLinePos);
+    }
+  } else if (m_pTextDataNode) {
+    iBlock *= 2;
+    if (iBlock < iCount - 2) {
+      m_pLoader->m_iTotalLines = m_Blocks.ElementAt(iBlock + 1);
+    }
+    m_pBreak->Reset();
+    if (m_bRichText) {
+      IFDE_XMLNode* pContainerNode = GetXMLContainerNode();
+      if (!pContainerNode) {
+        return TRUE;
+      }
+      IFDE_XMLNode* pXMLNode = m_pLoader->m_pXMLNode;
+      if (pXMLNode == NULL) {
+        return TRUE;
+      }
+      IFDE_XMLNode* pSaveXMLNode = m_pLoader->m_pXMLNode;
+      for (; pXMLNode;
+           pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+        FX_BOOL bFlag = LoadRichText(pXMLNode, szText, fLinePos,
+                                     m_pLoader->m_pParentStyle, TRUE);
+        if (!bFlag) {
+          break;
+        }
+      }
+      while (pXMLNode == NULL) {
+        pXMLNode = pSaveXMLNode->GetNodeItem(IFDE_XMLNode::Parent);
+        if (pXMLNode == pContainerNode) {
+          break;
+        }
+        FX_BOOL bFlag =
+            LoadRichText(pXMLNode, szText, fLinePos, m_pLoader->m_pParentStyle,
+                         TRUE, NULL, FALSE);
+        if (!bFlag) {
+          break;
+        }
+        pSaveXMLNode = pXMLNode;
+        pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling);
+        if (!pXMLNode) {
+          continue;
+        }
+        for (; pXMLNode;
+             pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+          FX_BOOL bFlag = LoadRichText(pXMLNode, szText, fLinePos,
+                                       m_pLoader->m_pParentStyle, TRUE);
+          if (!bFlag) {
+            break;
+          }
+        }
+      }
+    } else {
+      pNode = m_pLoader->m_pNode;
+      if (pNode == NULL) {
+        return TRUE;
+      }
+      LoadText(pNode, szText, fLinePos, TRUE);
+    }
+  }
+  if (iBlock == iCount) {
+    delete m_pTabstopContext;
+    m_pTabstopContext = nullptr;
+    delete m_pLoader;
+    m_pLoader = nullptr;
+  }
+  return TRUE;
+}
+void CXFA_TextLayout::ItemBlocks(const CFX_RectF& rtText, int32_t iBlockIndex) {
+  if (!m_pLoader) {
+    return;
+  }
+  int32_t iCountHeight = m_pLoader->m_lineHeights.GetSize();
+  if (iCountHeight == 0) {
+    return;
+  }
+  FX_BOOL bEndItem = TRUE;
+  int32_t iBlockCount = m_Blocks.GetSize();
+  FX_FLOAT fLinePos = m_pLoader->m_fStartLineOffset;
+  int32_t iLineIndex = 0;
+  if (iBlockIndex > 0) {
+    int32_t iBlockHeightCount = m_pLoader->m_BlocksHeight.GetSize();
+    iBlockHeightCount /= 2;
+    if (iBlockHeightCount >= iBlockIndex) {
+      for (int32_t i = 0; i < iBlockIndex; i++) {
+        fLinePos -= m_pLoader->m_BlocksHeight.ElementAt(i * 2 + 1);
+      }
+    } else {
+      fLinePos = 0;
+    }
+    iLineIndex = m_Blocks.ElementAt(iBlockCount - 1) +
+                 m_Blocks.ElementAt(iBlockCount - 2);
+  }
+  int32_t i = 0;
+  for (i = iLineIndex; i < iCountHeight; i++) {
+    FX_FLOAT fLineHeight = m_pLoader->m_lineHeights.ElementAt(i);
+    if (fLinePos + fLineHeight - rtText.height > 0.001) {
+      m_Blocks.Add(iLineIndex);
+      m_Blocks.Add(i - iLineIndex);
+      bEndItem = FALSE;
+      break;
+    }
+    fLinePos += fLineHeight;
+  }
+  if (iCountHeight > 0 && (i - iLineIndex) > 0 && bEndItem) {
+    m_Blocks.Add(iLineIndex);
+    m_Blocks.Add(i - iLineIndex);
+  }
+}
+FX_BOOL CXFA_TextLayout::DrawString(CFX_RenderDevice* pFxDevice,
+                                    const CFX_Matrix& tmDoc2Device,
+                                    const CFX_RectF& rtClip,
+                                    int32_t iBlock) {
+  IFDE_RenderDevice* pDevice = IFDE_RenderDevice::Create(pFxDevice);
+  if (pDevice == NULL) {
+    return FALSE;
+  }
+  FDE_HDEVICESTATE state = pDevice->SaveState();
+  pDevice->SetClipRect(rtClip);
+  IFDE_SolidBrush* pSolidBrush =
+      (IFDE_SolidBrush*)IFDE_Brush::Create(FDE_BRUSHTYPE_Solid);
+  IFDE_Pen* pPen = IFDE_Pen::Create();
+  FXSYS_assert(pDevice);
+  FXSYS_assert(pSolidBrush);
+  FXSYS_assert(pPen);
+  if (m_pieceLines.GetSize() == 0) {
+    int32_t iBlockCount = CountBlocks();
+    for (int32_t i = 0; i < iBlockCount; i++) {
+      Layout(i);
+    }
+  }
+  FXTEXT_CHARPOS* pCharPos = NULL;
+  int32_t iCharCount = 0;
+  int32_t iLineStart = 0;
+  int32_t iPieceLines = m_pieceLines.GetSize();
+  int32_t iCount = m_Blocks.GetSize();
+  if (iCount > 0) {
+    iBlock *= 2;
+    if (iBlock < iCount) {
+      iLineStart = m_Blocks.ElementAt(iBlock);
+      iPieceLines = m_Blocks.ElementAt(iBlock + 1);
+    } else {
+      iPieceLines = 0;
+    }
+  }
+  for (int32_t i = 0; i < iPieceLines; i++) {
+    if (i + iLineStart >= m_pieceLines.GetSize()) {
+      break;
+    }
+    CXFA_PieceLine* pPieceLine = m_pieceLines.GetAt(i + iLineStart);
+    int32_t iPieces = pPieceLine->m_textPieces.GetSize();
+    int32_t j = 0;
+    for (j = 0; j < iPieces; j++) {
+      const XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(j);
+      int32_t iChars = pPiece->iChars;
+      if (iCharCount < iChars) {
+        FX_Free(pCharPos);
+        pCharPos = FX_Alloc(FXTEXT_CHARPOS, iChars);
+        iCharCount = iChars;
+      }
+      FXSYS_memset(pCharPos, 0, iCharCount * sizeof(FXTEXT_CHARPOS));
+      RenderString(pDevice, pSolidBrush, pPieceLine, j, pCharPos, tmDoc2Device);
+    }
+    for (j = 0; j < iPieces; j++) {
+      RenderPath(pDevice, pPen, pPieceLine, j, pCharPos, tmDoc2Device);
+    }
+  }
+  pDevice->RestoreState(state);
+  FX_Free(pCharPos);
+  pSolidBrush->Release();
+  pPen->Release();
+  pDevice->Release();
+  return iPieceLines;
+}
+void CXFA_TextLayout::UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom) {
+  fHeight -= fBottom;
+  if (fHeight < 0.1f) {
+    return;
+  }
+  switch (m_textParser.GetVAlgin(m_pTextProvider)) {
+    case XFA_ATTRIBUTEENUM_Middle:
+      fHeight /= 2.0f;
+      break;
+    case XFA_ATTRIBUTEENUM_Bottom:
+      break;
+    default:
+      return;
+  }
+  int32_t iCount = m_pieceLines.GetSize();
+  for (int32_t i = 0; i < iCount; i++) {
+    CXFA_PieceLine* pPieceLine = m_pieceLines.GetAt(i);
+    int32_t iPieces = pPieceLine->m_textPieces.GetSize();
+    for (int32_t j = 0; j < iPieces; j++) {
+      XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(j);
+      CFX_RectF& rect = pPiece->rtPiece;
+      rect.top += fHeight;
+    }
+  }
+}
+FX_BOOL CXFA_TextLayout::Loader(const CFX_SizeF& szText,
+                                FX_FLOAT& fLinePos,
+                                FX_BOOL bSavePieces) {
+  if (m_pAllocator == NULL) {
+    m_pAllocator = FX_CreateAllocator(FX_ALLOCTYPE_Static, 256, 0);
+  }
+  GetTextDataNode();
+  if (m_pTextDataNode == NULL) {
+    return TRUE;
+  }
+  if (m_bRichText) {
+    IFDE_XMLNode* pXMLContainer = GetXMLContainerNode();
+    if (pXMLContainer) {
+      if (!m_textParser.IsParsed()) {
+        m_textParser.DoParse(pXMLContainer, m_pTextProvider);
+      }
+      IFDE_CSSComputedStyle* pRootStyle =
+          m_textParser.CreateRootStyle(m_pTextProvider);
+      LoadRichText(pXMLContainer, szText, fLinePos, pRootStyle, bSavePieces);
+      pRootStyle->Release();
+    }
+  } else {
+    LoadText(m_pTextDataNode, szText, fLinePos, bSavePieces);
+  }
+  return TRUE;
+}
+void CXFA_TextLayout::LoadText(CXFA_Node* pNode,
+                               const CFX_SizeF& szText,
+                               FX_FLOAT& fLinePos,
+                               FX_BOOL bSavePieces) {
+  InitBreak(szText.x);
+  CXFA_Para para = m_pTextProvider->GetParaNode();
+  FX_FLOAT fSpaceAbove = 0;
+  if (para) {
+    fSpaceAbove = para.GetSpaceAbove();
+    if (fSpaceAbove < 0.1f) {
+      fSpaceAbove = 0;
+    }
+    int32_t verAlign = para.GetVerticalAlign();
+    switch (verAlign) {
+      case XFA_ATTRIBUTEENUM_Top:
+      case XFA_ATTRIBUTEENUM_Middle:
+      case XFA_ATTRIBUTEENUM_Bottom: {
+        fLinePos += fSpaceAbove;
+        break;
+      }
+    }
+  }
+  CFX_WideString wsText = pNode->GetContent();
+  wsText.TrimRight(L" ");
+  FX_BOOL bRet = AppendChar(wsText, fLinePos, fSpaceAbove, bSavePieces);
+  if (bRet && m_pLoader) {
+    m_pLoader->m_pNode = pNode;
+  } else {
+    EndBreak(FX_RTFBREAK_ParagraphBreak, fLinePos, bSavePieces);
+  }
+}
+FX_BOOL CXFA_TextLayout::LoadRichText(IFDE_XMLNode* pXMLNode,
+                                      const CFX_SizeF& szText,
+                                      FX_FLOAT& fLinePos,
+                                      IFDE_CSSComputedStyle* pParentStyle,
+                                      FX_BOOL bSavePieces,
+                                      CXFA_LinkUserData* pLinkData,
+                                      FX_BOOL bEndBreak,
+                                      FX_BOOL bIsOl,
+                                      int32_t iLiCount) {
+  if (pXMLNode == NULL) {
+    return FALSE;
+  }
+  CXFA_TextParseContext* pContext =
+      m_textParser.GetParseContextFromMap(pXMLNode);
+  FDE_CSSDISPLAY eDisplay = FDE_CSSDISPLAY_None;
+  FX_BOOL bContentNode = FALSE;
+  FX_FLOAT fSpaceBelow = 0;
+  IFDE_CSSComputedStyle* pStyle = NULL;
+  CFX_WideString wsName;
+  if (bEndBreak) {
+    FX_BOOL bCurOl = FALSE;
+    FX_BOOL bCurLi = FALSE;
+    IFDE_XMLElement* pElement = NULL;
+    if (pContext) {
+      if (m_bBlockContinue ||
+          (m_pLoader && pXMLNode == m_pLoader->m_pXMLNode)) {
+        m_bBlockContinue = TRUE;
+      }
+      if (pXMLNode->GetType() == FDE_XMLNODE_Text) {
+        bContentNode = TRUE;
+      } else if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
+        pElement = (IFDE_XMLElement*)pXMLNode;
+        pElement->GetLocalTagName(wsName);
+      }
+      if (wsName == FX_WSTRC(L"ol")) {
+        bIsOl = TRUE;
+        bCurOl = TRUE;
+      }
+      if (m_bBlockContinue || bContentNode == FALSE) {
+        eDisplay = pContext->GetDisplay();
+        if (eDisplay != FDE_CSSDISPLAY_Block &&
+            eDisplay != FDE_CSSDISPLAY_Inline &&
+            eDisplay != FDE_CSSDISPLAY_ListItem) {
+          return TRUE;
+        }
+        pStyle = m_textParser.ComputeStyle(pXMLNode, pParentStyle);
+        InitBreak(bContentNode ? pParentStyle : pStyle, eDisplay, szText.x,
+                  pXMLNode, pParentStyle);
+        if ((eDisplay == FDE_CSSDISPLAY_Block ||
+             eDisplay == FDE_CSSDISPLAY_ListItem) &&
+            pStyle &&
+            (wsName.IsEmpty() ||
+             (wsName != FX_WSTRC(L"body") && wsName != FX_WSTRC(L"html") &&
+              wsName != FX_WSTRC(L"ol") && wsName != FX_WSTRC(L"ul")))) {
+          const FDE_CSSRECT* pRect =
+              pStyle->GetBoundaryStyles()->GetMarginWidth();
+          if (pRect) {
+            fLinePos += pRect->top.GetValue();
+            fSpaceBelow = pRect->bottom.GetValue();
+          }
+        }
+        if (wsName == FX_WSTRC(L"a")) {
+          CFX_WideString wsLinkContent;
+          FXSYS_assert(pElement);
+          pElement->GetString(FX_WSTRC(L"href").GetPtr(), wsLinkContent);
+          if (!wsLinkContent.IsEmpty()) {
+            pLinkData = FXTARGET_NewWith(m_pAllocator) CXFA_LinkUserData(
+                m_pAllocator,
+                wsLinkContent.GetBuffer(wsLinkContent.GetLength()));
+            wsLinkContent.ReleaseBuffer(wsLinkContent.GetLength());
+          }
+        }
+        int32_t iTabCount =
+            m_textParser.CountTabs(bContentNode ? pParentStyle : pStyle);
+        FX_BOOL bSpaceRun =
+            m_textParser.IsSpaceRun(bContentNode ? pParentStyle : pStyle);
+        CFX_WideString wsText;
+        if (bContentNode && iTabCount == 0) {
+          ((IFDE_XMLText*)pXMLNode)->GetText(wsText);
+        } else if (wsName == FX_WSTRC(L"br")) {
+          wsText = L'\n';
+        } else if (wsName == FX_WSTRC(L"li")) {
+          bCurLi = TRUE;
+          if (bIsOl) {
+            wsText.Format(L"%d.  ", iLiCount);
+          } else {
+            wsText = 0x00B7 + FX_WSTRC(L"  ");
+          }
+        } else if (!bContentNode) {
+          if (iTabCount > 0) {
+            while (iTabCount-- > 0)
+              wsText += L'\t';
+          } else {
+            m_textParser.GetEmbbedObj(m_pTextProvider, pXMLNode, wsText);
+          }
+        }
+        int32_t iLength = wsText.GetLength();
+        if (iLength > 0 && bContentNode && !bSpaceRun) {
+          ProcessText(wsText);
+        }
+        if (m_pLoader) {
+          if (wsText.GetLength() > 0 &&
+              (m_pLoader->m_dwFlags & XFA_LOADERCNTXTFLG_FILTERSPACE)) {
+            wsText.TrimLeft(0x20);
+          }
+          if (FDE_CSSDISPLAY_Block == eDisplay) {
+            m_pLoader->m_dwFlags |= XFA_LOADERCNTXTFLG_FILTERSPACE;
+          } else if (FDE_CSSDISPLAY_Inline == eDisplay &&
+                     (m_pLoader->m_dwFlags & XFA_LOADERCNTXTFLG_FILTERSPACE)) {
+            m_pLoader->m_dwFlags &= ~XFA_LOADERCNTXTFLG_FILTERSPACE;
+          } else if (wsText.GetLength() > 0 &&
+                     (0x20 == wsText.GetAt(wsText.GetLength() - 1))) {
+            m_pLoader->m_dwFlags |= XFA_LOADERCNTXTFLG_FILTERSPACE;
+          } else if (wsText.GetLength() != 0) {
+            m_pLoader->m_dwFlags &= ~XFA_LOADERCNTXTFLG_FILTERSPACE;
+          }
+        }
+        if (wsText.GetLength() > 0) {
+          if (m_pLoader == NULL || m_pLoader->m_iChar == 0) {
+            if (pLinkData) {
+              pLinkData->AddRef();
+            }
+            CXFA_TextUserData* pUserData = FXTARGET_NewWith(m_pAllocator)
+                CXFA_TextUserData(m_pAllocator,
+                                  bContentNode ? pParentStyle : pStyle,
+                                  pLinkData);
+            m_pBreak->SetUserData(pUserData);
+          }
+          if (AppendChar(wsText, fLinePos, 0, bSavePieces)) {
+            if (m_pLoader) {
+              m_pLoader->m_dwFlags &= ~XFA_LOADERCNTXTFLG_FILTERSPACE;
+            }
+            if (IsEnd(bSavePieces)) {
+              if (m_pLoader && m_pLoader->m_iTotalLines > -1) {
+                m_pLoader->m_pXMLNode = pXMLNode;
+                m_pLoader->m_pParentStyle = pParentStyle;
+              }
+              if (pStyle)
+                pStyle->Release();
+              return FALSE;
+            }
+            return TRUE;
+          }
+        }
+      }
+    }
+    FX_BOOL ret = TRUE;
+    for (IFDE_XMLNode* pChildNode =
+             pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild);
+         pChildNode;
+         pChildNode = pChildNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+      if (bCurOl) {
+        iLiCount++;
+      }
+      ret = LoadRichText(pChildNode, szText, fLinePos,
+                         pContext ? pStyle : pParentStyle, bSavePieces,
+                         pLinkData, TRUE, bIsOl, iLiCount);
+      if (ret == FALSE) {
+        return FALSE;
+      }
+    }
+    if (m_pLoader) {
+      if (FDE_CSSDISPLAY_Block == eDisplay) {
+        m_pLoader->m_dwFlags |= XFA_LOADERCNTXTFLG_FILTERSPACE;
+      }
+    }
+    if (bCurLi) {
+      EndBreak(FX_RTFBREAK_LineBreak, fLinePos, bSavePieces);
+    }
+  } else {
+    if (pContext) {
+      eDisplay = pContext->GetDisplay();
+    }
+  }
+  if (m_bBlockContinue) {
+    if (pContext && !bContentNode) {
+      FX_DWORD dwStatus = (eDisplay == FDE_CSSDISPLAY_Block)
+                              ? FX_RTFBREAK_ParagraphBreak
+                              : FX_RTFBREAK_PieceBreak;
+      EndBreak(dwStatus, fLinePos, bSavePieces);
+      if (eDisplay == FDE_CSSDISPLAY_Block) {
+        fLinePos += fSpaceBelow;
+        if (m_pTabstopContext) {
+          m_pTabstopContext->RemoveAll();
+        }
+      }
+      if (wsName == FX_WSTRC(L"a")) {
+        if (pLinkData) {
+          pLinkData->Release();
+          pLinkData = nullptr;
+        }
+      }
+      if (IsEnd(bSavePieces)) {
+        if (pStyle) {
+          pStyle->Release();
+        }
+        if (m_pLoader && m_pLoader->m_iTotalLines > -1) {
+          m_pLoader->m_pXMLNode =
+              pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling);
+          m_pLoader->m_pParentStyle = pParentStyle;
+        }
+        return FALSE;
+      }
+    }
+  }
+  if (pStyle)
+    pStyle->Release();
+  return TRUE;
+}
+FX_BOOL CXFA_TextLayout::AppendChar(const CFX_WideString& wsText,
+                                    FX_FLOAT& fLinePos,
+                                    FX_FLOAT fSpaceAbove,
+                                    FX_BOOL bSavePieces) {
+  FX_DWORD dwStatus = 0;
+  int32_t iChar = 0;
+  if (m_pLoader) {
+    iChar = m_pLoader->m_iChar;
+  }
+  int32_t iLength = wsText.GetLength();
+  for (int32_t i = iChar; i < iLength; i++) {
+    FX_WCHAR wch = wsText.GetAt(i);
+    if (wch == 0xA0) {
+      wch = 0x20;
+    }
+    if ((dwStatus = m_pBreak->AppendChar(wch)) > FX_RTFBREAK_PieceBreak) {
+      AppendTextLine(dwStatus, fLinePos, bSavePieces);
+      if (IsEnd(bSavePieces)) {
+        if (m_pLoader)
+          m_pLoader->m_iChar = i;
+        return TRUE;
+      }
+      if (dwStatus == FX_RTFBREAK_ParagraphBreak && m_bRichText) {
+        fLinePos += fSpaceAbove;
+      }
+    }
+  }
+  if (m_pLoader) {
+    m_pLoader->m_iChar = 0;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_TextLayout::IsEnd(FX_BOOL bSavePieces) {
+  if (!bSavePieces) {
+    return FALSE;
+  }
+  if (m_pLoader && m_pLoader->m_iTotalLines > 0) {
+    return m_iLines >= m_pLoader->m_iTotalLines;
+  }
+  return FALSE;
+}
+void CXFA_TextLayout::ProcessText(CFX_WideString& wsText) {
+  int32_t iLen = wsText.GetLength();
+  if (iLen == 0) {
+    return;
+  }
+  FX_WCHAR* psz = wsText.GetBuffer(iLen);
+  int32_t iTrimLeft = 0;
+  FX_WCHAR wch = 0, wPrev = 0;
+  for (int32_t i = 0; i < iLen; i++) {
+    wch = psz[i];
+    if (wch < 0x20) {
+      wch = 0x20;
+    }
+    if (wch == 0x20 && wPrev == 0x20) {
+      continue;
+    }
+    wPrev = wch;
+    psz[iTrimLeft++] = wch;
+  }
+  wsText.ReleaseBuffer(iLen);
+  wsText = wsText.Left(iTrimLeft);
+}
+void CXFA_TextLayout::EndBreak(FX_DWORD dwStatus,
+                               FX_FLOAT& fLinePos,
+                               FX_BOOL bSavePieces) {
+  dwStatus = m_pBreak->EndBreak(dwStatus);
+  if (dwStatus > FX_RTFBREAK_PieceBreak) {
+    AppendTextLine(dwStatus, fLinePos, bSavePieces, TRUE);
+  }
+}
+void CXFA_TextLayout::DoTabstops(IFDE_CSSComputedStyle* pStyle,
+                                 CXFA_PieceLine* pPieceLine) {
+  if (m_pTabstopContext == NULL || m_pTabstopContext->m_iTabCount == 0) {
+    return;
+  }
+  if (pStyle == NULL || pPieceLine == NULL) {
+    return;
+  }
+  int32_t iPieces = pPieceLine->m_textPieces.GetSize();
+  if (iPieces == 0) {
+    return;
+  }
+  XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(iPieces - 1);
+  int32_t& iTabstopsIndex = m_pTabstopContext->m_iTabIndex;
+  int32_t iCount = m_textParser.CountTabs(pStyle);
+  if (iTabstopsIndex > m_pTabstopContext->m_iTabCount - 1) {
+    return;
+  }
+  if (iCount > 0) {
+    iTabstopsIndex++;
+    m_pTabstopContext->m_bTabstops = TRUE;
+    FX_FLOAT fRight = 0;
+    if (iPieces > 1) {
+      XFA_TextPiece* p = pPieceLine->m_textPieces.GetAt(iPieces - 2);
+      fRight = p->rtPiece.right();
+    }
+    m_pTabstopContext->m_fTabWidth =
+        pPiece->rtPiece.width + pPiece->rtPiece.left - fRight;
+  } else if (iTabstopsIndex > -1) {
+    FX_FLOAT fLeft = 0;
+    if (m_pTabstopContext->m_bTabstops) {
+      XFA_TABSTOPS* pTabstops =
+          m_pTabstopContext->m_tabstops.GetDataPtr(iTabstopsIndex);
+      FX_DWORD dwAlgin = pTabstops->dwAlign;
+      if (dwAlgin == FX_HashCode_String_GetW(L"center", 6)) {
+        fLeft = pPiece->rtPiece.width / 2.0f;
+      } else if (dwAlgin == FX_HashCode_String_GetW(L"right", 5) ||
+                 dwAlgin == FX_HashCode_String_GetW(L"before", 6)) {
+        fLeft = pPiece->rtPiece.width;
+      } else if (dwAlgin == FX_HashCode_String_GetW(L"decimal", 7)) {
+        int32_t iChars = pPiece->iChars;
+        for (int32_t i = 0; i < iChars; i++) {
+          if (pPiece->pszText[i] == L'.') {
+            break;
+          }
+          fLeft += pPiece->pWidths[i] / 20000.0f;
+        }
+      }
+      m_pTabstopContext->m_fLeft =
+          std::min(fLeft, m_pTabstopContext->m_fTabWidth);
+      m_pTabstopContext->m_bTabstops = FALSE;
+      m_pTabstopContext->m_fTabWidth = 0;
+    }
+    pPiece->rtPiece.left -= m_pTabstopContext->m_fLeft;
+  }
+}
+void CXFA_TextLayout::AppendTextLine(FX_DWORD dwStatus,
+                                     FX_FLOAT& fLinePos,
+                                     FX_BOOL bSavePieces,
+                                     FX_BOOL bEndBreak) {
+  int32_t iPieces = m_pBreak->CountBreakPieces();
+  if (iPieces < 1) {
+    return;
+  }
+  IFDE_CSSComputedStyle* pStyle = NULL;
+  if (bSavePieces) {
+    CXFA_PieceLine* pPieceLine = FXTARGET_NewWith(m_pAllocator) CXFA_PieceLine;
+    m_pieceLines.Add(pPieceLine);
+    if (m_pTabstopContext) {
+      m_pTabstopContext->Reset();
+    }
+    FX_FLOAT fLineStep = 0, fBaseLine = 0;
+    int32_t i = 0;
+    for (i = 0; i < iPieces; i++) {
+      const CFX_RTFPiece* pPiece = m_pBreak->GetBreakPiece(i);
+      CXFA_TextUserData* pUserData = (CXFA_TextUserData*)pPiece->m_pUserData;
+      if (pUserData)
+        pStyle = pUserData->m_pStyle;
+      FX_FLOAT fVerScale = pPiece->m_iVerticalScale / 100.0f;
+      XFA_TextPiece* pTP = FXTARGET_NewWith(m_pAllocator) XFA_TextPiece();
+      pTP->pszText =
+          (FX_WCHAR*)m_pAllocator->Alloc(pPiece->m_iChars * sizeof(FX_WCHAR));
+      pTP->pWidths =
+          (int32_t*)m_pAllocator->Alloc(pPiece->m_iChars * sizeof(int32_t));
+      pTP->iChars = pPiece->m_iChars;
+      pPiece->GetString(pTP->pszText);
+      pPiece->GetWidths(pTP->pWidths);
+      pTP->iBidiLevel = pPiece->m_iBidiLevel;
+      pTP->iHorScale = pPiece->m_iHorizontalScale;
+      pTP->iVerScale = pPiece->m_iVerticalScale;
+      m_textParser.GetUnderline(m_pTextProvider, pStyle, pTP->iUnderline,
+                                pTP->iPeriod);
+      m_textParser.GetLinethrough(m_pTextProvider, pStyle, pTP->iLineThrough);
+      pTP->dwColor = m_textParser.GetColor(m_pTextProvider, pStyle);
+      pTP->pFont = m_textParser.GetFont(m_pTextProvider, pStyle);
+      pTP->fFontSize = m_textParser.GetFontSize(m_pTextProvider, pStyle);
+      pTP->rtPiece.left = pPiece->m_iStartPos / 20000.0f;
+      pTP->rtPiece.width = pPiece->m_iWidth / 20000.0f;
+      pTP->rtPiece.height = (FX_FLOAT)pPiece->m_iFontSize * fVerScale / 20.0f;
+      FX_FLOAT fBaseLineTemp =
+          m_textParser.GetBaseline(m_pTextProvider, pStyle);
+      pTP->rtPiece.top = fBaseLineTemp;
+      pPieceLine->m_textPieces.Add(pTP);
+      FX_FLOAT fLineHeight = m_textParser.GetLineHeight(
+          m_pTextProvider, pStyle, m_iLines == 0, fVerScale);
+      if (fBaseLineTemp > 0) {
+        FX_FLOAT fLineHeightTmp = fBaseLineTemp + pTP->rtPiece.height;
+        if (fLineHeight < fLineHeightTmp) {
+          fLineHeight = fLineHeightTmp;
+        } else {
+          fBaseLineTemp = 0;
+        }
+      } else if (fBaseLine < -fBaseLineTemp) {
+        fBaseLine = -fBaseLineTemp;
+      }
+      fLineStep = std::max(fLineStep, fLineHeight);
+      if (pUserData && pUserData->m_pLinkData) {
+        pUserData->m_pLinkData->AddRef();
+        pTP->pLinkData = pUserData->m_pLinkData;
+      } else {
+        pTP->pLinkData = NULL;
+      }
+      DoTabstops(pStyle, pPieceLine);
+    }
+    for (i = 0; i < iPieces; i++) {
+      XFA_TextPiece* pTP = pPieceLine->m_textPieces.GetAt(i);
+      FX_FLOAT& fTop = pTP->rtPiece.top;
+      FX_FLOAT fBaseLineTemp = fTop;
+      fTop = fLinePos + fLineStep - pTP->rtPiece.height - fBaseLineTemp;
+      fTop = std::max(0.0f, fTop);
+    }
+    fLinePos += fLineStep + fBaseLine;
+  } else {
+    FX_FLOAT fLineStep = 0;
+    FX_FLOAT fLineWidth = 0;
+    for (int32_t i = 0; i < iPieces; i++) {
+      const CFX_RTFPiece* pPiece = m_pBreak->GetBreakPiece(i);
+      CXFA_TextUserData* pUserData = (CXFA_TextUserData*)pPiece->m_pUserData;
+      if (pUserData)
+        pStyle = pUserData->m_pStyle;
+      FX_FLOAT fVerScale = pPiece->m_iVerticalScale / 100.0f;
+      FX_FLOAT fBaseLine = m_textParser.GetBaseline(m_pTextProvider, pStyle);
+      FX_FLOAT fLineHeight = m_textParser.GetLineHeight(
+          m_pTextProvider, pStyle, m_iLines == 0, fVerScale);
+      if (fBaseLine > 0) {
+        FX_FLOAT fLineHeightTmp =
+            fBaseLine + (FX_FLOAT)pPiece->m_iFontSize * fVerScale / 20.0f;
+        if (fLineHeight < fLineHeightTmp) {
+          fLineHeight = fLineHeightTmp;
+        }
+      }
+      fLineStep = std::max(fLineStep, fLineHeight);
+      fLineWidth += pPiece->m_iWidth / 20000.0f;
+    }
+    fLinePos += fLineStep;
+    m_fMaxWidth = std::max(m_fMaxWidth, fLineWidth);
+    if (m_pLoader && m_pLoader->m_bSaveLineHeight) {
+      FX_FLOAT fHeight = fLinePos - m_pLoader->m_fLastPos;
+      m_pLoader->m_fLastPos = fLinePos;
+      m_pLoader->m_lineHeights.Add(fHeight);
+    }
+  }
+  if (pStyle) {
+    pStyle->AddRef();
+  }
+  m_pBreak->ClearBreakPieces();
+  if (dwStatus == FX_RTFBREAK_ParagraphBreak) {
+    m_pBreak->Reset();
+    if (!pStyle && bEndBreak) {
+      CXFA_Para para = m_pTextProvider->GetParaNode();
+      if (para) {
+        FX_FLOAT fStartPos = para.GetMarginLeft();
+        FX_FLOAT fIndent = para.GetTextIndent();
+        if (fIndent > 0) {
+          fStartPos += fIndent;
+        }
+        FX_FLOAT fSpaceBelow = para.GetSpaceBelow();
+        if (fSpaceBelow < 0.1f) {
+          fSpaceBelow = 0;
+        }
+        m_pBreak->SetLineStartPos(fStartPos);
+        fLinePos += fSpaceBelow;
+      }
+    }
+  }
+  if (pStyle) {
+    FX_FLOAT fStart = 0;
+    const FDE_CSSRECT* pRect = pStyle->GetBoundaryStyles()->GetMarginWidth();
+    if (pRect) {
+      fStart = pRect->left.GetValue();
+    }
+    FX_FLOAT fTextIndent =
+        pStyle->GetParagraphStyles()->GetTextIndent().GetValue();
+    if (fTextIndent < 0) {
+      fStart -= fTextIndent;
+    }
+    m_pBreak->SetLineStartPos(fStart);
+    pStyle->Release();
+  }
+  m_iLines++;
+}
+void CXFA_TextLayout::RenderString(IFDE_RenderDevice* pDevice,
+                                   IFDE_SolidBrush* pBrush,
+                                   CXFA_PieceLine* pPieceLine,
+                                   int32_t iPiece,
+                                   FXTEXT_CHARPOS* pCharPos,
+                                   const CFX_Matrix& tmDoc2Device) {
+  const XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(iPiece);
+  int32_t iCount = GetDisplayPos(pPiece, pCharPos);
+  if (iCount > 0) {
+    pBrush->SetColor(pPiece->dwColor);
+    pDevice->DrawString(pBrush, pPiece->pFont, pCharPos, iCount,
+                        pPiece->fFontSize, &tmDoc2Device);
+  }
+  pPieceLine->m_charCounts.Add(iCount);
+}
+void CXFA_TextLayout::RenderPath(IFDE_RenderDevice* pDevice,
+                                 IFDE_Pen* pPen,
+                                 CXFA_PieceLine* pPieceLine,
+                                 int32_t iPiece,
+                                 FXTEXT_CHARPOS* pCharPos,
+                                 const CFX_Matrix& tmDoc2Device) {
+  XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(iPiece);
+  FX_BOOL bNoUnderline = pPiece->iUnderline < 1 || pPiece->iUnderline > 2;
+  FX_BOOL bNoLineThrough = pPiece->iLineThrough < 1 || pPiece->iLineThrough > 2;
+  if (bNoUnderline && bNoLineThrough) {
+    return;
+  }
+  pPen->SetColor(pPiece->dwColor);
+  IFDE_Path* pPath = IFDE_Path::Create();
+  int32_t iChars = GetDisplayPos(pPiece, pCharPos);
+  if (iChars > 0) {
+    CFX_PointF pt1, pt2;
+    FX_FLOAT fEndY = pCharPos[0].m_OriginY + 1.05f;
+    int32_t i = 0;
+    if (pPiece->iPeriod == XFA_ATTRIBUTEENUM_Word) {
+      for (int32_t i = 0; i < pPiece->iUnderline; i++) {
+        for (int32_t j = 0; j < iChars; j++) {
+          pt1.x = pCharPos[j].m_OriginX;
+          pt2.x =
+              pt1.x + pCharPos[j].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
+          pt1.y = pt2.y = fEndY;
+          pPath->AddLine(pt1, pt2);
+        }
+        fEndY += 2.0f;
+      }
+    } else {
+      pt1.x = pCharPos[0].m_OriginX;
+      pt2.x =
+          pCharPos[iChars - 1].m_OriginX +
+          pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
+      for (int32_t i = 0; i < pPiece->iUnderline; i++) {
+        pt1.y = pt2.y = fEndY;
+        pPath->AddLine(pt1, pt2);
+        fEndY += 2.0f;
+      }
+    }
+    fEndY = pCharPos[0].m_OriginY - pPiece->rtPiece.height * 0.25f;
+    pt1.x = pCharPos[0].m_OriginX;
+    pt2.x = pCharPos[iChars - 1].m_OriginX +
+            pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
+    for (i = 0; i < pPiece->iLineThrough; i++) {
+      pt1.y = pt2.y = fEndY;
+      pPath->AddLine(pt1, pt2);
+      fEndY += 2.0f;
+    }
+  } else {
+    if (bNoLineThrough &&
+        (bNoUnderline || pPiece->iPeriod != XFA_ATTRIBUTEENUM_All)) {
+      goto XFA_RenderPathRet;
+    }
+    int32_t iCharsTmp = 0;
+    int32_t iPiecePrev = iPiece, iPieceNext = iPiece;
+    while (iPiecePrev > 0) {
+      iPiecePrev--;
+      iCharsTmp = pPieceLine->m_charCounts.GetAt(iPiecePrev);
+      if (iCharsTmp > 0) {
+        break;
+      }
+    }
+    if (iCharsTmp == 0) {
+      goto XFA_RenderPathRet;
+    }
+    iCharsTmp = 0;
+    int32_t iPieces = pPieceLine->m_textPieces.GetSize();
+    while (iPieceNext < iPieces - 1) {
+      iPieceNext++;
+      iCharsTmp = pPieceLine->m_charCounts.GetAt(iPieceNext);
+      if (iCharsTmp > 0) {
+        break;
+      }
+    }
+    if (iCharsTmp == 0) {
+      goto XFA_RenderPathRet;
+    }
+    FX_FLOAT fOrgX = 0.0f, fEndX = 0.0f;
+    pPiece = pPieceLine->m_textPieces.GetAt(iPiecePrev);
+    iChars = GetDisplayPos(pPiece, pCharPos);
+    if (iChars < 1) {
+      goto XFA_RenderPathRet;
+    }
+    fOrgX = pCharPos[iChars - 1].m_OriginX +
+            pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
+    pPiece = pPieceLine->m_textPieces.GetAt(iPieceNext);
+    iChars = GetDisplayPos(pPiece, pCharPos);
+    if (iChars < 1) {
+      goto XFA_RenderPathRet;
+    }
+    fEndX = pCharPos[0].m_OriginX;
+    CFX_PointF pt1, pt2;
+    pt1.x = fOrgX, pt2.x = fEndX;
+    FX_FLOAT fEndY = pCharPos[0].m_OriginY + 1.05f;
+    int32_t i = 0;
+    for (i = 0; i < pPiece->iUnderline; i++) {
+      pt1.y = pt2.y = fEndY;
+      pPath->AddLine(pt1, pt2);
+      fEndY += 2.0f;
+    }
+    fEndY = pCharPos[0].m_OriginY - pPiece->rtPiece.height * 0.25f;
+    for (i = 0; i < pPiece->iLineThrough; i++) {
+      pt1.y = pt2.y = fEndY;
+      pPath->AddLine(pt1, pt2);
+      fEndY += 2.0f;
+    }
+  }
+  pDevice->DrawPath(pPen, 1, pPath, &tmDoc2Device);
+XFA_RenderPathRet:
+  pPath->Release();
+}
+int32_t CXFA_TextLayout::GetDisplayPos(const XFA_TextPiece* pPiece,
+                                       FXTEXT_CHARPOS* pCharPos,
+                                       FX_BOOL bCharCode) {
+  if (pPiece == NULL) {
+    return 0;
+  }
+  FX_RTFTEXTOBJ tr;
+  if (!ToRun(pPiece, tr)) {
+    return 0;
+  }
+  return m_pBreak->GetDisplayPos(&tr, pCharPos, bCharCode);
+}
+FX_BOOL CXFA_TextLayout::ToRun(const XFA_TextPiece* pPiece, FX_RTFTEXTOBJ& tr) {
+  int32_t iLength = pPiece->iChars;
+  if (iLength < 1) {
+    return FALSE;
+  }
+  tr.pStr = pPiece->pszText;
+  tr.pFont = pPiece->pFont;
+  tr.pRect = &pPiece->rtPiece;
+  tr.pWidths = pPiece->pWidths;
+  tr.iLength = iLength;
+  tr.fFontSize = pPiece->fFontSize;
+  tr.iBidiLevel = pPiece->iBidiLevel;
+  tr.iCharRotation = 0;
+  tr.wLineBreakChar = L'\n';
+  tr.iVerticalScale = pPiece->iVerScale;
+  tr.dwLayoutStyles = FX_RTFLAYOUTSTYLE_ExpandTab;
+  tr.iHorizontalScale = pPiece->iHorScale;
+  return TRUE;
+}
diff --git a/xfa/fxfa/app/xfa_textlayout.h b/xfa/fxfa/app/xfa_textlayout.h
new file mode 100644
index 0000000..9cc1e29
--- /dev/null
+++ b/xfa/fxfa/app/xfa_textlayout.h
@@ -0,0 +1,425 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_APP_XFA_TEXTLAYOUT_H_
+#define XFA_FXFA_APP_XFA_TEXTLAYOUT_H_
+
+#include "xfa/fde/css/fde_css.h"
+#include "xfa/fde/fde_brush.h"
+#include "xfa/fde/fde_renderdevice.h"
+#include "xfa/fgas/layout/fgas_rtfbreak.h"
+#include "xfa/fxfa/app/xfa_ffdoc.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+
+#define XFA_LOADERCNTXTFLG_FILTERSPACE 0x001
+
+class CXFA_Para;
+class CXFA_Font;
+class CXFA_TextTabstopsContext;
+
+class IXFA_TextProvider {
+ public:
+  virtual ~IXFA_TextProvider() {}
+  virtual CXFA_Node* GetTextNode(FX_BOOL& bRichText) = 0;
+  virtual CXFA_Para GetParaNode() = 0;
+  virtual CXFA_Font GetFontNode() = 0;
+  virtual FX_BOOL IsCheckButtonAndAutoWidth() = 0;
+  virtual CXFA_FFDoc* GetDocNode() = 0;
+  virtual FX_BOOL GetEmbbedObj(FX_BOOL bURI,
+                               FX_BOOL bRaw,
+                               const CFX_WideString& wsAttr,
+                               CFX_WideString& wsValue) = 0;
+};
+
+class CXFA_CSSTagProvider : public IFDE_CSSTagProvider {
+ public:
+  CXFA_CSSTagProvider() : m_bTagAviliable(FALSE), m_bContent(FALSE) {}
+  virtual ~CXFA_CSSTagProvider();
+  virtual CFX_WideStringC GetTagName() { return m_wsTagName; }
+  virtual FX_POSITION GetFirstAttribute() {
+    return m_Attributes.GetStartPosition();
+  }
+  virtual void GetNextAttribute(FX_POSITION& pos,
+                                CFX_WideStringC& wsAttr,
+                                CFX_WideStringC& wsValue);
+  void SetTagNameObj(const CFX_WideString& wsName) { m_wsTagName = wsName; }
+  void SetAttribute(const CFX_WideString& wsAttr,
+                    const CFX_WideString& wsValue);
+  FX_BOOL m_bTagAviliable;
+  FX_BOOL m_bContent;
+
+ protected:
+  CFX_WideString m_wsTagName;
+  CFX_MapPtrToPtr m_Attributes;
+};
+
+class CXFA_TextParseContext : public CFX_Target {
+ public:
+  CXFA_TextParseContext()
+      : m_pParentStyle(nullptr),
+        m_ppMatchedDecls(nullptr),
+        m_dwMatchedDecls(0),
+        m_eDisplay(FDE_CSSDISPLAY_None) {}
+  ~CXFA_TextParseContext() {
+    if (m_pParentStyle)
+      m_pParentStyle->Release();
+    FX_Free(m_ppMatchedDecls);
+  }
+  void SetDisplay(FDE_CSSDISPLAY eDisplay) { m_eDisplay = eDisplay; }
+  FDE_CSSDISPLAY GetDisplay() const { return m_eDisplay; }
+  void SetDecls(const IFDE_CSSDeclaration** ppDeclArray, int32_t iDeclCount);
+  const IFDE_CSSDeclaration** GetDecls() {
+    return (const IFDE_CSSDeclaration**)m_ppMatchedDecls;
+  }
+  FX_DWORD CountDecls() const { return m_dwMatchedDecls; }
+  IFDE_CSSComputedStyle* m_pParentStyle;
+
+ protected:
+  IFDE_CSSDeclaration** m_ppMatchedDecls;
+  FX_DWORD m_dwMatchedDecls;
+  FDE_CSSDISPLAY m_eDisplay;
+};
+
+class CXFA_TextParser {
+ public:
+  CXFA_TextParser() : m_pAllocator(NULL), m_pSelector(NULL), m_pUASheet(NULL) {}
+  virtual ~CXFA_TextParser();
+  void Reset();
+  void DoParse(IFDE_XMLNode* pXMLContainer, IXFA_TextProvider* pTextProvider);
+  IFDE_CSSComputedStyle* CreateRootStyle(IXFA_TextProvider* pTextProvider);
+  IFDE_CSSComputedStyle* ComputeStyle(IFDE_XMLNode* pXMLNode,
+                                      IFDE_CSSComputedStyle* pParentStyle);
+  FX_BOOL IsParsed() const { return m_pAllocator != NULL; }
+
+  int32_t GetVAlgin(IXFA_TextProvider* pTextProvider) const;
+  FX_FLOAT GetTabInterval(IFDE_CSSComputedStyle* pStyle) const;
+  int32_t CountTabs(IFDE_CSSComputedStyle* pStyle) const;
+  FX_BOOL IsSpaceRun(IFDE_CSSComputedStyle* pStyle) const;
+  FX_BOOL GetTabstops(IFDE_CSSComputedStyle* pStyle,
+                      CXFA_TextTabstopsContext* pTabstopContext);
+  IFX_Font* GetFont(IXFA_TextProvider* pTextProvider,
+                    IFDE_CSSComputedStyle* pStyle) const;
+  FX_FLOAT GetFontSize(IXFA_TextProvider* pTextProvider,
+                       IFDE_CSSComputedStyle* pStyle) const;
+  int32_t GetHorScale(IXFA_TextProvider* pTextProvider,
+                      IFDE_CSSComputedStyle* pStyle,
+                      IFDE_XMLNode* pXMLNode) const;
+  int32_t GetVerScale(IXFA_TextProvider* pTextProvider,
+                      IFDE_CSSComputedStyle* pStyle) const;
+  void GetUnderline(IXFA_TextProvider* pTextProvider,
+                    IFDE_CSSComputedStyle* pStyle,
+                    int32_t& iUnderline,
+                    int32_t& iPeriod) const;
+  void GetLinethrough(IXFA_TextProvider* pTextProvider,
+                      IFDE_CSSComputedStyle* pStyle,
+                      int32_t& iLinethrough) const;
+  FX_ARGB GetColor(IXFA_TextProvider* pTextProvider,
+                   IFDE_CSSComputedStyle* pStyle) const;
+  FX_FLOAT GetBaseline(IXFA_TextProvider* pTextProvider,
+                       IFDE_CSSComputedStyle* pStyle) const;
+  FX_FLOAT GetLineHeight(IXFA_TextProvider* pTextProvider,
+                         IFDE_CSSComputedStyle* pStyle,
+                         FX_BOOL bFirst,
+                         FX_FLOAT fVerScale) const;
+  FX_BOOL GetEmbbedObj(IXFA_TextProvider* pTextProvider,
+                       IFDE_XMLNode* pXMLNode,
+                       CFX_WideString& wsValue);
+  CXFA_TextParseContext* GetParseContextFromMap(IFDE_XMLNode* pXMLNode);
+
+ private:
+  void InitCSSData(IXFA_TextProvider* pTextProvider);
+  void ParseRichText(IFDE_XMLNode* pXMLNode,
+                     IFDE_CSSComputedStyle* pParentStyle);
+  void ParseTagInfo(IFDE_XMLNode* pXMLNode, CXFA_CSSTagProvider& tagProvider);
+  IFDE_CSSStyleSheet* LoadDefaultSheetStyle();
+  IFDE_CSSComputedStyle* CreateStyle(IFDE_CSSComputedStyle* pParentStyle);
+  IFX_MEMAllocator* m_pAllocator;
+  IFDE_CSSStyleSelector* m_pSelector;
+  IFDE_CSSStyleSheet* m_pUASheet;
+  CFX_MapPtrTemplate<IFDE_XMLNode*, CXFA_TextParseContext*>
+      m_mapXMLNodeToParseContext;
+};
+
+class CXFA_LoaderContext {
+ public:
+  CXFA_LoaderContext()
+      : m_bSaveLineHeight(FALSE),
+        m_fWidth(0),
+        m_fHeight(0),
+        m_fLastPos(0),
+        m_fStartLineOffset(0),
+        m_iChar(0),
+        m_iTotalLines(-1),
+        m_pXMLNode(NULL),
+        m_pNode(NULL),
+        m_pParentStyle(NULL),
+        m_dwFlags(0) {}
+  FX_BOOL m_bSaveLineHeight;
+  FX_FLOAT m_fWidth;
+  FX_FLOAT m_fHeight;
+  FX_FLOAT m_fLastPos;
+  FX_FLOAT m_fStartLineOffset;
+  int32_t m_iChar;
+  int32_t m_iLines;
+  int32_t m_iTotalLines;
+  IFDE_XMLNode* m_pXMLNode;
+  CXFA_Node* m_pNode;
+  IFDE_CSSComputedStyle* m_pParentStyle;
+  CFX_ArrayTemplate<FX_FLOAT> m_lineHeights;
+  FX_DWORD m_dwFlags;
+  CFX_FloatArray m_BlocksHeight;
+};
+
+class CXFA_LinkUserData : public IFX_Unknown, public CFX_Target {
+ public:
+  CXFA_LinkUserData(IFX_MEMAllocator* pAllocator, FX_WCHAR* pszText)
+      : m_pAllocator(pAllocator), m_dwRefCount(1) {
+    m_pszURLContent = pszText;
+  }
+  ~CXFA_LinkUserData() {}
+  virtual FX_DWORD Release() {
+    FX_DWORD dwRefCount = --m_dwRefCount;
+    if (dwRefCount <= 0) {
+      FXTARGET_DeleteWith(CXFA_LinkUserData, m_pAllocator, this);
+    }
+    return dwRefCount;
+  }
+  virtual FX_DWORD AddRef() { return ++m_dwRefCount; }
+
+ public:
+  const FX_WCHAR* GetLinkURL() { return m_pszURLContent; }
+
+ protected:
+  IFX_MEMAllocator* m_pAllocator;
+  FX_DWORD m_dwRefCount;
+  CFX_WideString m_pszURLContent;
+};
+
+class CXFA_TextUserData : public IFX_Unknown, public CFX_Target {
+ public:
+  CXFA_TextUserData(IFX_MEMAllocator* pAllocator, IFDE_CSSComputedStyle* pStyle)
+      : m_pStyle(pStyle),
+        m_pLinkData(nullptr),
+        m_pAllocator(pAllocator),
+        m_dwRefCount(0) {
+    FXSYS_assert(m_pAllocator);
+    if (m_pStyle)
+      m_pStyle->AddRef();
+  }
+  CXFA_TextUserData(IFX_MEMAllocator* pAllocator,
+                    IFDE_CSSComputedStyle* pStyle,
+                    CXFA_LinkUserData* pLinkData)
+      : m_pStyle(pStyle),
+        m_pLinkData(pLinkData),
+        m_pAllocator(pAllocator),
+        m_dwRefCount(0) {
+    FXSYS_assert(m_pAllocator);
+    if (m_pStyle)
+      m_pStyle->AddRef();
+  }
+  ~CXFA_TextUserData() {
+    if (m_pStyle)
+      m_pStyle->Release();
+    if (m_pLinkData)
+      m_pLinkData->Release();
+  }
+  virtual FX_DWORD Release() {
+    FX_DWORD dwRefCount = --m_dwRefCount;
+    if (dwRefCount == 0) {
+      FXTARGET_DeleteWith(CXFA_TextUserData, m_pAllocator, this);
+    }
+    return dwRefCount;
+  }
+  virtual FX_DWORD AddRef() { return ++m_dwRefCount; }
+
+  IFDE_CSSComputedStyle* m_pStyle;
+  CXFA_LinkUserData* m_pLinkData;
+
+ protected:
+  IFX_MEMAllocator* m_pAllocator;
+  FX_DWORD m_dwRefCount;
+};
+
+class XFA_TextPiece : public CFX_Target {
+ public:
+  XFA_TextPiece() : pszText(nullptr), pFont(nullptr), pLinkData(nullptr) {}
+  ~XFA_TextPiece() {
+    if (pLinkData)
+      pLinkData->Release();
+  }
+
+  FX_WCHAR* pszText;
+  int32_t iChars;
+  int32_t* pWidths;
+  int32_t iHorScale;
+  int32_t iVerScale;
+  int32_t iBidiLevel;
+  int32_t iUnderline;
+  int32_t iPeriod;
+  int32_t iLineThrough;
+  IFX_Font* pFont;
+  FX_ARGB dwColor;
+  FX_FLOAT fFontSize;
+  CFX_RectF rtPiece;
+  CXFA_LinkUserData* pLinkData;
+};
+typedef CFX_ArrayTemplate<XFA_TextPiece*> CXFA_PieceArray;
+
+class CXFA_PieceLine : public CFX_Target {
+ public:
+  CXFA_PieceLine() {}
+  CXFA_PieceArray m_textPieces;
+  CFX_Int32Array m_charCounts;
+};
+typedef CFX_ArrayTemplate<CXFA_PieceLine*> CXFA_PieceLineArray;
+
+struct XFA_TABSTOPS {
+  FX_DWORD dwAlign;
+  FX_FLOAT fTabstops;
+};
+
+class CXFA_TextTabstopsContext {
+ public:
+  CXFA_TextTabstopsContext()
+      : m_iTabCount(0),
+        m_iTabIndex(-1),
+        m_bTabstops(FALSE),
+        m_fTabWidth(0),
+        m_fLeft(0) {}
+  void Append(FX_DWORD dwAlign, FX_FLOAT fTabstops) {
+    int32_t i = 0;
+    for (i = 0; i < m_iTabCount; i++) {
+      XFA_TABSTOPS* pTabstop = m_tabstops.GetDataPtr(i);
+      if (fTabstops < pTabstop->fTabstops) {
+        break;
+      }
+    }
+    m_tabstops.InsertSpaceAt(i, 1);
+    XFA_TABSTOPS tabstop;
+    tabstop.dwAlign = dwAlign;
+    tabstop.fTabstops = fTabstops;
+    m_tabstops.SetAt(i, tabstop);
+    m_iTabCount++;
+  }
+  void RemoveAll() {
+    m_tabstops.RemoveAll();
+    m_iTabCount = 0;
+  }
+  void Reset() {
+    m_iTabIndex = -1;
+    m_bTabstops = FALSE;
+    m_fTabWidth = 0;
+    m_fLeft = 0;
+  }
+  CFX_ArrayTemplate<XFA_TABSTOPS> m_tabstops;
+  int32_t m_iTabCount;
+  int32_t m_iTabIndex;
+  FX_BOOL m_bTabstops;
+  FX_FLOAT m_fTabWidth;
+  FX_FLOAT m_fLeft;
+};
+
+class CXFA_TextLayout {
+ public:
+  CXFA_TextLayout(IXFA_TextProvider* pTextProvider);
+  virtual ~CXFA_TextLayout();
+  int32_t GetText(CFX_WideString& wsText);
+  FX_FLOAT GetLayoutHeight();
+  FX_FLOAT StartLayout(FX_FLOAT fWidth = -1);
+  FX_BOOL DoLayout(int32_t iBlockIndex,
+                   FX_FLOAT& fCalcHeight,
+                   FX_FLOAT fContentAreaHeight = -1,
+                   FX_FLOAT fTextHeight = -1);
+
+  FX_BOOL CalcSize(const CFX_SizeF& minSize,
+                   const CFX_SizeF& maxSize,
+                   CFX_SizeF& defaultSize);
+  FX_BOOL Layout(const CFX_SizeF& size, FX_FLOAT* fHeight = NULL);
+  void ItemBlocks(const CFX_RectF& rtText, int32_t iBlockIndex);
+  FX_BOOL DrawString(CFX_RenderDevice* pFxDevice,
+                     const CFX_Matrix& tmDoc2Device,
+                     const CFX_RectF& rtClip,
+                     int32_t iBlock = 0);
+  FX_BOOL IsLoaded() const { return m_pieceLines.GetSize() > 0; }
+  void Unload();
+  const CXFA_PieceLineArray* GetPieceLines();
+
+  FX_BOOL m_bHasBlock;
+  CFX_Int32Array m_Blocks;
+
+ private:
+  void GetTextDataNode();
+  IFDE_XMLNode* GetXMLContainerNode();
+  IFX_RTFBreak* CreateBreak(FX_BOOL bDefault);
+  void InitBreak(FX_FLOAT fLineWidth);
+  void InitBreak(IFDE_CSSComputedStyle* pStyle,
+                 FDE_CSSDISPLAY eDisplay,
+                 FX_FLOAT fLineWidth,
+                 IFDE_XMLNode* pXMLNode,
+                 IFDE_CSSComputedStyle* pParentStyle = NULL);
+  FX_BOOL Loader(const CFX_SizeF& szText,
+                 FX_FLOAT& fLinePos,
+                 FX_BOOL bSavePieces = TRUE);
+  void LoadText(CXFA_Node* pNode,
+                const CFX_SizeF& szText,
+                FX_FLOAT& fLinePos,
+                FX_BOOL bSavePieces);
+  FX_BOOL LoadRichText(IFDE_XMLNode* pXMLNode,
+                       const CFX_SizeF& szText,
+                       FX_FLOAT& fLinePos,
+                       IFDE_CSSComputedStyle* pParentStyle,
+                       FX_BOOL bSavePieces,
+                       CXFA_LinkUserData* pLinkData = NULL,
+                       FX_BOOL bEndBreak = TRUE,
+                       FX_BOOL bIsOl = FALSE,
+                       int32_t iLiCount = 0);
+  FX_BOOL AppendChar(const CFX_WideString& wsText,
+                     FX_FLOAT& fLinePos,
+                     FX_FLOAT fSpaceAbove,
+                     FX_BOOL bSavePieces);
+  void AppendTextLine(FX_DWORD dwStatus,
+                      FX_FLOAT& fLinePos,
+                      FX_BOOL bSavePieces,
+                      FX_BOOL bEndBreak = FALSE);
+  void EndBreak(FX_DWORD dwStatus, FX_FLOAT& fLinePos, FX_BOOL bDefault);
+  FX_BOOL IsEnd(FX_BOOL bSavePieces);
+  void ProcessText(CFX_WideString& wsText);
+  void UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom);
+  void RenderString(IFDE_RenderDevice* pDevice,
+                    IFDE_SolidBrush* pBrush,
+                    CXFA_PieceLine* pPieceLine,
+                    int32_t iPiece,
+                    FXTEXT_CHARPOS* pCharPos,
+                    const CFX_Matrix& tmDoc2Device);
+  void RenderPath(IFDE_RenderDevice* pDevice,
+                  IFDE_Pen* pPen,
+                  CXFA_PieceLine* pPieceLine,
+                  int32_t iPiece,
+                  FXTEXT_CHARPOS* pCharPos,
+                  const CFX_Matrix& tmDoc2Device);
+  int32_t GetDisplayPos(const XFA_TextPiece* pPiece,
+                        FXTEXT_CHARPOS* pCharPos,
+                        FX_BOOL bCharCode = FALSE);
+  FX_BOOL ToRun(const XFA_TextPiece* pPiece, FX_RTFTEXTOBJ& tr);
+  void DoTabstops(IFDE_CSSComputedStyle* pStyle, CXFA_PieceLine* pPieceLine);
+  FX_BOOL Layout(int32_t iBlock);
+  int32_t CountBlocks() const;
+
+  IXFA_TextProvider* m_pTextProvider;
+  CXFA_Node* m_pTextDataNode;
+  FX_BOOL m_bRichText;
+  IFX_MEMAllocator* m_pAllocator;
+  IFX_RTFBreak* m_pBreak;
+  CXFA_LoaderContext* m_pLoader;
+  int32_t m_iLines;
+  FX_FLOAT m_fMaxWidth;
+  CXFA_TextParser m_textParser;
+  CXFA_PieceLineArray m_pieceLines;
+  CXFA_TextTabstopsContext* m_pTabstopContext;
+  FX_BOOL m_bBlockContinue;
+};
+
+#endif  // XFA_FXFA_APP_XFA_TEXTLAYOUT_H_
diff --git a/xfa/fxfa/fm2js/xfa_error.cpp b/xfa/fxfa/fm2js/xfa_error.cpp
new file mode 100644
index 0000000..69ce608
--- /dev/null
+++ b/xfa/fxfa/fm2js/xfa_error.cpp
@@ -0,0 +1,21 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/fm2js/xfa_error.h"
+
+static const FX_WCHAR* const gs_lpStrErrorMsgInfo[] = {
+    L"unsupported char '%c'",         L"bad suffix on number",
+    L"invalidate char '%c'",          L"expected identifier instead of '%s'",
+    L"expected '%s' instead of '%s'", L"expected 'endif' instead of '%s'",
+    L"unexpected expression '%s'",    L"expected operator '%s' instead of '%s'",
+    L"expected non-empty expression",
+};
+
+const FX_WCHAR* XFA_FM_ErrorMsg(XFA_FM_ERRMSG msg) {
+  if (msg < FMERR_MAXIMUM)
+    return gs_lpStrErrorMsgInfo[msg];
+  return L"";
+}
diff --git a/xfa/fxfa/fm2js/xfa_error.h b/xfa/fxfa/fm2js/xfa_error.h
new file mode 100644
index 0000000..1da1e24
--- /dev/null
+++ b/xfa/fxfa/fm2js/xfa_error.h
@@ -0,0 +1,35 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_FM2JS_XFA_ERROR_H_
+#define XFA_FXFA_FM2JS_XFA_ERROR_H_
+
+#include "core/include/fxcrt/fx_string.h"
+#include "core/include/fxcrt/fx_system.h"
+
+enum XFA_FM_ERRMSG {
+  FMERR_UNSUPPORTED_CHAR,
+  FMERR_BAD_SUFFIX_NUMBER,
+  FMERR_INVALIDATE_CHAR,
+  FMERR_EXPECTED_IDENTIFIER,
+  FMERR_EXPECTED_TOKEN,
+  FMERR_EXPECTED_IFEND,
+  FMERR_UNEXPECTED_EXPRESSION,
+  FMERR_EXPTECTED_OPERATOR,
+  FMERR_EXPECTED_NON_EMPTY_EXPRESSION,
+  FMERR_MAXIMUM
+};
+
+class CXFA_FMErrorInfo {
+ public:
+  CXFA_FMErrorInfo() : linenum(0) {}
+  ~CXFA_FMErrorInfo() {}
+  FX_DWORD linenum;
+  CFX_WideString message;
+};
+const FX_WCHAR* XFA_FM_ErrorMsg(XFA_FM_ERRMSG msg);
+
+#endif  // XFA_FXFA_FM2JS_XFA_ERROR_H_
diff --git a/xfa/fxfa/fm2js/xfa_expression.cpp b/xfa/fxfa/fm2js/xfa_expression.cpp
new file mode 100644
index 0000000..b4b1a1a
--- /dev/null
+++ b/xfa/fxfa/fm2js/xfa_expression.cpp
@@ -0,0 +1,627 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/fm2js/xfa_expression.h"
+
+#include "core/include/fxcrt/fx_basic.h"
+
+namespace {
+
+const CFX_WideStringC RUNTIMEBLOCKTEMPARRAY =
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime_block_temp_array");
+
+const CFX_WideStringC RUNTIMEBLOCKTEMPARRAYINDEX =
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime_block_temp_array_index");
+
+}  // namespace
+
+CXFA_FMExpression::CXFA_FMExpression(FX_DWORD line)
+    : m_type(XFA_FM_EXPTYPE_UNKNOWN), m_line(line) {}
+
+CXFA_FMExpression::CXFA_FMExpression(FX_DWORD line, XFA_FM_EXPTYPE type)
+    : m_type(type), m_line(line) {}
+
+void CXFA_FMExpression::ToJavaScript(CFX_WideTextBuf& javascript) {}
+
+void CXFA_FMExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {}
+
+CXFA_FMFunctionDefinition::CXFA_FMFunctionDefinition(
+    FX_DWORD line,
+    FX_BOOL isGlobal,
+    const CFX_WideStringC& wsName,
+    CFX_WideStringCArray* pArguments,
+    CFX_PtrArray* pExpressions)
+    : CXFA_FMExpression(line, XFA_FM_EXPTYPE_FUNC),
+      m_wsName(wsName),
+      m_pArguments(pArguments),
+      m_pExpressions(pExpressions),
+      m_isGlobal(isGlobal) {}
+
+CXFA_FMFunctionDefinition::~CXFA_FMFunctionDefinition() {
+  if (m_pArguments) {
+    m_pArguments->RemoveAll();
+    delete m_pArguments;
+  }
+  if (m_pExpressions) {
+    for (int i = 0; i < m_pExpressions->GetSize(); ++i) {
+      delete reinterpret_cast<CXFA_FMExpression*>(m_pExpressions->GetAt(i));
+    }
+    m_pExpressions->RemoveAll();
+    delete m_pExpressions;
+  }
+}
+
+void CXFA_FMFunctionDefinition::ToJavaScript(CFX_WideTextBuf& javascript) {
+  if (m_isGlobal && (!m_pExpressions || m_pExpressions->GetSize() == 0)) {
+    javascript << FX_WSTRC(L"// comments only");
+    return;
+  }
+  if (m_isGlobal) {
+    javascript << FX_WSTRC(L"(\n");
+  }
+  javascript << FX_WSTRC(L"function ");
+  if (m_wsName.GetAt(0) == L'!') {
+    CFX_WideString tempName = EXCLAMATION_IN_IDENTIFIER + m_wsName.Mid(1);
+    javascript << tempName;
+  } else {
+    javascript << m_wsName;
+  }
+  javascript << FX_WSTRC(L"(");
+  if (m_pArguments != 0) {
+    CFX_WideStringC identifier = 0;
+    for (int i = 0; i < m_pArguments->GetSize(); ++i) {
+      identifier = m_pArguments->GetAt(i);
+      if (identifier.GetAt(0) == L'!') {
+        CFX_WideString tempIdentifier =
+            EXCLAMATION_IN_IDENTIFIER + identifier.Mid(1);
+        javascript << tempIdentifier;
+      } else {
+        javascript << identifier;
+      }
+      if (i + 1 < m_pArguments->GetSize()) {
+        javascript << FX_WSTRC(L", ");
+      }
+    }
+  }
+  javascript << FX_WSTRC(L")\n{\n");
+  javascript << FX_WSTRC(L"var ");
+  javascript << RUNTIMEFUNCTIONRETURNVALUE;
+  javascript << FX_WSTRC(L" = null;\n");
+  if (m_pExpressions) {
+    for (int i = 0; i < m_pExpressions->GetSize(); ++i) {
+      CXFA_FMExpression* e =
+          reinterpret_cast<CXFA_FMExpression*>(m_pExpressions->GetAt(i));
+      if (i + 1 < m_pExpressions->GetSize()) {
+        e->ToJavaScript(javascript);
+      } else {
+        e->ToImpliedReturnJS(javascript);
+      }
+    }
+  }
+  javascript << FX_WSTRC(L"return ");
+  if (m_isGlobal) {
+    javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+    javascript << FX_WSTRC(L"(");
+    javascript << RUNTIMEFUNCTIONRETURNVALUE;
+    javascript << FX_WSTRC(L")");
+  } else {
+    javascript << RUNTIMEFUNCTIONRETURNVALUE;
+  }
+  javascript << FX_WSTRC(L";\n}\n");
+  if (m_isGlobal) {
+    javascript << FX_WSTRC(L").call(this);\n");
+  }
+}
+
+void CXFA_FMFunctionDefinition::ToImpliedReturnJS(CFX_WideTextBuf&) {}
+
+CXFA_FMVarExpression::CXFA_FMVarExpression(FX_DWORD line,
+                                           const CFX_WideStringC& wsName,
+                                           CXFA_FMExpression* pInit)
+    : CXFA_FMExpression(line, XFA_FM_EXPTYPE_VAR),
+      m_wsName(wsName),
+      m_pInit(pInit) {}
+
+void CXFA_FMVarExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  javascript << FX_WSTRC(L"var ");
+  CFX_WideString tempName = m_wsName;
+  if (m_wsName.GetAt(0) == L'!') {
+    tempName = EXCLAMATION_IN_IDENTIFIER + m_wsName.Mid(1);
+  }
+  javascript << tempName;
+  javascript << FX_WSTRC(L" = ");
+  if (m_pInit) {
+    m_pInit->ToJavaScript(javascript);
+    javascript << tempName;
+    javascript << FX_WSTRC(L" = ");
+    javascript << XFA_FM_EXPTypeToString(VARFILTER);
+    javascript << FX_WSTRC(L"(");
+    javascript << tempName;
+    javascript << FX_WSTRC(L");\n");
+  } else {
+    javascript << FX_WSTRC(L"\"\";\n");
+  }
+}
+
+void CXFA_FMVarExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
+  javascript << FX_WSTRC(L"var ");
+  CFX_WideString tempName = m_wsName;
+  if (m_wsName.GetAt(0) == L'!') {
+    tempName = EXCLAMATION_IN_IDENTIFIER + m_wsName.Mid(1);
+  }
+  javascript << tempName;
+  javascript << FX_WSTRC(L" = ");
+  if (m_pInit) {
+    m_pInit->ToJavaScript(javascript);
+    javascript << tempName;
+    javascript << FX_WSTRC(L" = ");
+    javascript << XFA_FM_EXPTypeToString(VARFILTER);
+    javascript << FX_WSTRC(L"(");
+    javascript << tempName;
+    javascript << FX_WSTRC(L");\n");
+  } else {
+    javascript << FX_WSTRC(L"\"\";\n");
+  }
+  javascript << RUNTIMEFUNCTIONRETURNVALUE;
+  javascript << FX_WSTRC(L" = ");
+  javascript << tempName;
+  javascript << FX_WSTRC(L";\n");
+}
+
+CXFA_FMExpExpression::CXFA_FMExpExpression(FX_DWORD line,
+                                           CXFA_FMSimpleExpression* pExpression)
+    : CXFA_FMExpression(line, XFA_FM_EXPTYPE_EXP), m_pExpression(pExpression) {}
+
+void CXFA_FMExpExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  if (m_pExpression->GetOperatorToken() == TOKassign) {
+    m_pExpression->ToJavaScript(javascript);
+  } else {
+    m_pExpression->ToJavaScript(javascript);
+    javascript << FX_WSTRC(L";\n");
+  }
+}
+
+void CXFA_FMExpExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
+  if (m_pExpression->GetOperatorToken() == TOKassign) {
+    m_pExpression->ToImpliedReturnJS(javascript);
+  } else {
+    if (m_pExpression->GetOperatorToken() == TOKstar ||
+        m_pExpression->GetOperatorToken() == TOKdotstar ||
+        m_pExpression->GetOperatorToken() == TOKdotscream ||
+        m_pExpression->GetOperatorToken() == TOKdotdot ||
+        m_pExpression->GetOperatorToken() == TOKdot) {
+      javascript << RUNTIMEFUNCTIONRETURNVALUE;
+      javascript << FX_WSTRC(L" = ");
+      javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+      javascript << FX_WSTRC(L"(");
+      m_pExpression->ToJavaScript(javascript);
+      javascript << FX_WSTRC(L");\n");
+    } else {
+      javascript << RUNTIMEFUNCTIONRETURNVALUE;
+      javascript << FX_WSTRC(L" = ");
+      m_pExpression->ToJavaScript(javascript);
+      javascript << FX_WSTRC(L";\n");
+    }
+  }
+}
+
+CXFA_FMBlockExpression::CXFA_FMBlockExpression(FX_DWORD line,
+                                               CFX_PtrArray* pExpressionList)
+    : CXFA_FMExpression(line, XFA_FM_EXPTYPE_BLOCK),
+      m_pExpressionList(pExpressionList) {}
+
+CXFA_FMBlockExpression::~CXFA_FMBlockExpression() {
+  if (m_pExpressionList) {
+    for (int i = 0; i < m_pExpressionList->GetSize(); ++i) {
+      delete reinterpret_cast<CXFA_FMExpression*>(m_pExpressionList->GetAt(i));
+    }
+    m_pExpressionList->RemoveAll();
+    delete m_pExpressionList;
+  }
+}
+
+void CXFA_FMBlockExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  javascript << FX_WSTRC(L"{\n");
+  if (m_pExpressionList) {
+    for (int i = 0; i < m_pExpressionList->GetSize(); ++i) {
+      CXFA_FMExpression* e =
+          reinterpret_cast<CXFA_FMExpression*>(m_pExpressionList->GetAt(i));
+      e->ToJavaScript(javascript);
+    }
+  }
+  javascript << FX_WSTRC(L"}\n");
+}
+
+void CXFA_FMBlockExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
+  javascript << FX_WSTRC(L"{\n");
+  if (m_pExpressionList) {
+    for (int i = 0; i < m_pExpressionList->GetSize(); ++i) {
+      CXFA_FMExpression* e =
+          reinterpret_cast<CXFA_FMExpression*>(m_pExpressionList->GetAt(i));
+      if (i + 1 == m_pExpressionList->GetSize()) {
+        e->ToImpliedReturnJS(javascript);
+      } else {
+        e->ToJavaScript(javascript);
+      }
+    }
+  }
+  javascript << FX_WSTRC(L"}\n");
+}
+
+CXFA_FMDoExpression::CXFA_FMDoExpression(FX_DWORD line,
+                                         CXFA_FMExpression* pList)
+    : CXFA_FMExpression(line), m_pList(pList) {}
+
+void CXFA_FMDoExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  m_pList->ToJavaScript(javascript);
+}
+
+void CXFA_FMDoExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
+  m_pList->ToImpliedReturnJS(javascript);
+}
+
+CXFA_FMIfExpression::CXFA_FMIfExpression(FX_DWORD line,
+                                         CXFA_FMSimpleExpression* pExpression,
+                                         CXFA_FMExpression* pIfExpression,
+                                         CXFA_FMExpression* pElseExpression)
+    : CXFA_FMExpression(line, XFA_FM_EXPTYPE_IF),
+      m_pExpression(pExpression),
+      m_pIfExpression(pIfExpression),
+      m_pElseExpression(pElseExpression) {}
+
+void CXFA_FMIfExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  javascript << FX_WSTRC(L"if (");
+  if (m_pExpression) {
+    javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+    javascript << FX_WSTRC(L"(");
+    m_pExpression->ToJavaScript(javascript);
+    javascript << FX_WSTRC(L")");
+  }
+  javascript << FX_WSTRC(L")\n");
+  if (m_pIfExpression) {
+    m_pIfExpression->ToJavaScript(javascript);
+  }
+  if (m_pElseExpression) {
+    if (m_pElseExpression->GetExpType() == XFA_FM_EXPTYPE_IF) {
+      javascript << FX_WSTRC(L"else\n");
+      javascript << FX_WSTRC(L"{\n");
+      m_pElseExpression->ToJavaScript(javascript);
+      javascript << FX_WSTRC(L"}\n");
+    } else {
+      javascript << FX_WSTRC(L"else\n");
+      m_pElseExpression->ToJavaScript(javascript);
+    }
+  }
+}
+
+void CXFA_FMIfExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
+  javascript << RUNTIMEFUNCTIONRETURNVALUE;
+  javascript << FX_WSTRC(L" = 0;\n");
+  javascript << FX_WSTRC(L"if (");
+  if (m_pExpression) {
+    javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+    javascript << FX_WSTRC(L"(");
+    m_pExpression->ToJavaScript(javascript);
+    javascript << FX_WSTRC(L")");
+  }
+  javascript << FX_WSTRC(L")\n");
+  if (m_pIfExpression) {
+    m_pIfExpression->ToImpliedReturnJS(javascript);
+  }
+  if (m_pElseExpression) {
+    if (m_pElseExpression->GetExpType() == XFA_FM_EXPTYPE_IF) {
+      javascript << FX_WSTRC(L"else\n");
+      javascript << FX_WSTRC(L"{\n");
+      m_pElseExpression->ToImpliedReturnJS(javascript);
+      javascript << FX_WSTRC(L"}\n");
+    } else {
+      javascript << FX_WSTRC(L"else\n");
+      m_pElseExpression->ToImpliedReturnJS(javascript);
+    }
+  }
+}
+
+CXFA_FMLoopExpression::~CXFA_FMLoopExpression() {}
+
+void CXFA_FMLoopExpression::ToJavaScript(CFX_WideTextBuf& javascript) {}
+
+void CXFA_FMLoopExpression::ToImpliedReturnJS(CFX_WideTextBuf&) {}
+
+CXFA_FMWhileExpression::CXFA_FMWhileExpression(
+    FX_DWORD line,
+    CXFA_FMSimpleExpression* pCondition,
+    CXFA_FMExpression* pExpression)
+    : CXFA_FMLoopExpression(line),
+      m_pCondition(pCondition),
+      m_pExpression(pExpression) {}
+
+void CXFA_FMWhileExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  javascript << FX_WSTRC(L"while (");
+  m_pCondition->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L")\n");
+  m_pExpression->ToJavaScript(javascript);
+}
+
+void CXFA_FMWhileExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
+  javascript << RUNTIMEFUNCTIONRETURNVALUE;
+  javascript << FX_WSTRC(L" = 0;\n");
+  javascript << FX_WSTRC(L"while (");
+  m_pCondition->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L")\n");
+  m_pExpression->ToImpliedReturnJS(javascript);
+}
+
+CXFA_FMBreakExpression::CXFA_FMBreakExpression(FX_DWORD line)
+    : CXFA_FMExpression(line, XFA_FM_EXPTYPE_BREAK) {}
+
+CXFA_FMBreakExpression::~CXFA_FMBreakExpression() {}
+
+void CXFA_FMBreakExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  javascript << RUNTIMEFUNCTIONRETURNVALUE;
+  javascript << FX_WSTRC(L" = 0;\n");
+  javascript << FX_WSTRC(L"break;\n");
+}
+
+void CXFA_FMBreakExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
+  javascript << RUNTIMEFUNCTIONRETURNVALUE;
+  javascript << FX_WSTRC(L" = 0;\n");
+  javascript << FX_WSTRC(L"break;\n");
+}
+
+CXFA_FMContinueExpression::CXFA_FMContinueExpression(FX_DWORD line)
+    : CXFA_FMExpression(line, XFA_FM_EXPTYPE_CONTINUE) {}
+
+CXFA_FMContinueExpression::~CXFA_FMContinueExpression() {}
+
+void CXFA_FMContinueExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  javascript << RUNTIMEFUNCTIONRETURNVALUE;
+  javascript << FX_WSTRC(L" = 0;\n");
+  javascript << FX_WSTRC(L"continue;\n");
+}
+
+void CXFA_FMContinueExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
+  javascript << RUNTIMEFUNCTIONRETURNVALUE;
+  javascript << FX_WSTRC(L" = 0;\n");
+  javascript << FX_WSTRC(L"continue;\n");
+}
+
+CXFA_FMForExpression::CXFA_FMForExpression(FX_DWORD line,
+                                           const CFX_WideStringC& wsVariant,
+                                           CXFA_FMSimpleExpression* pAssignment,
+                                           CXFA_FMSimpleExpression* pAccessor,
+                                           int32_t iDirection,
+                                           CXFA_FMSimpleExpression* pStep,
+                                           CXFA_FMExpression* pList)
+    : CXFA_FMLoopExpression(line),
+      m_wsVariant(wsVariant),
+      m_pAssignment(pAssignment),
+      m_pAccessor(pAccessor),
+      m_iDirection(iDirection),
+      m_pStep(pStep),
+      m_pList(pList) {}
+
+void CXFA_FMForExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  javascript << FX_WSTRC(L"{\nvar ");
+  CFX_WideString tempVariant;
+  if (m_wsVariant.GetAt(0) == L'!') {
+    tempVariant = EXCLAMATION_IN_IDENTIFIER + m_wsVariant.Mid(1);
+    javascript << tempVariant;
+  } else {
+    tempVariant = m_wsVariant;
+    javascript << m_wsVariant;
+  }
+  javascript << FX_WSTRC(L" = null;\n");
+  javascript << FX_WSTRC(L"for (");
+  javascript << tempVariant;
+  javascript << FX_WSTRC(L" = ");
+  javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+  javascript << FX_WSTRC(L"(");
+  m_pAssignment->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L"); ");
+  javascript << tempVariant;
+  if (m_iDirection == 1) {
+    javascript << FX_WSTRC(L" <= ");
+    javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+    javascript << FX_WSTRC(L"(");
+    m_pAccessor->ToJavaScript(javascript);
+    javascript << FX_WSTRC(L"); ");
+    javascript << tempVariant;
+    javascript << FX_WSTRC(L" += ");
+  } else {
+    javascript << FX_WSTRC(L" >= ");
+    javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+    javascript << FX_WSTRC(L"(");
+    m_pAccessor->ToJavaScript(javascript);
+    javascript << FX_WSTRC(L"); ");
+    javascript << tempVariant;
+    javascript << FX_WSTRC(L" -= ");
+  }
+  if (m_pStep) {
+    javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+    javascript << FX_WSTRC(L"(");
+    m_pStep->ToJavaScript(javascript);
+    javascript << FX_WSTRC(L")");
+  } else {
+    javascript << FX_WSTRC(L"1");
+  }
+  javascript << FX_WSTRC(L")\n");
+  m_pList->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L"}\n");
+}
+
+void CXFA_FMForExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
+  javascript << RUNTIMEFUNCTIONRETURNVALUE;
+  javascript << FX_WSTRC(L" = 0;\n");
+  javascript << FX_WSTRC(L"{\nvar ");
+  CFX_WideString tempVariant;
+  if (m_wsVariant.GetAt(0) == L'!') {
+    tempVariant = EXCLAMATION_IN_IDENTIFIER + m_wsVariant.Mid(1);
+    javascript << tempVariant;
+  } else {
+    tempVariant = m_wsVariant;
+    javascript << m_wsVariant;
+  }
+  javascript << FX_WSTRC(L" = null;\n");
+  javascript << FX_WSTRC(L"for (");
+  javascript << tempVariant;
+  javascript << FX_WSTRC(L" = ");
+  javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+  javascript << FX_WSTRC(L"(");
+  m_pAssignment->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L"); ");
+  javascript << tempVariant;
+  if (m_iDirection == 1) {
+    javascript << FX_WSTRC(L" <= ");
+    javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+    javascript << FX_WSTRC(L"(");
+    m_pAccessor->ToJavaScript(javascript);
+    javascript << FX_WSTRC(L"); ");
+    javascript << tempVariant;
+    javascript << FX_WSTRC(L" += ");
+  } else {
+    javascript << FX_WSTRC(L" >= ");
+    javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+    javascript << FX_WSTRC(L"(");
+    m_pAccessor->ToJavaScript(javascript);
+    javascript << FX_WSTRC(L"); ");
+    javascript << tempVariant;
+    javascript << FX_WSTRC(L" -= ");
+  }
+  if (m_pStep) {
+    javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+    javascript << FX_WSTRC(L"(");
+    m_pStep->ToJavaScript(javascript);
+    javascript << FX_WSTRC(L")");
+  } else {
+    javascript << FX_WSTRC(L"1");
+  }
+  javascript << FX_WSTRC(L")\n");
+  m_pList->ToImpliedReturnJS(javascript);
+  javascript << FX_WSTRC(L"}\n");
+}
+
+CXFA_FMForeachExpression::CXFA_FMForeachExpression(
+    FX_DWORD line,
+    const CFX_WideStringC& wsIdentifier,
+    CFX_PtrArray* pAccessors,
+    CXFA_FMExpression* pList)
+    : CXFA_FMLoopExpression(line),
+      m_wsIdentifier(wsIdentifier),
+      m_pAccessors(pAccessors),
+      m_pList(pList) {}
+
+CXFA_FMForeachExpression::~CXFA_FMForeachExpression() {
+  if (m_pAccessors) {
+    for (int i = 0; i < m_pAccessors->GetSize(); ++i) {
+      delete reinterpret_cast<CXFA_FMSimpleExpression*>(m_pAccessors->GetAt(i));
+    }
+    m_pAccessors->RemoveAll();
+    delete m_pAccessors;
+  }
+}
+
+void CXFA_FMForeachExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  javascript << FX_WSTRC(L"{\n");
+  javascript << FX_WSTRC(L"var ");
+  if (m_wsIdentifier.GetAt(0) == L'!') {
+    CFX_WideString tempIdentifier =
+        EXCLAMATION_IN_IDENTIFIER + m_wsIdentifier.Mid(1);
+    javascript << tempIdentifier;
+  } else {
+    javascript << m_wsIdentifier;
+  }
+  javascript << FX_WSTRC(L" = null;\n");
+  javascript << FX_WSTRC(L"var ");
+  javascript << RUNTIMEBLOCKTEMPARRAY;
+  javascript << FX_WSTRC(L" = ");
+  javascript << XFA_FM_EXPTypeToString(CONCATFMOBJECT);
+  javascript << FX_WSTRC(L"(");
+
+  for (int i = 0; i < m_pAccessors->GetSize(); ++i) {
+    CXFA_FMSimpleExpression* s =
+        reinterpret_cast<CXFA_FMSimpleExpression*>(m_pAccessors->GetAt(i));
+    s->ToJavaScript(javascript);
+    if (i + 1 < m_pAccessors->GetSize()) {
+      javascript << FX_WSTRC(L", ");
+    }
+  }
+  javascript << FX_WSTRC(L");\n");
+  javascript << FX_WSTRC(L"var ");
+  javascript << RUNTIMEBLOCKTEMPARRAYINDEX;
+  javascript << FX_WSTRC(L" = 0;\n");
+  javascript << FX_WSTRC(L"while(");
+  javascript << RUNTIMEBLOCKTEMPARRAYINDEX;
+  javascript << FX_WSTRC(L" < ");
+  javascript << RUNTIMEBLOCKTEMPARRAY;
+  javascript << FX_WSTRC(L".length)\n{\n");
+  if (m_wsIdentifier.GetAt(0) == L'!') {
+    CFX_WideString tempIdentifier =
+        EXCLAMATION_IN_IDENTIFIER + m_wsIdentifier.Mid(1);
+    javascript << tempIdentifier;
+  } else {
+    javascript << m_wsIdentifier;
+  }
+  javascript << FX_WSTRC(L" = ");
+  javascript << RUNTIMEBLOCKTEMPARRAY;
+  javascript << FX_WSTRC(L"[");
+  javascript << RUNTIMEBLOCKTEMPARRAYINDEX;
+  javascript << FX_WSTRC(L"++];\n");
+  m_pList->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L"}\n");
+  javascript << FX_WSTRC(L"}\n");
+}
+
+void CXFA_FMForeachExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
+  javascript << RUNTIMEFUNCTIONRETURNVALUE;
+  javascript << FX_WSTRC(L" = 0;\n");
+  javascript << FX_WSTRC(L"{\n");
+  javascript << FX_WSTRC(L"var ");
+  if (m_wsIdentifier.GetAt(0) == L'!') {
+    CFX_WideString tempIdentifier =
+        EXCLAMATION_IN_IDENTIFIER + m_wsIdentifier.Mid(1);
+    javascript << tempIdentifier;
+  } else {
+    javascript << m_wsIdentifier;
+  }
+  javascript << FX_WSTRC(L" = null;\n");
+  javascript << FX_WSTRC(L"var ");
+  javascript << RUNTIMEBLOCKTEMPARRAY;
+  javascript << FX_WSTRC(L" = ");
+  javascript << XFA_FM_EXPTypeToString(CONCATFMOBJECT);
+  javascript << FX_WSTRC(L"(");
+  for (int i = 0; i < m_pAccessors->GetSize(); ++i) {
+    CXFA_FMSimpleExpression* s =
+        reinterpret_cast<CXFA_FMSimpleExpression*>(m_pAccessors->GetAt(i));
+    s->ToJavaScript(javascript);
+    if (i + 1 < m_pAccessors->GetSize()) {
+      javascript << FX_WSTRC(L", ");
+    }
+  }
+  javascript << FX_WSTRC(L");\n");
+  javascript << FX_WSTRC(L"var ");
+  javascript << RUNTIMEBLOCKTEMPARRAYINDEX;
+  javascript << FX_WSTRC(L" = 0;\n");
+  javascript << FX_WSTRC(L"while(");
+  javascript << RUNTIMEBLOCKTEMPARRAYINDEX;
+  javascript << FX_WSTRC(L" < ");
+  javascript << RUNTIMEBLOCKTEMPARRAY;
+  javascript << FX_WSTRC(L".length)\n{\n");
+  if (m_wsIdentifier.GetAt(0) == L'!') {
+    CFX_WideString tempIdentifier =
+        EXCLAMATION_IN_IDENTIFIER + m_wsIdentifier.Mid(1);
+    javascript << tempIdentifier;
+  } else {
+    javascript << m_wsIdentifier;
+  }
+  javascript << FX_WSTRC(L" = ");
+  javascript << RUNTIMEBLOCKTEMPARRAY;
+  javascript << FX_WSTRC(L"[");
+  javascript << RUNTIMEBLOCKTEMPARRAYINDEX;
+  javascript << FX_WSTRC(L"++];\n");
+  m_pList->ToImpliedReturnJS(javascript);
+  javascript << FX_WSTRC(L"}\n");
+  javascript << FX_WSTRC(L"}\n");
+}
diff --git a/xfa/fxfa/fm2js/xfa_expression.h b/xfa/fxfa/fm2js/xfa_expression.h
new file mode 100644
index 0000000..0b99e8d
--- /dev/null
+++ b/xfa/fxfa/fm2js/xfa_expression.h
@@ -0,0 +1,191 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_FM2JS_XFA_EXPRESSION_H_
+#define XFA_FXFA_FM2JS_XFA_EXPRESSION_H_
+
+#include <memory>
+
+#include "xfa/fxfa/fm2js/xfa_simpleexpression.h"
+
+enum XFA_FM_EXPTYPE {
+  XFA_FM_EXPTYPE_UNKNOWN,
+  XFA_FM_EXPTYPE_FUNC,
+  XFA_FM_EXPTYPE_VAR,
+  XFA_FM_EXPTYPE_EXP,
+  XFA_FM_EXPTYPE_BLOCK,
+  XFA_FM_EXPTYPE_IF,
+  XFA_FM_EXPTYPE_BREAK,
+  XFA_FM_EXPTYPE_CONTINUE,
+};
+
+class CXFA_FMExpression {
+ public:
+  explicit CXFA_FMExpression(FX_DWORD line);
+  CXFA_FMExpression(FX_DWORD line, XFA_FM_EXPTYPE type);
+  virtual ~CXFA_FMExpression() {}
+  virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+  virtual void ToImpliedReturnJS(CFX_WideTextBuf&);
+  FX_DWORD GetLine() { return m_line; }
+  XFA_FM_EXPTYPE GetExpType() const { return m_type; }
+
+ protected:
+  XFA_FM_EXPTYPE m_type;
+  FX_DWORD m_line;
+};
+
+class CXFA_FMFunctionDefinition : public CXFA_FMExpression {
+ public:
+  CXFA_FMFunctionDefinition(FX_DWORD line,
+                            FX_BOOL isGlobal,
+                            const CFX_WideStringC& wsName,
+                            CFX_WideStringCArray* pArguments,
+                            CFX_PtrArray* pExpressions);
+  ~CXFA_FMFunctionDefinition() override;
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+  void ToImpliedReturnJS(CFX_WideTextBuf&) override;
+
+ private:
+  CFX_WideStringC m_wsName;
+  CFX_WideStringCArray* m_pArguments;
+  CFX_PtrArray* m_pExpressions;
+  FX_BOOL m_isGlobal;
+};
+
+class CXFA_FMVarExpression : public CXFA_FMExpression {
+ public:
+  CXFA_FMVarExpression(FX_DWORD line,
+                       const CFX_WideStringC& wsName,
+                       CXFA_FMExpression* pInit);
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+  void ToImpliedReturnJS(CFX_WideTextBuf&) override;
+
+ private:
+  CFX_WideStringC m_wsName;
+  std::unique_ptr<CXFA_FMExpression> m_pInit;
+};
+
+class CXFA_FMExpExpression : public CXFA_FMExpression {
+ public:
+  CXFA_FMExpExpression(FX_DWORD line, CXFA_FMSimpleExpression* pExpression);
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+  void ToImpliedReturnJS(CFX_WideTextBuf&) override;
+
+ private:
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pExpression;
+};
+
+class CXFA_FMBlockExpression : public CXFA_FMExpression {
+ public:
+  CXFA_FMBlockExpression(FX_DWORD line, CFX_PtrArray* pExpressionList);
+  ~CXFA_FMBlockExpression() override;
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+  void ToImpliedReturnJS(CFX_WideTextBuf&) override;
+
+ private:
+  CFX_PtrArray* m_pExpressionList;
+};
+
+class CXFA_FMDoExpression : public CXFA_FMExpression {
+ public:
+  CXFA_FMDoExpression(FX_DWORD line, CXFA_FMExpression* pList);
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+  void ToImpliedReturnJS(CFX_WideTextBuf&) override;
+
+ private:
+  std::unique_ptr<CXFA_FMExpression> m_pList;
+};
+
+class CXFA_FMIfExpression : public CXFA_FMExpression {
+ public:
+  CXFA_FMIfExpression(FX_DWORD line,
+                      CXFA_FMSimpleExpression* pExpression,
+                      CXFA_FMExpression* pIfExpression,
+                      CXFA_FMExpression* pElseExpression);
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+  void ToImpliedReturnJS(CFX_WideTextBuf&) override;
+
+ private:
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pExpression;
+  std::unique_ptr<CXFA_FMExpression> m_pIfExpression;
+  std::unique_ptr<CXFA_FMExpression> m_pElseExpression;
+};
+
+class CXFA_FMLoopExpression : public CXFA_FMExpression {
+ public:
+  explicit CXFA_FMLoopExpression(FX_DWORD line) : CXFA_FMExpression(line) {}
+  ~CXFA_FMLoopExpression() override;
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+  void ToImpliedReturnJS(CFX_WideTextBuf&) override;
+};
+
+class CXFA_FMWhileExpression : public CXFA_FMLoopExpression {
+ public:
+  CXFA_FMWhileExpression(FX_DWORD line,
+                         CXFA_FMSimpleExpression* pCodition,
+                         CXFA_FMExpression* pExpression);
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+  void ToImpliedReturnJS(CFX_WideTextBuf&) override;
+
+ private:
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pCondition;
+  std::unique_ptr<CXFA_FMExpression> m_pExpression;
+};
+
+class CXFA_FMBreakExpression : public CXFA_FMExpression {
+ public:
+  explicit CXFA_FMBreakExpression(FX_DWORD line);
+  ~CXFA_FMBreakExpression() override;
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+  void ToImpliedReturnJS(CFX_WideTextBuf&) override;
+};
+
+class CXFA_FMContinueExpression : public CXFA_FMExpression {
+ public:
+  explicit CXFA_FMContinueExpression(FX_DWORD line);
+  ~CXFA_FMContinueExpression() override;
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+  void ToImpliedReturnJS(CFX_WideTextBuf&) override;
+};
+
+class CXFA_FMForExpression : public CXFA_FMLoopExpression {
+ public:
+  CXFA_FMForExpression(FX_DWORD line,
+                       const CFX_WideStringC& wsVariant,
+                       CXFA_FMSimpleExpression* pAssignment,
+                       CXFA_FMSimpleExpression* pAccessor,
+                       int32_t iDirection,
+                       CXFA_FMSimpleExpression* pStep,
+                       CXFA_FMExpression* pList);
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+  void ToImpliedReturnJS(CFX_WideTextBuf&) override;
+
+ private:
+  CFX_WideStringC m_wsVariant;
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pAssignment;
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pAccessor;
+  int32_t m_iDirection;
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pStep;
+  std::unique_ptr<CXFA_FMExpression> m_pList;
+};
+
+class CXFA_FMForeachExpression : public CXFA_FMLoopExpression {
+ public:
+  CXFA_FMForeachExpression(FX_DWORD line,
+                           const CFX_WideStringC& wsIdentifier,
+                           CFX_PtrArray* pAccessors,
+                           CXFA_FMExpression* pList);
+  ~CXFA_FMForeachExpression() override;
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+  void ToImpliedReturnJS(CFX_WideTextBuf&) override;
+
+ private:
+  CFX_WideStringC m_wsIdentifier;
+  CFX_PtrArray* m_pAccessors;
+  std::unique_ptr<CXFA_FMExpression> m_pList;
+};
+
+#endif  // XFA_FXFA_FM2JS_XFA_EXPRESSION_H_
diff --git a/xfa/fxfa/fm2js/xfa_fm2jsapi.cpp b/xfa/fxfa/fm2js/xfa_fm2jsapi.cpp
new file mode 100644
index 0000000..3a6bc17
--- /dev/null
+++ b/xfa/fxfa/fm2js/xfa_fm2jsapi.cpp
@@ -0,0 +1,65 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+
+#include "core/include/fxcrt/fx_basic.h"
+#include "xfa/fxfa/fm2js/xfa_fm2jscontext.h"
+#include "xfa/fxfa/fm2js/xfa_program.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int32_t XFA_FM2JS_Translate(const CFX_WideStringC& wsFormcalc,
+                            CFX_WideTextBuf& wsJavascript,
+                            CFX_WideString& wsError) {
+  if (wsFormcalc.IsEmpty()) {
+    wsJavascript.Clear();
+    wsError.Empty();
+    return 0;
+  }
+  int32_t status = 0;
+  CXFA_FMProgram program;
+  status = program.Init(wsFormcalc);
+  if (status) {
+    wsError = program.GetError().message;
+    return status;
+  }
+  status = program.ParseProgram();
+  if (status) {
+    wsError = program.GetError().message;
+    return status;
+  }
+  program.TranslateProgram(wsJavascript);
+  return 0;
+}
+XFA_HFM2JSCONTEXT XFA_FM2JS_ContextCreate() {
+  return (XFA_HFM2JSCONTEXT)CXFA_FM2JSContext::Create();
+}
+void XFA_FM2JS_ContextInitialize(XFA_HFM2JSCONTEXT hFM2JSContext,
+                                 FXJSE_HRUNTIME hScriptRuntime,
+                                 FXJSE_HCONTEXT hScriptContext,
+                                 CXFA_Document* pDocument) {
+  CXFA_FM2JSContext* pContext =
+      reinterpret_cast<CXFA_FM2JSContext*>(hFM2JSContext);
+  pContext->Initialize(hScriptRuntime, hScriptContext, pDocument);
+}
+void XFA_FM2JS_GlobalPropertyGetter(XFA_HFM2JSCONTEXT hFM2JSContext,
+                                    FXJSE_HVALUE hValue) {
+  CXFA_FM2JSContext* pContext =
+      reinterpret_cast<CXFA_FM2JSContext*>(hFM2JSContext);
+  pContext->GlobalPropertyGetter(hValue);
+}
+void XFA_FM2JS_ContextRelease(XFA_HFM2JSCONTEXT hFM2JSContext) {
+  CXFA_FM2JSContext* pContext =
+      reinterpret_cast<CXFA_FM2JSContext*>(hFM2JSContext);
+  pContext->Release();
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/xfa/fxfa/fm2js/xfa_fm2jsapi.h b/xfa/fxfa/fm2js/xfa_fm2jsapi.h
new file mode 100644
index 0000000..246bc8f
--- /dev/null
+++ b/xfa/fxfa/fm2js/xfa_fm2jsapi.h
@@ -0,0 +1,37 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_FM2JS_XFA_FM2JSAPI_H_
+#define XFA_FXFA_FM2JS_XFA_FM2JSAPI_H_
+
+#include "core/include/fxcrt/fx_basic.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/include/fxjse/fxjse.h"
+
+#define FOXIT_XFA_FM2JS_FORMCALC_RUNTIME "foxit_xfa_formcalc_runtime"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct XFA_HFM2JSCONTEXT_ { void** pData; } * XFA_HFM2JSCONTEXT;
+int32_t XFA_FM2JS_Translate(const CFX_WideStringC& wsFormcalc,
+                            CFX_WideTextBuf& wsJavascript,
+                            CFX_WideString& wsError);
+XFA_HFM2JSCONTEXT XFA_FM2JS_ContextCreate();
+void XFA_FM2JS_ContextInitialize(XFA_HFM2JSCONTEXT hFM2JSContext,
+                                 FXJSE_HRUNTIME hScriptRuntime,
+                                 FXJSE_HCONTEXT hScriptContext,
+                                 CXFA_Document* pDocument);
+void XFA_FM2JS_GlobalPropertyGetter(XFA_HFM2JSCONTEXT hFM2JSContext,
+                                    FXJSE_HVALUE hValue);
+void XFA_FM2JS_ContextRelease(XFA_HFM2JSCONTEXT hFM2JSContext);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // XFA_FXFA_FM2JS_XFA_FM2JSAPI_H_
diff --git a/xfa/fxfa/fm2js/xfa_fm2jscontext.cpp b/xfa/fxfa/fm2js/xfa_fm2jscontext.cpp
new file mode 100644
index 0000000..9de6e1c
--- /dev/null
+++ b/xfa/fxfa/fm2js/xfa_fm2jscontext.cpp
@@ -0,0 +1,7223 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/fm2js/xfa_fm2jscontext.h"
+
+#include <time.h>
+
+#include "core/include/fxcrt/fx_ext.h"
+#include "xfa/fgas/localization/fgas_locale.h"
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_localevalue.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+
+#define FINANCIAL_PRECISION 0.00000001
+
+namespace {
+
+struct XFA_FMHtmlReserveCode {
+  uint32_t m_uCode;
+  const FX_WCHAR* m_htmlReserve;
+};
+struct XFA_FMHtmlHashedReserveCode {
+  uint32_t m_uHash;
+  const FX_WCHAR* m_htmlReserve;
+  uint32_t m_uCode;
+};
+
+const XFA_FMHtmlHashedReserveCode reservesForDecode[] = {
+    {0x00018b62, L"Mu", 924},       {0x00019083, L"Nu", 925},
+    {0x00019ab9, L"Pi", 928},       {0x0001c3c1, L"Xi", 926},
+    {0x000210ac, L"ge", 8805},      {0x000210bb, L"gt", 62},
+    {0x00022a51, L"le", 8804},      {0x00022a60, L"lt", 60},
+    {0x00022f82, L"mu", 956},       {0x00023493, L"ne", 8800},
+    {0x00023497, L"ni", 8715},      {0x000234a3, L"nu", 957},
+    {0x000239c1, L"or", 8744},      {0x00023ed9, L"pi", 960},
+    {0x000267e1, L"xi", 958},       {0x00c41789, L"lceil", 8968},
+    {0x00eef34f, L"thetasym", 977}, {0x012d7ead, L"lcirc", 206},
+    {0x01637b56, L"agrave", 224},   {0x020856da, L"crarr", 8629},
+    {0x022188c3, L"gamma", 947},    {0x033586d3, L"nbsp", 160},
+    {0x04f4c358, L"nsub", 8836},    {0x0581466a, L"dagger", 8224},
+    {0x06b1f790, L"oelig", 339},    {0x06e490d4, L"Chi", 935},
+    {0x0718c6a1, L"ETH", 208},      {0x07196ada, L"Eta", 919},
+    {0x07f667ca, L"Ugrave", 217},   {0x083a8a21, L"Phi", 934},
+    {0x083ac28c, L"Psi", 936},      {0x086f26a9, L"Rho", 929},
+    {0x089b5b51, L"aring", 229},    {0x08a39f4a, L"Tau", 932},
+    {0x08b6188b, L"THORN", 222},    {0x09ce792a, L"icirc", 238},
+    {0x09f9d61e, L"amp", 38},       {0x09f9db33, L"and", 8743},
+    {0x09f9db36, L"ang", 8736},     {0x0a2e3514, L"cap", 8745},
+    {0x0a2e58f4, L"chi", 967},      {0x0a2e9ba8, L"cup", 8746},
+    {0x0a4897d0, L"deg", 176},      {0x0a6332fa, L"eta", 951},
+    {0x0a633301, L"eth", 240},      {0x0acc4d4b, L"int", 8747},
+    {0x0b1b3d35, L"loz", 9674},     {0x0b1b4c8b, L"lrm", 8206},
+    {0x0b4fd9b1, L"not", 172},      {0x0b845241, L"phi", 966},
+    {0x0b84576f, L"piv", 982},      {0x0b848aac, L"psi", 968},
+    {0x0bb8df5e, L"reg", 174},      {0x0bb8eec9, L"rho", 961},
+    {0x0bb9034b, L"rlm", 8207},     {0x0bd33d14, L"shy", 173},
+    {0x0bd34229, L"sim", 8764},     {0x0bd37faa, L"sub", 8834},
+    {0x0bd37fb5, L"sum", 8721},     {0x0bd37fb8, L"sup", 8835},
+    {0x0bed676a, L"tau", 964},      {0x0c07f32e, L"uml", 168},
+    {0x0c71032c, L"yen", 165},      {0x0c7f2889, L"szlig", 223},
+    {0x0c8badbb, L"zwj", 8205},     {0x10ba4dba, L"Egrave", 200},
+    {0x10f1ea24, L"para", 182},     {0x10f1ea37, L"part", 8706},
+    {0x115b2337, L"perp", 8869},    {0x12b10d15, L"prod", 8719},
+    {0x12b10d21, L"prop", 8733},    {0x12dfa9f4, L"rfloor", 8971},
+    {0x12eb4736, L"Agrave", 192},   {0x12fff2b7, L"pund", 163},
+    {0x13fda9f2, L"tilde", 732},    {0x1417fd62, L"times", 215},
+    {0x154fc726, L"ecirc", 234},    {0x165aa451, L"sigma", 963},
+    {0x1709124a, L"Dagger", 8225},  {0x192f78d5, L"iexcl", 161},
+    {0x1b7ed8d7, L"rArr", 8658},    {0x1ec88c68, L"rang", 9002},
+    {0x1ec8a0f7, L"rarr", 8594},    {0x1eda07f3, L"atilde", 227},
+    {0x1f3182c4, L"real", 8476},    {0x1fc34f8b, L"yacute", 253},
+    {0x20d11522, L"acirc", 226},    {0x21933a9b, L"rsaquo", 8250},
+    {0x21f44907, L"uacute", 250},   {0x220cca72, L"acute", 180},
+    {0x242cded1, L"alefsym", 8501}, {0x2655c66a, L"delta", 948},
+    {0x269e4b4d, L"exist", 8707},   {0x273379fa, L"micro", 181},
+    {0x27a37440, L"forall", 8704},  {0x2854e62c, L"minus", 8722},
+    {0x28636f81, L"cedil", 184},    {0x2887357b, L"iacute", 237},
+    {0x2994d5ff, L"frac12", 189},   {0x2994d601, L"frac14", 188},
+    {0x2994e043, L"frac34", 190},   {0x2a1feb41, L"lambda", 955},
+    {0x2ab215f3, L"apos", 39},      {0x2ab82ef7, L"eacute", 233},
+    {0x2b3592ef, L"auml", 228},     {0x2ce92873, L"aacute", 225},
+    {0x2daff48a, L"oslash", 248},   {0x2ef68882, L"aelig", 230},
+    {0x3061d3d3, L"Atilde", 195},   {0x314b1b6b, L"Yacute", 221},
+    {0x337c14e7, L"Uacute", 218},   {0x37676aca, L"cent", 162},
+    {0x37d0b841, L"circ", 710},     {0x386e7947, L"cong", 8773},
+    {0x386e839b, L"copy", 169},     {0x3a0e225a, L"Epsilon", 917},
+    {0x3ba7b721, L"Lambda", 923},   {0x3bd9abe6, L"Alpha", 913},
+    {0x3c3ffad7, L"Eacute", 201},   {0x3cfaf69f, L"brvbar", 166},
+    {0x3d54a489, L"omega", 969},    {0x3e70f453, L"Aacute", 193},
+    {0x3f37c06a, L"Oslash", 216},   {0x40e1b34e, L"diams", 9830},
+    {0x416596df, L"plusmn", 177},   {0x4354ff16, L"Ucirc", 219},
+    {0x454fce6a, L"Upsilon", 933},  {0x4610ad35, L"emsp", 8195},
+    {0x462afb76, L"ensp", 8194},    {0x46e30073, L"euml", 235},
+    {0x46e31a1b, L"euro", 8364},    {0x46f2eada, L"lowast", 8727},
+    {0x4dca26cf, L"Auml", 196},     {0x4e2d6083, L"image", 8465},
+    {0x4f964ee8, L"notin", 8713},   {0x50917a7a, L"epsilon", 949},
+    {0x52f9a4cd, L"Kappa", 922},    {0x5496f410, L"Ocirc", 212},
+    {0x568cbf34, L"zeta", 950},     {0x57badd20, L"ntilde", 241},
+    {0x58662109, L"zwnj", 8204},    {0x5b39870f, L"empty", 8709},
+    {0x5bd3268a, L"upsilon", 965},  {0x5e2bf8a3, L"Gamma", 915},
+    {0x5f73c13a, L"rsquo", 8217},   {0x61f2bc4d, L"iota", 953},
+    {0x625bbcf3, L"isin", 8712},    {0x62906df7, L"iuml", 239},
+    {0x64a5cb31, L"Aring", 197},    {0x66f25c4a, L"sbquo", 8218},
+    {0x6851ab60, L"spades", 9824},  {0x6942a900, L"Ntilde", 209},
+    {0x69779453, L"Euml", 203},     {0x6cda6e23, L"current", 164},
+    {0x70b5b634, L"lsquo", 8216},   {0x715a3706, L"Ecirc", 202},
+    {0x71e8bf8d, L"tdquo", 8221},   {0x72651431, L"Sigma", 931},
+    {0x7569813b, L"iquest", 191},   {0x776a436a, L"equiv", 8801},
+    {0x79215314, L"Zeta", 918},     {0x79b81224, L"ograve", 242},
+    {0x7c2f8b23, L"macr", 175},     {0x7cdb8502, L"Acirc", 194},
+    {0x8185c62e, L"ndash", 8211},   {0x8260364a, L"Delta", 916},
+    {0x846619ad, L"mdash", 8212},   {0x8550fb50, L"OElig", 338},
+    {0x88eb5b85, L"ldquo", 8220},   {0x8b3fde04, L"Ograve", 210},
+    {0x8bc5794b, L"ordf", 170},     {0x8bc57952, L"ordm", 186},
+    {0x8c14923d, L"ouml", 246},     {0x8c5a7cd6, L"theta", 952},
+    {0x8d61812b, L"thorn", 254},    {0x912b95aa, L"asymp", 8776},
+    {0x947faf81, L"middot", 183},   {0x9629202e, L"lfloor", 8970},
+    {0x972e9ec1, L"otilde", 245},   {0x9748f231, L"otimes", 8855},
+    {0x995f1469, L"Omega", 937},    {0x99eb5349, L"quot", 34},
+    {0x9aeb639e, L"hellip", 8230},  {0xa0ae2f86, L"Scaron", 352},
+    {0xa4dcb0d5, L"lsaquo", 8249},  {0xa53dbf41, L"oacute", 243},
+    {0xa5ae9e7b, L"bdquo", 8222},   {0xa602d7ba, L"sdot", 8901},
+    {0xa61ce86f, L"sect", 167},     {0xa6e4c3d7, L"sigmaf", 962},
+    {0xa7c1c74f, L"sube", 8838},    {0xa7c20ee9, L"sup1", 185},
+    {0xa7c20eea, L"sup2", 178},     {0xa7c20eeb, L"sup3", 179},
+    {0xa7c20f1d, L"supe", 8839},    {0xa8b66aa1, L"Otilde", 213},
+    {0xad958c42, L"AElig", 198},    {0xaea9261d, L"Ouml", 214},
+    {0xb040eafa, L"uArr", 8657},    {0xb07c2e1c, L"beta", 946},
+    {0xb220e92f, L"bull", 8226},    {0xb22750c4, L"ccedil", 231},
+    {0xb38ab31a, L"uarr", 8593},    {0xb598b683, L"uuml", 252},
+    {0xb6c58b21, L"Oacute", 211},   {0xb6d2a617, L"oline", 8254},
+    {0xba9fd989, L"dArr", 8659},    {0xbb5ccd41, L"lgrave", 204},
+    {0xbd39b44c, L"weierp", 8472},  {0xbde9a1a9, L"darr", 8595},
+    {0xc027e329, L"permil", 8240},  {0xc2451389, L"upsih", 978},
+    {0xc3af1ca4, L"Ccedil", 199},   {0xcd164249, L"fnof", 402},
+    {0xcf6c8467, L"hearts", 9829},  {0xd1228390, L"trade", 8482},
+    {0xd1462407, L"yuml", 255},     {0xd2cf2253, L"oplus", 8853},
+    {0xd310c1fc, L"Beta", 914},     {0xd59c4d74, L"infin", 8734},
+    {0xd64d470d, L"hArr", 8660},    {0xd67d9c75, L"divide", 247},
+    {0xd698dd37, L"Omicron", 927},  {0xd82d4a63, L"Uuml", 220},
+    {0xd9970f2d, L"harr", 8596},    {0xda91fd99, L"clubs", 9827},
+    {0xdbe5bdcc, L"there4", 8756},  {0xdd7671bd, L"prime", 8242},
+    {0xdfcf3c06, L"alpha", 945},    {0xe0213063, L"saron", 353},
+    {0xe1911d83, L"radic", 8730},   {0xe2e75468, L"raquo", 187},
+    {0xe6e27a5e, L"lacute", 205},   {0xe74a8f36, L"ucirc", 251},
+    {0xe864ecb6, L"Theta", 920},    {0xecddde5e, L"nabla", 8711},
+    {0xed1c3557, L"omicron", 959},  {0xef82228f, L"rceil", 8969},
+    {0xf1fab491, L"lArr", 8656},    {0xf3dab7e7, L"Yuml", 376},
+    {0xf4294962, L"laquo", 171},    {0xf5446822, L"lang", 9001},
+    {0xf5447cb1, L"larr", 8592},    {0xf66e9bea, L"ugrave", 249},
+    {0xf6b4ce70, L"lota", 921},     {0xf6ef34ed, L"kappa", 954},
+    {0xf72a3a56, L"thinsp", 8201},  {0xf752801a, L"luml", 207},
+    {0xf88c8430, L"ocirc", 244},    {0xf9676178, L"frasl", 8260},
+    {0xfd01885e, L"igrave", 236},   {0xff3281da, L"egrave", 232},
+};
+
+const XFA_FMHtmlReserveCode reservesForEncode[] = {
+    {34, L"quot"},     {38, L"amp"},      {39, L"apos"},
+    {60, L"lt"},       {62, L"gt"},       {160, L"nbsp"},
+    {161, L"iexcl"},   {162, L"cent"},    {163, L"pund"},
+    {164, L"current"}, {165, L"yen"},     {166, L"brvbar"},
+    {167, L"sect"},    {168, L"uml"},     {169, L"copy"},
+    {170, L"ordf"},    {171, L"laquo"},   {172, L"not"},
+    {173, L"shy"},     {174, L"reg"},     {175, L"macr"},
+    {176, L"deg"},     {177, L"plusmn"},  {178, L"sup2"},
+    {179, L"sup3"},    {180, L"acute"},   {181, L"micro"},
+    {182, L"para"},    {183, L"middot"},  {184, L"cedil"},
+    {185, L"sup1"},    {186, L"ordm"},    {187, L"raquo"},
+    {188, L"frac14"},  {189, L"frac12"},  {190, L"frac34"},
+    {191, L"iquest"},  {192, L"Agrave"},  {193, L"Aacute"},
+    {194, L"Acirc"},   {195, L"Atilde"},  {196, L"Auml"},
+    {197, L"Aring"},   {198, L"AElig"},   {199, L"Ccedil"},
+    {200, L"Egrave"},  {201, L"Eacute"},  {202, L"Ecirc"},
+    {203, L"Euml"},    {204, L"lgrave"},  {205, L"lacute"},
+    {206, L"lcirc"},   {207, L"luml"},    {208, L"ETH"},
+    {209, L"Ntilde"},  {210, L"Ograve"},  {211, L"Oacute"},
+    {212, L"Ocirc"},   {213, L"Otilde"},  {214, L"Ouml"},
+    {215, L"times"},   {216, L"Oslash"},  {217, L"Ugrave"},
+    {218, L"Uacute"},  {219, L"Ucirc"},   {220, L"Uuml"},
+    {221, L"Yacute"},  {222, L"THORN"},   {223, L"szlig"},
+    {224, L"agrave"},  {225, L"aacute"},  {226, L"acirc"},
+    {227, L"atilde"},  {228, L"auml"},    {229, L"aring"},
+    {230, L"aelig"},   {231, L"ccedil"},  {232, L"egrave"},
+    {233, L"eacute"},  {234, L"ecirc"},   {235, L"euml"},
+    {236, L"igrave"},  {237, L"iacute"},  {238, L"icirc"},
+    {239, L"iuml"},    {240, L"eth"},     {241, L"ntilde"},
+    {242, L"ograve"},  {243, L"oacute"},  {244, L"ocirc"},
+    {245, L"otilde"},  {246, L"ouml"},    {247, L"divide"},
+    {248, L"oslash"},  {249, L"ugrave"},  {250, L"uacute"},
+    {251, L"ucirc"},   {252, L"uuml"},    {253, L"yacute"},
+    {254, L"thorn"},   {255, L"yuml"},    {338, L"OElig"},
+    {339, L"oelig"},   {352, L"Scaron"},  {353, L"saron"},
+    {376, L"Yuml"},    {402, L"fnof"},    {710, L"circ"},
+    {732, L"tilde"},   {913, L"Alpha"},   {914, L"Beta"},
+    {915, L"Gamma"},   {916, L"Delta"},   {917, L"Epsilon"},
+    {918, L"Zeta"},    {919, L"Eta"},     {920, L"Theta"},
+    {921, L"lota"},    {922, L"Kappa"},   {923, L"Lambda"},
+    {924, L"Mu"},      {925, L"Nu"},      {926, L"Xi"},
+    {927, L"Omicron"}, {928, L"Pi"},      {929, L"Rho"},
+    {931, L"Sigma"},   {932, L"Tau"},     {933, L"Upsilon"},
+    {934, L"Phi"},     {935, L"Chi"},     {936, L"Psi"},
+    {937, L"Omega"},   {945, L"alpha"},   {946, L"beta"},
+    {947, L"gamma"},   {948, L"delta"},   {949, L"epsilon"},
+    {950, L"zeta"},    {951, L"eta"},     {952, L"theta"},
+    {953, L"iota"},    {954, L"kappa"},   {955, L"lambda"},
+    {956, L"mu"},      {957, L"nu"},      {958, L"xi"},
+    {959, L"omicron"}, {960, L"pi"},      {961, L"rho"},
+    {962, L"sigmaf"},  {963, L"sigma"},   {964, L"tau"},
+    {965, L"upsilon"}, {966, L"phi"},     {967, L"chi"},
+    {968, L"psi"},     {969, L"omega"},   {977, L"thetasym"},
+    {978, L"upsih"},   {982, L"piv"},     {8194, L"ensp"},
+    {8195, L"emsp"},   {8201, L"thinsp"}, {8204, L"zwnj"},
+    {8205, L"zwj"},    {8206, L"lrm"},    {8207, L"rlm"},
+    {8211, L"ndash"},  {8212, L"mdash"},  {8216, L"lsquo"},
+    {8217, L"rsquo"},  {8218, L"sbquo"},  {8220, L"ldquo"},
+    {8221, L"tdquo"},  {8222, L"bdquo"},  {8224, L"dagger"},
+    {8225, L"Dagger"}, {8226, L"bull"},   {8230, L"hellip"},
+    {8240, L"permil"}, {8242, L"prime"},  {8249, L"lsaquo"},
+    {8250, L"rsaquo"}, {8254, L"oline"},  {8260, L"frasl"},
+    {8364, L"euro"},   {8465, L"image"},  {8472, L"weierp"},
+    {8476, L"real"},   {8482, L"trade"},  {8501, L"alefsym"},
+    {8592, L"larr"},   {8593, L"uarr"},   {8594, L"rarr"},
+    {8595, L"darr"},   {8596, L"harr"},   {8629, L"crarr"},
+    {8656, L"lArr"},   {8657, L"uArr"},   {8658, L"rArr"},
+    {8659, L"dArr"},   {8660, L"hArr"},   {8704, L"forall"},
+    {8706, L"part"},   {8707, L"exist"},  {8709, L"empty"},
+    {8711, L"nabla"},  {8712, L"isin"},   {8713, L"notin"},
+    {8715, L"ni"},     {8719, L"prod"},   {8721, L"sum"},
+    {8722, L"minus"},  {8727, L"lowast"}, {8730, L"radic"},
+    {8733, L"prop"},   {8734, L"infin"},  {8736, L"ang"},
+    {8743, L"and"},    {8744, L"or"},     {8745, L"cap"},
+    {8746, L"cup"},    {8747, L"int"},    {8756, L"there4"},
+    {8764, L"sim"},    {8773, L"cong"},   {8776, L"asymp"},
+    {8800, L"ne"},     {8801, L"equiv"},  {8804, L"le"},
+    {8805, L"ge"},     {8834, L"sub"},    {8835, L"sup"},
+    {8836, L"nsub"},   {8838, L"sube"},   {8839, L"supe"},
+    {8853, L"oplus"},  {8855, L"otimes"}, {8869, L"perp"},
+    {8901, L"sdot"},   {8968, L"lceil"},  {8969, L"rceil"},
+    {8970, L"lfloor"}, {8971, L"rfloor"}, {9001, L"lang"},
+    {9002, L"rang"},   {9674, L"loz"},    {9824, L"spades"},
+    {9827, L"clubs"},  {9829, L"hearts"}, {9830, L"diams"},
+};
+
+}  // namespace
+
+void CXFA_FM2JSContext::Abs(FXJSE_HOBJECT hThis,
+                            const CFX_ByteStringC& szFuncName,
+                            CFXJSE_Arguments& args) {
+  if (args.GetLength() == 1) {
+    FXJSE_HVALUE argOne = args.GetValue(0);
+    if (HValueIsNull(hThis, argOne)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      FX_DOUBLE dValue = HValueToDouble(hThis, argOne);
+      if (dValue < 0) {
+        dValue = -dValue;
+      }
+      FXJSE_Value_SetDouble(args.GetReturnValue(), dValue);
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Abs");
+  }
+}
+void CXFA_FM2JSContext::Avg(FXJSE_HOBJECT hThis,
+                            const CFX_ByteStringC& szFuncName,
+                            CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  int32_t argc = args.GetLength();
+  uint32_t uCount = 0;
+  FX_DOUBLE dSum = 0.0;
+  if (argc >= 1) {
+    FXJSE_HVALUE argValue = 0;
+    for (int32_t i = 0; i < argc; i++) {
+      argValue = args.GetValue(i);
+      if (FXJSE_Value_IsNull(argValue)) {
+        FXJSE_Value_Release(argValue);
+        continue;
+      } else if (FXJSE_Value_IsArray(argValue)) {
+        FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+        FXJSE_Value_GetObjectProp(argValue, "length", lengthValue);
+        int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
+        FXJSE_Value_Release(lengthValue);
+        if (iLength > 2) {
+          FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+          FXJSE_Value_GetObjectPropByIdx(argValue, 1, propertyValue);
+          FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+          if (FXJSE_Value_IsNull(propertyValue)) {
+            for (int32_t j = 2; j < iLength; j++) {
+              FXJSE_Value_GetObjectPropByIdx(argValue, j, jsObjectValue);
+              FXJSE_HVALUE defaultPropValue = FXJSE_Value_Create(hruntime);
+              GetObjectDefaultValue(jsObjectValue, defaultPropValue);
+              if (!FXJSE_Value_IsNull(defaultPropValue)) {
+                dSum += HValueToDouble(hThis, defaultPropValue);
+                uCount++;
+              }
+              FXJSE_Value_Release(defaultPropValue);
+            }
+          } else {
+            CFX_ByteString propertyStr;
+            FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+            FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+            for (int32_t j = 2; j < iLength; j++) {
+              FXJSE_Value_GetObjectPropByIdx(argValue, j, jsObjectValue);
+              FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
+                                        newPropertyValue);
+              if (!FXJSE_Value_IsNull(newPropertyValue)) {
+                dSum += HValueToDouble(hThis, newPropertyValue);
+                uCount++;
+              }
+            }
+            FXJSE_Value_Release(newPropertyValue);
+          }
+          FXJSE_Value_Release(jsObjectValue);
+          FXJSE_Value_Release(propertyValue);
+        }
+      } else {
+        dSum += HValueToDouble(hThis, argValue);
+        uCount++;
+      }
+      FXJSE_Value_Release(argValue);
+    }
+    argValue = 0;
+  }
+  if (0 == uCount) {
+    FXJSE_Value_SetNull(args.GetReturnValue());
+  } else {
+    FXJSE_Value_SetDouble(args.GetReturnValue(), dSum / uCount);
+  }
+}
+void CXFA_FM2JSContext::Ceil(FXJSE_HOBJECT hThis,
+                             const CFX_ByteStringC& szFuncName,
+                             CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 1) {
+    FXJSE_HVALUE argValue = GetSimpleHValue(hThis, args, 0);
+    if (HValueIsNull(hThis, argValue)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      FXJSE_Value_SetFloat(args.GetReturnValue(),
+                           FXSYS_ceil(HValueToFloat(hThis, argValue)));
+    }
+    FXJSE_Value_Release(argValue);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Ceil");
+  }
+}
+void CXFA_FM2JSContext::Count(FXJSE_HOBJECT hThis,
+                              const CFX_ByteStringC& szFuncName,
+                              CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  int32_t argc = args.GetLength();
+  uint32_t uCount = 0;
+  FXJSE_HVALUE argValue = 0;
+  for (int32_t i = 0; i < argc; i++) {
+    argValue = args.GetValue(i);
+    if (FXJSE_Value_IsNull(argValue)) {
+      FXJSE_Value_Release(argValue);
+      continue;
+    } else if (FXJSE_Value_IsArray(argValue)) {
+      FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectProp(argValue, "length", lengthValue);
+      int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
+      FXJSE_Value_Release(lengthValue);
+      if (iLength > 2) {
+        FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+        FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+        FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+        FXJSE_Value_GetObjectPropByIdx(argValue, 1, propertyValue);
+        FXJSE_Value_GetObjectPropByIdx(argValue, 2, jsObjectValue);
+        if (FXJSE_Value_IsNull(propertyValue)) {
+          for (int32_t i = 2; i < iLength; i++) {
+            FXJSE_Value_GetObjectPropByIdx(argValue, i, jsObjectValue);
+            GetObjectDefaultValue(jsObjectValue, newPropertyValue);
+            if (!FXJSE_Value_IsNull(newPropertyValue)) {
+              uCount++;
+            }
+          }
+        } else {
+          CFX_ByteString propertyStr;
+          FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+          for (int32_t i = 2; i < iLength; i++) {
+            FXJSE_Value_GetObjectPropByIdx(argValue, i, jsObjectValue);
+            FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
+                                      newPropertyValue);
+            uCount += (FXJSE_Value_IsNull(newPropertyValue) ? 0 : 1);
+          }
+        }
+        FXJSE_Value_Release(propertyValue);
+        FXJSE_Value_Release(jsObjectValue);
+        FXJSE_Value_Release(newPropertyValue);
+      } else {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+      }
+    } else if (FXJSE_Value_IsObject(argValue)) {
+      FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+      GetObjectDefaultValue(argValue, newPropertyValue);
+      if (!FXJSE_Value_IsNull(newPropertyValue)) {
+        uCount++;
+      }
+      FXJSE_Value_Release(newPropertyValue);
+    } else {
+      uCount++;
+    }
+    FXJSE_Value_Release(argValue);
+  }
+  argValue = 0;
+  FXJSE_Value_SetInteger(args.GetReturnValue(), (int32_t)uCount);
+}
+void CXFA_FM2JSContext::Floor(FXJSE_HOBJECT hThis,
+                              const CFX_ByteStringC& szFuncName,
+                              CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 1) {
+    FXJSE_HVALUE argValue = GetSimpleHValue(hThis, args, 0);
+    if (HValueIsNull(hThis, argValue)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      FXJSE_Value_SetFloat(args.GetReturnValue(),
+                           FXSYS_floor(HValueToFloat(hThis, argValue)));
+    }
+    FXJSE_Value_Release(argValue);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Floor");
+  }
+}
+void CXFA_FM2JSContext::Max(FXJSE_HOBJECT hThis,
+                            const CFX_ByteStringC& szFuncName,
+                            CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  int32_t argc = args.GetLength();
+  uint32_t uCount = 0;
+  FX_DOUBLE dMaxValue = 0.0;
+  FXJSE_HVALUE argValue = 0;
+  for (int32_t i = 0; i < argc; i++) {
+    argValue = args.GetValue(i);
+    if (FXJSE_Value_IsNull(argValue)) {
+      FXJSE_Value_Release(argValue);
+      continue;
+    } else if (FXJSE_Value_IsArray(argValue)) {
+      FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectProp(argValue, "length", lengthValue);
+      int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
+      FXJSE_Value_Release(lengthValue);
+      if (iLength > 2) {
+        FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+        FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+        FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+        FXJSE_Value_GetObjectPropByIdx(argValue, 1, propertyValue);
+        FXJSE_Value_GetObjectPropByIdx(argValue, 2, jsObjectValue);
+        if (FXJSE_Value_IsNull(propertyValue)) {
+          for (int32_t i = 2; i < iLength; i++) {
+            FXJSE_Value_GetObjectPropByIdx(argValue, i, jsObjectValue);
+            GetObjectDefaultValue(jsObjectValue, newPropertyValue);
+            if (!FXJSE_Value_IsNull(newPropertyValue)) {
+              uCount++;
+              if (uCount == 1) {
+                dMaxValue = HValueToDouble(hThis, newPropertyValue);
+              } else {
+                FX_DOUBLE dValue = HValueToDouble(hThis, newPropertyValue);
+                if (dMaxValue < dValue) {
+                  dMaxValue = dValue;
+                }
+              }
+            }
+          }
+        } else {
+          CFX_ByteString propertyStr;
+          FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+          for (int32_t i = 2; i < iLength; i++) {
+            FXJSE_Value_GetObjectPropByIdx(argValue, i, jsObjectValue);
+            FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
+                                      newPropertyValue);
+            if (!FXJSE_Value_IsNull(newPropertyValue)) {
+              uCount++;
+              if (uCount == 1) {
+                dMaxValue = HValueToDouble(hThis, newPropertyValue);
+              } else {
+                FX_DOUBLE dValue = HValueToDouble(hThis, newPropertyValue);
+                if (dMaxValue < dValue) {
+                  dMaxValue = dValue;
+                }
+              }
+            }
+          }
+        }
+        FXJSE_Value_Release(propertyValue);
+        FXJSE_Value_Release(jsObjectValue);
+        FXJSE_Value_Release(newPropertyValue);
+      } else {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+      }
+    } else if (FXJSE_Value_IsObject(argValue)) {
+      FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+      GetObjectDefaultValue(argValue, newPropertyValue);
+      if (!FXJSE_Value_IsNull(newPropertyValue)) {
+        uCount++;
+        if (uCount == 1) {
+          dMaxValue = HValueToDouble(hThis, newPropertyValue);
+        } else {
+          FX_DOUBLE dValue = HValueToDouble(hThis, newPropertyValue);
+          if (dMaxValue < dValue) {
+            dMaxValue = dValue;
+          }
+        }
+      }
+      FXJSE_Value_Release(newPropertyValue);
+    } else {
+      uCount++;
+      if (uCount == 1) {
+        dMaxValue = HValueToDouble(hThis, argValue);
+      } else {
+        FX_DOUBLE dValue = HValueToDouble(hThis, argValue);
+        if (dMaxValue < dValue) {
+          dMaxValue = dValue;
+        }
+      }
+    }
+    FXJSE_Value_Release(argValue);
+  }
+  argValue = 0;
+  if (uCount) {
+    FXJSE_Value_SetDouble(args.GetReturnValue(), dMaxValue);
+  } else {
+    FXJSE_Value_SetNull(args.GetReturnValue());
+  }
+}
+void CXFA_FM2JSContext::Min(FXJSE_HOBJECT hThis,
+                            const CFX_ByteStringC& szFuncName,
+                            CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  int32_t argc = args.GetLength();
+  uint32_t uCount = 0;
+  FX_DOUBLE dMinValue = 0.0;
+  FXJSE_HVALUE argValue = 0;
+  for (int32_t i = 0; i < argc; i++) {
+    argValue = args.GetValue(i);
+    if (FXJSE_Value_IsNull(argValue)) {
+      FXJSE_Value_Release(argValue);
+      continue;
+    } else if (FXJSE_Value_IsArray(argValue)) {
+      FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectProp(argValue, "length", lengthValue);
+      int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
+      FXJSE_Value_Release(lengthValue);
+      if (iLength > 2) {
+        FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+        FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+        FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+        FXJSE_Value_GetObjectPropByIdx(argValue, 1, propertyValue);
+        FXJSE_Value_GetObjectPropByIdx(argValue, 2, jsObjectValue);
+        if (FXJSE_Value_IsNull(propertyValue)) {
+          for (int32_t i = 2; i < iLength; i++) {
+            FXJSE_Value_GetObjectPropByIdx(argValue, i, jsObjectValue);
+            GetObjectDefaultValue(jsObjectValue, newPropertyValue);
+            if (!FXJSE_Value_IsNull(newPropertyValue)) {
+              uCount++;
+              if (uCount == 1) {
+                dMinValue = HValueToDouble(hThis, newPropertyValue);
+              } else {
+                FX_DOUBLE dValue = HValueToDouble(hThis, newPropertyValue);
+                if (dMinValue > dValue) {
+                  dMinValue = dValue;
+                }
+              }
+            }
+          }
+        } else {
+          CFX_ByteString propertyStr;
+          FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+          for (int32_t i = 2; i < iLength; i++) {
+            FXJSE_Value_GetObjectPropByIdx(argValue, i, jsObjectValue);
+            FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
+                                      newPropertyValue);
+            if (!FXJSE_Value_IsNull(newPropertyValue)) {
+              uCount++;
+              if (uCount == 1) {
+                dMinValue = HValueToDouble(hThis, newPropertyValue);
+              } else {
+                FX_DOUBLE dValue = HValueToDouble(hThis, newPropertyValue);
+                if (dMinValue > dValue) {
+                  dMinValue = dValue;
+                }
+              }
+            }
+          }
+        }
+        FXJSE_Value_Release(propertyValue);
+        FXJSE_Value_Release(jsObjectValue);
+        FXJSE_Value_Release(newPropertyValue);
+      } else {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+      }
+    } else if (FXJSE_Value_IsObject(argValue)) {
+      FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+      GetObjectDefaultValue(argValue, newPropertyValue);
+      if (!FXJSE_Value_IsNull(newPropertyValue)) {
+        uCount++;
+        if (uCount == 1) {
+          dMinValue = HValueToDouble(hThis, newPropertyValue);
+        } else {
+          FX_DOUBLE dValue = HValueToDouble(hThis, newPropertyValue);
+          if (dMinValue > dValue) {
+            dMinValue = dValue;
+          }
+        }
+      }
+      FXJSE_Value_Release(newPropertyValue);
+    } else {
+      uCount++;
+      if (uCount == 1) {
+        dMinValue = HValueToDouble(hThis, argValue);
+      } else {
+        FX_DOUBLE dValue = HValueToDouble(hThis, argValue);
+        if (dMinValue > dValue) {
+          dMinValue = dValue;
+        }
+      }
+    }
+    FXJSE_Value_Release(argValue);
+  }
+  argValue = 0;
+  if (uCount) {
+    FXJSE_Value_SetDouble(args.GetReturnValue(), dMinValue);
+  } else {
+    FXJSE_Value_SetNull(args.GetReturnValue());
+  }
+}
+void CXFA_FM2JSContext::Mod(FXJSE_HOBJECT hThis,
+                            const CFX_ByteStringC& szFuncName,
+                            CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  if (args.GetLength() == 2) {
+    FXJSE_HVALUE argOne = args.GetValue(0);
+    FXJSE_HVALUE argTwo = args.GetValue(1);
+    if (FXJSE_Value_IsNull(argOne) || FXJSE_Value_IsNull(argTwo)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      FX_DOUBLE dDividend = 0.0;
+      FX_DOUBLE dDividor = 0.0;
+      if (FXJSE_Value_IsArray(argOne)) {
+        FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+        FXJSE_Value_GetObjectProp(argOne, "length", lengthValue);
+        int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
+        FXJSE_Value_Release(lengthValue);
+        if (iLength > 2) {
+          FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+          FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+          FXJSE_Value_GetObjectPropByIdx(argOne, 1, propertyValue);
+          FXJSE_Value_GetObjectPropByIdx(argOne, 2, jsObjectValue);
+          if (FXJSE_Value_IsNull(propertyValue)) {
+            dDividend = HValueToDouble(hThis, jsObjectValue);
+          } else {
+            CFX_ByteString propertyStr;
+            FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+            FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+            FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
+                                      newPropertyValue);
+            dDividend = HValueToDouble(hThis, newPropertyValue);
+            FXJSE_Value_Release(newPropertyValue);
+          }
+          FXJSE_Value_Release(propertyValue);
+          FXJSE_Value_Release(jsObjectValue);
+        } else {
+          pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+        }
+      } else {
+        dDividend = HValueToDouble(hThis, argOne);
+      }
+      if (FXJSE_Value_IsArray(argTwo)) {
+        FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+        FXJSE_Value_GetObjectProp(argTwo, "length", lengthValue);
+        int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
+        FXJSE_Value_Release(lengthValue);
+        if (iLength > 2) {
+          FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+          FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+          FXJSE_Value_GetObjectPropByIdx(argTwo, 1, propertyValue);
+          FXJSE_Value_GetObjectPropByIdx(argTwo, 2, jsObjectValue);
+          if (FXJSE_Value_IsNull(propertyValue)) {
+            dDividor = HValueToDouble(hThis, jsObjectValue);
+          } else {
+            CFX_ByteString propertyStr;
+            FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+            FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+            FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
+                                      newPropertyValue);
+            dDividor = HValueToDouble(hThis, newPropertyValue);
+            FXJSE_Value_Release(newPropertyValue);
+          }
+          FXJSE_Value_Release(propertyValue);
+          FXJSE_Value_Release(jsObjectValue);
+        } else {
+          pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+        }
+      } else {
+        dDividor = HValueToDouble(hThis, argTwo);
+      }
+      if (dDividor) {
+        FXJSE_Value_SetDouble(
+            args.GetReturnValue(),
+            dDividend - dDividor * (int32_t)(dDividend / dDividor));
+      } else {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_DIVIDE_ZERO);
+      }
+    }
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Mod");
+  }
+}
+void CXFA_FM2JSContext::Round(FXJSE_HOBJECT hThis,
+                              const CFX_ByteStringC& szFuncName,
+                              CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  int32_t argc = args.GetLength();
+  uint8_t uPrecision = 0;
+  if (argc == 1) {
+    FXJSE_HVALUE argOne = args.GetValue(0);
+    if (FXJSE_Value_IsNull(argOne)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      FX_DOUBLE dValue = 0.0;
+      if (FXJSE_Value_IsArray(argOne)) {
+        FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+        FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+        FXJSE_Value_GetObjectPropByIdx(argOne, 1, propertyValue);
+        FXJSE_Value_GetObjectPropByIdx(argOne, 2, jsObjectValue);
+        if (FXJSE_Value_IsNull(propertyValue)) {
+          dValue = HValueToDouble(hThis, jsObjectValue);
+        } else {
+          CFX_ByteString propertyStr;
+          FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+          FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+          FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
+                                    newPropertyValue);
+          dValue = HValueToDouble(hThis, newPropertyValue);
+          FXJSE_Value_Release(newPropertyValue);
+        }
+        FXJSE_Value_Release(propertyValue);
+        FXJSE_Value_Release(jsObjectValue);
+      } else {
+        dValue = HValueToDouble(hThis, argOne);
+      }
+      CFX_Decimal decimalValue((FX_FLOAT)dValue, uPrecision);
+      CFX_WideString wsValue = decimalValue;
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(), wsValue.UTF8Encode());
+    }
+    FXJSE_Value_Release(argOne);
+  } else if (argc == 2) {
+    FXJSE_HVALUE argOne = args.GetValue(0);
+    FXJSE_HVALUE argTwo = args.GetValue(1);
+    if (FXJSE_Value_IsNull(argOne) || FXJSE_Value_IsNull(argTwo)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      FX_DOUBLE dValue = 0.0;
+      if (FXJSE_Value_IsArray(argOne)) {
+        FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+        FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+        FXJSE_Value_GetObjectPropByIdx(argOne, 1, propertyValue);
+        FXJSE_Value_GetObjectPropByIdx(argOne, 2, jsObjectValue);
+        if (FXJSE_Value_IsNull(propertyValue)) {
+          dValue = HValueToDouble(hThis, jsObjectValue);
+        } else {
+          CFX_ByteString propertyStr;
+          FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+          FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+          FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
+                                    newPropertyValue);
+          dValue = HValueToDouble(hThis, newPropertyValue);
+          FXJSE_Value_Release(newPropertyValue);
+        }
+        FXJSE_Value_Release(propertyValue);
+        FXJSE_Value_Release(jsObjectValue);
+      } else {
+        dValue = HValueToDouble(hThis, argOne);
+      }
+      FX_DOUBLE dPrecision = 0.0;
+      if (FXJSE_Value_IsArray(argTwo)) {
+        FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+        FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+        FXJSE_Value_GetObjectPropByIdx(argTwo, 1, propertyValue);
+        FXJSE_Value_GetObjectPropByIdx(argTwo, 2, jsObjectValue);
+        if (FXJSE_Value_IsNull(propertyValue)) {
+          dPrecision = HValueToDouble(hThis, jsObjectValue);
+        } else {
+          CFX_ByteString propertyStr;
+          FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+          FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+          FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
+                                    newPropertyValue);
+          dPrecision = HValueToDouble(hThis, newPropertyValue);
+          FXJSE_Value_Release(newPropertyValue);
+        }
+        FXJSE_Value_Release(propertyValue);
+        FXJSE_Value_Release(jsObjectValue);
+      } else {
+        dPrecision = HValueToDouble(hThis, argTwo);
+      }
+      if (dPrecision < 0) {
+        uPrecision = 0;
+      } else if (dPrecision > 12.0) {
+        uPrecision = 12;
+      } else {
+        uPrecision = (uint8_t)dPrecision;
+      }
+      CFX_Decimal decimalValue((FX_FLOAT)dValue, uPrecision);
+      CFX_WideString wsValue = decimalValue;
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(), wsValue.UTF8Encode());
+    }
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Round");
+  }
+}
+void CXFA_FM2JSContext::Sum(FXJSE_HOBJECT hThis,
+                            const CFX_ByteStringC& szFuncName,
+                            CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  int32_t argc = args.GetLength();
+  uint32_t uCount = 0;
+  FX_DOUBLE dSum = 0.0;
+  if (argc) {
+    FXJSE_HVALUE argValue = 0;
+    for (int32_t i = 0; i < argc; i++) {
+      argValue = args.GetValue(i);
+      if (FXJSE_Value_IsNull(argValue)) {
+        FXJSE_Value_Release(argValue);
+        continue;
+      } else if (FXJSE_Value_IsArray(argValue)) {
+        FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+        FXJSE_Value_GetObjectProp(argValue, "length", lengthValue);
+        int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
+        FXJSE_Value_Release(lengthValue);
+        if (iLength > 2) {
+          FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+          FXJSE_Value_GetObjectPropByIdx(argValue, 1, propertyValue);
+          FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+          FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+          if (FXJSE_Value_IsNull(propertyValue)) {
+            for (int32_t j = 2; j < iLength; j++) {
+              FXJSE_Value_GetObjectPropByIdx(argValue, j, jsObjectValue);
+              GetObjectDefaultValue(jsObjectValue, newPropertyValue);
+              if (!FXJSE_Value_IsNull(newPropertyValue)) {
+                dSum += HValueToDouble(hThis, jsObjectValue);
+                uCount++;
+              }
+            }
+          } else {
+            CFX_ByteString propertyStr;
+            FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+            for (int32_t j = 2; j < iLength; j++) {
+              FXJSE_Value_GetObjectPropByIdx(argValue, j, jsObjectValue);
+              FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr,
+                                        newPropertyValue);
+              if (!FXJSE_Value_IsNull(newPropertyValue)) {
+                dSum += HValueToDouble(hThis, newPropertyValue);
+                uCount++;
+              }
+            }
+          }
+          FXJSE_Value_Release(newPropertyValue);
+          FXJSE_Value_Release(jsObjectValue);
+          FXJSE_Value_Release(propertyValue);
+        } else {
+          pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+        }
+      } else if (FXJSE_Value_IsObject(argValue)) {
+        FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+        GetObjectDefaultValue(argValue, newPropertyValue);
+        if (!FXJSE_Value_IsNull(newPropertyValue)) {
+          dSum += HValueToDouble(hThis, argValue);
+          uCount++;
+        }
+        FXJSE_Value_Release(newPropertyValue);
+      } else {
+        dSum += HValueToDouble(hThis, argValue);
+        uCount++;
+      }
+      FXJSE_Value_Release(argValue);
+    }
+    argValue = 0;
+  }
+  if (uCount < 1) {
+    FXJSE_Value_SetNull(args.GetReturnValue());
+  } else {
+    FXJSE_Value_SetDouble(args.GetReturnValue(), dSum);
+  }
+}
+void CXFA_FM2JSContext::Date(FXJSE_HOBJECT hThis,
+                             const CFX_ByteStringC& szFuncName,
+                             CFXJSE_Arguments& args) {
+  if (args.GetLength() == 0) {
+    struct tm* pTmStruct = 0;
+    time_t currentTime;
+    time(&currentTime);
+    pTmStruct = gmtime(&currentTime);
+    CFX_ByteString bufferYear;
+    CFX_ByteString bufferMon;
+    CFX_ByteString bufferDay;
+    bufferYear.Format("%d", pTmStruct->tm_year + 1900);
+    bufferMon.Format("%02d", pTmStruct->tm_mon + 1);
+    bufferDay.Format("%02d", pTmStruct->tm_mday);
+    CFX_ByteString bufferCurrent = bufferYear + bufferMon + bufferDay;
+    int32_t dDays = DateString2Num(bufferCurrent);
+    FXJSE_Value_SetInteger(args.GetReturnValue(), dDays);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Date");
+  }
+}
+void CXFA_FM2JSContext::Date2Num(FXJSE_HOBJECT hThis,
+                                 const CFX_ByteStringC& szFuncName,
+                                 CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if ((argc > 0) && (argc < 4)) {
+    FX_BOOL bFlags = FALSE;
+    CFX_ByteString dateString;
+    CFX_ByteString formatString;
+    CFX_ByteString localString;
+    FXJSE_HVALUE dateValue = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE formatValue = 0;
+    FXJSE_HVALUE localValue = 0;
+    if (HValueIsNull(hThis, dateValue)) {
+      bFlags = TRUE;
+    } else {
+      HValueToUTF8String(dateValue, dateString);
+    }
+    if (argc > 1) {
+      formatValue = GetSimpleHValue(hThis, args, 1);
+      if (HValueIsNull(hThis, formatValue)) {
+        bFlags = TRUE;
+      } else {
+        HValueToUTF8String(formatValue, formatString);
+      }
+    }
+    if (argc == 3) {
+      localValue = GetSimpleHValue(hThis, args, 2);
+      if (HValueIsNull(hThis, localValue)) {
+        bFlags = TRUE;
+      } else {
+        HValueToUTF8String(localValue, localString);
+      }
+    }
+    if (!bFlags) {
+      CFX_ByteString szIsoDateString;
+      FX_BOOL bRet = Local2IsoDate(hThis, dateString, formatString, localString,
+                                   szIsoDateString);
+      if (bRet) {
+        FXJSE_Value_SetInteger(args.GetReturnValue(),
+                               DateString2Num(szIsoDateString));
+      } else {
+        FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
+      }
+    } else {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    }
+    FXJSE_Value_Release(dateValue);
+    if (argc > 1) {
+      FXJSE_Value_Release(formatValue);
+      if (argc == 3) {
+        FXJSE_Value_Release(localValue);
+      }
+    }
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Date2Num");
+  }
+}
+void CXFA_FM2JSContext::DateFmt(FXJSE_HOBJECT hThis,
+                                const CFX_ByteStringC& szFuncName,
+                                CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if (argc < 3) {
+    FX_BOOL bFlags = FALSE;
+    int32_t iStyle = 0;
+    CFX_ByteString szLocal;
+    FXJSE_HVALUE argStyle = 0;
+    FXJSE_HVALUE argLocal = 0;
+    if (argc > 0) {
+      argStyle = GetSimpleHValue(hThis, args, 0);
+      if (FXJSE_Value_IsNull(argStyle)) {
+        bFlags = TRUE;
+      }
+      iStyle = (int32_t)HValueToFloat(hThis, argStyle);
+      if (iStyle > 4 || iStyle < 0) {
+        iStyle = 0;
+      }
+    }
+    if (argc == 2) {
+      argLocal = GetSimpleHValue(hThis, args, 1);
+      if (FXJSE_Value_IsNull(argLocal)) {
+        bFlags = TRUE;
+      } else {
+        HValueToUTF8String(argLocal, szLocal);
+      }
+    }
+    if (!bFlags) {
+      CFX_ByteString formatStr;
+      GetStandardDateFormat(hThis, iStyle, szLocal, formatStr);
+      if (formatStr.IsEmpty()) {
+        formatStr = "";
+      }
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(), formatStr);
+    } else {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    }
+    if (argc > 0) {
+      FXJSE_Value_Release(argStyle);
+      if (argc == 2) {
+        FXJSE_Value_Release(argLocal);
+      }
+    }
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Date2Num");
+  }
+}
+void CXFA_FM2JSContext::IsoDate2Num(FXJSE_HOBJECT hThis,
+                                    const CFX_ByteStringC& szFuncName,
+                                    CFXJSE_Arguments& args) {
+  if (args.GetLength() == 1) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    if (FXJSE_Value_IsNull(argOne)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      CFX_ByteString szArgString;
+      HValueToUTF8String(argOne, szArgString);
+      int32_t dDays = DateString2Num(szArgString);
+      FXJSE_Value_SetInteger(args.GetReturnValue(), (int32_t)dDays);
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"IsoDate2Num");
+  }
+}
+void CXFA_FM2JSContext::IsoTime2Num(FXJSE_HOBJECT hThis,
+                                    const CFX_ByteStringC& szFuncName,
+                                    CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 1) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    if (HValueIsNull(hThis, argOne)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      CXFA_Document* pDoc = pContext->GetDocument();
+      FXSYS_assert(pDoc);
+      IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
+      CFX_ByteString szArgString;
+      HValueToUTF8String(argOne, szArgString);
+      szArgString = szArgString.Mid(szArgString.Find('T', 0) + 1);
+      if (szArgString.IsEmpty()) {
+        FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
+        FXJSE_Value_Release(argOne);
+        return;
+      }
+      CXFA_LocaleValue timeValue(
+          XFA_VT_TIME,
+          CFX_WideString::FromUTF8(szArgString, szArgString.GetLength()),
+          (CXFA_LocaleMgr*)pMgr);
+      if (timeValue.IsValid()) {
+        CFX_Unitime uniTime = timeValue.GetTime();
+        int32_t hour = uniTime.GetHour();
+        int32_t min = uniTime.GetMinute();
+        int32_t second = uniTime.GetSecond();
+        int32_t milSecond = uniTime.GetMillisecond();
+        IFX_Locale* pDefLocale = pMgr->GetDefLocale();
+        FXSYS_assert(pDefLocale);
+        FX_TIMEZONE tzLocale;
+        pDefLocale->GetTimeZone(tzLocale);
+        int32_t mins = hour * 60 + min;
+        mins -= (tzLocale.tzHour * 60);
+        while (mins > 1440) {
+          mins -= 1440;
+        }
+        while (mins < 0) {
+          mins += 1440;
+        }
+        hour = mins / 60;
+        min = mins % 60;
+        int32_t iResult =
+            hour * 3600000 + min * 60000 + second * 1000 + milSecond + 1;
+        FXJSE_Value_SetInteger(args.GetReturnValue(), iResult);
+      } else {
+        FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
+      }
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"IsoTime2Num");
+  }
+}
+void CXFA_FM2JSContext::LocalDateFmt(FXJSE_HOBJECT hThis,
+                                     const CFX_ByteStringC& szFuncName,
+                                     CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if (argc < 3) {
+    FX_BOOL bFlags = FALSE;
+    int32_t iStyle = 0;
+    CFX_ByteString szLocal;
+    FXJSE_HVALUE argStyle = 0;
+    FXJSE_HVALUE argLocal = 0;
+    if (argc > 0) {
+      argStyle = GetSimpleHValue(hThis, args, 0);
+      if (FXJSE_Value_IsNull(argStyle)) {
+        bFlags = TRUE;
+      }
+      iStyle = (int32_t)HValueToFloat(hThis, argStyle);
+      if (iStyle > 4 || iStyle < 0) {
+        iStyle = 0;
+      }
+    }
+    if (argc == 2) {
+      argLocal = GetSimpleHValue(hThis, args, 1);
+      if (FXJSE_Value_IsNull(argLocal)) {
+        bFlags = TRUE;
+      } else {
+        HValueToUTF8String(argLocal, szLocal);
+      }
+    }
+    if (!bFlags) {
+      CFX_ByteString formatStr;
+      GetLocalDateFormat(hThis, iStyle, szLocal, formatStr, FALSE);
+      if (formatStr.IsEmpty()) {
+        formatStr = "";
+      }
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(), formatStr);
+    } else {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    }
+    if (argc > 0) {
+      FXJSE_Value_Release(argStyle);
+      if (argc == 2) {
+        FXJSE_Value_Release(argLocal);
+      }
+    }
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"LocalDateFmt");
+  }
+}
+void CXFA_FM2JSContext::LocalTimeFmt(FXJSE_HOBJECT hThis,
+                                     const CFX_ByteStringC& szFuncName,
+                                     CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if (argc < 3) {
+    FX_BOOL bFlags = FALSE;
+    int32_t iStyle = 0;
+    CFX_ByteString szLocal;
+    FXJSE_HVALUE argStyle = 0;
+    FXJSE_HVALUE argLocal = 0;
+    if (argc > 0) {
+      argStyle = GetSimpleHValue(hThis, args, 0);
+      if (FXJSE_Value_IsNull(argStyle)) {
+        bFlags = TRUE;
+      }
+      iStyle = (int32_t)HValueToFloat(hThis, argStyle);
+      if (iStyle > 4 || iStyle < 0) {
+        iStyle = 0;
+      }
+    }
+    if (argc == 2) {
+      argLocal = GetSimpleHValue(hThis, args, 1);
+      if (FXJSE_Value_IsNull(argLocal)) {
+        bFlags = TRUE;
+      } else {
+        HValueToUTF8String(argLocal, szLocal);
+      }
+    }
+    if (!bFlags) {
+      CFX_ByteString formatStr;
+      GetLocalTimeFormat(hThis, iStyle, szLocal, formatStr, FALSE);
+      if (formatStr.IsEmpty()) {
+        formatStr = "";
+      }
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(), formatStr);
+    } else {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    }
+    if (argc > 0) {
+      FXJSE_Value_Release(argStyle);
+      if (argc == 2) {
+        FXJSE_Value_Release(argLocal);
+      }
+    }
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"LocalTimeFmt");
+  }
+}
+void CXFA_FM2JSContext::Num2Date(FXJSE_HOBJECT hThis,
+                                 const CFX_ByteStringC& szFuncName,
+                                 CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if ((argc > 0) && (argc < 4)) {
+    FX_BOOL bFlags = FALSE;
+    int32_t dDate;
+    CFX_ByteString formatString;
+    CFX_ByteString localString;
+    FXJSE_HVALUE dateValue = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE formatValue = 0;
+    FXJSE_HVALUE localValue = 0;
+    if (HValueIsNull(hThis, dateValue)) {
+      bFlags = TRUE;
+    } else {
+      dDate = (int32_t)HValueToFloat(hThis, dateValue);
+      bFlags = dDate < 1;
+    }
+    if (argc > 1) {
+      formatValue = GetSimpleHValue(hThis, args, 1);
+      if (HValueIsNull(hThis, formatValue)) {
+        bFlags = TRUE;
+      } else {
+        HValueToUTF8String(formatValue, formatString);
+      }
+    }
+    if (argc == 3) {
+      localValue = GetSimpleHValue(hThis, args, 2);
+      if (HValueIsNull(hThis, localValue)) {
+        bFlags = TRUE;
+      } else {
+        HValueToUTF8String(localValue, localString);
+      }
+    }
+    if (!bFlags) {
+      int32_t iYear = 1900;
+      int32_t iMonth = 1;
+      int32_t iDay = 1;
+      int32_t i = 0;
+      while (dDate > 0) {
+        if (iMonth == 2) {
+          if ((!((iYear + i) % 4) && ((iYear + i) % 100)) ||
+              !((iYear + i) % 400)) {
+            if (dDate > 29) {
+              ++iMonth;
+              if (iMonth > 12) {
+                iMonth = 1;
+                ++i;
+              }
+              iDay = 1;
+              dDate -= 29;
+            } else {
+              iDay += static_cast<int32_t>(dDate) - 1;
+              dDate = 0;
+            }
+          } else {
+            if (dDate > 28) {
+              ++iMonth;
+              if (iMonth > 12) {
+                iMonth = 1;
+                ++i;
+              }
+              iDay = 1;
+              dDate -= 28;
+            } else {
+              iDay += static_cast<int32_t>(dDate) - 1;
+              dDate = 0;
+            }
+          }
+        } else if (iMonth < 8) {
+          if ((iMonth % 2 == 0)) {
+            if (dDate > 30) {
+              ++iMonth;
+              if (iMonth > 12) {
+                iMonth = 1;
+                ++i;
+              }
+              iDay = 1;
+              dDate -= 30;
+            } else {
+              iDay += static_cast<int32_t>(dDate) - 1;
+              dDate = 0;
+            }
+          } else {
+            if (dDate > 31) {
+              ++iMonth;
+              if (iMonth > 12) {
+                iMonth = 1;
+                ++i;
+              }
+              iDay = 1;
+              dDate -= 31;
+            } else {
+              iDay += static_cast<int32_t>(dDate) - 1;
+              dDate = 0;
+            }
+          }
+        } else {
+          if (iMonth % 2 != 0) {
+            if (dDate > 30) {
+              ++iMonth;
+              if (iMonth > 12) {
+                iMonth = 1;
+                ++i;
+              }
+              iDay = 1;
+              dDate -= 30;
+            } else {
+              iDay += static_cast<int32_t>(dDate) - 1;
+              dDate = 0;
+            }
+          } else {
+            if (dDate > 31) {
+              ++iMonth;
+              if (iMonth > 12) {
+                iMonth = 1;
+                ++i;
+              }
+              iDay = 1;
+              dDate -= 31;
+            } else {
+              iDay += static_cast<int32_t>(dDate) - 1;
+              dDate = 0;
+            }
+          }
+        }
+      }
+      CFX_ByteString szIsoDateString;
+      szIsoDateString.Format("%d%02d%02d", iYear + i, iMonth, iDay);
+      CFX_ByteString szLocalDateString;
+      IsoDate2Local(hThis, szIsoDateString, formatString, localString,
+                    szLocalDateString);
+      if (szLocalDateString.IsEmpty()) {
+        szLocalDateString = "";
+      }
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(), szLocalDateString);
+    } else {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    }
+    FXJSE_Value_Release(dateValue);
+    if (argc > 1) {
+      FXJSE_Value_Release(formatValue);
+      if (argc == 3) {
+        FXJSE_Value_Release(localValue);
+      }
+    }
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Num2Date");
+  }
+}
+void CXFA_FM2JSContext::Num2GMTime(FXJSE_HOBJECT hThis,
+                                   const CFX_ByteStringC& szFuncName,
+                                   CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if ((argc > 0) && (argc < 4)) {
+    FX_BOOL bFlags = FALSE;
+    int32_t iTime;
+    CFX_ByteString formatString;
+    CFX_ByteString localString;
+    FXJSE_HVALUE timeValue = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE formatValue = 0;
+    FXJSE_HVALUE localValue = 0;
+    if (FXJSE_Value_IsNull(timeValue)) {
+      bFlags = TRUE;
+    } else {
+      iTime = (int32_t)HValueToFloat(hThis, timeValue);
+      if (FXSYS_abs(iTime) < 1.0) {
+        bFlags = TRUE;
+      }
+    }
+    if (argc > 1) {
+      formatValue = GetSimpleHValue(hThis, args, 1);
+      if (FXJSE_Value_IsNull(formatValue)) {
+        bFlags = TRUE;
+      } else {
+        HValueToUTF8String(formatValue, formatString);
+      }
+    }
+    if (argc == 3) {
+      localValue = GetSimpleHValue(hThis, args, 2);
+      if (FXJSE_Value_IsNull(localValue)) {
+        bFlags = TRUE;
+      } else {
+        HValueToUTF8String(localValue, localString);
+      }
+    }
+    if (!bFlags) {
+      CFX_ByteString szGMTTimeString;
+      Num2AllTime(hThis, iTime, formatString, localString, TRUE,
+                  szGMTTimeString);
+      if (szGMTTimeString.IsEmpty()) {
+        szGMTTimeString = "";
+      }
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(), szGMTTimeString);
+    } else {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    }
+    FXJSE_Value_Release(timeValue);
+    if (argc > 1) {
+      FXJSE_Value_Release(formatValue);
+      if (argc == 3) {
+        FXJSE_Value_Release(localValue);
+      }
+    }
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Num2GMTime");
+  }
+}
+void CXFA_FM2JSContext::Num2Time(FXJSE_HOBJECT hThis,
+                                 const CFX_ByteStringC& szFuncName,
+                                 CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if ((argc > 0) && (argc < 4)) {
+    FX_BOOL bFlags = FALSE;
+    FX_FLOAT fTime;
+    CFX_ByteString formatString;
+    CFX_ByteString localString;
+    FXJSE_HVALUE timeValue = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE formatValue = 0;
+    FXJSE_HVALUE localValue = 0;
+    if (FXJSE_Value_IsNull(timeValue)) {
+      bFlags = TRUE;
+    } else {
+      fTime = HValueToFloat(hThis, timeValue);
+      if (FXSYS_fabs(fTime) < 1.0) {
+        bFlags = TRUE;
+      }
+    }
+    if (argc > 1) {
+      formatValue = GetSimpleHValue(hThis, args, 1);
+      if (FXJSE_Value_IsNull(formatValue)) {
+        bFlags = TRUE;
+      } else {
+        HValueToUTF8String(formatValue, formatString);
+      }
+    }
+    if (argc == 3) {
+      localValue = GetSimpleHValue(hThis, args, 2);
+      if (FXJSE_Value_IsNull(localValue)) {
+        bFlags = TRUE;
+      } else {
+        HValueToUTF8String(localValue, localString);
+      }
+    }
+    if (!bFlags) {
+      CFX_ByteString szLocalTimeString;
+      Num2AllTime(hThis, (int32_t)fTime, formatString, localString, FALSE,
+                  szLocalTimeString);
+      if (szLocalTimeString.IsEmpty()) {
+        szLocalTimeString = "";
+      }
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(), szLocalTimeString);
+    } else {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    }
+    FXJSE_Value_Release(timeValue);
+    if (argc > 1) {
+      FXJSE_Value_Release(formatValue);
+      if (argc == 3) {
+        FXJSE_Value_Release(localValue);
+      }
+    }
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Num2Time");
+  }
+}
+void CXFA_FM2JSContext::Time(FXJSE_HOBJECT hThis,
+                             const CFX_ByteStringC& szFuncName,
+                             CFXJSE_Arguments& args) {
+  if (args.GetLength() == 0) {
+    time_t now;
+    time(&now);
+    struct tm* pGmt = gmtime(&now);
+    int32_t iGMHour = pGmt->tm_hour;
+    int32_t iGMMin = pGmt->tm_min;
+    int32_t iGMSec = pGmt->tm_sec;
+    FXJSE_Value_SetInteger(args.GetReturnValue(),
+                           ((iGMHour * 3600 + iGMMin * 60 + iGMSec) * 1000));
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Time");
+  }
+}
+void CXFA_FM2JSContext::Time2Num(FXJSE_HOBJECT hThis,
+                                 const CFX_ByteStringC& szFuncName,
+                                 CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if ((argc > 0) && (argc < 4)) {
+    FX_BOOL bFlags = FALSE;
+    CFX_ByteString timeString;
+    CFX_ByteString formatString;
+    CFX_ByteString localString;
+    FXJSE_HVALUE timeValue = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE formatValue = 0;
+    FXJSE_HVALUE localValue = 0;
+    if (HValueIsNull(hThis, timeValue)) {
+      bFlags = TRUE;
+    } else {
+      HValueToUTF8String(timeValue, timeString);
+    }
+    if (argc > 1) {
+      formatValue = GetSimpleHValue(hThis, args, 1);
+      if (HValueIsNull(hThis, formatValue)) {
+        bFlags = TRUE;
+      } else {
+        HValueToUTF8String(formatValue, formatString);
+      }
+    }
+    if (argc == 3) {
+      localValue = GetSimpleHValue(hThis, args, 2);
+      if (HValueIsNull(hThis, localValue)) {
+        bFlags = TRUE;
+      } else {
+        HValueToUTF8String(localValue, localString);
+      }
+    }
+    if (!bFlags) {
+      CXFA_FM2JSContext* pContext =
+          (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+      CXFA_Document* pDoc = pContext->GetDocument();
+      IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
+      IFX_Locale* pLocale = NULL;
+      if (localString.IsEmpty()) {
+        CXFA_Node* pThisNode =
+            ToNode(pDoc->GetScriptContext()->GetThisObject());
+        FXSYS_assert(pThisNode);
+        CXFA_WidgetData widgetData(pThisNode);
+        pLocale = widgetData.GetLocal();
+      } else {
+        pLocale = pMgr->GetLocaleByName(
+            CFX_WideString::FromUTF8(localString, localString.GetLength()));
+      }
+      CFX_WideString wsFormat;
+      if (formatString.IsEmpty()) {
+        pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
+      } else {
+        wsFormat =
+            CFX_WideString::FromUTF8(formatString, formatString.GetLength());
+      }
+      wsFormat = FX_WSTRC(L"time{") + wsFormat;
+      wsFormat += FX_WSTRC(L"}");
+      CXFA_LocaleValue timeValue(
+          XFA_VT_TIME,
+          CFX_WideString::FromUTF8(timeString, timeString.GetLength()),
+          wsFormat, pLocale, (CXFA_LocaleMgr*)pMgr);
+      if (timeValue.IsValid()) {
+        CFX_Unitime uniTime = timeValue.GetTime();
+        int32_t hour = uniTime.GetHour();
+        int32_t min = uniTime.GetMinute();
+        int32_t second = uniTime.GetSecond();
+        int32_t milSecond = uniTime.GetMillisecond();
+        int32_t mins = hour * 60 + min;
+        IXFA_TimeZoneProvider* pProvider = IXFA_TimeZoneProvider::Get();
+        if (pProvider) {
+          FX_TIMEZONE tz;
+          pProvider->GetTimeZone(tz);
+          mins -= (tz.tzHour * 60);
+          while (mins > 1440) {
+            mins -= 1440;
+          }
+          while (mins < 0) {
+            mins += 1440;
+          }
+          hour = mins / 60;
+          min = mins % 60;
+        }
+        int32_t iResult =
+            hour * 3600000 + min * 60000 + second * 1000 + milSecond + 1;
+        FXJSE_Value_SetInteger(args.GetReturnValue(), iResult);
+      } else {
+        FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
+      }
+    } else {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    }
+    FXJSE_Value_Release(timeValue);
+    if (argc > 1) {
+      FXJSE_Value_Release(formatValue);
+      if (argc == 3) {
+        FXJSE_Value_Release(localValue);
+      }
+    }
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Time2Num");
+  }
+}
+void CXFA_FM2JSContext::TimeFmt(FXJSE_HOBJECT hThis,
+                                const CFX_ByteStringC& szFuncName,
+                                CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if (argc < 3) {
+    FX_BOOL bFlags = FALSE;
+    int32_t iStyle = 0;
+    CFX_ByteString szLocal;
+    FXJSE_HVALUE argStyle = 0;
+    FXJSE_HVALUE argLocal = 0;
+    if (argc > 0) {
+      argStyle = GetSimpleHValue(hThis, args, 0);
+      if (FXJSE_Value_IsNull(argStyle)) {
+        bFlags = TRUE;
+      }
+      iStyle = (int32_t)HValueToFloat(hThis, argStyle);
+      if (iStyle > 4 || iStyle < 0) {
+        iStyle = 0;
+      }
+    }
+    if (argc == 2) {
+      argLocal = GetSimpleHValue(hThis, args, 1);
+      if (FXJSE_Value_IsNull(argLocal)) {
+        bFlags = TRUE;
+      } else {
+        HValueToUTF8String(argLocal, szLocal);
+      }
+    }
+    if (!bFlags) {
+      CFX_ByteString formatStr;
+      GetStandardTimeFormat(hThis, iStyle, szLocal, formatStr);
+      if (formatStr.IsEmpty()) {
+        formatStr = "";
+      }
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(), formatStr);
+    } else {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    }
+    if (argc > 0) {
+      FXJSE_Value_Release(argStyle);
+      if (argc == 2) {
+        FXJSE_Value_Release(argLocal);
+      }
+    }
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"TimeFmt");
+  }
+}
+FX_BOOL CXFA_FM2JSContext::IsIsoDateFormat(const FX_CHAR* pData,
+                                           int32_t iLength,
+                                           int32_t& iStyle,
+                                           int32_t& iYear,
+                                           int32_t& iMonth,
+                                           int32_t& iDay) {
+  iYear = 0;
+  iMonth = 1;
+  iDay = 1;
+  FX_BOOL iRet = FALSE;
+  if (iLength < 4) {
+    return iRet;
+  }
+  FX_CHAR strYear[5];
+  strYear[4] = '\0';
+  for (int32_t i = 0; i < 4; ++i) {
+    if (*(pData + i) <= '9' && *(pData + i) >= '0') {
+      strYear[i] = *(pData + i);
+    } else {
+      return iRet;
+    }
+  }
+  iYear = FXSYS_atoi(strYear);
+  iStyle = 0;
+  if (iLength > 4) {
+    if (*(pData + 4) == '-') {
+      iStyle = 1;
+    } else {
+      iStyle = 0;
+    }
+  } else {
+    iRet = TRUE;
+    return iRet;
+  }
+  FX_CHAR strTemp[3];
+  strTemp[2] = '\0';
+  int32_t iPosOff = 0;
+  if (iStyle == 0) {
+    iPosOff = 4;
+    if (iLength == 4) {
+      iRet = TRUE;
+      return iRet;
+    }
+  } else {
+    iPosOff = 5;
+    if (iLength == 4) {
+      iRet = TRUE;
+      return iRet;
+    }
+  }
+  if ((*(pData + iPosOff) > '9' || *(pData + iPosOff) < '0') ||
+      (*(pData + iPosOff + 1) > '9' || *(pData + iPosOff + 1) < '0')) {
+    return iRet;
+  }
+  strTemp[0] = *(pData + iPosOff);
+  strTemp[1] = *(pData + iPosOff + 1);
+  iMonth = FXSYS_atoi(strTemp);
+  if (iMonth > 12 || iMonth < 1) {
+    return iRet;
+  }
+  if (iStyle == 0) {
+    iPosOff += 2;
+    if (iLength == 6) {
+      iRet = 1;
+      return iRet;
+    }
+  } else {
+    iPosOff += 3;
+    if (iLength == 7) {
+      iRet = 1;
+      return iRet;
+    }
+  }
+  if ((*(pData + iPosOff) > '9' || *(pData + iPosOff) < '0') ||
+      (*(pData + iPosOff + 1) > '9' || *(pData + iPosOff + 1) < '0')) {
+    return iRet;
+  }
+  strTemp[0] = *(pData + iPosOff);
+  strTemp[1] = *(pData + iPosOff + 1);
+  iDay = FXSYS_atoi(strTemp);
+  if (iPosOff + 2 < iLength) {
+    return iRet;
+  }
+  if ((!(iYear % 4) && (iYear % 100)) || !(iYear % 400)) {
+    if (iMonth == 2) {
+      if (iDay > 29) {
+        return iRet;
+      }
+    } else {
+      if (iMonth < 8) {
+        if (iDay > (iMonth % 2 == 0 ? 30 : 31)) {
+          return iRet;
+        }
+      } else {
+        if (iDay > (iMonth % 2 == 0 ? 31 : 30)) {
+          return iRet;
+        }
+      }
+    }
+  } else {
+    if (iMonth == 2) {
+      if (iDay > 28) {
+        return iRet;
+      }
+    } else {
+      if (iMonth < 8) {
+        if (iDay > (iMonth % 2 == 0 ? 30 : 31)) {
+          return iRet;
+        }
+      } else {
+        if (iDay > (iMonth % 2 == 0 ? 31 : 30)) {
+          return iRet;
+        }
+      }
+    }
+  }
+  iRet = TRUE;
+  return iRet;
+}
+FX_BOOL CXFA_FM2JSContext::IsIsoTimeFormat(const FX_CHAR* pData,
+                                           int32_t iLength,
+                                           int32_t& iHour,
+                                           int32_t& iMinute,
+                                           int32_t& iSecond,
+                                           int32_t& iMilliSecond,
+                                           int32_t& iZoneHour,
+                                           int32_t& iZoneMinute) {
+  iHour = 0;
+  iMinute = 0;
+  iSecond = 0;
+  iMilliSecond = 0;
+  iZoneHour = 0;
+  iZoneMinute = 0;
+  if (!pData) {
+    return FALSE;
+  }
+  int32_t iRet = FALSE;
+  FX_CHAR strTemp[3];
+  strTemp[2] = '\0';
+  int32_t iIndex = 0;
+  int32_t iZone = 0;
+  int32_t i = iIndex;
+  while (i < iLength) {
+    if ((*(pData + i) > '9' || *(pData + i) < '0') && *(pData + i) != ':') {
+      iZone = i;
+      break;
+    }
+    ++i;
+  }
+  if (i == iLength) {
+    iZone = iLength;
+  }
+  int32_t iPos = 0;
+  while (iIndex < iZone) {
+    if (iIndex >= iZone) {
+      break;
+    }
+    if (*(pData + iIndex) > '9' || *(pData + iIndex) < '0') {
+      return iRet;
+    }
+    strTemp[0] = *(pData + iIndex);
+    if (*(pData + iIndex + 1) > '9' || *(pData + iIndex + 1) < '0') {
+      return iRet;
+    }
+    strTemp[1] = *(pData + iIndex + 1);
+    if (FXSYS_atoi(strTemp) > 60) {
+      return iRet;
+    }
+    if (*(pData + 2) == ':') {
+      if (iPos == 0) {
+        iHour = FXSYS_atoi(strTemp);
+        ++iPos;
+      } else if (iPos == 1) {
+        iMinute = FXSYS_atoi(strTemp);
+        ++iPos;
+      } else {
+        iSecond = FXSYS_atoi(strTemp);
+      }
+      iIndex += 3;
+    } else {
+      if (iPos == 0) {
+        iHour = FXSYS_atoi(strTemp);
+        ++iPos;
+      } else if (iPos == 1) {
+        iMinute = FXSYS_atoi(strTemp);
+        ++iPos;
+      } else if (iPos == 2) {
+        iSecond = FXSYS_atoi(strTemp);
+        ++iPos;
+      }
+      iIndex += 2;
+    }
+  }
+  if (*(pData + iIndex) == '.') {
+    ++iIndex;
+    FX_CHAR strTemp[4];
+    strTemp[3] = '\0';
+    if (*(pData + iIndex) > '9' || *(pData + iIndex) < '0') {
+      return iRet;
+    }
+    strTemp[0] = *(pData + iIndex);
+    if (*(pData + iIndex + 1) > '9' || *(pData + iIndex + 1) < '0') {
+      return iRet;
+    }
+    strTemp[1] = *(pData + iIndex + 1);
+    if (*(pData + iIndex + 2) > '9' || *(pData + iIndex + 2) < '0') {
+      return iRet;
+    }
+    strTemp[2] = *(pData + iIndex + 2);
+    iMilliSecond = FXSYS_atoi(strTemp);
+    if (iMilliSecond > 100) {
+      iMilliSecond = 0;
+      return iRet;
+    }
+    iIndex += 3;
+  }
+  int32_t iSign = 1;
+  if (*(pData + iIndex) == 'z' || *(pData + iIndex) == 'Z') {
+    iRet = 1;
+    return iRet;
+  } else if (*(pData + iIndex) == '+') {
+    ++iIndex;
+  } else if (*(pData + iIndex) == '-') {
+    iSign = -1;
+    ++iIndex;
+  }
+  iPos = 0;
+  while (iIndex < iLength) {
+    if (iIndex >= iLength) {
+      return iRet;
+    }
+    if (*(pData + iIndex) > '9' || *(pData + iIndex) < '0') {
+      return iRet;
+    }
+    strTemp[0] = *(pData + iIndex);
+    if (*(pData + iIndex + 1) > '9' || *(pData + iIndex + 1) < '0') {
+      return iRet;
+    }
+    strTemp[1] = *(pData + iIndex + 1);
+    if (FXSYS_atoi(strTemp) > 60) {
+      return iRet;
+    }
+    if (*(pData + 2) == ':') {
+      if (iPos == 0) {
+        iZoneHour = FXSYS_atoi(strTemp);
+      } else if (iPos == 1) {
+        iZoneMinute = FXSYS_atoi(strTemp);
+      }
+      iIndex += 3;
+    } else {
+      if (!iPos) {
+        iZoneHour = FXSYS_atoi(strTemp);
+        ++iPos;
+      } else if (iPos == 1) {
+        iZoneMinute = FXSYS_atoi(strTemp);
+        ++iPos;
+      }
+      iIndex += 2;
+    }
+  }
+  if (iIndex < iLength) {
+    return iRet;
+  }
+  iZoneHour *= iSign;
+  iRet = TRUE;
+  return iRet;
+}
+FX_BOOL CXFA_FM2JSContext::IsIsoDateTimeFormat(const FX_CHAR* pData,
+                                               int32_t iLength,
+                                               int32_t& iYear,
+                                               int32_t& iMonth,
+                                               int32_t& iDay,
+                                               int32_t& iHour,
+                                               int32_t& iMinute,
+                                               int32_t& iSecond,
+                                               int32_t& iMillionSecond,
+                                               int32_t& iZoneHour,
+                                               int32_t& iZoneMinute) {
+  iYear = 0;
+  iMonth = 0;
+  iDay = 0;
+  iHour = 0;
+  iMinute = 0;
+  iSecond = 0;
+  if (!pData) {
+    return FALSE;
+  }
+  int32_t iRet = FALSE;
+  int32_t iIndex = 0;
+  while (*(pData + iIndex) != 'T' && *(pData + iIndex) != 't') {
+    if (iIndex >= iLength) {
+      return iRet;
+    }
+    ++iIndex;
+  }
+  if (iIndex != 8 && iIndex != 10) {
+    return iRet;
+  }
+  int32_t iStyle = -1;
+  iRet = IsIsoDateFormat(pData, iIndex, iStyle, iYear, iMonth, iDay);
+  if (!iRet) {
+    return iRet;
+  }
+  if (*(pData + iIndex) != 'T' && *(pData + iIndex) != 't') {
+    return iRet;
+  }
+  ++iIndex;
+  if (((iLength - iIndex > 13) && (iLength - iIndex < 6)) &&
+      (iLength - iIndex != 15)) {
+    return iRet;
+  }
+  iRet = IsIsoTimeFormat(pData + iIndex, iLength - iIndex, iHour, iMinute,
+                         iSecond, iMillionSecond, iZoneHour, iZoneMinute);
+  if (!iRet) {
+    return iRet;
+  }
+  iRet = TRUE;
+  return iRet;
+}
+FX_BOOL CXFA_FM2JSContext::Local2IsoDate(FXJSE_HOBJECT hThis,
+                                         const CFX_ByteStringC& szDate,
+                                         const CFX_ByteStringC& szFormat,
+                                         const CFX_ByteStringC& szLocale,
+                                         CFX_ByteString& strIsoDate) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  CXFA_Document* pDoc = pContext->GetDocument();
+  if (!pDoc) {
+    return FALSE;
+  }
+  IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
+  IFX_Locale* pLocale = NULL;
+  if (szLocale.IsEmpty()) {
+    CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
+    FXSYS_assert(pThisNode);
+    CXFA_WidgetData widgetData(pThisNode);
+    pLocale = widgetData.GetLocal();
+  } else {
+    pLocale = pMgr->GetLocaleByName(
+        CFX_WideString::FromUTF8(szLocale.GetCStr(), szLocale.GetLength()));
+  }
+  if (!pLocale) {
+    return FALSE;
+  }
+  CFX_WideString wsFormat;
+  if (szFormat.IsEmpty()) {
+    pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
+  } else {
+    wsFormat =
+        CFX_WideString::FromUTF8(szFormat.GetCStr(), szFormat.GetLength());
+  }
+  CXFA_LocaleValue widgetValue(
+      XFA_VT_DATE,
+      CFX_WideString::FromUTF8(szDate.GetCStr(), szDate.GetLength()), wsFormat,
+      pLocale, (CXFA_LocaleMgr*)pMgr);
+  CFX_Unitime dt = widgetValue.GetDate();
+  strIsoDate.Format("%4d-%02d-%02d", dt.GetYear(), dt.GetMonth(), dt.GetDay());
+  return TRUE;
+}
+FX_BOOL CXFA_FM2JSContext::Local2IsoTime(FXJSE_HOBJECT hThis,
+                                         const CFX_ByteStringC& szTime,
+                                         const CFX_ByteStringC& szFormat,
+                                         const CFX_ByteStringC& szLocale,
+                                         CFX_ByteString& strIsoTime) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  CXFA_Document* pDoc = pContext->GetDocument();
+  if (!pDoc) {
+    return FALSE;
+  }
+  IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
+  IFX_Locale* pLocale = NULL;
+  if (szLocale.IsEmpty()) {
+    CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
+    FXSYS_assert(pThisNode);
+    CXFA_WidgetData widgetData(pThisNode);
+    pLocale = widgetData.GetLocal();
+  } else {
+    pLocale = pMgr->GetLocaleByName(
+        CFX_WideString::FromUTF8(szLocale.GetCStr(), szLocale.GetLength()));
+  }
+  if (!pLocale) {
+    return FALSE;
+  }
+  CFX_WideString wsFormat;
+  if (szFormat.IsEmpty()) {
+    pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
+  } else {
+    wsFormat =
+        CFX_WideString::FromUTF8(szFormat.GetCStr(), szFormat.GetLength());
+  }
+  wsFormat = FX_WSTRC(L"time{") + wsFormat;
+  wsFormat += FX_WSTRC(L"}");
+  CXFA_LocaleValue widgetValue(
+      XFA_VT_TIME,
+      CFX_WideString::FromUTF8(szTime.GetCStr(), szTime.GetLength()), wsFormat,
+      pLocale, (CXFA_LocaleMgr*)pMgr);
+  CFX_Unitime utime = widgetValue.GetTime();
+  strIsoTime.Format("%02d:%02d:%02d.%03d", utime.GetHour(), utime.GetMinute(),
+                    utime.GetSecond(), utime.GetMillisecond());
+  return TRUE;
+}
+FX_BOOL CXFA_FM2JSContext::IsoDate2Local(FXJSE_HOBJECT hThis,
+                                         const CFX_ByteStringC& szDate,
+                                         const CFX_ByteStringC& szFormat,
+                                         const CFX_ByteStringC& szLocale,
+                                         CFX_ByteString& strLocalDate) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  CXFA_Document* pDoc = pContext->GetDocument();
+  if (!pDoc) {
+    return FALSE;
+  }
+  IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
+  IFX_Locale* pLocale = NULL;
+  if (szLocale.IsEmpty()) {
+    CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
+    FXSYS_assert(pThisNode);
+    CXFA_WidgetData widgetData(pThisNode);
+    pLocale = widgetData.GetLocal();
+  } else {
+    pLocale = pMgr->GetLocaleByName(
+        CFX_WideString::FromUTF8(szLocale.GetCStr(), szLocale.GetLength()));
+  }
+  if (!pLocale) {
+    return FALSE;
+  }
+  CFX_WideString wsFormat;
+  if (szFormat.IsEmpty()) {
+    pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
+  } else {
+    wsFormat =
+        CFX_WideString::FromUTF8(szFormat.GetCStr(), szFormat.GetLength());
+  }
+  CXFA_LocaleValue widgetValue(
+      XFA_VT_DATE,
+      CFX_WideString::FromUTF8(szDate.GetCStr(), szDate.GetLength()),
+      (CXFA_LocaleMgr*)pMgr);
+  CFX_WideString wsRet;
+  widgetValue.FormatPatterns(wsRet, wsFormat, pLocale,
+                             XFA_VALUEPICTURE_Display);
+  strLocalDate = FX_UTF8Encode(wsRet, wsRet.GetLength());
+  return TRUE;
+}
+FX_BOOL CXFA_FM2JSContext::IsoTime2Local(FXJSE_HOBJECT hThis,
+                                         const CFX_ByteStringC& szTime,
+                                         const CFX_ByteStringC& szFormat,
+                                         const CFX_ByteStringC& szLocale,
+                                         CFX_ByteString& strLocalTime) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  CXFA_Document* pDoc = pContext->GetDocument();
+  if (!pDoc) {
+    return FALSE;
+  }
+  IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
+  IFX_Locale* pLocale = NULL;
+  if (szLocale.IsEmpty()) {
+    CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
+    FXSYS_assert(pThisNode);
+    CXFA_WidgetData widgetData(pThisNode);
+    pLocale = widgetData.GetLocal();
+  } else {
+    pLocale = pMgr->GetLocaleByName(
+        CFX_WideString::FromUTF8(szLocale.GetCStr(), szLocale.GetLength()));
+  }
+  if (!pLocale) {
+    return FALSE;
+  }
+  CFX_WideString wsFormat;
+  if (szFormat.IsEmpty()) {
+    pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
+  } else {
+    wsFormat =
+        CFX_WideString::FromUTF8(szFormat.GetCStr(), szFormat.GetLength());
+  }
+  wsFormat = FX_WSTRC(L"time{") + wsFormat;
+  wsFormat += FX_WSTRC(L"}");
+  CXFA_LocaleValue widgetValue(
+      XFA_VT_TIME,
+      CFX_WideString::FromUTF8(szTime.GetCStr(), szTime.GetLength()),
+      (CXFA_LocaleMgr*)pMgr);
+  CFX_WideString wsRet;
+  widgetValue.FormatPatterns(wsRet, wsFormat, pLocale,
+                             XFA_VALUEPICTURE_Display);
+  strLocalTime = FX_UTF8Encode(wsRet, wsRet.GetLength());
+  return TRUE;
+}
+FX_BOOL CXFA_FM2JSContext::GetGMTTime(FXJSE_HOBJECT hThis,
+                                      const CFX_ByteStringC& szTime,
+                                      const CFX_ByteStringC& szFormat,
+                                      const CFX_ByteStringC& szLocale,
+                                      CFX_ByteString& strGMTTime) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  CXFA_Document* pDoc = pContext->GetDocument();
+  if (!pDoc) {
+    return FALSE;
+  }
+  IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
+  IFX_Locale* pLocale = NULL;
+  if (szLocale.IsEmpty()) {
+    CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
+    FXSYS_assert(pThisNode);
+    CXFA_WidgetData widgetData(pThisNode);
+    pLocale = widgetData.GetLocal();
+  } else {
+    pLocale = pMgr->GetLocaleByName(
+        CFX_WideString::FromUTF8(szLocale.GetCStr(), szLocale.GetLength()));
+  }
+  if (!pLocale) {
+    return FALSE;
+  }
+  CFX_WideString wsFormat;
+  if (szFormat.IsEmpty()) {
+    pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
+  } else {
+    wsFormat =
+        CFX_WideString::FromUTF8(szFormat.GetCStr(), szFormat.GetLength());
+  }
+  wsFormat = FX_WSTRC(L"time{") + wsFormat;
+  wsFormat += FX_WSTRC(L"}");
+  CXFA_LocaleValue widgetValue(
+      XFA_VT_TIME,
+      CFX_WideString::FromUTF8(szTime.GetCStr(), szTime.GetLength()),
+      (CXFA_LocaleMgr*)pMgr);
+  CFX_WideString wsRet;
+  widgetValue.FormatPatterns(wsRet, wsFormat, pLocale,
+                             XFA_VALUEPICTURE_Display);
+  strGMTTime = FX_UTF8Encode(wsRet, wsRet.GetLength());
+  return TRUE;
+}
+int32_t CXFA_FM2JSContext::DateString2Num(const CFX_ByteStringC& szDateString) {
+  FX_BOOL bFlags = FALSE;
+  int32_t iLength = szDateString.GetLength();
+  FX_BOOL iRet = FALSE;
+  int32_t iStyle = -1;
+  int32_t iYear = 0;
+  int32_t iMonth = 0;
+  int32_t iDay = 0;
+  int32_t iHour = 0;
+  int32_t iMinute = 0;
+  int32_t iSecond = 0;
+  int32_t iMillionSecond = 0;
+  int32_t iZoneHour = 0;
+  int32_t iZoneMinute = 0;
+  if (iLength <= 10) {
+    iRet = IsIsoDateFormat(szDateString.GetCStr(), iLength, iStyle, iYear,
+                           iMonth, iDay);
+  } else {
+    iRet = IsIsoDateTimeFormat(szDateString.GetCStr(), iLength, iYear, iMonth,
+                               iDay, iHour, iMinute, iSecond, iMillionSecond,
+                               iZoneHour, iZoneMinute);
+  }
+  if (!iRet) {
+    bFlags = TRUE;
+  }
+  FX_FLOAT dDays = 0;
+  int32_t i = 1;
+  if (iYear < 1900) {
+    bFlags = TRUE;
+  }
+  if (!bFlags) {
+    while (iYear - i >= 1900) {
+      if ((!((iYear - i) % 4) && ((iYear - i) % 100)) || !((iYear - i) % 400)) {
+        dDays += 366;
+      } else {
+        dDays += 365;
+      }
+      ++i;
+    }
+    i = 1;
+    while (i < iMonth) {
+      if (i == 2) {
+        if ((!(iYear % 4) && (iYear % 100)) || !(iYear % 400)) {
+          dDays += 29;
+        } else {
+          dDays += 28;
+        }
+      } else if (i <= 7) {
+        if (i % 2 == 0) {
+          dDays += 30;
+        } else {
+          dDays += 31;
+        }
+      } else {
+        if (i % 2 == 0) {
+          dDays += 31;
+        } else {
+          dDays += 30;
+        }
+      }
+      ++i;
+    }
+    i = 0;
+    while (iDay - i > 0) {
+      dDays += 1;
+      ++i;
+    }
+  } else {
+    dDays = 0;
+  }
+  return (int32_t)dDays;
+}
+#define XFA_N 19
+static uint8_t g_sAltTable_Date[] = {
+    XFA_N, XFA_N, XFA_N, 3,     9,     XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+    XFA_N, 2,     XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+    XFA_N, XFA_N, 1,     XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+    XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+    XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+    XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+};
+static uint8_t g_sAltTable_Time[] = {
+    14,    XFA_N, XFA_N, 3,     9,     XFA_N, XFA_N, 15,    XFA_N, XFA_N, XFA_N,
+    XFA_N, 6,     XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, 7,     XFA_N, XFA_N, XFA_N,
+    XFA_N, XFA_N, 1,     17,    XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+    XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, 15,    XFA_N, XFA_N, XFA_N, XFA_N,
+    XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+    XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+};
+static void XFA_FM_AlternateDateTimeSymbols(CFX_WideString& wsPattern,
+                                            const CFX_WideString& wsAltSymbols,
+                                            uint8_t* pAltTable) {
+  int32_t nLength = wsPattern.GetLength();
+  FX_BOOL bInConstRange = FALSE;
+  FX_BOOL bEscape = FALSE;
+  int32_t i = 0, n = 0;
+  while (i < nLength) {
+    FX_WCHAR wc = wsPattern[i];
+    if (wc == L'\'') {
+      bInConstRange = !bInConstRange;
+      if (bEscape) {
+        i++;
+      } else {
+        wsPattern.Delete(i);
+        nLength--;
+      }
+      bEscape = !bEscape;
+      continue;
+    }
+    if (!bInConstRange && (n = wc - L'A') >= 0 && n <= (L'a' - L'A')) {
+      int32_t nAlt = (int32_t)pAltTable[n];
+      if (nAlt != XFA_N) {
+        wsPattern.SetAt(i, wsAltSymbols[nAlt]);
+      }
+    }
+    i++;
+    bEscape = FALSE;
+  }
+}
+#undef XFA_N
+void CXFA_FM2JSContext::GetLocalDateFormat(FXJSE_HOBJECT hThis,
+                                           int32_t iStyle,
+                                           const CFX_ByteStringC& szLocalStr,
+                                           CFX_ByteString& strFormat,
+                                           FX_BOOL bStandard) {
+  FX_LOCALEDATETIMESUBCATEGORY strStyle;
+  switch (iStyle) {
+    case 0:
+      strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
+      break;
+    case 1:
+      strStyle = FX_LOCALEDATETIMESUBCATEGORY_Short;
+      break;
+    case 2:
+      strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
+      break;
+    case 3:
+      strStyle = FX_LOCALEDATETIMESUBCATEGORY_Long;
+      break;
+    case 4:
+      strStyle = FX_LOCALEDATETIMESUBCATEGORY_Full;
+      break;
+    default:
+      strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
+      break;
+  }
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  CXFA_Document* pDoc = pContext->GetDocument();
+  if (!pDoc) {
+    return;
+  }
+  IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
+  IFX_Locale* pLocale = NULL;
+  if (szLocalStr.IsEmpty()) {
+    CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
+    FXSYS_assert(pThisNode);
+    CXFA_WidgetData widgetData(pThisNode);
+    pLocale = widgetData.GetLocal();
+  } else {
+    pLocale = pMgr->GetLocaleByName(
+        CFX_WideString::FromUTF8(szLocalStr.GetCStr(), szLocalStr.GetLength()));
+  }
+  if (!pLocale) {
+    return;
+  }
+  CFX_WideString strRet;
+  pLocale->GetDatePattern(strStyle, strRet);
+  if (!bStandard) {
+    CFX_WideString wsSymbols;
+    pLocale->GetDateTimeSymbols(wsSymbols);
+    XFA_FM_AlternateDateTimeSymbols(strRet, wsSymbols, g_sAltTable_Date);
+  }
+  strFormat = FX_UTF8Encode(strRet, strRet.GetLength());
+}
+void CXFA_FM2JSContext::GetLocalTimeFormat(FXJSE_HOBJECT hThis,
+                                           int32_t iStyle,
+                                           const CFX_ByteStringC& szLocalStr,
+                                           CFX_ByteString& strFormat,
+                                           FX_BOOL bStandard) {
+  FX_LOCALEDATETIMESUBCATEGORY strStyle;
+  switch (iStyle) {
+    case 0:
+      strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
+      break;
+    case 1:
+      strStyle = FX_LOCALEDATETIMESUBCATEGORY_Short;
+      break;
+    case 2:
+      strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
+      break;
+    case 3:
+      strStyle = FX_LOCALEDATETIMESUBCATEGORY_Long;
+      break;
+    case 4:
+      strStyle = FX_LOCALEDATETIMESUBCATEGORY_Full;
+      break;
+    default:
+      strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
+      break;
+  }
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  CXFA_Document* pDoc = pContext->GetDocument();
+  if (!pDoc) {
+    return;
+  }
+  IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
+  IFX_Locale* pLocale = NULL;
+  if (szLocalStr.IsEmpty()) {
+    CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
+    FXSYS_assert(pThisNode);
+    CXFA_WidgetData widgetData(pThisNode);
+    pLocale = widgetData.GetLocal();
+  } else {
+    pLocale = pMgr->GetLocaleByName(
+        CFX_WideString::FromUTF8(szLocalStr.GetCStr(), szLocalStr.GetLength()));
+  }
+  if (!pLocale) {
+    return;
+  }
+  CFX_WideString strRet;
+  pLocale->GetTimePattern(strStyle, strRet);
+  if (!bStandard) {
+    CFX_WideString wsSymbols;
+    pLocale->GetDateTimeSymbols(wsSymbols);
+    XFA_FM_AlternateDateTimeSymbols(strRet, wsSymbols, g_sAltTable_Time);
+  }
+  strFormat = FX_UTF8Encode(strRet, strRet.GetLength());
+}
+void CXFA_FM2JSContext::GetStandardDateFormat(FXJSE_HOBJECT hThis,
+                                              int32_t iStyle,
+                                              const CFX_ByteStringC& szLocalStr,
+                                              CFX_ByteString& strFormat) {
+  GetLocalDateFormat(hThis, iStyle, szLocalStr, strFormat, TRUE);
+}
+void CXFA_FM2JSContext::GetStandardTimeFormat(FXJSE_HOBJECT hThis,
+                                              int32_t iStyle,
+                                              const CFX_ByteStringC& szLocalStr,
+                                              CFX_ByteString& strFormat) {
+  GetLocalTimeFormat(hThis, iStyle, szLocalStr, strFormat, TRUE);
+}
+void CXFA_FM2JSContext::Num2AllTime(FXJSE_HOBJECT hThis,
+                                    int32_t iTime,
+                                    const CFX_ByteStringC& szFormat,
+                                    const CFX_ByteStringC& szLocale,
+                                    FX_BOOL bGM,
+                                    CFX_ByteString& strTime) {
+  int32_t iHour = 0;
+  int32_t iMin = 0;
+  int32_t iSec = 0;
+  int32_t iZoneHour = 0;
+  int32_t iZoneMin = 0;
+  int32_t iZoneSec = 0;
+  iHour = static_cast<int>(iTime) / 3600000;
+  iMin = (static_cast<int>(iTime) - iHour * 3600000) / 60000;
+  iSec = (static_cast<int>(iTime) - iHour * 3600000 - iMin * 60000) / 1000;
+  if (!bGM) {
+    GetLocalTimeZone(iZoneHour, iZoneMin, iZoneSec);
+    iHour += iZoneHour;
+    iMin += iZoneMin;
+    iSec += iZoneSec;
+  }
+  int32_t iRet = 0;
+  CFX_ByteString strIsoTime;
+  strIsoTime.Format("%02d:%02d:%02d", iHour, iMin, iSec);
+  if (bGM) {
+    iRet = GetGMTTime(hThis, strIsoTime, szFormat, szLocale, strTime);
+  } else {
+    iRet = IsoTime2Local(hThis, strIsoTime, szFormat, szLocale, strTime);
+  }
+  if (!iRet) {
+    strTime = "";
+  }
+}
+
+void CXFA_FM2JSContext::GetLocalTimeZone(int32_t& iHour,
+                                         int32_t& iMin,
+                                         int32_t& iSec) {
+  time_t now;
+  time(&now);
+  struct tm* pGmt = gmtime(&now);
+  int32_t iGMHour = pGmt->tm_hour;
+  int32_t iGMMin = pGmt->tm_min;
+  int32_t iGMSec = pGmt->tm_sec;
+  struct tm* pLocal = localtime(&now);
+  int32_t iLocalHour = pLocal->tm_hour;
+  int32_t iLocalMin = pLocal->tm_min;
+  int32_t iLocalSec = pLocal->tm_sec;
+  iHour = iLocalHour - iGMHour;
+  iMin = iLocalMin - iGMMin;
+  iSec = iLocalSec - iGMSec;
+}
+void CXFA_FM2JSContext::Apr(FXJSE_HOBJECT hThis,
+                            const CFX_ByteStringC& szFuncName,
+                            CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 3) {
+    FX_BOOL bFlags = FALSE;
+    FX_DOUBLE nPrincipal = 0;
+    FX_DOUBLE nPayment = 0;
+    FX_DOUBLE nPeriods = 0;
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+    FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
+    bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) ||
+              HValueIsNull(hThis, argThree));
+    if (bFlags) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      nPrincipal = HValueToDouble(hThis, argOne);
+      nPayment = HValueToDouble(hThis, argTwo);
+      nPeriods = HValueToDouble(hThis, argThree);
+      bFlags = ((nPrincipal <= 0) || (nPayment <= 0) || (nPeriods <= 0));
+      if (bFlags) {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+      } else {
+        FX_DOUBLE r =
+            2 * (nPeriods * nPayment - nPrincipal) / (nPeriods * nPrincipal);
+        FX_DOUBLE nTemp = 1;
+        for (int32_t i = 0; i < nPeriods; ++i) {
+          nTemp *= (1 + r);
+        }
+        FX_DOUBLE nRet = r * nTemp / (nTemp - 1) - nPayment / nPrincipal;
+        while ((nRet > FINANCIAL_PRECISION || nRet < -FINANCIAL_PRECISION) &&
+               (!bFlags)) {
+          FX_DOUBLE nDerivative = 0;
+          nDerivative =
+              ((nTemp + r * nPeriods * (nTemp / (1 + r))) * (nTemp - 1) -
+               (r * nTemp * nPeriods * (nTemp / (1 + r)))) /
+              ((nTemp - 1) * (nTemp - 1));
+          if (nDerivative == 0) {
+            bFlags = TRUE;
+            continue;
+          }
+          r = r - nRet / nDerivative;
+          nTemp = 1;
+          for (int32_t i = 0; i < nPeriods; ++i) {
+            nTemp *= (1 + r);
+          }
+          nRet = r * nTemp / (nTemp - 1) - nPayment / nPrincipal;
+        }
+        if (bFlags) {
+          FXJSE_Value_SetNull(args.GetReturnValue());
+        } else {
+          r = r * 12;
+          FXJSE_Value_SetDouble(args.GetReturnValue(), r);
+        }
+      }
+    }
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+    FXJSE_Value_Release(argThree);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Apr");
+  }
+}
+void CXFA_FM2JSContext::CTerm(FXJSE_HOBJECT hThis,
+                              const CFX_ByteStringC& szFuncName,
+                              CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 3) {
+    FX_BOOL bFlags = FALSE;
+    FX_FLOAT nRate = 0;
+    FX_FLOAT nFutureValue = 0;
+    FX_FLOAT nInitAmount = 0;
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+    FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
+    bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) ||
+              HValueIsNull(hThis, argThree));
+    if (bFlags) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      nRate = HValueToFloat(hThis, argOne);
+      nFutureValue = HValueToFloat(hThis, argTwo);
+      nInitAmount = HValueToFloat(hThis, argThree);
+      bFlags = ((nRate <= 0) || (nFutureValue <= 0) || (nInitAmount <= 0));
+      if (bFlags) {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+      } else {
+        FXJSE_Value_SetFloat(args.GetReturnValue(),
+                             FXSYS_log((FX_FLOAT)(nFutureValue / nInitAmount)) /
+                                 FXSYS_log((FX_FLOAT)(1 + nRate)));
+      }
+    }
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+    FXJSE_Value_Release(argThree);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"CTerm");
+  }
+}
+void CXFA_FM2JSContext::FV(FXJSE_HOBJECT hThis,
+                           const CFX_ByteStringC& szFuncName,
+                           CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 3) {
+    FX_BOOL bFlags = FALSE;
+    FX_DOUBLE nAmount = 0;
+    FX_DOUBLE nRate = 0;
+    FX_DOUBLE nPeriod = 0;
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+    FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
+    bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) ||
+              HValueIsNull(hThis, argThree));
+    if (bFlags) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      nAmount = HValueToDouble(hThis, argOne);
+      nRate = HValueToDouble(hThis, argTwo);
+      nPeriod = HValueToDouble(hThis, argThree);
+      bFlags = ((nRate < 0) || (nPeriod <= 0) || (nAmount <= 0));
+      if (bFlags) {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+      } else {
+        FX_DOUBLE dResult = 0;
+        if (!nRate) {
+          dResult = nAmount * nPeriod;
+        } else {
+          FX_DOUBLE nTemp = 1;
+          for (int i = 0; i < nPeriod; ++i) {
+            nTemp *= 1 + nRate;
+          }
+          dResult = nAmount * (nTemp - 1) / nRate;
+        }
+        FXJSE_Value_SetDouble(args.GetReturnValue(), dResult);
+      }
+    }
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+    FXJSE_Value_Release(argThree);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"FV");
+  }
+}
+void CXFA_FM2JSContext::IPmt(FXJSE_HOBJECT hThis,
+                             const CFX_ByteStringC& szFuncName,
+                             CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 5) {
+    FX_BOOL bFlags = FALSE;
+    FX_FLOAT nPrincpalAmount = 0;
+    FX_FLOAT nRate = 0;
+    FX_FLOAT nPayment = 0;
+    FX_FLOAT nFirstMonth = 0;
+    FX_FLOAT nNumberOfMonths = 0;
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+    FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
+    FXJSE_HVALUE argFour = GetSimpleHValue(hThis, args, 3);
+    FXJSE_HVALUE argFive = GetSimpleHValue(hThis, args, 4);
+    bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) ||
+              HValueIsNull(hThis, argThree) || HValueIsNull(hThis, argFour) ||
+              HValueIsNull(hThis, argFive));
+    if (bFlags) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      nPrincpalAmount = HValueToFloat(hThis, argOne);
+      nRate = HValueToFloat(hThis, argTwo);
+      nPayment = HValueToFloat(hThis, argThree);
+      nFirstMonth = HValueToFloat(hThis, argFour);
+      nNumberOfMonths = HValueToFloat(hThis, argFive);
+      bFlags = ((nPrincpalAmount <= 0) || (nRate <= 0) || (nPayment <= 0) ||
+                (nFirstMonth < 0) || (nNumberOfMonths < 0));
+      if (bFlags) {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+      } else {
+        FX_FLOAT fResult = 0;
+        FX_FLOAT nRateOfMonth = nRate / 12;
+        int32_t iNums =
+            (int32_t)((FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount)) -
+                       FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount -
+                                              nRateOfMonth))) /
+                      FXSYS_log10((FX_FLOAT)(1 + nRateOfMonth)));
+        int32_t iEnd = (int32_t)(nFirstMonth + nNumberOfMonths - 1);
+        if (iEnd > iNums) {
+          iEnd = iNums;
+        }
+        FX_FLOAT nSum = 0;
+        if (nPayment < nPrincpalAmount * nRateOfMonth) {
+          bFlags = TRUE;
+          fResult = 0;
+        }
+        if (!bFlags) {
+          int32_t i = 0;
+          for (i = 0; i < nFirstMonth - 1; ++i) {
+            nPrincpalAmount -= nPayment - nPrincpalAmount * nRateOfMonth;
+          }
+          for (; i < iEnd; ++i) {
+            nSum += nPrincpalAmount * nRateOfMonth;
+            nPrincpalAmount -= nPayment - nPrincpalAmount * nRateOfMonth;
+          }
+          fResult = nSum;
+        }
+        FXJSE_Value_SetFloat(args.GetReturnValue(), fResult);
+      }
+    }
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+    FXJSE_Value_Release(argThree);
+    FXJSE_Value_Release(argFour);
+    FXJSE_Value_Release(argFive);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"IPmt");
+  }
+}
+void CXFA_FM2JSContext::NPV(FXJSE_HOBJECT hThis,
+                            const CFX_ByteStringC& szFuncName,
+                            CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  int32_t argc = args.GetLength();
+  if (argc > 2) {
+    FX_BOOL bFlags = FALSE;
+    FXJSE_HVALUE* argValues = FX_Alloc(FXJSE_HVALUE, argc);
+    for (int32_t i = 0; i < argc; i++) {
+      argValues[i] = GetSimpleHValue(hThis, args, i);
+      if (HValueIsNull(hThis, argValues[i])) {
+        bFlags = TRUE;
+      }
+    }
+    if (!bFlags) {
+      FX_DOUBLE nRate = 0;
+      nRate = HValueToDouble(hThis, argValues[0]);
+      if (nRate <= 0) {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+      } else {
+        FX_DOUBLE* pData = FX_Alloc(FX_DOUBLE, argc - 1);
+        for (int32_t i = 1; i < argc; i++) {
+          pData[i - 1] = HValueToDouble(hThis, argValues[i]);
+        }
+        FX_DOUBLE nSum = 0;
+        int32_t iIndex = 0;
+        for (int32_t i = 0; i < argc - 1; i++) {
+          FX_DOUBLE nTemp = 1;
+          for (int32_t j = 0; j <= i; j++) {
+            nTemp *= 1 + nRate;
+          }
+          FX_DOUBLE nNum = *(pData + iIndex++);
+          nSum += nNum / nTemp;
+        }
+        FXJSE_Value_SetDouble(args.GetReturnValue(), nSum);
+        FX_Free(pData);
+        pData = 0;
+      }
+    } else {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    }
+    for (int32_t i = 0; i < argc; i++) {
+      FXJSE_Value_Release(argValues[i]);
+    }
+    FX_Free(argValues);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"NPV");
+  }
+}
+void CXFA_FM2JSContext::Pmt(FXJSE_HOBJECT hThis,
+                            const CFX_ByteStringC& szFuncName,
+                            CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 3) {
+    FX_BOOL bFlags = FALSE;
+    FX_FLOAT nPrincipal = 0;
+    FX_FLOAT nRate = 0;
+    FX_FLOAT nPeriods = 0;
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+    FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
+    bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) ||
+              HValueIsNull(hThis, argThree));
+    if (bFlags) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      nPrincipal = HValueToFloat(hThis, argOne);
+      nRate = HValueToFloat(hThis, argTwo);
+      nPeriods = HValueToFloat(hThis, argThree);
+      bFlags = ((nPrincipal <= 0) || (nRate <= 0) || (nPeriods <= 0));
+      if (bFlags) {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+      } else {
+        FX_FLOAT nSum = 0;
+        FX_FLOAT nTmp = 1 + nRate;
+        nSum = nTmp;
+        for (int32_t i = 0; i < nPeriods - 1; ++i) {
+          nSum *= nTmp;
+        }
+        FXJSE_Value_SetFloat(args.GetReturnValue(),
+                             (nPrincipal * nRate * nSum) / (nSum - 1));
+      }
+    }
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+    FXJSE_Value_Release(argThree);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Pmt");
+  }
+}
+void CXFA_FM2JSContext::PPmt(FXJSE_HOBJECT hThis,
+                             const CFX_ByteStringC& szFuncName,
+                             CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 5) {
+    FX_BOOL bFlags = FALSE;
+    FX_FLOAT nPrincpalAmount = 0;
+    FX_FLOAT nRate = 0;
+    FX_FLOAT nPayment = 0;
+    FX_FLOAT nFirstMonth = 0;
+    FX_FLOAT nNumberOfMonths = 0;
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+    FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
+    FXJSE_HVALUE argFour = GetSimpleHValue(hThis, args, 3);
+    FXJSE_HVALUE argFive = GetSimpleHValue(hThis, args, 4);
+    bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) ||
+              HValueIsNull(hThis, argThree) || HValueIsNull(hThis, argFour) ||
+              HValueIsNull(hThis, argFive));
+    if (bFlags) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      nPrincpalAmount = HValueToFloat(hThis, argOne);
+      nRate = HValueToFloat(hThis, argTwo);
+      nPayment = HValueToFloat(hThis, argThree);
+      nFirstMonth = HValueToFloat(hThis, argFour);
+      nNumberOfMonths = HValueToFloat(hThis, argFive);
+      bFlags = ((nPrincpalAmount <= 0) || (nRate <= 0) || (nPayment <= 0) ||
+                (nFirstMonth < 0) || (nNumberOfMonths < 0));
+      if (bFlags) {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+      } else {
+        int32_t iEnd = (int32_t)(nFirstMonth + nNumberOfMonths - 1);
+        FX_FLOAT nSum = 0;
+        FX_FLOAT nRateOfMonth = nRate / 12;
+        int32_t iNums =
+            (int32_t)((FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount)) -
+                       FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount -
+                                              nRateOfMonth))) /
+                      FXSYS_log10((FX_FLOAT)(1 + nRateOfMonth)));
+        if (iEnd > iNums) {
+          iEnd = iNums;
+        }
+        if (nPayment < nPrincpalAmount * nRateOfMonth) {
+          bFlags = TRUE;
+        }
+        if (!bFlags) {
+          int32_t i = 0;
+          for (i = 0; i < nFirstMonth - 1; ++i) {
+            nPrincpalAmount -= nPayment - nPrincpalAmount * nRateOfMonth;
+          }
+          FX_FLOAT nTemp = 0;
+          for (; i < iEnd; ++i) {
+            nTemp = nPayment - nPrincpalAmount * nRateOfMonth;
+            nSum += nTemp;
+            nPrincpalAmount -= nTemp;
+          }
+          FXJSE_Value_SetFloat(args.GetReturnValue(), nSum);
+        } else {
+          pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+        }
+      }
+    }
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+    FXJSE_Value_Release(argThree);
+    FXJSE_Value_Release(argFour);
+    FXJSE_Value_Release(argFive);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"PPmt");
+  }
+}
+void CXFA_FM2JSContext::PV(FXJSE_HOBJECT hThis,
+                           const CFX_ByteStringC& szFuncName,
+                           CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 3) {
+    FX_BOOL bFlags = FALSE;
+    FX_DOUBLE nAmount = 0;
+    FX_DOUBLE nRate = 0;
+    FX_DOUBLE nPeriod = 0;
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+    FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
+    bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) ||
+              HValueIsNull(hThis, argThree));
+    if (bFlags) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      nAmount = HValueToDouble(hThis, argOne);
+      nRate = HValueToDouble(hThis, argTwo);
+      nPeriod = HValueToDouble(hThis, argThree);
+      bFlags = ((nAmount <= 0) || (nRate < 0) || (nPeriod <= 0));
+      if (bFlags) {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+      } else {
+        FX_DOUBLE nTemp = 1;
+        for (int32_t i = 0; i < nPeriod; ++i) {
+          nTemp *= 1 + nRate;
+        }
+        nTemp = 1 / nTemp;
+        FXJSE_Value_SetDouble(args.GetReturnValue(),
+                              nAmount * ((1 - nTemp) / nRate));
+      }
+    }
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+    FXJSE_Value_Release(argThree);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"PV");
+  }
+}
+void CXFA_FM2JSContext::Rate(FXJSE_HOBJECT hThis,
+                             const CFX_ByteStringC& szFuncName,
+                             CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 3) {
+    FX_BOOL bFlags = FALSE;
+    FX_FLOAT nFuture = 0;
+    FX_FLOAT nPresent = 0;
+    FX_FLOAT nTotalNumber = 0;
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+    FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
+    bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) ||
+              HValueIsNull(hThis, argThree));
+    if (bFlags) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      nFuture = HValueToFloat(hThis, argOne);
+      nPresent = HValueToFloat(hThis, argTwo);
+      nTotalNumber = HValueToFloat(hThis, argThree);
+      bFlags = ((nFuture <= 0) || (nPresent < 0) || (nTotalNumber <= 0));
+      if (bFlags) {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+      } else {
+        FXJSE_Value_SetFloat(args.GetReturnValue(),
+                             (FXSYS_pow((FX_FLOAT)(nFuture / nPresent),
+                                        (FX_FLOAT)(1 / nTotalNumber)) -
+                              1));
+      }
+    }
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+    FXJSE_Value_Release(argThree);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Rate");
+  }
+}
+void CXFA_FM2JSContext::Term(FXJSE_HOBJECT hThis,
+                             const CFX_ByteStringC& szFuncName,
+                             CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 3) {
+    FX_BOOL bFlags = FALSE;
+    FX_FLOAT nMount = 0;
+    FX_FLOAT nRate = 0;
+    FX_FLOAT nFuture = 0;
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+    FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
+    bFlags = (FXJSE_Value_IsNull(argOne) || FXJSE_Value_IsNull(argTwo) ||
+              FXJSE_Value_IsNull(argThree));
+    if (bFlags) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      nMount = HValueToFloat(hThis, argOne);
+      nRate = HValueToFloat(hThis, argTwo);
+      nFuture = HValueToFloat(hThis, argThree);
+      bFlags = ((nMount <= 0) || (nRate <= 0) || (nFuture <= 0));
+      if (bFlags) {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+      } else {
+        FXJSE_Value_SetFloat(
+            args.GetReturnValue(),
+            (FXSYS_log((FX_FLOAT)(nFuture / nMount * nRate) + 1) /
+             FXSYS_log((FX_FLOAT)(1 + nRate))));
+      }
+    }
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+    FXJSE_Value_Release(argThree);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Term");
+  }
+}
+void CXFA_FM2JSContext::Choose(FXJSE_HOBJECT hThis,
+                               const CFX_ByteStringC& szFuncName,
+                               CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  int32_t argc = args.GetLength();
+  if (argc > 1) {
+    FXJSE_HVALUE argOne = args.GetValue(0);
+    FX_BOOL argOneIsNull = FALSE;
+    int32_t iIndex = 0;
+    argOneIsNull = HValueIsNull(hThis, argOne);
+    if (!argOneIsNull) {
+      iIndex = (int32_t)HValueToFloat(hThis, argOne);
+    }
+    FXJSE_Value_Release(argOne);
+    if (argOneIsNull) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else if (iIndex < 1) {
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
+    } else {
+      FX_BOOL bFound = FALSE;
+      FX_BOOL bStopCounterFlags = FALSE;
+      int32_t iArgIndex = 1;
+      int32_t iValueIndex = 0;
+      while (!bFound && !bStopCounterFlags && (iArgIndex < argc)) {
+        FXJSE_HVALUE argIndexValue = args.GetValue(iArgIndex);
+        if (FXJSE_Value_IsArray(argIndexValue)) {
+          FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+          FXJSE_Value_GetObjectProp(argIndexValue, "length", lengthValue);
+          int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
+          FXJSE_Value_Release(lengthValue);
+          if (iLength > 3) {
+            bStopCounterFlags = TRUE;
+          }
+          iValueIndex += (iLength - 2);
+          if (iValueIndex >= iIndex) {
+            FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+            FXJSE_HVALUE jsobjectValue = FXJSE_Value_Create(hruntime);
+            FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
+            FXJSE_Value_GetObjectPropByIdx(argIndexValue, 1, propertyValue);
+            FXJSE_Value_GetObjectPropByIdx(
+                argIndexValue, ((iLength - 1) - (iValueIndex - iIndex)),
+                jsobjectValue);
+            if (FXJSE_Value_IsNull(propertyValue)) {
+              GetObjectDefaultValue(jsobjectValue, newProperty);
+            } else {
+              CFX_ByteString propStr;
+              FXJSE_Value_ToUTF8String(propertyValue, propStr);
+              FXJSE_Value_GetObjectProp(jsobjectValue, propStr, newProperty);
+            }
+            CFX_ByteString bsChoosed;
+            HValueToUTF8String(newProperty, bsChoosed);
+            FXJSE_Value_SetUTF8String(args.GetReturnValue(), bsChoosed);
+            FXJSE_Value_Release(newProperty);
+            FXJSE_Value_Release(jsobjectValue);
+            FXJSE_Value_Release(propertyValue);
+            bFound = TRUE;
+          }
+        } else {
+          iValueIndex++;
+          if (iValueIndex == iIndex) {
+            CFX_ByteString bsChoosed;
+            HValueToUTF8String(argIndexValue, bsChoosed);
+            FXJSE_Value_SetUTF8String(args.GetReturnValue(), bsChoosed);
+            bFound = TRUE;
+          }
+        }
+        FXJSE_Value_Release(argIndexValue);
+        iArgIndex++;
+      }
+      if (!bFound) {
+        FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
+      }
+    }
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Choose");
+  }
+}
+void CXFA_FM2JSContext::Exists(FXJSE_HOBJECT hThis,
+                               const CFX_ByteStringC& szFuncName,
+                               CFXJSE_Arguments& args) {
+  if (args.GetLength() == 1) {
+    FXJSE_HVALUE argOne = args.GetValue(0);
+    FXJSE_Value_SetInteger(args.GetReturnValue(), FXJSE_Value_IsObject(argOne));
+    FXJSE_Value_Release(argOne);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Exists");
+  }
+}
+void CXFA_FM2JSContext::HasValue(FXJSE_HOBJECT hThis,
+                                 const CFX_ByteStringC& szFuncName,
+                                 CFXJSE_Arguments& args) {
+  if (args.GetLength() == 1) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    if (FXJSE_Value_IsUTF8String(argOne)) {
+      CFX_ByteString valueStr;
+      FXJSE_Value_ToUTF8String(argOne, valueStr);
+      valueStr.TrimLeft();
+      FXJSE_Value_SetInteger(args.GetReturnValue(), (!valueStr.IsEmpty()));
+    } else if (FXJSE_Value_IsNumber(argOne) || FXJSE_Value_IsBoolean(argOne)) {
+      FXJSE_Value_SetInteger(args.GetReturnValue(), TRUE);
+    } else {
+      FXJSE_Value_SetInteger(args.GetReturnValue(), FALSE);
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"HasValue");
+  }
+}
+void CXFA_FM2JSContext::Oneof(FXJSE_HOBJECT hThis,
+                              const CFX_ByteStringC& szFuncName,
+                              CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if (argc > 1) {
+    FX_BOOL bFlags = FALSE;
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE* parametersValue = 0;
+    int32_t iCount = 0;
+    unfoldArgs(hThis, args, parametersValue, iCount, 1);
+    for (int32_t i = 0; i < iCount; i++) {
+      if (simpleValueCompare(hThis, argOne, parametersValue[i])) {
+        bFlags = TRUE;
+        break;
+      }
+    }
+    FXJSE_Value_SetInteger(args.GetReturnValue(), bFlags);
+    FXJSE_Value_Release(argOne);
+    for (int32_t i = 0; i < iCount; i++) {
+      FXJSE_Value_Release(parametersValue[i]);
+    }
+    FX_Free(parametersValue);
+    parametersValue = 0;
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Oneof");
+  }
+}
+void CXFA_FM2JSContext::Within(FXJSE_HOBJECT hThis,
+                               const CFX_ByteStringC& szFuncName,
+                               CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if (argc == 3) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    if (FXJSE_Value_IsNull(argOne)) {
+      FXJSE_Value_SetUndefined(args.GetReturnValue());
+    } else {
+      FXJSE_HVALUE argLow = GetSimpleHValue(hThis, args, 1);
+      FXJSE_HVALUE argHeight = GetSimpleHValue(hThis, args, 2);
+      if (FXJSE_Value_IsNumber(argOne)) {
+        FX_FLOAT oneNumber = HValueToFloat(hThis, argOne);
+        FX_FLOAT lowNumber = HValueToFloat(hThis, argLow);
+        FX_FLOAT heightNumber = HValueToFloat(hThis, argHeight);
+        FXJSE_Value_SetInteger(
+            args.GetReturnValue(),
+            ((oneNumber >= lowNumber) && (oneNumber <= heightNumber)));
+      } else {
+        CFX_ByteString oneString;
+        CFX_ByteString lowString;
+        CFX_ByteString heightString;
+        HValueToUTF8String(argOne, oneString);
+        HValueToUTF8String(argLow, lowString);
+        HValueToUTF8String(argHeight, heightString);
+        FXJSE_Value_SetInteger(args.GetReturnValue(),
+                               ((oneString.Compare(lowString) >= 0) &&
+                                (oneString.Compare(heightString) <= 0)));
+      }
+      FXJSE_Value_Release(argLow);
+      FXJSE_Value_Release(argHeight);
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Within");
+  }
+}
+void CXFA_FM2JSContext::If(FXJSE_HOBJECT hThis,
+                           const CFX_ByteStringC& szFuncName,
+                           CFXJSE_Arguments& args) {
+  if (args.GetLength() == 3) {
+    FXJSE_HVALUE argCondition = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argFirstValue = GetSimpleHValue(hThis, args, 1);
+    FXJSE_HVALUE argSecondValue = GetSimpleHValue(hThis, args, 2);
+    FX_BOOL bCondition = FXJSE_Value_ToBoolean(argCondition);
+    FXJSE_Value_Set(args.GetReturnValue(),
+                    bCondition ? argFirstValue : argSecondValue);
+    FXJSE_Value_Release(argSecondValue);
+    FXJSE_Value_Release(argFirstValue);
+    FXJSE_Value_Release(argCondition);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"If");
+  }
+}
+void CXFA_FM2JSContext::Eval(FXJSE_HOBJECT hThis,
+                             const CFX_ByteStringC& szFuncName,
+                             CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  if (args.GetLength() == 1) {
+    FXJSE_HVALUE scriptValue = GetSimpleHValue(hThis, args, 0);
+    CFX_ByteString utf8ScriptString;
+    HValueToUTF8String(scriptValue, utf8ScriptString);
+    if (utf8ScriptString.IsEmpty()) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      CFX_WideTextBuf wsJavaScriptBuf;
+      CFX_WideString javaScript;
+      CFX_WideString wsError;
+      XFA_FM2JS_Translate(CFX_WideString::FromUTF8(
+                              utf8ScriptString, utf8ScriptString.GetLength()),
+                          wsJavaScriptBuf, wsError);
+      FXJSE_HCONTEXT hContext = FXJSE_Context_Create(hruntime);
+      FXJSE_HVALUE returnValue = FXJSE_Value_Create(hruntime);
+      javaScript = wsJavaScriptBuf.GetWideString();
+      FXJSE_ExecuteScript(hContext,
+                          FX_UTF8Encode(javaScript, javaScript.GetLength()),
+                          returnValue);
+      FXJSE_Value_Set(args.GetReturnValue(), returnValue);
+      FXJSE_Value_Release(returnValue);
+      FXJSE_Context_Release(hContext);
+    }
+    FXJSE_Value_Release(scriptValue);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Eval");
+  }
+}
+void CXFA_FM2JSContext::Ref(FXJSE_HOBJECT hThis,
+                            const CFX_ByteStringC& szFuncName,
+                            CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  if (args.GetLength() == 1) {
+    FXJSE_HVALUE argOne = args.GetValue(0);
+    if (FXJSE_Value_IsNull(argOne)) {
+      FXJSE_HVALUE rgValues[3];
+      for (int32_t i = 0; i < 3; i++) {
+        rgValues[i] = FXJSE_Value_Create(hruntime);
+      }
+      FXJSE_Value_SetInteger(rgValues[0], 4);
+      FXJSE_Value_SetNull(rgValues[1]);
+      FXJSE_Value_SetNull(rgValues[2]);
+      FXJSE_Value_SetArray(args.GetReturnValue(), 3, rgValues);
+      for (int32_t i = 0; i < 3; i++) {
+        FXJSE_Value_Release(rgValues[i]);
+      }
+    } else if (FXJSE_Value_IsArray(argOne)) {
+#ifndef NDEBUG
+      FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectProp(argOne, "length", lengthValue);
+      FXSYS_assert(FXJSE_Value_ToInteger(lengthValue) >= 3);
+      FXJSE_Value_Release(lengthValue);
+#endif
+      FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+      FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectPropByIdx(argOne, 1, propertyValue);
+      FXJSE_Value_GetObjectPropByIdx(argOne, 2, jsObjectValue);
+      if (FXJSE_Value_IsNull(jsObjectValue)) {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+      } else if (FXJSE_Value_IsNull(propertyValue) &&
+                 (!FXJSE_Value_IsNull(jsObjectValue))) {
+        FXJSE_HVALUE rgValues[3];
+        for (int32_t i = 0; i < 3; i++) {
+          rgValues[i] = FXJSE_Value_Create(hruntime);
+        }
+        FXJSE_Value_SetInteger(rgValues[0], 3);
+        FXJSE_Value_SetNull(rgValues[1]);
+        FXJSE_Value_Set(rgValues[2], jsObjectValue);
+        FXJSE_Value_SetArray(args.GetReturnValue(), 3, rgValues);
+        for (int32_t i = 0; i < 3; i++) {
+          FXJSE_Value_Release(rgValues[i]);
+        }
+      } else {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+      }
+      FXJSE_Value_Release(jsObjectValue);
+      FXJSE_Value_Release(propertyValue);
+    } else if (FXJSE_Value_IsObject(argOne)) {
+      FXJSE_HVALUE rgValues[3];
+      for (int32_t i = 0; i < 3; i++) {
+        rgValues[i] = FXJSE_Value_Create(hruntime);
+      }
+      FXJSE_Value_SetInteger(rgValues[0], 3);
+      FXJSE_Value_SetNull(rgValues[1]);
+      FXJSE_Value_Set(rgValues[2], argOne);
+      FXJSE_Value_SetArray(args.GetReturnValue(), 3, rgValues);
+      for (int32_t i = 0; i < 3; i++) {
+        FXJSE_Value_Release(rgValues[i]);
+      }
+    } else if (FXJSE_Value_IsBoolean(argOne) ||
+               FXJSE_Value_IsUTF8String(argOne) ||
+               FXJSE_Value_IsNumber(argOne)) {
+      FXJSE_Value_Set(args.GetReturnValue(), argOne);
+    } else {
+      pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Ref");
+  }
+}
+void CXFA_FM2JSContext::UnitType(FXJSE_HOBJECT hThis,
+                                 const CFX_ByteStringC& szFuncName,
+                                 CFXJSE_Arguments& args) {
+  if (args.GetLength() == 1) {
+    FXJSE_HVALUE unitspanValue = GetSimpleHValue(hThis, args, 0);
+    if (FXJSE_Value_IsNull(unitspanValue)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+      FXJSE_Value_Release(unitspanValue);
+      return;
+    }
+    CFX_ByteString unitspanString;
+    HValueToUTF8String(unitspanValue, unitspanString);
+    if (unitspanString.IsEmpty()) {
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(), "in");
+    } else {
+      enum XFA_FM2JS_VALUETYPE_ParserStatus {
+        VALUETYPE_START,
+        VALUETYPE_HAVEINVALIDCHAR,
+        VALUETYPE_HAVEDIGIT,
+        VALUETYPE_HAVEDIGITWHITE,
+        VALUETYPE_ISCM,
+        VALUETYPE_ISMM,
+        VALUETYPE_ISPT,
+        VALUETYPE_ISMP,
+        VALUETYPE_ISIN,
+      };
+      unitspanString.MakeLower();
+      CFX_WideString wsTypeString =
+          CFX_WideString::FromUTF8(unitspanString, unitspanString.GetLength());
+      const FX_WCHAR* pData = wsTypeString;
+      int32_t u = 0;
+      int32_t uLen = wsTypeString.GetLength();
+      while (*(pData + u) == 0x20 || *(pData + u) == 0x09 ||
+             *(pData + u) == 0x0B || *(pData + u) == 0x0C ||
+             *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
+        u++;
+      }
+      XFA_FM2JS_VALUETYPE_ParserStatus eParserStatus = VALUETYPE_START;
+      FX_WCHAR typeChar;
+      while (u < uLen) {
+        typeChar = *(pData + u);
+        if (typeChar == 0x20 || typeChar == 0x09 || typeChar == 0x0B ||
+            typeChar == 0x0C || typeChar == 0x0A || typeChar == 0x0D) {
+          if (eParserStatus == VALUETYPE_HAVEDIGIT ||
+              eParserStatus == VALUETYPE_HAVEDIGITWHITE) {
+            eParserStatus = VALUETYPE_HAVEDIGITWHITE;
+          } else {
+            eParserStatus = VALUETYPE_ISIN;
+            break;
+          }
+        } else if ((typeChar >= '0' && typeChar <= '9') || typeChar == '-' ||
+                   typeChar == '.') {
+          if (eParserStatus == VALUETYPE_HAVEDIGITWHITE) {
+            eParserStatus = VALUETYPE_ISIN;
+            break;
+          } else {
+            eParserStatus = VALUETYPE_HAVEDIGIT;
+          }
+        } else if ((typeChar == 'c' || typeChar == 'p') && (u + 1 < uLen)) {
+          FX_WCHAR nextChar = *(pData + u + 1);
+          if ((eParserStatus == VALUETYPE_START ||
+               eParserStatus == VALUETYPE_HAVEDIGIT ||
+               eParserStatus == VALUETYPE_HAVEDIGITWHITE) &&
+              (nextChar > '9' || nextChar < '0') && nextChar != '.' &&
+              nextChar != '-') {
+            eParserStatus = (typeChar == 'c') ? VALUETYPE_ISCM : VALUETYPE_ISPT;
+            break;
+          } else {
+            eParserStatus = VALUETYPE_HAVEINVALIDCHAR;
+          }
+        } else if (typeChar == 'm' && (u + 1 < uLen)) {
+          FX_WCHAR nextChar = *(pData + u + 1);
+          if ((eParserStatus == VALUETYPE_START ||
+               eParserStatus == VALUETYPE_HAVEDIGIT ||
+               eParserStatus == VALUETYPE_HAVEDIGITWHITE) &&
+              (nextChar > '9' || nextChar < '0') && nextChar != '.' &&
+              nextChar != '-') {
+            eParserStatus = VALUETYPE_ISMM;
+            if (nextChar == 'p' ||
+                ((u + 5 < uLen) && *(pData + u + 1) == 'i' &&
+                 *(pData + u + 2) == 'l' && *(pData + u + 3) == 'l' &&
+                 *(pData + u + 4) == 'i' && *(pData + u + 5) == 'p')) {
+              eParserStatus = VALUETYPE_ISMP;
+            }
+            break;
+          }
+        } else {
+          eParserStatus = VALUETYPE_HAVEINVALIDCHAR;
+        }
+        u++;
+      }
+      switch (eParserStatus) {
+        case VALUETYPE_ISCM:
+          FXJSE_Value_SetUTF8String(args.GetReturnValue(), "cm");
+          break;
+        case VALUETYPE_ISMM:
+          FXJSE_Value_SetUTF8String(args.GetReturnValue(), "mm");
+          break;
+        case VALUETYPE_ISPT:
+          FXJSE_Value_SetUTF8String(args.GetReturnValue(), "pt");
+          break;
+        case VALUETYPE_ISMP:
+          FXJSE_Value_SetUTF8String(args.GetReturnValue(), "mp");
+          break;
+        default:
+          FXJSE_Value_SetUTF8String(args.GetReturnValue(), "in");
+          break;
+      }
+    }
+    FXJSE_Value_Release(unitspanValue);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"UnitType");
+  }
+}
+void CXFA_FM2JSContext::UnitValue(FXJSE_HOBJECT hThis,
+                                  const CFX_ByteStringC& szFuncName,
+                                  CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if ((argc == 1) || (argc == 2)) {
+    FXJSE_HVALUE unitspanValue = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE unitValue = 0;
+    CFX_ByteString unitspanString;
+    FX_DOUBLE dFirstNumber = 0;
+    CFX_ByteString strFirstUnit;
+    CFX_ByteString strUnit;
+    if (FXJSE_Value_IsNull(unitspanValue)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      HValueToUTF8String(unitspanValue, unitspanString);
+      const FX_CHAR* pData = unitspanString;
+      if (pData) {
+        int32_t u = 0;
+        while (*(pData + u) == 0x20 || *(pData + u) == 0x09 ||
+               *(pData + u) == 0x0B || *(pData + u) == 0x0C ||
+               *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
+          ++u;
+        }
+        while (u < unitspanString.GetLength()) {
+          if ((*(pData + u) > '9' || *(pData + u) < '0') &&
+              *(pData + u) != '.' && *(pData + u) != '-') {
+            break;
+          }
+          ++u;
+        }
+        FX_CHAR* pTemp = NULL;
+        dFirstNumber = strtod(pData, &pTemp);
+        while (*(pData + u) == ' ' || *(pData + u) == 0x09 ||
+               *(pData + u) == 0x0B || *(pData + u) == 0x0C ||
+               *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
+          ++u;
+        }
+        int32_t uLen = unitspanString.GetLength();
+        while (u < uLen) {
+          if (*(pData + u) == ' ') {
+            break;
+          }
+          strFirstUnit += (*(pData + u));
+          ++u;
+        }
+        strFirstUnit.MakeLower();
+        if (argc == 2) {
+          unitValue = GetSimpleHValue(hThis, args, 1);
+          CFX_ByteString unitTempString;
+          HValueToUTF8String(unitValue, unitTempString);
+          const FX_CHAR* pData = unitTempString;
+          int32_t u = 0;
+          while (*(pData + u) == ' ' || *(pData + u) == 0x09 ||
+                 *(pData + u) == 0x0B || *(pData + u) == 0x0C ||
+                 *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
+            ++u;
+          }
+          while (u < unitTempString.GetLength()) {
+            if ((*(pData + u) > '9' || *(pData + u) < '0') &&
+                *(pData + u) != '.') {
+              break;
+            }
+            ++u;
+          }
+          while (*(pData + u) == ' ' || *(pData + u) == 0x09 ||
+                 *(pData + u) == 0x0B || *(pData + u) == 0x0C ||
+                 *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
+            ++u;
+          }
+          int32_t uLen = unitTempString.GetLength();
+          while (u < uLen) {
+            if (*(pData + u) == ' ') {
+              break;
+            }
+            strUnit += (*(pData + u));
+            ++u;
+          }
+          strUnit.MakeLower();
+        } else {
+          strUnit = strFirstUnit;
+        }
+        FX_DOUBLE dResult = 0;
+        if (strFirstUnit.Equal("in") || strFirstUnit.Equal("inches")) {
+          if (strUnit.Equal("mm") || strUnit.Equal("millimeters")) {
+            dResult = dFirstNumber * 25.4;
+          } else if (strUnit.Equal("cm") || strUnit.Equal("centimeters")) {
+            dResult = dFirstNumber * 2.54;
+          } else if (strUnit.Equal("pt") || strUnit.Equal("points")) {
+            dResult = dFirstNumber / 72;
+          } else if (strUnit.Equal("mp") || strUnit.Equal("millipoints")) {
+            dResult = dFirstNumber / 72000;
+          } else {
+            dResult = dFirstNumber;
+          }
+        } else if (strFirstUnit.Equal("mm") ||
+                   strFirstUnit.Equal("millimeters")) {
+          if (strUnit.Equal("mm") || strUnit.Equal("millimeters")) {
+            dResult = dFirstNumber;
+          } else if (strUnit.Equal("cm") || strUnit.Equal("centimeters")) {
+            dResult = dFirstNumber / 10;
+          } else if (strUnit.Equal("pt") || strUnit.Equal("points")) {
+            dResult = dFirstNumber / 25.4 / 72;
+          } else if (strUnit.Equal("mp") || strUnit.Equal("millipoints")) {
+            dResult = dFirstNumber / 25.4 / 72000;
+          } else {
+            dResult = dFirstNumber / 25.4;
+          }
+        } else if (strFirstUnit.Equal("cm") ||
+                   strFirstUnit.Equal("centimeters")) {
+          if (strUnit.Equal("mm") || strUnit.Equal("millimeters")) {
+            dResult = dFirstNumber * 10;
+          } else if (strUnit.Equal("cm") || strUnit.Equal("centimeters")) {
+            dResult = dFirstNumber;
+          } else if (strUnit.Equal("pt") || strUnit.Equal("points")) {
+            dResult = dFirstNumber / 2.54 / 72;
+          } else if (strUnit.Equal("mp") || strUnit.Equal("millipoints")) {
+            dResult = dFirstNumber / 2.54 / 72000;
+          } else {
+            dResult = dFirstNumber / 2.54;
+          }
+        } else if (strFirstUnit.Equal("pt") || strFirstUnit.Equal("points")) {
+          if (strUnit.Equal("mm") || strUnit.Equal("millimeters")) {
+            dResult = dFirstNumber / 72 * 25.4;
+          } else if (strUnit.Equal("cm") || strUnit.Equal("centimeters")) {
+            dResult = dFirstNumber / 72 * 2.54;
+          } else if (strUnit.Equal("pt") || strUnit.Equal("points")) {
+            dResult = dFirstNumber;
+          } else if (strUnit.Equal("mp") || strUnit.Equal("millipoints")) {
+            dResult = dFirstNumber * 1000;
+          } else {
+            dResult = dFirstNumber / 72;
+          }
+        } else if (strFirstUnit.Equal("mp") ||
+                   strFirstUnit.Equal("millipoints")) {
+          if (strUnit.Equal("mm") || strUnit.Equal("millimeters")) {
+            dResult = dFirstNumber / 72000 * 25.4;
+          } else if (strUnit.Equal("cm") || strUnit.Equal("centimeters")) {
+            dResult = dFirstNumber / 72000 * 2.54;
+          } else if (strUnit.Equal("pt") || strUnit.Equal("points")) {
+            dResult = dFirstNumber / 1000;
+          } else if (strUnit.Equal("mp") || strUnit.Equal("millipoints")) {
+            dResult = dFirstNumber;
+          } else {
+            dResult = dFirstNumber / 72000;
+          }
+        }
+        FXJSE_Value_SetDouble(args.GetReturnValue(), dResult);
+      } else {
+        FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
+      }
+    }
+    FXJSE_Value_Release(unitspanValue);
+    if (argc == 2) {
+      FXJSE_Value_Release(unitValue);
+    }
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"UnitValue");
+  }
+}
+void CXFA_FM2JSContext::At(FXJSE_HOBJECT hThis,
+                           const CFX_ByteStringC& szFuncName,
+                           CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 2) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+    if (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      CFX_ByteString stringTwo;
+      HValueToUTF8String(argTwo, stringTwo);
+      if (stringTwo.IsEmpty()) {
+        FXJSE_Value_SetInteger(args.GetReturnValue(), 1);
+      } else {
+        CFX_ByteString stringOne;
+        HValueToUTF8String(argOne, stringOne);
+        FX_STRSIZE iPosition = stringOne.Find(stringTwo);
+        FXJSE_Value_SetInteger(args.GetReturnValue(), iPosition + 1);
+      }
+    }
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"At");
+  }
+}
+void CXFA_FM2JSContext::Concat(FXJSE_HOBJECT hThis,
+                               const CFX_ByteStringC& szFuncName,
+                               CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  int32_t argc = args.GetLength();
+  if (argc >= 1) {
+    CFX_ByteString resultString;
+    FX_BOOL bAllNull = TRUE;
+    FXJSE_HVALUE* argValues = FX_Alloc(FXJSE_HVALUE, argc);
+    for (int32_t i = 0; i < argc; i++) {
+      argValues[i] = GetSimpleHValue(hThis, args, i);
+      if (!HValueIsNull(hThis, argValues[i])) {
+        CFX_ByteString valueStr;
+        HValueToUTF8String(argValues[i], valueStr);
+        resultString += valueStr;
+        bAllNull = FALSE;
+      }
+    }
+    for (int32_t i = 0; i < argc; i++) {
+      FXJSE_Value_Release(argValues[i]);
+    }
+    FX_Free(argValues);
+    if (bAllNull) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultString);
+    }
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Concat");
+  }
+}
+void CXFA_FM2JSContext::Decode(FXJSE_HOBJECT hThis,
+                               const CFX_ByteStringC& szFuncName,
+                               CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  int32_t argc = args.GetLength();
+  if (argc == 1) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    if (HValueIsNull(hThis, argOne)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      CFX_ByteString toDecodeString;
+      HValueToUTF8String(argOne, toDecodeString);
+      CFX_ByteTextBuf resultBuf;
+      DecodeURL(toDecodeString, resultBuf);
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(),
+                                resultBuf.GetByteString());
+    }
+    FXJSE_Value_Release(argOne);
+  } else if (argc == 2) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+    if (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      CFX_ByteString toDecodeString;
+      HValueToUTF8String(argOne, toDecodeString);
+      CFX_ByteString identifyString;
+      HValueToUTF8String(argTwo, identifyString);
+      CFX_ByteTextBuf resultBuf;
+      if (identifyString.EqualNoCase("html")) {
+        DecodeHTML(toDecodeString, resultBuf);
+      } else if (identifyString.EqualNoCase("xml")) {
+        DecodeXML(toDecodeString, resultBuf);
+      } else {
+        DecodeURL(toDecodeString, resultBuf);
+      }
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(),
+                                resultBuf.GetByteString());
+    }
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Decode");
+  }
+}
+void CXFA_FM2JSContext::DecodeURL(const CFX_ByteStringC& szURLString,
+                                  CFX_ByteTextBuf& szResultString) {
+  CFX_WideString wsURLString =
+      CFX_WideString::FromUTF8(szURLString.GetCStr(), szURLString.GetLength());
+  const FX_WCHAR* pData = wsURLString;
+  int32_t iLen = wsURLString.GetLength();
+  int32_t i = 0;
+  FX_WCHAR ch = 0;
+  FX_WCHAR chTemp = 0;
+  CFX_WideTextBuf wsResultBuf;
+  while (i < iLen) {
+    ch = *(pData + i);
+    if ('%' == ch) {
+      chTemp = 0;
+      int32_t iCount = 0;
+      while (iCount < 2) {
+        ++i;
+        ch = *(pData + i);
+        if (ch <= '9' && ch >= '0') {
+          if (!iCount) {
+            chTemp += (ch - '0') * 16;
+          } else {
+            chTemp += (ch - '0');
+          }
+        } else {
+          if (ch <= 'F' && ch >= 'A') {
+            if (!iCount) {
+              chTemp += (ch - 'A' + 10) * 16;
+            } else {
+              chTemp += (ch - 'A' + 10);
+            }
+          } else if (ch <= 'f' && ch >= 'a') {
+            if (!iCount) {
+              chTemp += (ch - 'a' + 10) * 16;
+            } else {
+              chTemp += (ch - 'a' + 10);
+            }
+          } else {
+            wsResultBuf.Clear();
+            return;
+          }
+        }
+        ++iCount;
+      }
+      wsResultBuf.AppendChar(chTemp);
+    } else {
+      wsResultBuf.AppendChar(ch);
+    }
+    ++i;
+  }
+  wsResultBuf.AppendChar(0);
+  szResultString.Clear();
+  szResultString << FX_UTF8Encode(wsResultBuf.GetBuffer(),
+                                  wsResultBuf.GetLength());
+}
+void CXFA_FM2JSContext::DecodeHTML(const CFX_ByteStringC& szHTMLString,
+                                   CFX_ByteTextBuf& szResultString) {
+  CFX_WideString wsHTMLString = CFX_WideString::FromUTF8(
+      szHTMLString.GetCStr(), szHTMLString.GetLength());
+  FX_WCHAR strString[9];
+  int32_t iStrIndex = 0;
+  int32_t iLen = wsHTMLString.GetLength();
+  int32_t i = 0;
+  int32_t iCode = 0;
+  FX_WCHAR ch = 0;
+  const FX_WCHAR* pData = wsHTMLString;
+  CFX_WideTextBuf wsResultBuf;
+  while (i < iLen) {
+    ch = *(pData + i);
+    if (ch == '&') {
+      ++i;
+      ch = *(pData + i);
+      if (ch == '#') {
+        ++i;
+        ch = *(pData + i);
+        if (ch == 'x' || ch == 'X') {
+          ++i;
+          ch = *(pData + i);
+          if ((ch >= '0' && ch <= '9') || (ch <= 'f' && ch >= 'a') ||
+              (ch <= 'F' && ch >= 'A')) {
+            while (ch != ';' && i < iLen) {
+              if (ch >= '0' && ch <= '9') {
+                iCode += ch - '0';
+              } else if (ch <= 'f' && ch >= 'a') {
+                iCode += ch - 'a' + 10;
+              } else if (ch <= 'F' && ch >= 'A') {
+                iCode += ch - 'A' + 10;
+              } else {
+                wsResultBuf.Clear();
+                return;
+              }
+              ++i;
+              iCode *= 16;
+              ch = *(pData + i);
+            }
+            iCode /= 16;
+          }
+        } else {
+          wsResultBuf.Clear();
+          return;
+        }
+      } else {
+        while (ch != ';' && i < iLen) {
+          strString[iStrIndex++] = ch;
+          ++i;
+          ch = *(pData + i);
+        }
+        strString[iStrIndex] = 0;
+      }
+    } else {
+      wsResultBuf.AppendChar(ch);
+      ++i;
+      continue;
+    }
+    uint32_t iData = 0;
+    if (HTMLSTR2Code(strString, iData)) {
+      wsResultBuf.AppendChar((FX_WCHAR)iData);
+    } else {
+      wsResultBuf.AppendChar(iCode);
+    }
+    iStrIndex = 0;
+    strString[iStrIndex] = 0;
+    ++i;
+  }
+  wsResultBuf.AppendChar(0);
+  szResultString.Clear();
+  szResultString << FX_UTF8Encode(wsResultBuf.GetBuffer(),
+                                  wsResultBuf.GetLength());
+}
+void CXFA_FM2JSContext::DecodeXML(const CFX_ByteStringC& szXMLString,
+                                  CFX_ByteTextBuf& szResultString) {
+  CFX_WideString wsXMLString =
+      CFX_WideString::FromUTF8(szXMLString.GetCStr(), szXMLString.GetLength());
+  FX_WCHAR strString[9];
+  int32_t iStrIndex = 0;
+  int32_t iLen = wsXMLString.GetLength();
+  int32_t i = 0;
+  int32_t iCode = 0;
+  FX_WCHAR ch = 0;
+  const FX_WCHAR* pData = wsXMLString;
+  CFX_WideTextBuf wsXMLBuf;
+  while (i < iLen) {
+    ch = *(pData + i);
+    if (ch == '&') {
+      ++i;
+      ch = *(pData + i);
+      if (ch == '#') {
+        ++i;
+        ch = *(pData + i);
+        if (ch == 'x' || ch == 'X') {
+          ++i;
+          ch = *(pData + i);
+          if ((ch >= '0' && ch <= '9') || (ch <= 'f' && ch >= 'a') ||
+              (ch <= 'F' && ch >= 'A')) {
+            while (ch != ';') {
+              if (ch >= '0' && ch <= '9') {
+                iCode += ch - '0';
+              } else if (ch <= 'f' && ch >= 'a') {
+                iCode += ch - 'a' + 10;
+              } else if (ch <= 'F' && ch >= 'A') {
+                iCode += ch - 'A' + 10;
+              } else {
+                wsXMLBuf.Clear();
+                return;
+              }
+              ++i;
+              iCode *= 16;
+              ch = *(pData + i);
+            }
+            iCode /= 16;
+          }
+        } else {
+          wsXMLBuf.Clear();
+          return;
+        }
+      } else {
+        while (ch != ';' && i < iLen) {
+          strString[iStrIndex++] = ch;
+          ++i;
+          ch = *(pData + i);
+        }
+        strString[iStrIndex] = 0;
+      }
+    } else {
+      wsXMLBuf.AppendChar(ch);
+      ++i;
+      continue;
+    }
+    const FX_WCHAR* const strName[] = {L"quot", L"amp", L"apos", L"lt", L"gt"};
+    int32_t iIndex = 0;
+    while (iIndex < 5) {
+      if (FXSYS_memcmp(strString, strName[iIndex],
+                       FXSYS_wcslen(strName[iIndex])) == 0) {
+        break;
+      }
+      ++iIndex;
+    }
+    switch (iIndex) {
+      case 0:
+        wsXMLBuf.AppendChar('"');
+        break;
+      case 1:
+        wsXMLBuf.AppendChar('&');
+        break;
+      case 2:
+        wsXMLBuf.AppendChar('\'');
+        break;
+      case 3:
+        wsXMLBuf.AppendChar('<');
+        break;
+      case 4:
+        wsXMLBuf.AppendChar('>');
+        break;
+      default:
+        wsXMLBuf.AppendChar(iCode);
+        break;
+    }
+    iStrIndex = 0;
+    strString[iStrIndex] = 0;
+    ++i;
+    iCode = 0;
+  }
+  wsXMLBuf.AppendChar(0);
+  szResultString.Clear();
+  szResultString << FX_UTF8Encode(wsXMLBuf.GetBuffer(), wsXMLBuf.GetLength());
+}
+void CXFA_FM2JSContext::Encode(FXJSE_HOBJECT hThis,
+                               const CFX_ByteStringC& szFuncName,
+                               CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  int32_t argc = args.GetLength();
+  if (argc == 1) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    if (HValueIsNull(hThis, argOne)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      CFX_ByteString toEncodeString;
+      HValueToUTF8String(argOne, toEncodeString);
+      CFX_ByteTextBuf resultBuf;
+      EncodeURL(toEncodeString, resultBuf);
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(),
+                                resultBuf.GetByteString());
+    }
+    FXJSE_Value_Release(argOne);
+  } else if (argc == 2) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+    if (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      CFX_ByteString toEncodeString;
+      HValueToUTF8String(argOne, toEncodeString);
+      CFX_ByteString identifyString;
+      HValueToUTF8String(argTwo, identifyString);
+      CFX_ByteTextBuf resultBuf;
+      if (identifyString.EqualNoCase("html")) {
+        EncodeHTML(toEncodeString, resultBuf);
+      } else if (identifyString.EqualNoCase("xml")) {
+        EncodeXML(toEncodeString, resultBuf);
+      } else {
+        EncodeURL(toEncodeString, resultBuf);
+      }
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(),
+                                resultBuf.GetByteString());
+    }
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Encode");
+  }
+}
+void CXFA_FM2JSContext::EncodeURL(const CFX_ByteStringC& szURLString,
+                                  CFX_ByteTextBuf& szResultBuf) {
+  CFX_WideString wsURLString =
+      CFX_WideString::FromUTF8(szURLString.GetCStr(), szURLString.GetLength());
+  CFX_WideTextBuf wsResultBuf;
+  FX_WCHAR ch = 0;
+  int32_t iLength = wsURLString.GetLength();
+  FX_WCHAR strEncode[4];
+  strEncode[0] = '%';
+  strEncode[3] = 0;
+  FX_WCHAR strUnsafe[] = {' ', '<',  '>', '"', '#', '%', '{', '}',
+                          '|', '\\', '^', '~', '[', ']', '`'};
+  FX_WCHAR strReserved[] = {';', '/', '?', ':', '@', '=', '&'};
+  FX_WCHAR strSpecial[] = {'$', '-', '+', '!', '*', '\'', '(', ')', ','};
+  const FX_WCHAR* strCode = L"0123456789abcdef";
+  for (int32_t u = 0; u < iLength; ++u) {
+    ch = wsURLString.GetAt(u);
+    int32_t i = 0;
+    int32_t iCount = sizeof(strUnsafe) / sizeof(strUnsafe[0]);
+    while (i < iCount) {
+      if (ch == strUnsafe[i]) {
+        int32_t iIndex = ch / 16;
+        strEncode[1] = strCode[iIndex];
+        strEncode[2] = strCode[ch - iIndex * 16];
+        wsResultBuf << FX_WSTRC(strEncode);
+        break;
+      }
+      ++i;
+    }
+    if (i < iCount) {
+      continue;
+    }
+    i = 0;
+    iCount = sizeof(strReserved) / sizeof(strReserved[0]);
+    while (i < iCount) {
+      if (ch == strReserved[i]) {
+        int32_t iIndex = ch / 16;
+        strEncode[1] = strCode[iIndex];
+        strEncode[2] = strCode[ch - iIndex * 16];
+        wsResultBuf << FX_WSTRC(strEncode);
+        break;
+      }
+      ++i;
+    }
+    if (i < iCount) {
+      continue;
+    }
+    i = 0;
+    iCount = sizeof(strSpecial) / sizeof(strSpecial[0]);
+    while (i < iCount) {
+      if (ch == strSpecial[i]) {
+        wsResultBuf.AppendChar(ch);
+        break;
+      }
+      ++i;
+    }
+    if (i < iCount) {
+      continue;
+    }
+    if (ch >= 0x80 && ch <= 0xff) {
+      int32_t iIndex = ch / 16;
+      strEncode[1] = strCode[iIndex];
+      strEncode[2] = strCode[ch - iIndex * 16];
+      wsResultBuf << FX_WSTRC(strEncode);
+    } else if (ch <= 0x1f || ch == 0x7f) {
+      int32_t iIndex = ch / 16;
+      strEncode[1] = strCode[iIndex];
+      strEncode[2] = strCode[ch - iIndex * 16];
+      wsResultBuf << FX_WSTRC(strEncode);
+    } else if (ch >= 0x20 && ch <= 0x7e) {
+      wsResultBuf.AppendChar(ch);
+    } else {
+      int32_t iRadix = 16;
+      CFX_WideString strTmp;
+      while (ch >= iRadix) {
+        FX_WCHAR tmp = strCode[ch % iRadix];
+        ch /= iRadix;
+        strTmp += tmp;
+      }
+      strTmp += strCode[ch];
+      int32_t iLen = strTmp.GetLength();
+      if (iLen < 2) {
+        break;
+      }
+      int32_t iIndex = 0;
+      if (iLen % 2 != 0) {
+        strEncode[1] = '0';
+        strEncode[2] = strTmp.GetAt(iLen - 1);
+        iIndex = iLen - 2;
+      } else {
+        strEncode[1] = strTmp.GetAt(iLen - 1);
+        strEncode[2] = strTmp.GetAt(iLen - 2);
+        iIndex = iLen - 3;
+      }
+      wsResultBuf << FX_WSTRC(strEncode);
+      while (iIndex > 0) {
+        strEncode[1] = strTmp.GetAt(iIndex);
+        strEncode[2] = strTmp.GetAt(iIndex - 1);
+        iIndex -= 2;
+        wsResultBuf << FX_WSTRC(strEncode);
+      }
+    }
+  }
+  wsResultBuf.AppendChar(0);
+  szResultBuf.Clear();
+  szResultBuf << FX_UTF8Encode(wsResultBuf.GetBuffer(),
+                               wsResultBuf.GetLength());
+}
+void CXFA_FM2JSContext::EncodeHTML(const CFX_ByteStringC& szHTMLString,
+                                   CFX_ByteTextBuf& szResultBuf) {
+  CFX_ByteString str = szHTMLString.GetCStr();
+  CFX_WideString wsHTMLString = CFX_WideString::FromUTF8(str, str.GetLength());
+  const FX_WCHAR* strCode = L"0123456789abcdef";
+  FX_WCHAR strEncode[9];
+  strEncode[0] = '&';
+  strEncode[1] = '#';
+  strEncode[2] = 'x';
+  strEncode[5] = ';';
+  strEncode[6] = 0;
+  strEncode[7] = ';';
+  strEncode[8] = 0;
+  CFX_WideTextBuf wsResultBuf;
+  uint32_t ch = 0;
+  int32_t iLen = wsHTMLString.GetLength();
+  int32_t i = 0;
+  const FX_WCHAR* pData = wsHTMLString;
+  int32_t iIndex = 0;
+  CFX_WideString htmlReserve;
+  while (i < iLen) {
+    ch = *(pData + i);
+    htmlReserve.Empty();
+    if (HTMLCode2STR(ch, htmlReserve)) {
+      wsResultBuf.AppendChar(L'&');
+      wsResultBuf << htmlReserve;
+      wsResultBuf.AppendChar(L';');
+    } else {
+      if (ch >= 32 && ch <= 126) {
+        wsResultBuf.AppendChar((FX_WCHAR)ch);
+      } else if (ch < 256) {
+        iIndex = ch / 16;
+        strEncode[3] = strCode[iIndex];
+        strEncode[4] = strCode[ch - iIndex * 16];
+        strEncode[5] = ';';
+        strEncode[6] = 0;
+        wsResultBuf << FX_WSTRC(strEncode);
+      } else {
+        int32_t iBigByte = ch / 256;
+        int32_t iLittleByte = ch % 256;
+        strEncode[3] = strCode[iBigByte / 16];
+        strEncode[4] = strCode[iBigByte % 16];
+        strEncode[5] = strCode[iLittleByte / 16];
+        strEncode[6] = strCode[iLittleByte % 16];
+        wsResultBuf << FX_WSTRC(strEncode);
+      }
+    }
+    ++i;
+  }
+  wsResultBuf.AppendChar(0);
+  szResultBuf.Clear();
+  szResultBuf << FX_UTF8Encode(wsResultBuf.GetBuffer(),
+                               wsResultBuf.GetLength());
+}
+void CXFA_FM2JSContext::EncodeXML(const CFX_ByteStringC& szXMLString,
+                                  CFX_ByteTextBuf& szResultBuf) {
+  CFX_WideString wsXMLString =
+      CFX_WideString::FromUTF8(szXMLString.GetCStr(), szXMLString.GetLength());
+  CFX_WideTextBuf wsResultBuf;
+  enum {
+    QUOT,
+    AMP,
+    APOS,
+    LT,
+    GT,
+  };
+  FX_WCHAR strEncode[9];
+  strEncode[0] = '&';
+  strEncode[1] = '#';
+  strEncode[2] = 'x';
+  strEncode[5] = ';';
+  strEncode[6] = 0;
+  strEncode[7] = ';';
+  strEncode[8] = 0;
+  const FX_WCHAR* const strName[] = {L"quot", L"amp", L"apos", L"lt", L"gt"};
+  const FX_WCHAR* strCode = L"0123456789abcdef";
+  FX_WCHAR ch = 0;
+  int32_t iLength = wsXMLString.GetLength();
+  int32_t iIndex = 0;
+  int32_t u = 0;
+  const FX_WCHAR* pData = wsXMLString;
+  for (u = 0; u < iLength; ++u) {
+    ch = *(pData + u);
+    switch (ch) {
+      case '"':
+        wsResultBuf.AppendChar('&');
+        wsResultBuf << CFX_WideStringC(strName[QUOT]);
+        wsResultBuf.AppendChar(';');
+        break;
+      case '&':
+        wsResultBuf.AppendChar('&');
+        wsResultBuf << CFX_WideStringC(strName[AMP]);
+        wsResultBuf.AppendChar(';');
+        break;
+      case '\'':
+        wsResultBuf.AppendChar('&');
+        wsResultBuf << CFX_WideStringC(strName[APOS]);
+        wsResultBuf.AppendChar(';');
+        break;
+      case '<':
+        wsResultBuf.AppendChar('&');
+        wsResultBuf << CFX_WideStringC(strName[LT]);
+        wsResultBuf.AppendChar(';');
+        break;
+      case '>':
+        wsResultBuf.AppendChar('&');
+        wsResultBuf << CFX_WideStringC(strName[GT]);
+        wsResultBuf.AppendChar(';');
+        break;
+      default: {
+        if (ch >= 32 && ch <= 126) {
+          wsResultBuf.AppendChar(ch);
+        } else if (ch < 256) {
+          iIndex = ch / 16;
+          strEncode[3] = strCode[iIndex];
+          strEncode[4] = strCode[ch - iIndex * 16];
+          strEncode[5] = ';';
+          strEncode[6] = 0;
+          wsResultBuf << FX_WSTRC(strEncode);
+        } else {
+          int32_t iBigByte = ch / 256;
+          int32_t iLittleByte = ch % 256;
+          strEncode[3] = strCode[iBigByte / 16];
+          strEncode[4] = strCode[iBigByte % 16];
+          strEncode[5] = strCode[iLittleByte / 16];
+          strEncode[6] = strCode[iLittleByte % 16];
+          wsResultBuf << FX_WSTRC(strEncode);
+        }
+      } break;
+    }
+  }
+  wsResultBuf.AppendChar(0);
+  szResultBuf.Clear();
+  szResultBuf << FX_UTF8Encode(wsResultBuf.GetBuffer(),
+                               wsResultBuf.GetLength());
+}
+FX_BOOL CXFA_FM2JSContext::HTMLSTR2Code(const CFX_WideStringC& pData,
+                                        uint32_t& iCode) {
+  int32_t iLength = pData.GetLength();
+  uint32_t uHash = FX_HashCode_String_GetW(pData.GetPtr(), iLength);
+  XFA_FMHtmlHashedReserveCode htmlhashedreservecode;
+  int32_t iStart = 0,
+          iEnd = (sizeof(reservesForDecode) / sizeof(reservesForDecode[0])) - 1;
+  int32_t iMid = (iStart + iEnd) / 2;
+  do {
+    iMid = (iStart + iEnd) / 2;
+    htmlhashedreservecode = reservesForDecode[iMid];
+    if (uHash == htmlhashedreservecode.m_uHash) {
+      iCode = htmlhashedreservecode.m_uCode;
+      return TRUE;
+    } else if (uHash < htmlhashedreservecode.m_uHash) {
+      iEnd = iMid - 1;
+    } else {
+      iStart = iMid + 1;
+    }
+  } while (iStart <= iEnd);
+  return FALSE;
+}
+FX_BOOL CXFA_FM2JSContext::HTMLCode2STR(uint32_t iCode,
+                                        CFX_WideString& wsHTMLReserve) {
+  XFA_FMHtmlReserveCode htmlreservecode;
+  int32_t iStart = 0,
+          iEnd = (sizeof(reservesForEncode) / sizeof(reservesForEncode[0])) - 1;
+  int32_t iMid = (iStart + iEnd) / 2;
+  do {
+    iMid = (iStart + iEnd) / 2;
+    htmlreservecode = reservesForEncode[iMid];
+    if (iCode == htmlreservecode.m_uCode) {
+      wsHTMLReserve = htmlreservecode.m_htmlReserve;
+      return TRUE;
+    } else if (iCode < htmlreservecode.m_uCode) {
+      iEnd = iMid - 1;
+    } else {
+      iStart = iMid + 1;
+    }
+  } while (iStart <= iEnd);
+  return FALSE;
+}
+static FX_BOOL XFA_PATTERN_STRING_Type(const CFX_ByteStringC& szPattern,
+                                       FX_DWORD& patternType) {
+  CFX_WideString wsPattern =
+      CFX_WideString::FromUTF8(szPattern.GetCStr(), szPattern.GetLength());
+  if (FX_WSTRC(L"datetime") == wsPattern.Left(8)) {
+    patternType = XFA_VT_DATETIME;
+    return TRUE;
+  } else if (FX_WSTRC(L"date") == wsPattern.Left(4)) {
+    patternType = wsPattern.Find(L"time") > 0 ? XFA_VT_DATETIME : XFA_VT_DATE;
+    return TRUE;
+  } else if (FX_WSTRC(L"time") == wsPattern.Left(4)) {
+    patternType = XFA_VT_TIME;
+    return TRUE;
+  } else if (FX_WSTRC(L"text") == wsPattern.Left(4)) {
+    patternType = XFA_VT_TEXT;
+    return TRUE;
+  } else if (FX_WSTRC(L"num") == wsPattern.Left(3)) {
+    if (FX_WSTRC(L"integer") == wsPattern.Mid(4, 7)) {
+      patternType = XFA_VT_INTEGER;
+    } else if (FX_WSTRC(L"decimal") == wsPattern.Mid(4, 7)) {
+      patternType = XFA_VT_DECIMAL;
+    } else if (FX_WSTRC(L"currency") == wsPattern.Mid(4, 8)) {
+      patternType = XFA_VT_FLOAT;
+    } else if (FX_WSTRC(L"percent") == wsPattern.Mid(4, 7)) {
+      patternType = XFA_VT_FLOAT;
+    } else {
+      patternType = XFA_VT_FLOAT;
+    }
+    return TRUE;
+  }
+  patternType = XFA_VT_NULL;
+  wsPattern.MakeLower();
+  const FX_WCHAR* pData = wsPattern;
+  int32_t iLength = wsPattern.GetLength();
+  int32_t iIndex = 0;
+  FX_BOOL bSingleQuotation = FALSE;
+  FX_WCHAR patternChar;
+  while (iIndex < iLength) {
+    patternChar = *(pData + iIndex);
+    if (patternChar == 0x27) {
+      bSingleQuotation = !bSingleQuotation;
+    } else if (!bSingleQuotation &&
+               (patternChar == 'y' || patternChar == 'j')) {
+      patternType = XFA_VT_DATE;
+      iIndex++;
+      FX_WCHAR timePatternChar;
+      while (iIndex < iLength) {
+        timePatternChar = *(pData + iIndex);
+        if (timePatternChar == 0x27) {
+          bSingleQuotation = !bSingleQuotation;
+        } else if (!bSingleQuotation && timePatternChar == 't') {
+          patternType = XFA_VT_DATETIME;
+          break;
+        }
+        iIndex++;
+      }
+      break;
+    } else if (!bSingleQuotation &&
+               (patternChar == 'h' || patternChar == 'k')) {
+      patternType = XFA_VT_TIME;
+      break;
+    } else if (!bSingleQuotation &&
+               (patternChar == 'a' || patternChar == 'x' ||
+                patternChar == 'o' || patternChar == '0')) {
+      patternType = XFA_VT_TEXT;
+      if (patternChar == 'x' || patternChar == 'o' || patternChar == '0') {
+        break;
+      }
+    } else if (!bSingleQuotation &&
+               (patternChar == 'z' || patternChar == 's' ||
+                patternChar == 'e' || patternChar == 'v' ||
+                patternChar == '8' || patternChar == ',' ||
+                patternChar == '.' || patternChar == '$')) {
+      patternType = XFA_VT_FLOAT;
+      if (patternChar == 'v' || patternChar == '8' || patternChar == '$') {
+        break;
+      }
+    }
+    iIndex++;
+  }
+  if (patternType == XFA_VT_NULL) {
+    patternType = XFA_VT_TEXT | XFA_VT_FLOAT;
+  }
+  return FALSE;
+}
+void CXFA_FM2JSContext::Format(FXJSE_HOBJECT hThis,
+                               const CFX_ByteStringC& szFuncName,
+                               CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  int32_t argc = args.GetLength();
+  if (argc >= 2) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+    CFX_ByteString szPattern;
+    HValueToUTF8String(argOne, szPattern);
+    CFX_ByteString szValue;
+    HValueToUTF8String(argTwo, szValue);
+    CXFA_Document* pDoc = pContext->GetDocument();
+    IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
+    CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
+    FXSYS_assert(pThisNode);
+    CXFA_WidgetData widgetData(pThisNode);
+    IFX_Locale* pLocale = widgetData.GetLocal();
+    FX_DWORD patternType;
+    FX_BOOL bCompelte = XFA_PATTERN_STRING_Type(szPattern, patternType);
+    CFX_WideString wsPattern =
+        CFX_WideString::FromUTF8(szPattern, szPattern.GetLength());
+    CFX_WideString wsValue =
+        CFX_WideString::FromUTF8(szValue, szValue.GetLength());
+    if (!bCompelte) {
+      switch (patternType) {
+        case XFA_VT_DATETIME: {
+          FX_STRSIZE iTChar = wsPattern.Find(L'T');
+          CFX_WideString wsDatePattern = FX_WSTRC(L"date{");
+          wsDatePattern += wsPattern.Left(iTChar);
+          wsDatePattern += FX_WSTRC(L"} ");
+          CFX_WideString wsTimePattern = FX_WSTRC(L"time{");
+          wsTimePattern += wsPattern.Mid(iTChar + 1);
+          wsTimePattern += FX_WSTRC(L"}");
+          wsPattern = wsDatePattern + wsTimePattern;
+        } break;
+        case XFA_VT_DATE: {
+          wsPattern = FX_WSTRC(L"date{") + wsPattern;
+          wsPattern += FX_WSTRC(L"}");
+        } break;
+        case XFA_VT_TIME: {
+          wsPattern = FX_WSTRC(L"time{") + wsPattern;
+          wsPattern += FX_WSTRC(L"}");
+        } break;
+        case XFA_VT_TEXT: {
+          wsPattern = FX_WSTRC(L"text{") + wsPattern;
+          wsPattern += FX_WSTRC(L"}");
+        } break;
+        case XFA_VT_FLOAT: {
+          wsPattern = FX_WSTRC(L"num{") + wsPattern;
+          wsPattern += FX_WSTRC(L"}");
+        } break;
+        default: {
+          CFX_WideString wsTestPattern;
+          wsTestPattern = FX_WSTRC(L"num{") + wsPattern;
+          wsTestPattern += FX_WSTRC(L"}");
+          CXFA_LocaleValue tempLocaleValue(XFA_VT_FLOAT, wsValue, wsTestPattern,
+                                           pLocale, (CXFA_LocaleMgr*)pMgr);
+          if (tempLocaleValue.IsValid()) {
+            wsPattern = wsTestPattern;
+            patternType = XFA_VT_FLOAT;
+          } else {
+            wsTestPattern = FX_WSTRC(L"text{") + wsPattern;
+            wsTestPattern += FX_WSTRC(L"}");
+            wsPattern = wsTestPattern;
+            patternType = XFA_VT_TEXT;
+          }
+        } break;
+      }
+    }
+    CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern, pLocale,
+                                 (CXFA_LocaleMgr*)pMgr);
+    CFX_WideString wsRet;
+    if (localeValue.FormatPatterns(wsRet, wsPattern, pLocale,
+                                   XFA_VALUEPICTURE_Display)) {
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(),
+                                FX_UTF8Encode(wsRet, wsRet.GetLength()));
+    } else {
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
+    }
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Format");
+  }
+}
+void CXFA_FM2JSContext::Left(FXJSE_HOBJECT hThis,
+                             const CFX_ByteStringC& szFuncName,
+                             CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 2) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+    FX_BOOL argIsNull = FALSE;
+    if ((HValueIsNull(hThis, argOne)) || (HValueIsNull(hThis, argTwo))) {
+      argIsNull = TRUE;
+    }
+    if (argIsNull) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      CFX_ByteString sourceString;
+      HValueToUTF8String(argOne, sourceString);
+      int32_t count = HValueToInteger(hThis, argTwo);
+      if (count < 0) {
+        count = 0;
+      }
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(),
+                                sourceString.Left(count));
+    }
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Left");
+  }
+}
+void CXFA_FM2JSContext::Len(FXJSE_HOBJECT hThis,
+                            const CFX_ByteStringC& szFuncName,
+                            CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 1) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    if (HValueIsNull(hThis, argOne)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      CFX_ByteString sourceString;
+      HValueToUTF8String(argOne, sourceString);
+      FXJSE_Value_SetInteger(args.GetReturnValue(), sourceString.GetLength());
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Len");
+  }
+}
+void CXFA_FM2JSContext::Lower(FXJSE_HOBJECT hThis,
+                              const CFX_ByteStringC& szFuncName,
+                              CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if ((argc > 0) && (argc < 3)) {
+    CFX_ByteString argString;
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE localeValue = 0;
+    if (HValueIsNull(hThis, argOne)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      if (argc == 2) {
+        localeValue = GetSimpleHValue(hThis, args, 1);
+      }
+      HValueToUTF8String(argOne, argString);
+      CFX_WideTextBuf lowStringBuf;
+      CFX_WideString wsArgString =
+          CFX_WideString::FromUTF8(argString, argString.GetLength());
+      const FX_WCHAR* pData = wsArgString;
+      int32_t iLen = argString.GetLength();
+      int32_t i = 0;
+      int32_t ch = 0;
+      while (i < iLen) {
+        ch = *(pData + i);
+        if (ch >= 0x41 && ch <= 0x5A) {
+          ch += 32;
+        } else if (ch >= 0xC0 && ch <= 0xDE) {
+          ch += 32;
+        } else if (ch == 0x100 || ch == 0x102 || ch == 0x104) {
+          ch += 1;
+        }
+        lowStringBuf.AppendChar(ch);
+        ++i;
+      }
+      lowStringBuf.AppendChar(0);
+      FXJSE_Value_SetUTF8String(
+          args.GetReturnValue(),
+          FX_UTF8Encode(lowStringBuf.GetBuffer(), lowStringBuf.GetLength()));
+      if (argc == 2) {
+        FXJSE_Value_Release(localeValue);
+      }
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Lower");
+  }
+}
+void CXFA_FM2JSContext::Ltrim(FXJSE_HOBJECT hThis,
+                              const CFX_ByteStringC& szFuncName,
+                              CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 1) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    if (HValueIsNull(hThis, argOne)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      CFX_ByteString sourceString;
+      HValueToUTF8String(argOne, sourceString);
+      sourceString.TrimLeft();
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(), sourceString);
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Ltrim");
+  }
+}
+void CXFA_FM2JSContext::Parse(FXJSE_HOBJECT hThis,
+                              const CFX_ByteStringC& szFuncName,
+                              CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 2) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+    if (HValueIsNull(hThis, argTwo)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      CFX_ByteString szPattern;
+      HValueToUTF8String(argOne, szPattern);
+      CFX_ByteString szValue;
+      HValueToUTF8String(argTwo, szValue);
+      CXFA_Document* pDoc = pContext->GetDocument();
+      IFX_LocaleMgr* pMgr = (IFX_LocaleMgr*)pDoc->GetLocalMgr();
+      CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
+      FXSYS_assert(pThisNode);
+      CXFA_WidgetData widgetData(pThisNode);
+      IFX_Locale* pLocale = widgetData.GetLocal();
+      FX_DWORD patternType;
+      FX_BOOL bCompletePattern =
+          XFA_PATTERN_STRING_Type(szPattern, patternType);
+      CFX_WideString wsPattern =
+          CFX_WideString::FromUTF8(szPattern, szPattern.GetLength());
+      CFX_WideString wsValue =
+          CFX_WideString::FromUTF8(szValue, szValue.GetLength());
+      CFX_ByteString szParsedValue;
+      if (bCompletePattern) {
+        CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern, pLocale,
+                                     (CXFA_LocaleMgr*)pMgr);
+        if (localeValue.IsValid()) {
+          szParsedValue = FX_UTF8Encode(localeValue.GetValue());
+          FXJSE_Value_SetUTF8String(args.GetReturnValue(), szParsedValue);
+        } else {
+          FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
+        }
+      } else {
+        switch (patternType) {
+          case XFA_VT_DATETIME: {
+            FX_STRSIZE iTChar = wsPattern.Find(L'T');
+            CFX_WideString wsDatePattern = FX_WSTRC(L"date{");
+            wsDatePattern += wsPattern.Left(iTChar);
+            wsDatePattern += FX_WSTRC(L"} ");
+            CFX_WideString wsTimePattern = FX_WSTRC(L"time{");
+            wsTimePattern += wsPattern.Mid(iTChar + 1);
+            wsTimePattern += FX_WSTRC(L"}");
+            wsPattern = wsDatePattern + wsTimePattern;
+            CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern,
+                                         pLocale, (CXFA_LocaleMgr*)pMgr);
+            if (localeValue.IsValid()) {
+              szParsedValue = FX_UTF8Encode(localeValue.GetValue());
+              FXJSE_Value_SetUTF8String(args.GetReturnValue(), szParsedValue);
+            } else {
+              FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
+            }
+          } break;
+          case XFA_VT_DATE: {
+            wsPattern = FX_WSTRC(L"date{") + wsPattern;
+            wsPattern += FX_WSTRC(L"}");
+            CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern,
+                                         pLocale, (CXFA_LocaleMgr*)pMgr);
+            if (localeValue.IsValid()) {
+              szParsedValue = FX_UTF8Encode(localeValue.GetValue());
+              FXJSE_Value_SetUTF8String(args.GetReturnValue(), szParsedValue);
+            } else {
+              FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
+            }
+          } break;
+          case XFA_VT_TIME: {
+            wsPattern = FX_WSTRC(L"time{") + wsPattern;
+            wsPattern += FX_WSTRC(L"}");
+            CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern,
+                                         pLocale, (CXFA_LocaleMgr*)pMgr);
+            if (localeValue.IsValid()) {
+              szParsedValue = FX_UTF8Encode(localeValue.GetValue());
+              FXJSE_Value_SetUTF8String(args.GetReturnValue(), szParsedValue);
+            } else {
+              FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
+            }
+          } break;
+          case XFA_VT_TEXT: {
+            wsPattern = FX_WSTRC(L"text{") + wsPattern;
+            wsPattern += FX_WSTRC(L"}");
+            CXFA_LocaleValue localeValue(XFA_VT_TEXT, wsValue, wsPattern,
+                                         pLocale, (CXFA_LocaleMgr*)pMgr);
+            if (localeValue.IsValid()) {
+              szParsedValue = FX_UTF8Encode(localeValue.GetValue());
+              FXJSE_Value_SetUTF8String(args.GetReturnValue(), szParsedValue);
+            } else {
+              FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
+            }
+          } break;
+          case XFA_VT_FLOAT: {
+            wsPattern = FX_WSTRC(L"num{") + wsPattern;
+            wsPattern += FX_WSTRC(L"}");
+            CXFA_LocaleValue localeValue(XFA_VT_FLOAT, wsValue, wsPattern,
+                                         pLocale, (CXFA_LocaleMgr*)pMgr);
+            if (localeValue.IsValid()) {
+              FXJSE_Value_SetDouble(args.GetReturnValue(),
+                                    localeValue.GetDoubleNum());
+            } else {
+              FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
+            }
+          } break;
+          default: {
+            CFX_WideString wsTestPattern;
+            wsTestPattern = FX_WSTRC(L"num{") + wsPattern;
+            wsTestPattern += FX_WSTRC(L"}");
+            CXFA_LocaleValue localeValue(XFA_VT_FLOAT, wsValue, wsTestPattern,
+                                         pLocale, (CXFA_LocaleMgr*)pMgr);
+            if (localeValue.IsValid()) {
+              FXJSE_Value_SetDouble(args.GetReturnValue(),
+                                    localeValue.GetDoubleNum());
+            } else {
+              wsTestPattern = FX_WSTRC(L"text{") + wsPattern;
+              wsTestPattern += FX_WSTRC(L"}");
+              CXFA_LocaleValue localeValue(XFA_VT_TEXT, wsValue, wsTestPattern,
+                                           pLocale, (CXFA_LocaleMgr*)pMgr);
+              if (localeValue.IsValid()) {
+                szParsedValue = FX_UTF8Encode(localeValue.GetValue());
+                FXJSE_Value_SetUTF8String(args.GetReturnValue(), szParsedValue);
+              } else {
+                FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
+              }
+            }
+          } break;
+        }
+      }
+    }
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Parse");
+  }
+}
+void CXFA_FM2JSContext::Replace(FXJSE_HOBJECT hThis,
+                                const CFX_ByteStringC& szFuncName,
+                                CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if ((argc == 2) || (argc == 3)) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+    FXJSE_HVALUE argThree = 0;
+    CFX_ByteString oneString;
+    CFX_ByteString twoString;
+    CFX_ByteString threeString;
+    if (!HValueIsNull(hThis, argOne) && !HValueIsNull(hThis, argTwo)) {
+      HValueToUTF8String(argOne, oneString);
+      HValueToUTF8String(argTwo, twoString);
+    }
+    if (argc == 3) {
+      argThree = GetSimpleHValue(hThis, args, 2);
+      HValueToUTF8String(argThree, threeString);
+    }
+    int32_t iSrcLen = oneString.GetLength();
+    int32_t iFindLen = twoString.GetLength();
+    CFX_ByteTextBuf resultString;
+    int32_t iFindIndex = 0;
+    uint8_t ch = 0;
+    for (int32_t u = 0; u < iSrcLen; ++u) {
+      ch = oneString.GetAt(u);
+      if (ch == twoString.GetAt(iFindIndex)) {
+        int32_t iTemp = u + 1;
+        ++iFindIndex;
+        uint8_t chTemp = 0;
+        while (iFindIndex < iFindLen) {
+          chTemp = oneString.GetAt(iTemp);
+          if (chTemp == twoString.GetAt(iFindIndex)) {
+            ++iTemp;
+            ++iFindIndex;
+          } else {
+            iFindIndex = 0;
+            break;
+          }
+        }
+        if (iFindIndex == iFindLen) {
+          resultString << threeString;
+          u += iFindLen - 1;
+          iFindIndex = 0;
+        } else {
+          resultString.AppendChar(ch);
+        }
+      } else {
+        resultString.AppendChar(ch);
+      }
+    }
+    resultString.AppendChar(0);
+    FXJSE_Value_SetUTF8String(args.GetReturnValue(),
+                              resultString.GetByteString());
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+    if (argc == 3) {
+      FXJSE_Value_Release(argThree);
+    }
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Replace");
+  }
+}
+void CXFA_FM2JSContext::Right(FXJSE_HOBJECT hThis,
+                              const CFX_ByteStringC& szFuncName,
+                              CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 2) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+    FX_BOOL argIsNull = FALSE;
+    if ((HValueIsNull(hThis, argOne)) || (HValueIsNull(hThis, argTwo))) {
+      argIsNull = TRUE;
+    }
+    if (argIsNull) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      CFX_ByteString sourceString;
+      HValueToUTF8String(argOne, sourceString);
+      int32_t count = HValueToInteger(hThis, argTwo);
+      if (count < 0) {
+        count = 0;
+      }
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(),
+                                sourceString.Right(count));
+    }
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Right");
+  }
+}
+void CXFA_FM2JSContext::Rtrim(FXJSE_HOBJECT hThis,
+                              const CFX_ByteStringC& szFuncName,
+                              CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 1) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    if (HValueIsNull(hThis, argOne)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      CFX_ByteString sourceString;
+      HValueToUTF8String(argOne, sourceString);
+      sourceString.TrimRight();
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(), sourceString);
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Rtrim");
+  }
+}
+void CXFA_FM2JSContext::Space(FXJSE_HOBJECT hThis,
+                              const CFX_ByteStringC& szFuncName,
+                              CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 1) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    if (FXJSE_Value_IsNull(argOne)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      int32_t count = 0;
+      count = HValueToInteger(hThis, argOne);
+      count = (count < 0) ? 0 : count;
+      CFX_ByteTextBuf spaceString;
+      int32_t index = 0;
+      while (index < count) {
+        spaceString.AppendByte(' ');
+        index++;
+      }
+      spaceString.AppendByte(0);
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(),
+                                spaceString.GetByteString());
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Space");
+  }
+}
+void CXFA_FM2JSContext::Str(FXJSE_HOBJECT hThis,
+                            const CFX_ByteStringC& szFuncName,
+                            CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if ((argc > 0) && (argc < 4)) {
+    FX_BOOL bFlags = FALSE;
+    FX_FLOAT fNumber;
+    int32_t iWidth = 10;
+    int32_t iPrecision = 0;
+    FXJSE_HVALUE numberValue = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE widthValue = 0;
+    FXJSE_HVALUE precisionValue = 0;
+    if (FXJSE_Value_IsNull(numberValue)) {
+      bFlags = TRUE;
+    } else {
+      fNumber = HValueToFloat(hThis, numberValue);
+    }
+    if (argc > 1) {
+      widthValue = GetSimpleHValue(hThis, args, 1);
+      iWidth = (int32_t)HValueToFloat(hThis, widthValue);
+    }
+    if (argc == 3) {
+      precisionValue = GetSimpleHValue(hThis, args, 2);
+      iPrecision = (int32_t)HValueToFloat(hThis, precisionValue);
+      if (iPrecision < 0) {
+        iPrecision = 0;
+      }
+    }
+    if (!bFlags) {
+      CFX_ByteString numberString;
+      CFX_ByteString formatStr = "%";
+      if (iPrecision) {
+        formatStr += ".";
+        formatStr += CFX_ByteString::FormatInteger(iPrecision);
+      }
+      formatStr += "f";
+      numberString.Format(formatStr, fNumber);
+      const FX_CHAR* pData = numberString;
+      int32_t iLength = numberString.GetLength();
+      int32_t u = 0;
+      while (u < iLength) {
+        if (*(pData + u) == '.') {
+          break;
+        }
+        ++u;
+      }
+      CFX_ByteTextBuf resultBuf;
+      if (u > iWidth || (iPrecision + u) >= iWidth) {
+        int32_t i = 0;
+        while (i < iWidth) {
+          resultBuf.AppendChar('*');
+          ++i;
+        }
+        resultBuf.AppendChar(0);
+      } else {
+        if (u == iLength) {
+          if (iLength > iWidth) {
+            int32_t i = 0;
+            while (i < iWidth) {
+              resultBuf.AppendChar('*');
+              ++i;
+            }
+          } else {
+            int32_t i = 0;
+            int32_t iSpace = iWidth - iLength;
+            while (i < iSpace) {
+              resultBuf.AppendChar(' ');
+              ++i;
+            }
+            resultBuf << pData;
+          }
+        } else {
+          int32_t iLeavingSpace = 0;
+          if (iPrecision == 0) {
+            iLeavingSpace = iWidth - (u + iPrecision);
+          } else {
+            iLeavingSpace = iWidth - (u + iPrecision + 1);
+          }
+          int32_t i = 0;
+          while (i < iLeavingSpace) {
+            resultBuf.AppendChar(' ');
+            ++i;
+          }
+          i = 0;
+          while (i < u) {
+            resultBuf.AppendChar(*(pData + i));
+            ++i;
+          }
+          if (iPrecision != 0) {
+            resultBuf.AppendChar('.');
+          }
+          u++;
+          i = 0;
+          while (u < iLength) {
+            if (i >= iPrecision) {
+              break;
+            }
+            resultBuf.AppendChar(*(pData + u));
+            ++i;
+            ++u;
+          }
+          while (i < iPrecision) {
+            resultBuf.AppendChar('0');
+            ++i;
+          }
+          resultBuf.AppendChar(0);
+        }
+      }
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(),
+                                resultBuf.GetByteString());
+    } else {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    }
+    FXJSE_Value_Release(numberValue);
+    if (argc > 1) {
+      FXJSE_Value_Release(widthValue);
+      if (argc == 3) {
+        FXJSE_Value_Release(precisionValue);
+      }
+    }
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Str");
+  }
+}
+void CXFA_FM2JSContext::Stuff(FXJSE_HOBJECT hThis,
+                              const CFX_ByteStringC& szFuncName,
+                              CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if ((argc == 3) || (argc == 4)) {
+    CFX_ByteString sourceString;
+    CFX_ByteString insertString;
+    int32_t iLength = 0;
+    int32_t iStart = 0;
+    int32_t iDelete = 0;
+    FXJSE_HVALUE sourceValue = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE startValue = GetSimpleHValue(hThis, args, 1);
+    FXJSE_HVALUE deleteValue = GetSimpleHValue(hThis, args, 2);
+    FXJSE_HVALUE insertValue = 0;
+    if (!FXJSE_Value_IsNull(sourceValue) && !FXJSE_Value_IsNull(startValue) &&
+        !FXJSE_Value_IsNull(deleteValue)) {
+      HValueToUTF8String(sourceValue, sourceString);
+      iLength = sourceString.GetLength();
+      iStart = (int32_t)HValueToFloat(hThis, startValue);
+      if (iStart < 1) {
+        iStart = 1;
+      }
+      if (iStart > iLength) {
+        iStart = iLength;
+      }
+      iDelete = (int32_t)HValueToFloat(hThis, deleteValue);
+      if (iDelete <= 0) {
+        iDelete = 0;
+      }
+    }
+    if (argc == 4) {
+      insertValue = GetSimpleHValue(hThis, args, 3);
+      HValueToUTF8String(insertValue, insertString);
+    }
+    iStart -= 1;
+    CFX_ByteTextBuf resultString;
+    int32_t i = 0;
+    while (i < iStart) {
+      resultString.AppendChar(sourceString.GetAt(i));
+      ++i;
+    }
+    resultString << insertString;
+    i = iStart + iDelete;
+    while (i < iLength) {
+      resultString.AppendChar(sourceString.GetAt(i));
+      ++i;
+    }
+    resultString.AppendChar(0);
+    FXJSE_Value_SetUTF8String(args.GetReturnValue(),
+                              resultString.GetByteString());
+    FXJSE_Value_Release(sourceValue);
+    FXJSE_Value_Release(startValue);
+    FXJSE_Value_Release(deleteValue);
+    if (argc == 4) {
+      FXJSE_Value_Release(insertValue);
+    }
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Stuff");
+  }
+}
+void CXFA_FM2JSContext::Substr(FXJSE_HOBJECT hThis,
+                               const CFX_ByteStringC& szFuncName,
+                               CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if (argc == 3) {
+    FXJSE_HVALUE stringValue = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE startValue = GetSimpleHValue(hThis, args, 1);
+    FXJSE_HVALUE endValue = GetSimpleHValue(hThis, args, 2);
+    if (HValueIsNull(hThis, stringValue) || (HValueIsNull(hThis, startValue)) ||
+        (HValueIsNull(hThis, endValue))) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      CFX_ByteString szSourceStr;
+      int32_t iStart = 0;
+      int32_t iCount = 0;
+      HValueToUTF8String(stringValue, szSourceStr);
+      int32_t iLength = szSourceStr.GetLength();
+      if (iLength == 0) {
+        FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
+      } else {
+        iStart = (int32_t)HValueToFloat(hThis, startValue);
+        iCount = (int32_t)HValueToFloat(hThis, endValue);
+        if (iStart < 1) {
+          iStart = 1;
+        }
+        if (iStart > iLength) {
+          iStart = iLength;
+        }
+        if (iCount <= 0) {
+          iCount = 0;
+        }
+        iStart -= 1;
+        FXJSE_Value_SetUTF8String(args.GetReturnValue(),
+                                  szSourceStr.Mid(iStart, iCount));
+      }
+    }
+    FXJSE_Value_Release(stringValue);
+    FXJSE_Value_Release(startValue);
+    FXJSE_Value_Release(endValue);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Substr");
+  }
+}
+void CXFA_FM2JSContext::Uuid(FXJSE_HOBJECT hThis,
+                             const CFX_ByteStringC& szFuncName,
+                             CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if ((argc == 0) || (argc == 1)) {
+    int32_t iNum = 0;
+    FXJSE_HVALUE argOne = 0;
+    if (argc == 1) {
+      argOne = GetSimpleHValue(hThis, args, 0);
+      iNum = (int32_t)HValueToFloat(hThis, argOne);
+    }
+    FX_GUID guid;
+    FX_GUID_CreateV4(&guid);
+    CFX_ByteString bsUId;
+    FX_GUID_ToString(&guid, bsUId, iNum);
+    FXJSE_Value_SetUTF8String(args.GetReturnValue(), bsUId);
+    if (argc == 1) {
+      FXJSE_Value_Release(argOne);
+    }
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Uuid");
+  }
+}
+void CXFA_FM2JSContext::Upper(FXJSE_HOBJECT hThis,
+                              const CFX_ByteStringC& szFuncName,
+                              CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if ((argc > 0) && (argc < 3)) {
+    CFX_ByteString argString;
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE localeValue = 0;
+    if (HValueIsNull(hThis, argOne)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      if (argc == 2) {
+        localeValue = GetSimpleHValue(hThis, args, 1);
+      }
+      HValueToUTF8String(argOne, argString);
+      CFX_WideTextBuf upperStringBuf;
+      CFX_WideString wsArgString =
+          CFX_WideString::FromUTF8(argString, argString.GetLength());
+      const FX_WCHAR* pData = wsArgString;
+      int32_t iLen = wsArgString.GetLength();
+      int32_t i = 0;
+      int32_t ch = 0;
+      while (i < iLen) {
+        ch = *(pData + i);
+        if (ch >= 0x61 && ch <= 0x7A) {
+          ch -= 32;
+        } else if (ch >= 0xE0 && ch <= 0xFE) {
+          ch -= 32;
+        } else if (ch == 0x101 || ch == 0x103 || ch == 0x105) {
+          ch -= 1;
+        }
+        upperStringBuf.AppendChar(ch);
+        ++i;
+      }
+      upperStringBuf.AppendChar(0);
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(),
+                                FX_UTF8Encode(upperStringBuf.GetBuffer(),
+                                              upperStringBuf.GetLength()));
+      if (argc == 2) {
+        FXJSE_Value_Release(localeValue);
+      }
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Upper");
+  }
+}
+void CXFA_FM2JSContext::WordNum(FXJSE_HOBJECT hThis,
+                                const CFX_ByteStringC& szFuncName,
+                                CFXJSE_Arguments& args) {
+  int32_t argc = args.GetLength();
+  if ((argc > 0) && (argc < 4)) {
+    FX_BOOL bFlags = FALSE;
+    FX_FLOAT fNumber;
+    int32_t iIdentifier = 0;
+    CFX_ByteString localeString;
+    FXJSE_HVALUE numberValue = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE identifierValue = 0;
+    FXJSE_HVALUE localeValue = 0;
+    if (FXJSE_Value_IsNull(numberValue)) {
+      bFlags = TRUE;
+    } else {
+      fNumber = HValueToFloat(hThis, numberValue);
+    }
+    if (argc > 1) {
+      identifierValue = GetSimpleHValue(hThis, args, 1);
+      if (FXJSE_Value_IsNull(identifierValue)) {
+        bFlags = TRUE;
+      } else {
+        iIdentifier = (int32_t)HValueToFloat(hThis, identifierValue);
+      }
+    }
+    if (argc == 3) {
+      localeValue = GetSimpleHValue(hThis, args, 2);
+      if (FXJSE_Value_IsNull(localeValue)) {
+        bFlags = TRUE;
+      } else {
+        HValueToUTF8String(localeValue, localeString);
+      }
+    }
+    if (!bFlags) {
+      if ((fNumber < 0) || (fNumber > 922337203685477550)) {
+        FXJSE_Value_SetUTF8String(args.GetReturnValue(), "*");
+      } else {
+        CFX_ByteTextBuf resultBuf;
+        CFX_ByteString numberString;
+        numberString.Format("%.2f", fNumber);
+        WordUS(numberString, iIdentifier, resultBuf);
+        FXJSE_Value_SetUTF8String(args.GetReturnValue(),
+                                  resultBuf.GetByteString());
+      }
+    } else {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    }
+    FXJSE_Value_Release(numberValue);
+    if (argc > 1) {
+      FXJSE_Value_Release(identifierValue);
+      if (argc == 3) {
+        FXJSE_Value_Release(localeValue);
+      }
+    }
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"WordNum");
+  }
+}
+void CXFA_FM2JSContext::TrillionUS(const CFX_ByteStringC& szData,
+                                   CFX_ByteTextBuf& strBuf) {
+  CFX_ByteStringC pUnits[] = {"zero", "one", "two",   "three", "four",
+                              "five", "six", "seven", "eight", "nine"};
+  CFX_ByteStringC pCapUnits[] = {"Zero", "One", "Two",   "Three", "Four",
+                                 "Five", "Six", "Seven", "Eight", "Nine"};
+  CFX_ByteStringC pTens[] = {"Ten",      "Eleven",  "Twelve",  "Thirteen",
+                             "Fourteen", "Fifteen", "Sixteen", "Seventeen",
+                             "Eighteen", "Nineteen"};
+  CFX_ByteStringC pLastTens[] = {"Twenty", "Thirty",  "Forty",  "Fifty",
+                                 "Sixty",  "Seventy", "Eighty", "Ninety"};
+  CFX_ByteStringC pComm[] = {" Hundred ", " Thousand ", " Million ",
+                             " Billion ", "Trillion"};
+  int32_t iComm = 0;
+  const FX_CHAR* pData = szData.GetCStr();
+  int32_t iLength = szData.GetLength();
+  if (iLength > 12) {
+    iComm = 4;
+  } else if (iLength > 9) {
+    iComm = 3;
+  } else if (iLength > 6) {
+    iComm = 2;
+  } else if (iLength > 3) {
+    iComm = 1;
+  }
+  int32_t iIndex = 0;
+  int32_t iFirstCount = iLength % 3;
+  if (iFirstCount == 0) {
+    iFirstCount = 3;
+  }
+  if (iFirstCount == 3) {
+    if (*(pData + iIndex) != '0') {
+      strBuf << pCapUnits[*(pData + iIndex) - '0'];
+      strBuf << pComm[0];
+    }
+    if (*(pData + iIndex + 1) == '0') {
+      strBuf << pCapUnits[*(pData + iIndex + 2) - '0'];
+    } else {
+      if (*(pData + iIndex + 1) > '1') {
+        strBuf << pLastTens[*(pData + iIndex + 1) - '2'];
+        strBuf << "-";
+        strBuf << pUnits[*(pData + iIndex + 2) - '0'];
+      } else if (*(pData + iIndex + 1) == '1') {
+        strBuf << pTens[*(pData + iIndex + 2) - '0'];
+      } else if (*(pData + iIndex + 1) == '0') {
+        strBuf << pCapUnits[*(pData + iIndex + 2) - '0'];
+      }
+    }
+    iIndex += 3;
+  } else if (iFirstCount == 2) {
+    if (*(pData + iIndex) == '0') {
+      strBuf << pCapUnits[*(pData + iIndex + 1) - '0'];
+    } else {
+      if (*(pData + iIndex) > '1') {
+        strBuf << pLastTens[*(pData + iIndex) - '2'];
+        strBuf << "-";
+        strBuf << pUnits[*(pData + iIndex + 1) - '0'];
+      } else if (*(pData + iIndex) == '1') {
+        strBuf << pTens[*(pData + iIndex + 1) - '0'];
+      } else if (*(pData + iIndex) == '0') {
+        strBuf << pCapUnits[*(pData + iIndex + 1) - '0'];
+      }
+    }
+    iIndex += 2;
+  } else if (iFirstCount == 1) {
+    strBuf << pCapUnits[*(pData + iIndex) - '0'];
+    iIndex += 1;
+  }
+  if (iLength > 3 && iFirstCount > 0) {
+    strBuf << pComm[iComm];
+    --iComm;
+  }
+  while (iIndex < iLength) {
+    if (*(pData + iIndex) != '0') {
+      strBuf << pCapUnits[*(pData + iIndex) - '0'];
+      strBuf << pComm[0];
+    }
+    if (*(pData + iIndex + 1) == '0') {
+      strBuf << pCapUnits[*(pData + iIndex + 2) - '0'];
+    } else {
+      if (*(pData + iIndex + 1) > '1') {
+        strBuf << pLastTens[*(pData + iIndex + 1) - '2'];
+        strBuf << "-";
+        strBuf << pUnits[*(pData + iIndex + 2) - '0'];
+      } else if (*(pData + iIndex + 1) == '1') {
+        strBuf << pTens[*(pData + iIndex + 2) - '0'];
+      } else if (*(pData + iIndex + 1) == '0') {
+        strBuf << pCapUnits[*(pData + iIndex + 2) - '0'];
+      }
+    }
+    if (iIndex < iLength - 3) {
+      strBuf << pComm[iComm];
+      --iComm;
+    }
+    iIndex += 3;
+  }
+}
+void CXFA_FM2JSContext::WordUS(const CFX_ByteStringC& szData,
+                               int32_t iStyle,
+                               CFX_ByteTextBuf& strBuf) {
+  const FX_CHAR* pData = szData.GetCStr();
+  int32_t iLength = szData.GetLength();
+  switch (iStyle) {
+    case 0: {
+      int32_t iIndex = 0;
+      while (iIndex < iLength) {
+        if (*(pData + iIndex) == '.') {
+          break;
+        }
+        ++iIndex;
+      }
+      iLength = iIndex;
+      iIndex = 0;
+      int32_t iCount = 0;
+      while (iIndex < iLength) {
+        iCount = (iLength - iIndex) % 12;
+        if (!iCount && iLength - iIndex > 0) {
+          iCount = 12;
+        }
+        TrillionUS(CFX_ByteStringC(pData + iIndex, iCount), strBuf);
+        iIndex += iCount;
+        if (iIndex < iLength) {
+          strBuf << " Trillion ";
+        }
+      }
+    } break;
+    case 1: {
+      int32_t iIndex = 0;
+      while (iIndex < iLength) {
+        if (*(pData + iIndex) == '.') {
+          break;
+        }
+        ++iIndex;
+      }
+      iLength = iIndex;
+      iIndex = 0;
+      int32_t iCount = 0;
+      while (iIndex < iLength) {
+        iCount = (iLength - iIndex) % 12;
+        if (!iCount && iLength - iIndex > 0) {
+          iCount = 12;
+        }
+        TrillionUS(CFX_ByteStringC(pData + iIndex, iCount), strBuf);
+        iIndex += iCount;
+        if (iIndex < iLength) {
+          strBuf << " Trillion ";
+        }
+      }
+      strBuf << " Dollars";
+    } break;
+    case 2: {
+      int32_t iIndex = 0;
+      while (iIndex < iLength) {
+        if (*(pData + iIndex) == '.') {
+          break;
+        }
+        ++iIndex;
+      }
+      int32_t iInteger = iIndex;
+      iIndex = 0;
+      int32_t iCount = 0;
+      while (iIndex < iInteger) {
+        iCount = (iInteger - iIndex) % 12;
+        if (!iCount && iLength - iIndex > 0) {
+          iCount = 12;
+        }
+        TrillionUS(CFX_ByteStringC(pData + iIndex, iCount), strBuf);
+        iIndex += iCount;
+        if (iIndex < iInteger) {
+          strBuf << " Trillion ";
+        }
+      }
+      strBuf << " Dollars";
+      if (iInteger < iLength) {
+        strBuf << " And ";
+        iIndex = iInteger + 1;
+        int32_t iCount = 0;
+        while (iIndex < iLength) {
+          iCount = (iLength - iIndex) % 12;
+          if (!iCount && iLength - iIndex > 0) {
+            iCount = 12;
+          }
+          TrillionUS(CFX_ByteStringC(pData + iIndex, iCount), strBuf);
+          iIndex += iCount;
+          if (iIndex < iLength) {
+            strBuf << " Trillion ";
+          }
+        }
+        strBuf << " Cents";
+      }
+    } break;
+    default:
+      break;
+  }
+}
+void CXFA_FM2JSContext::Get(FXJSE_HOBJECT hThis,
+                            const CFX_ByteStringC& szFuncName,
+                            CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  int32_t argc = args.GetLength();
+  if (argc == 1) {
+    CXFA_Document* pDoc = pContext->GetDocument();
+    if (!pDoc) {
+      return;
+    }
+    IXFA_AppProvider* pAppProvider =
+        pDoc->GetParser()->GetNotify()->GetAppProvider();
+    if (!pAppProvider) {
+      return;
+    }
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    CFX_ByteString urlString;
+    HValueToUTF8String(argOne, urlString);
+    IFX_FileRead* pFile = pAppProvider->DownloadURL(
+        CFX_WideString::FromUTF8(urlString, urlString.GetLength()));
+    if (pFile) {
+      int32_t size = pFile->GetSize();
+      uint8_t* pData = FX_Alloc(uint8_t, size);
+      pFile->ReadBlock(pData, size);
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(),
+                                CFX_ByteStringC(pData, size));
+      FX_Free(pData);
+      pFile->Release();
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Get");
+  }
+}
+void CXFA_FM2JSContext::Post(FXJSE_HOBJECT hThis,
+                             const CFX_ByteStringC& szFuncName,
+                             CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  int32_t argc = args.GetLength();
+  if ((argc >= 2) && (argc <= 5)) {
+    CXFA_Document* pDoc = pContext->GetDocument();
+    if (!pDoc) {
+      return;
+    }
+    IXFA_AppProvider* pAppProvider =
+        pDoc->GetParser()->GetNotify()->GetAppProvider();
+    if (!pAppProvider) {
+      return;
+    }
+    CFX_ByteString bsURL;
+    CFX_ByteString bsData;
+    CFX_ByteString bsContentType;
+    CFX_ByteString bsEncode;
+    CFX_ByteString bsHeader;
+    FXJSE_HVALUE argOne;
+    FXJSE_HVALUE argTwo;
+    FXJSE_HVALUE argThree;
+    FXJSE_HVALUE argFour;
+    FXJSE_HVALUE argFive;
+    argOne = GetSimpleHValue(hThis, args, 0);
+    HValueToUTF8String(argOne, bsURL);
+    argTwo = GetSimpleHValue(hThis, args, 1);
+    HValueToUTF8String(argTwo, bsData);
+    if (argc > 2) {
+      argThree = GetSimpleHValue(hThis, args, 2);
+      HValueToUTF8String(argThree, bsContentType);
+    }
+    if (argc > 3) {
+      argFour = GetSimpleHValue(hThis, args, 3);
+      HValueToUTF8String(argFour, bsEncode);
+    }
+    if (argc > 4) {
+      argFive = GetSimpleHValue(hThis, args, 4);
+      HValueToUTF8String(argFive, bsHeader);
+    }
+    CFX_WideString decodedResponse;
+    FX_BOOL bFlags = pAppProvider->PostRequestURL(
+        CFX_WideString::FromUTF8(bsURL, bsURL.GetLength()),
+        CFX_WideString::FromUTF8(bsData, bsData.GetLength()),
+        CFX_WideString::FromUTF8(bsContentType, bsContentType.GetLength()),
+        CFX_WideString::FromUTF8(bsEncode, bsEncode.GetLength()),
+        CFX_WideString::FromUTF8(bsHeader, bsHeader.GetLength()),
+        decodedResponse);
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+    if (argc > 2) {
+      FXJSE_Value_Release(argThree);
+    }
+    if (argc > 3) {
+      FXJSE_Value_Release(argFour);
+    }
+    if (argc > 4) {
+      FXJSE_Value_Release(argFive);
+    }
+    if (bFlags) {
+      FXJSE_Value_SetUTF8String(
+          args.GetReturnValue(),
+          FX_UTF8Encode(decodedResponse, decodedResponse.GetLength()));
+    } else {
+      pContext->ThrowScriptErrorMessage(XFA_IDS_SERVER_DENY);
+    }
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Post");
+  }
+}
+void CXFA_FM2JSContext::Put(FXJSE_HOBJECT hThis,
+                            const CFX_ByteStringC& szFuncName,
+                            CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  int32_t argc = args.GetLength();
+  if ((argc == 2) || (argc == 3)) {
+    CXFA_Document* pDoc = pContext->GetDocument();
+    if (!pDoc) {
+      return;
+    }
+    IXFA_AppProvider* pAppProvider =
+        pDoc->GetParser()->GetNotify()->GetAppProvider();
+    if (!pAppProvider) {
+      return;
+    }
+    CFX_ByteString bsURL;
+    CFX_ByteString bsData;
+    CFX_ByteString bsEncode;
+    FXJSE_HVALUE argOne;
+    FXJSE_HVALUE argTwo;
+    FXJSE_HVALUE argThree;
+    argOne = GetSimpleHValue(hThis, args, 0);
+    HValueToUTF8String(argOne, bsURL);
+    argTwo = GetSimpleHValue(hThis, args, 1);
+    HValueToUTF8String(argTwo, bsData);
+    if (argc > 2) {
+      argThree = GetSimpleHValue(hThis, args, 2);
+      HValueToUTF8String(argThree, bsEncode);
+    }
+    FX_BOOL bFlags = pAppProvider->PutRequestURL(
+        CFX_WideString::FromUTF8(bsURL, bsURL.GetLength()),
+        CFX_WideString::FromUTF8(bsData, bsData.GetLength()),
+        CFX_WideString::FromUTF8(bsEncode, bsEncode.GetLength()));
+    FXJSE_Value_Release(argOne);
+    FXJSE_Value_Release(argTwo);
+    if (argc > 2) {
+      FXJSE_Value_Release(argThree);
+    }
+    if (bFlags) {
+      FXJSE_Value_SetUTF8String(args.GetReturnValue(), "");
+    } else {
+      pContext->ThrowScriptErrorMessage(XFA_IDS_SERVER_DENY);
+    }
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Put");
+  }
+}
+void CXFA_FM2JSContext::assign_value_operator(FXJSE_HOBJECT hThis,
+                                              const CFX_ByteStringC& szFuncName,
+                                              CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  if (args.GetLength() == 2) {
+    FXJSE_HVALUE lValue = args.GetValue(0);
+    FXJSE_HVALUE rValue = GetSimpleHValue(hThis, args, 1);
+    FX_BOOL bSetStatus = TRUE;
+    if (FXJSE_Value_IsArray(lValue)) {
+      FXJSE_HVALUE leftLengthValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectProp(lValue, "length", leftLengthValue);
+      int32_t iLeftLength = FXJSE_Value_ToInteger(leftLengthValue);
+      FXJSE_Value_Release(leftLengthValue);
+      FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+      FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectPropByIdx(lValue, 1, propertyValue);
+      if (FXJSE_Value_IsNull(propertyValue)) {
+        for (int32_t i = 2; i < iLeftLength; i++) {
+          FXJSE_Value_GetObjectPropByIdx(lValue, i, jsObjectValue);
+          bSetStatus = SetObjectDefaultValue(jsObjectValue, rValue);
+          if (!bSetStatus) {
+            pContext->ThrowScriptErrorMessage(XFA_IDS_NOT_DEFAUL_VALUE);
+            break;
+          }
+        }
+      } else {
+        CFX_ByteString propertyStr;
+        FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+        for (int32_t i = 2; i < iLeftLength; i++) {
+          FXJSE_Value_GetObjectPropByIdx(lValue, i, jsObjectValue);
+          FXJSE_Value_SetObjectProp(jsObjectValue, propertyStr, rValue);
+        }
+      }
+      FXJSE_Value_Release(jsObjectValue);
+      FXJSE_Value_Release(propertyValue);
+    } else if (FXJSE_Value_IsObject(lValue)) {
+      bSetStatus = SetObjectDefaultValue(lValue, rValue);
+      if (!bSetStatus) {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_NOT_DEFAUL_VALUE);
+      }
+    }
+    FXJSE_Value_Set(args.GetReturnValue(), rValue);
+    FXJSE_Value_Release(lValue);
+    FXJSE_Value_Release(rValue);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::logical_or_operator(FXJSE_HOBJECT hThis,
+                                            const CFX_ByteStringC& szFuncName,
+                                            CFXJSE_Arguments& args) {
+  if (args.GetLength() == 2) {
+    FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+    if (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      FX_FLOAT first = HValueToFloat(hThis, argFirst);
+      FX_FLOAT second = HValueToFloat(hThis, argSecond);
+      FXJSE_Value_SetInteger(args.GetReturnValue(), (first || second) ? 1 : 0);
+    }
+    FXJSE_Value_Release(argFirst);
+    FXJSE_Value_Release(argSecond);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::logical_and_operator(FXJSE_HOBJECT hThis,
+                                             const CFX_ByteStringC& szFuncName,
+                                             CFXJSE_Arguments& args) {
+  if (args.GetLength() == 2) {
+    FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+    if (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      FX_FLOAT first = HValueToFloat(hThis, argFirst);
+      FX_FLOAT second = HValueToFloat(hThis, argSecond);
+      FXJSE_Value_SetInteger(args.GetReturnValue(), (first && second) ? 1 : 0);
+    }
+    FXJSE_Value_Release(argFirst);
+    FXJSE_Value_Release(argSecond);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::equality_operator(FXJSE_HOBJECT hThis,
+                                          const CFX_ByteStringC& szFuncName,
+                                          CFXJSE_Arguments& args) {
+  if (args.GetLength() == 2) {
+    if (fm_ref_equal(hThis, args)) {
+      FXJSE_Value_SetInteger(args.GetReturnValue(), 1);
+    } else {
+      FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+      FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+      if (FXJSE_Value_IsNull(argFirst) || FXJSE_Value_IsNull(argSecond)) {
+        FXJSE_Value_SetInteger(
+            args.GetReturnValue(),
+            (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond))
+                ? 1
+                : 0);
+      } else if (FXJSE_Value_IsUTF8String(argFirst) &&
+                 FXJSE_Value_IsUTF8String(argSecond)) {
+        CFX_ByteString firstOutput;
+        CFX_ByteString secondOutput;
+        FXJSE_Value_ToUTF8String(argFirst, firstOutput);
+        FXJSE_Value_ToUTF8String(argSecond, secondOutput);
+        FXJSE_Value_SetInteger(args.GetReturnValue(),
+                               firstOutput.Equal(secondOutput) ? 1 : 0);
+      } else {
+        FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+        FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+        FXJSE_Value_SetInteger(args.GetReturnValue(),
+                               (first == second) ? 1 : 0);
+      }
+      FXJSE_Value_Release(argFirst);
+      FXJSE_Value_Release(argSecond);
+    }
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::notequality_operator(FXJSE_HOBJECT hThis,
+                                             const CFX_ByteStringC& szFuncName,
+                                             CFXJSE_Arguments& args) {
+  if (args.GetLength() == 2) {
+    if (fm_ref_equal(hThis, args)) {
+      FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
+    } else {
+      FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+      FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+      if (FXJSE_Value_IsNull(argFirst) || FXJSE_Value_IsNull(argSecond)) {
+        FXJSE_Value_SetInteger(
+            args.GetReturnValue(),
+            (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond))
+                ? 0
+                : 1);
+      } else if (FXJSE_Value_IsUTF8String(argFirst) &&
+                 FXJSE_Value_IsUTF8String(argSecond)) {
+        CFX_ByteString firstOutput;
+        CFX_ByteString secondOutput;
+        FXJSE_Value_ToUTF8String(argFirst, firstOutput);
+        FXJSE_Value_ToUTF8String(argSecond, secondOutput);
+        FXJSE_Value_SetInteger(args.GetReturnValue(),
+                               firstOutput.Equal(secondOutput) ? 0 : 1);
+      } else {
+        FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+        FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+        FXJSE_Value_SetInteger(args.GetReturnValue(),
+                               (first == second) ? 0 : 1);
+      }
+      FXJSE_Value_Release(argFirst);
+      FXJSE_Value_Release(argSecond);
+    }
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+FX_BOOL CXFA_FM2JSContext::fm_ref_equal(FXJSE_HOBJECT hThis,
+                                        CFXJSE_Arguments& args) {
+  FX_BOOL bRet = FALSE;
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  FXJSE_HVALUE argFirst = args.GetValue(0);
+  FXJSE_HVALUE argSecond = args.GetValue(0);
+  if (FXJSE_Value_IsArray(argFirst) && FXJSE_Value_IsArray(argSecond)) {
+    FXJSE_HVALUE firstFlagValue = FXJSE_Value_Create(hruntime);
+    FXJSE_HVALUE secondFlagValue = FXJSE_Value_Create(hruntime);
+    FXJSE_Value_GetObjectPropByIdx(argFirst, 0, firstFlagValue);
+    FXJSE_Value_GetObjectPropByIdx(argSecond, 0, secondFlagValue);
+    if ((FXJSE_Value_ToInteger(firstFlagValue) == 3) &&
+        (FXJSE_Value_ToInteger(secondFlagValue) == 3)) {
+      FXJSE_HVALUE firstJSObject = FXJSE_Value_Create(hruntime);
+      FXJSE_HVALUE secondJSObject = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectPropByIdx(argFirst, 2, firstJSObject);
+      FXJSE_Value_GetObjectPropByIdx(argSecond, 2, secondJSObject);
+      if (!FXJSE_Value_IsNull(firstJSObject) &&
+          !FXJSE_Value_IsNull(secondJSObject)) {
+        bRet = (FXJSE_Value_ToObject(firstJSObject, NULL) ==
+                FXJSE_Value_ToObject(secondJSObject, NULL));
+      }
+      FXJSE_Value_Release(firstJSObject);
+      FXJSE_Value_Release(secondJSObject);
+    }
+    FXJSE_Value_Release(firstFlagValue);
+    FXJSE_Value_Release(secondFlagValue);
+  }
+  FXJSE_Value_Release(argFirst);
+  FXJSE_Value_Release(argSecond);
+  return bRet;
+}
+void CXFA_FM2JSContext::less_operator(FXJSE_HOBJECT hThis,
+                                      const CFX_ByteStringC& szFuncName,
+                                      CFXJSE_Arguments& args) {
+  if (args.GetLength() == 2) {
+    FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+    if (FXJSE_Value_IsNull(argFirst) || FXJSE_Value_IsNull(argSecond)) {
+      FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
+    } else if (FXJSE_Value_IsUTF8String(argFirst) &&
+               FXJSE_Value_IsUTF8String(argSecond)) {
+      CFX_ByteString firstOutput;
+      CFX_ByteString secondOutput;
+      FXJSE_Value_ToUTF8String(argFirst, firstOutput);
+      FXJSE_Value_ToUTF8String(argSecond, secondOutput);
+      FXJSE_Value_SetInteger(args.GetReturnValue(),
+                             (firstOutput.Compare(secondOutput) == -1) ? 1 : 0);
+    } else {
+      FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+      FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+      FXJSE_Value_SetInteger(args.GetReturnValue(), (first < second) ? 1 : 0);
+    }
+    FXJSE_Value_Release(argFirst);
+    FXJSE_Value_Release(argSecond);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::lessequal_operator(FXJSE_HOBJECT hThis,
+                                           const CFX_ByteStringC& szFuncName,
+                                           CFXJSE_Arguments& args) {
+  if (args.GetLength() == 2) {
+    FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+    if (FXJSE_Value_IsNull(argFirst) || FXJSE_Value_IsNull(argSecond)) {
+      FXJSE_Value_SetInteger(
+          args.GetReturnValue(),
+          (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) ? 1
+                                                                          : 0);
+    } else if (FXJSE_Value_IsUTF8String(argFirst) &&
+               FXJSE_Value_IsUTF8String(argSecond)) {
+      CFX_ByteString firstOutput;
+      CFX_ByteString secondOutput;
+      FXJSE_Value_ToUTF8String(argFirst, firstOutput);
+      FXJSE_Value_ToUTF8String(argSecond, secondOutput);
+      FXJSE_Value_SetInteger(args.GetReturnValue(),
+                             (firstOutput.Compare(secondOutput) != 1) ? 1 : 0);
+    } else {
+      FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+      FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+      FXJSE_Value_SetInteger(args.GetReturnValue(), (first <= second) ? 1 : 0);
+    }
+    FXJSE_Value_Release(argFirst);
+    FXJSE_Value_Release(argSecond);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::greater_operator(FXJSE_HOBJECT hThis,
+                                         const CFX_ByteStringC& szFuncName,
+                                         CFXJSE_Arguments& args) {
+  if (args.GetLength() == 2) {
+    FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+    if (FXJSE_Value_IsNull(argFirst) || FXJSE_Value_IsNull(argSecond)) {
+      FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
+    } else if (FXJSE_Value_IsUTF8String(argFirst) &&
+               FXJSE_Value_IsUTF8String(argSecond)) {
+      CFX_ByteString firstOutput;
+      CFX_ByteString secondOutput;
+      FXJSE_Value_ToUTF8String(argFirst, firstOutput);
+      FXJSE_Value_ToUTF8String(argSecond, secondOutput);
+      FXJSE_Value_SetInteger(args.GetReturnValue(),
+                             (firstOutput.Compare(secondOutput) == 1) ? 1 : 0);
+    } else {
+      FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+      FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+      FXJSE_Value_SetInteger(args.GetReturnValue(), (first > second) ? 1 : 0);
+    }
+    FXJSE_Value_Release(argFirst);
+    FXJSE_Value_Release(argSecond);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::greaterequal_operator(FXJSE_HOBJECT hThis,
+                                              const CFX_ByteStringC& szFuncName,
+                                              CFXJSE_Arguments& args) {
+  if (args.GetLength() == 2) {
+    FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+    if (FXJSE_Value_IsNull(argFirst) || FXJSE_Value_IsNull(argSecond)) {
+      FXJSE_Value_SetInteger(
+          args.GetReturnValue(),
+          (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) ? 1
+                                                                          : 0);
+    } else if (FXJSE_Value_IsUTF8String(argFirst) &&
+               FXJSE_Value_IsUTF8String(argSecond)) {
+      CFX_ByteString firstOutput;
+      CFX_ByteString secondOutput;
+      FXJSE_Value_ToUTF8String(argFirst, firstOutput);
+      FXJSE_Value_ToUTF8String(argSecond, secondOutput);
+      FXJSE_Value_SetInteger(args.GetReturnValue(),
+                             (firstOutput.Compare(secondOutput) != -1) ? 1 : 0);
+    } else {
+      FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+      FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+      FXJSE_Value_SetInteger(args.GetReturnValue(), (first >= second) ? 1 : 0);
+    }
+    FXJSE_Value_Release(argFirst);
+    FXJSE_Value_Release(argSecond);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::plus_operator(FXJSE_HOBJECT hThis,
+                                      const CFX_ByteStringC& szFuncName,
+                                      CFXJSE_Arguments& args) {
+  if (args.GetLength() == 2) {
+    FXJSE_HVALUE argFirst = args.GetValue(0);
+    FXJSE_HVALUE argSecond = args.GetValue(1);
+    if (HValueIsNull(hThis, argFirst) && HValueIsNull(hThis, argSecond)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+      FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+      FXJSE_Value_SetDouble(args.GetReturnValue(), first + second);
+    }
+    FXJSE_Value_Release(argFirst);
+    FXJSE_Value_Release(argSecond);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::minus_operator(FXJSE_HOBJECT hThis,
+                                       const CFX_ByteStringC& szFuncName,
+                                       CFXJSE_Arguments& args) {
+  if (args.GetLength() == 2) {
+    FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+    if (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+      FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+      FXJSE_Value_SetDouble(args.GetReturnValue(), first - second);
+    }
+    FXJSE_Value_Release(argFirst);
+    FXJSE_Value_Release(argSecond);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::multiple_operator(FXJSE_HOBJECT hThis,
+                                          const CFX_ByteStringC& szFuncName,
+                                          CFXJSE_Arguments& args) {
+  if (args.GetLength() == 2) {
+    FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+    if (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+      FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+      FXJSE_Value_SetDouble(args.GetReturnValue(), first * second);
+    }
+    FXJSE_Value_Release(argFirst);
+    FXJSE_Value_Release(argSecond);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::divide_operator(FXJSE_HOBJECT hThis,
+                                        const CFX_ByteStringC& szFuncName,
+                                        CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  if (args.GetLength() == 2) {
+    FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+    FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+    if (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+      FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+      if (second == 0.0) {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_DIVIDE_ZERO);
+      } else {
+        FXJSE_Value_SetDouble(args.GetReturnValue(), first / second);
+      }
+    }
+    FXJSE_Value_Release(argFirst);
+    FXJSE_Value_Release(argSecond);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::positive_operator(FXJSE_HOBJECT hThis,
+                                          const CFX_ByteStringC& szFuncName,
+                                          CFXJSE_Arguments& args) {
+  int32_t iLength = args.GetLength();
+  if (iLength == 1) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    if (FXJSE_Value_IsNull(argOne)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      FXJSE_Value_SetDouble(args.GetReturnValue(),
+                            0.0 + HValueToDouble(hThis, argOne));
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::negative_operator(FXJSE_HOBJECT hThis,
+                                          const CFX_ByteStringC& szFuncName,
+                                          CFXJSE_Arguments& args) {
+  int32_t iLength = args.GetLength();
+  if (iLength == 1) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    if (FXJSE_Value_IsNull(argOne)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      FXJSE_Value_SetDouble(args.GetReturnValue(),
+                            0.0 - HValueToDouble(hThis, argOne));
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::logical_not_operator(FXJSE_HOBJECT hThis,
+                                             const CFX_ByteStringC& szFuncName,
+                                             CFXJSE_Arguments& args) {
+  int32_t iLength = args.GetLength();
+  if (iLength == 1) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    if (FXJSE_Value_IsNull(argOne)) {
+      FXJSE_Value_SetNull(args.GetReturnValue());
+    } else {
+      FX_DOUBLE first = HValueToDouble(hThis, argOne);
+      FXJSE_Value_SetInteger(args.GetReturnValue(), (first == 0.0) ? 1 : 0);
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    CXFA_FM2JSContext* pContext =
+        (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::dot_accessor(FXJSE_HOBJECT hThis,
+                                     const CFX_ByteStringC& szFuncName,
+                                     CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  int32_t argc = args.GetLength();
+  if ((argc == 4) || (argc == 5)) {
+    FX_BOOL bIsStar = TRUE;
+    FXJSE_HVALUE argAccessor = args.GetValue(0);
+    CFX_ByteString bsAccessorName = args.GetUTF8String(1);
+    CFX_ByteString szName = args.GetUTF8String(2);
+    int32_t iIndexFlags = args.GetInt32(3);
+    int32_t iIndexValue = 0;
+    FXJSE_HVALUE argIndex = NULL;
+    if (argc == 5) {
+      bIsStar = FALSE;
+      argIndex = args.GetValue(4);
+      iIndexValue = HValueToInteger(hThis, argIndex);
+    }
+    CFX_ByteString szSomExp;
+    GenerateSomExpression(szName, iIndexFlags, iIndexValue, bIsStar, szSomExp);
+    if (FXJSE_Value_IsArray(argAccessor)) {
+      FXJSE_HVALUE hLengthValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectProp(argAccessor, "length", hLengthValue);
+      int32_t iLength = FXJSE_Value_ToInteger(hLengthValue);
+      FXJSE_Value_Release(hLengthValue);
+      int32_t iCounter = 0;
+      FXJSE_HVALUE** hResolveValues = FX_Alloc(FXJSE_HVALUE*, iLength - 2);
+      int32_t* iSizes = FX_Alloc(int32_t, iLength - 2);
+      for (int32_t i = 0; i < (iLength - 2); i++) {
+        iSizes[i] = 0;
+      }
+      FXJSE_HVALUE hJSObjValue = FXJSE_Value_Create(hruntime);
+      FX_BOOL bAttribute = FALSE;
+      for (int32_t i = 2; i < iLength; i++) {
+        FXJSE_Value_GetObjectPropByIdx(argAccessor, i, hJSObjValue);
+        XFA_RESOLVENODE_RS resoveNodeRS;
+        int32_t iRet = ResolveObjects(hThis, hJSObjValue, szSomExp,
+                                      resoveNodeRS, TRUE, szName.IsEmpty());
+        if (iRet > 0) {
+          ParseResolveResult(hThis, resoveNodeRS, hJSObjValue,
+                             hResolveValues[i - 2], iSizes[i - 2], bAttribute);
+          iCounter += iSizes[i - 2];
+        }
+      }
+      FXJSE_Value_Release(hJSObjValue);
+      if (iCounter > 0) {
+        FXJSE_HVALUE* rgValues = FX_Alloc(FXJSE_HVALUE, iCounter + 2);
+        for (int32_t i = 0; i < (iCounter + 2); i++) {
+          rgValues[i] = FXJSE_Value_Create(hruntime);
+        }
+        FXJSE_Value_SetInteger(rgValues[0], 1);
+        if (bAttribute) {
+          FXJSE_Value_SetUTF8String(rgValues[1], szName);
+        } else {
+          FXJSE_Value_SetNull(rgValues[1]);
+        }
+        int32_t iIndex = 2;
+        for (int32_t i = 0; i < iLength - 2; i++) {
+          for (int32_t j = 0; j < iSizes[i]; j++) {
+            FXJSE_Value_Set(rgValues[iIndex], hResolveValues[i][j]);
+            iIndex++;
+          }
+        }
+        FXJSE_Value_SetArray(args.GetReturnValue(), (iCounter + 2), rgValues);
+        for (int32_t i = 0; i < (iCounter + 2); i++) {
+          FXJSE_Value_Release(rgValues[i]);
+        }
+        FX_Free(rgValues);
+      } else {
+        CFX_WideString wsPropertyName =
+            CFX_WideString::FromUTF8(szName, szName.GetLength());
+        CFX_WideString wsSomExpression =
+            CFX_WideString::FromUTF8(szSomExp, szSomExp.GetLength());
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT,
+                                          (const FX_WCHAR*)wsPropertyName,
+                                          (const FX_WCHAR*)wsSomExpression);
+      }
+      for (int32_t i = 0; i < iLength - 2; i++) {
+        for (int32_t j = 0; j < iSizes[i]; j++) {
+          FXJSE_Value_Release(hResolveValues[i][j]);
+        }
+        if (iSizes[i] > 0) {
+          FX_Free(hResolveValues[i]);
+        }
+      }
+      FX_Free(hResolveValues);
+      FX_Free(iSizes);
+    } else {
+      XFA_RESOLVENODE_RS resoveNodeRS;
+      int32_t iRet = 0;
+      if (FXJSE_Value_IsObject(argAccessor) ||
+          (FXJSE_Value_IsNull(argAccessor) && bsAccessorName.IsEmpty())) {
+        iRet = ResolveObjects(hThis, argAccessor, szSomExp, resoveNodeRS, TRUE,
+                              szName.IsEmpty());
+      } else if (!FXJSE_Value_IsObject(argAccessor) &&
+                 !bsAccessorName.IsEmpty()) {
+        FX_BOOL bGetObject =
+            GetObjectByName(hThis, argAccessor, bsAccessorName);
+        if (bGetObject) {
+          iRet = ResolveObjects(hThis, argAccessor, szSomExp, resoveNodeRS,
+                                TRUE, szName.IsEmpty());
+        }
+      }
+      if (iRet > 0) {
+        FXJSE_HVALUE* hResolveValues;
+        int32_t iSize = 0;
+        FX_BOOL bAttribute = FALSE;
+        ParseResolveResult(hThis, resoveNodeRS, argAccessor, hResolveValues,
+                           iSize, bAttribute);
+        FXJSE_HVALUE* rgValues = FX_Alloc(FXJSE_HVALUE, iSize + 2);
+        for (int32_t i = 0; i < (iSize + 2); i++) {
+          rgValues[i] = FXJSE_Value_Create(hruntime);
+        }
+        FXJSE_Value_SetInteger(rgValues[0], 1);
+        if (bAttribute) {
+          FXJSE_Value_SetUTF8String(rgValues[1], szName);
+        } else {
+          FXJSE_Value_SetNull(rgValues[1]);
+        }
+        for (int32_t i = 0; i < iSize; i++) {
+          FXJSE_Value_Set(rgValues[i + 2], hResolveValues[i]);
+        }
+        FXJSE_Value_SetArray(args.GetReturnValue(), (iSize + 2), rgValues);
+        for (int32_t i = 0; i < (iSize + 2); i++) {
+          FXJSE_Value_Release(rgValues[i]);
+        }
+        FX_Free(rgValues);
+        for (int32_t i = 0; i < iSize; i++) {
+          FXJSE_Value_Release(hResolveValues[i]);
+        }
+        FX_Free(hResolveValues);
+      } else {
+        CFX_WideString wsPropertyName =
+            CFX_WideString::FromUTF8(szName, szName.GetLength());
+        CFX_WideString wsSomExpression =
+            CFX_WideString::FromUTF8(szSomExp, szSomExp.GetLength());
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT,
+                                          (const FX_WCHAR*)wsPropertyName,
+                                          (const FX_WCHAR*)wsSomExpression);
+      }
+    }
+    if (argc == 5) {
+      FXJSE_Value_Release(argIndex);
+    }
+    FXJSE_Value_Release(argAccessor);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::dotdot_accessor(FXJSE_HOBJECT hThis,
+                                        const CFX_ByteStringC& szFuncName,
+                                        CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  int32_t argc = args.GetLength();
+  if ((argc == 4) || (argc == 5)) {
+    FX_BOOL bIsStar = TRUE;
+    FXJSE_HVALUE argAccessor = args.GetValue(0);
+    CFX_ByteString bsAccessorName = args.GetUTF8String(1);
+    CFX_ByteString szName = args.GetUTF8String(2);
+    int32_t iIndexFlags = args.GetInt32(3);
+    int32_t iIndexValue = 0;
+    FXJSE_HVALUE argIndex = NULL;
+    if (argc == 5) {
+      bIsStar = FALSE;
+      argIndex = args.GetValue(4);
+      iIndexValue = HValueToInteger(hThis, argIndex);
+    }
+    CFX_ByteString szSomExp;
+    GenerateSomExpression(szName, iIndexFlags, iIndexValue, bIsStar, szSomExp);
+    if (FXJSE_Value_IsArray(argAccessor)) {
+      FXJSE_HVALUE hLengthValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectProp(argAccessor, "length", hLengthValue);
+      int32_t iLength = FXJSE_Value_ToInteger(hLengthValue);
+      int32_t iCounter = 0;
+      FXJSE_HVALUE** hResolveValues = FX_Alloc(FXJSE_HVALUE*, iLength - 2);
+      int32_t* iSizes = FX_Alloc(int32_t, iLength - 2);
+      FXJSE_HVALUE hJSObjValue = FXJSE_Value_Create(hruntime);
+      FX_BOOL bAttribute = FALSE;
+      for (int32_t i = 2; i < iLength; i++) {
+        FXJSE_Value_GetObjectPropByIdx(argAccessor, i, hJSObjValue);
+        XFA_RESOLVENODE_RS resoveNodeRS;
+        int32_t iRet =
+            ResolveObjects(hThis, hJSObjValue, szSomExp, resoveNodeRS, FALSE);
+        if (iRet > 0) {
+          ParseResolveResult(hThis, resoveNodeRS, hJSObjValue,
+                             hResolveValues[i - 2], iSizes[i - 2], bAttribute);
+          iCounter += iSizes[i - 2];
+        }
+      }
+      FXJSE_Value_Release(hJSObjValue);
+      if (iCounter > 0) {
+        FXJSE_HVALUE* rgValues = FX_Alloc(FXJSE_HVALUE, iCounter + 2);
+        for (int32_t i = 0; i < (iCounter + 2); i++) {
+          rgValues[i] = FXJSE_Value_Create(hruntime);
+        }
+        FXJSE_Value_SetInteger(rgValues[0], 1);
+        if (bAttribute) {
+          FXJSE_Value_SetUTF8String(rgValues[1], szName);
+        } else {
+          FXJSE_Value_SetNull(rgValues[1]);
+        }
+        int32_t iIndex = 2;
+        for (int32_t i = 0; i < iLength - 2; i++) {
+          for (int32_t j = 0; j < iSizes[i]; j++) {
+            FXJSE_Value_Set(rgValues[iIndex], hResolveValues[i][j]);
+            iIndex++;
+          }
+        }
+        FXJSE_Value_SetArray(args.GetReturnValue(), (iCounter + 2), rgValues);
+        for (int32_t i = 0; i < (iCounter + 2); i++) {
+          FXJSE_Value_Release(rgValues[i]);
+        }
+        FX_Free(rgValues);
+      } else {
+        CFX_WideString wsPropertyName =
+            CFX_WideString::FromUTF8(szName, szName.GetLength());
+        CFX_WideString wsSomExpression =
+            CFX_WideString::FromUTF8(szSomExp, szSomExp.GetLength());
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT,
+                                          (const FX_WCHAR*)wsPropertyName,
+                                          (const FX_WCHAR*)wsSomExpression);
+      }
+      for (int32_t i = 0; i < iLength - 2; i++) {
+        for (int32_t j = 0; j < iSizes[i]; j++) {
+          FXJSE_Value_Release(hResolveValues[i][j]);
+        }
+        FX_Free(hResolveValues[i]);
+      }
+      FX_Free(hResolveValues);
+      FX_Free(iSizes);
+      FXJSE_Value_Release(hLengthValue);
+    } else {
+      XFA_RESOLVENODE_RS resoveNodeRS;
+      int32_t iRet = 0;
+      if (FXJSE_Value_IsObject(argAccessor) ||
+          (FXJSE_Value_IsNull(argAccessor) && bsAccessorName.IsEmpty())) {
+        iRet =
+            ResolveObjects(hThis, argAccessor, szSomExp, resoveNodeRS, FALSE);
+      } else if (!FXJSE_Value_IsObject(argAccessor) &&
+                 !bsAccessorName.IsEmpty()) {
+        FX_BOOL bGetObject =
+            GetObjectByName(hThis, argAccessor, bsAccessorName);
+        if (bGetObject) {
+          iRet =
+              ResolveObjects(hThis, argAccessor, szSomExp, resoveNodeRS, FALSE);
+        }
+      }
+      if (iRet > 0) {
+        FXJSE_HVALUE* hResolveValues;
+        int32_t iSize = 0;
+        FX_BOOL bAttribute = FALSE;
+        ParseResolveResult(hThis, resoveNodeRS, argAccessor, hResolveValues,
+                           iSize, bAttribute);
+        FXJSE_HVALUE* rgValues = FX_Alloc(FXJSE_HVALUE, iSize + 2);
+        for (int32_t i = 0; i < (iSize + 2); i++) {
+          rgValues[i] = FXJSE_Value_Create(hruntime);
+        }
+        FXJSE_Value_SetInteger(rgValues[0], 1);
+        if (bAttribute) {
+          FXJSE_Value_SetUTF8String(rgValues[1], szName);
+        } else {
+          FXJSE_Value_SetNull(rgValues[1]);
+        }
+        for (int32_t i = 0; i < iSize; i++) {
+          FXJSE_Value_Set(rgValues[i + 2], hResolveValues[i]);
+        }
+        FXJSE_Value_SetArray(args.GetReturnValue(), (iSize + 2), rgValues);
+        for (int32_t i = 0; i < (iSize + 2); i++) {
+          FXJSE_Value_Release(rgValues[i]);
+        }
+        FX_Free(rgValues);
+        for (int32_t i = 0; i < iSize; i++) {
+          FXJSE_Value_Release(hResolveValues[i]);
+        }
+        FX_Free(hResolveValues);
+      } else {
+        CFX_WideString wsPropertyName =
+            CFX_WideString::FromUTF8(szName, szName.GetLength());
+        CFX_WideString wsSomExpression =
+            CFX_WideString::FromUTF8(szSomExp, szSomExp.GetLength());
+        pContext->ThrowScriptErrorMessage(XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT,
+                                          (const FX_WCHAR*)wsPropertyName,
+                                          (const FX_WCHAR*)wsSomExpression);
+      }
+    }
+    if (argc == 5) {
+      FXJSE_Value_Release(argIndex);
+    }
+    FXJSE_Value_Release(argAccessor);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::eval_translation(FXJSE_HOBJECT hThis,
+                                         const CFX_ByteStringC& szFuncName,
+                                         CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  int32_t argc = args.GetLength();
+  if (argc == 1) {
+    FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+    CFX_ByteString argString;
+    HValueToUTF8String(argOne, argString);
+    if (argString.IsEmpty()) {
+      pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+    } else {
+      CFX_WideString scriptString =
+          CFX_WideString::FromUTF8(argString, argString.GetLength());
+      CFX_WideTextBuf wsJavaScriptBuf;
+      CFX_WideString wsError;
+      XFA_FM2JS_Translate(scriptString, wsJavaScriptBuf, wsError);
+      if (wsError.IsEmpty()) {
+        CFX_WideString javaScript = wsJavaScriptBuf.GetWideString();
+        FXJSE_Value_SetUTF8String(
+            args.GetReturnValue(),
+            FX_UTF8Encode(javaScript, javaScript.GetLength()));
+      } else {
+        pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+      }
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                                      L"Eval");
+  }
+}
+void CXFA_FM2JSContext::is_fm_object(FXJSE_HOBJECT hThis,
+                                     const CFX_ByteStringC& szFuncName,
+                                     CFXJSE_Arguments& args) {
+  int32_t iLength = args.GetLength();
+  if (iLength == 1) {
+    FXJSE_HVALUE argOne = args.GetValue(0);
+    FXJSE_Value_SetBoolean(args.GetReturnValue(), FXJSE_Value_IsObject(argOne));
+    FXJSE_Value_Release(argOne);
+  } else {
+    FXJSE_Value_SetBoolean(args.GetReturnValue(), FALSE);
+  }
+}
+void CXFA_FM2JSContext::is_fm_array(FXJSE_HOBJECT hThis,
+                                    const CFX_ByteStringC& szFuncName,
+                                    CFXJSE_Arguments& args) {
+  int32_t iLength = args.GetLength();
+  if (iLength == 1) {
+    FXJSE_HVALUE argOne = args.GetValue(0);
+    FX_BOOL bIsArray = FXJSE_Value_IsArray(argOne);
+    FXJSE_Value_SetBoolean(args.GetReturnValue(), bIsArray);
+    FXJSE_Value_Release(argOne);
+  } else {
+    FXJSE_Value_SetBoolean(args.GetReturnValue(), FALSE);
+  }
+}
+void CXFA_FM2JSContext::get_fm_value(FXJSE_HOBJECT hThis,
+                                     const CFX_ByteStringC& szFuncName,
+                                     CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  int32_t iLength = args.GetLength();
+  if (iLength == 1) {
+    FXJSE_HVALUE argOne = args.GetValue(0);
+    if (FXJSE_Value_IsArray(argOne)) {
+      FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+      FXJSE_HVALUE jsobjectValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectPropByIdx(argOne, 1, propertyValue);
+      FXJSE_Value_GetObjectPropByIdx(argOne, 2, jsobjectValue);
+      if (FXJSE_Value_IsNull(propertyValue)) {
+        GetObjectDefaultValue(jsobjectValue, args.GetReturnValue());
+      } else {
+        CFX_ByteString propertyStr;
+        FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+        FXJSE_Value_GetObjectProp(jsobjectValue, propertyStr,
+                                  args.GetReturnValue());
+      }
+      FXJSE_Value_Release(propertyValue);
+      FXJSE_Value_Release(jsobjectValue);
+    } else if (FXJSE_Value_IsObject(argOne)) {
+      GetObjectDefaultValue(argOne, args.GetReturnValue());
+    } else {
+      FXJSE_Value_Set(args.GetReturnValue(), argOne);
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::get_fm_jsobj(FXJSE_HOBJECT hThis,
+                                     const CFX_ByteStringC& szFuncName,
+                                     CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      static_cast<CXFA_FM2JSContext*>(FXJSE_Value_ToObject(hThis, nullptr));
+  int32_t argc = args.GetLength();
+  if (argc == 1) {
+    FXJSE_HVALUE argOne = args.GetValue(0);
+    if (FXJSE_Value_IsArray(argOne)) {
+#ifndef NDEBUG
+      FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+      FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectProp(argOne, "length", lengthValue);
+      FXSYS_assert(FXJSE_Value_ToInteger(lengthValue) >= 3);
+      FXJSE_Value_Release(lengthValue);
+#endif
+      FXJSE_Value_GetObjectPropByIdx(argOne, 2, args.GetReturnValue());
+    } else {
+      FXJSE_Value_Set(args.GetReturnValue(), argOne);
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::fm_var_filter(FXJSE_HOBJECT hThis,
+                                      const CFX_ByteStringC& szFuncName,
+                                      CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  int32_t argc = args.GetLength();
+  if (argc == 1) {
+    FXJSE_HVALUE argOne = args.GetValue(0);
+    if (FXJSE_Value_IsArray(argOne)) {
+#ifndef NDEBUG
+      FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectProp(argOne, "length", lengthValue);
+      FXSYS_assert(FXJSE_Value_ToInteger(lengthValue) >= 3);
+      FXJSE_Value_Release(lengthValue);
+#endif
+      FXJSE_HVALUE flagsValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectPropByIdx(argOne, 0, flagsValue);
+      int32_t iFlags = FXJSE_Value_ToInteger(flagsValue);
+      FXJSE_Value_Release(flagsValue);
+      if (iFlags == 4) {
+        FXJSE_HVALUE rgValues[3];
+        for (int32_t i = 0; i < 3; i++) {
+          rgValues[i] = FXJSE_Value_Create(hruntime);
+        }
+        FXJSE_Value_SetInteger(rgValues[0], 3);
+        FXJSE_Value_SetNull(rgValues[1]);
+        FXJSE_Value_SetNull(rgValues[2]);
+        FXJSE_Value_SetArray(args.GetReturnValue(), 3, rgValues);
+        for (int32_t i = 0; i < 3; i++) {
+          FXJSE_Value_Release(rgValues[i]);
+        }
+      } else if (iFlags == 3) {
+        FXJSE_HVALUE objectValue = FXJSE_Value_Create(hruntime);
+        FXJSE_Value_GetObjectPropByIdx(argOne, 2, objectValue);
+        if (!FXJSE_Value_IsNull(objectValue)) {
+          FXJSE_Value_Set(args.GetReturnValue(), argOne);
+        } else {
+          pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+        }
+        FXJSE_Value_Release(objectValue);
+      } else {
+        FXJSE_HVALUE simpleValue = GetSimpleHValue(hThis, args, 0);
+        FXJSE_Value_Set(args.GetReturnValue(), simpleValue);
+        FXJSE_Value_Release(simpleValue);
+      }
+    } else {
+      FXJSE_HVALUE simpleValue = GetSimpleHValue(hThis, args, 0);
+      FXJSE_Value_Set(args.GetReturnValue(), simpleValue);
+      FXJSE_Value_Release(simpleValue);
+    }
+    FXJSE_Value_Release(argOne);
+  } else {
+    pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+  }
+}
+void CXFA_FM2JSContext::concat_fm_object(FXJSE_HOBJECT hThis,
+                                         const CFX_ByteStringC& szFuncName,
+                                         CFXJSE_Arguments& args) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  uint32_t iLength = 0;
+  int32_t argCount = args.GetLength();
+  FXJSE_HVALUE* argValues = FX_Alloc(FXJSE_HVALUE, argCount);
+  for (int32_t i = 0; i < argCount; i++) {
+    argValues[i] = args.GetValue(i);
+    if (FXJSE_Value_IsArray(argValues[i])) {
+      FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectProp(argValues[i], "length", lengthValue);
+      int32_t length = FXJSE_Value_ToInteger(lengthValue);
+      iLength = iLength + ((length > 2) ? (length - 2) : 0);
+      FXJSE_Value_Release(lengthValue);
+    }
+    iLength += 1;
+  }
+  FXJSE_HVALUE* returnValues = FX_Alloc(FXJSE_HVALUE, iLength);
+  for (int32_t i = 0; i < (int32_t)iLength; i++) {
+    returnValues[i] = FXJSE_Value_Create(hruntime);
+  }
+  int32_t index = 0;
+  for (int32_t i = 0; i < argCount; i++) {
+    if (FXJSE_Value_IsArray(argValues[i])) {
+      FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectProp(argValues[i], "length", lengthValue);
+      int32_t length = FXJSE_Value_ToInteger(lengthValue);
+      for (int32_t j = 2; j < length; j++) {
+        FXJSE_Value_GetObjectPropByIdx(argValues[i], j, returnValues[index]);
+        index++;
+      }
+      FXJSE_Value_Release(lengthValue);
+    }
+    FXJSE_Value_Set(returnValues[index], argValues[i]);
+    index++;
+  }
+  FXJSE_Value_SetArray(args.GetReturnValue(), iLength, returnValues);
+  for (int32_t i = 0; i < argCount; i++) {
+    FXJSE_Value_Release(argValues[i]);
+  }
+  FX_Free(argValues);
+  for (int32_t i = 0; i < (int32_t)iLength; i++) {
+    FXJSE_Value_Release(returnValues[i]);
+  }
+  FX_Free(returnValues);
+}
+FXJSE_HVALUE CXFA_FM2JSContext::GetSimpleHValue(FXJSE_HOBJECT hThis,
+                                                CFXJSE_Arguments& args,
+                                                uint32_t index) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  FXSYS_assert(index < (uint32_t)args.GetLength());
+  FXJSE_HVALUE argIndex = args.GetValue(index);
+  if (FXJSE_Value_IsArray(argIndex)) {
+    FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+    FXJSE_Value_GetObjectProp(argIndex, "length", lengthValue);
+    int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
+    FXJSE_Value_Release(lengthValue);
+    FXJSE_HVALUE simpleValue = FXJSE_Value_Create(hruntime);
+    if (iLength > 2) {
+      FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+      FXJSE_HVALUE jsobjectValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectPropByIdx(argIndex, 1, propertyValue);
+      FXJSE_Value_GetObjectPropByIdx(argIndex, 2, jsobjectValue);
+      if (FXJSE_Value_IsNull(propertyValue)) {
+        GetObjectDefaultValue(jsobjectValue, simpleValue);
+      } else {
+        CFX_ByteString propertyStr;
+        FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+        FXJSE_Value_GetObjectProp(jsobjectValue, propertyStr, simpleValue);
+      }
+      FXJSE_Value_Release(propertyValue);
+      FXJSE_Value_Release(jsobjectValue);
+    } else {
+      FXJSE_Value_SetUndefined(simpleValue);
+    }
+    FXJSE_Value_Release(argIndex);
+    return simpleValue;
+  } else if (FXJSE_Value_IsObject(argIndex)) {
+    FXJSE_HVALUE defaultValue = FXJSE_Value_Create(hruntime);
+    GetObjectDefaultValue(argIndex, defaultValue);
+    FXJSE_Value_Release(argIndex);
+    return defaultValue;
+  } else {
+    return argIndex;
+  }
+}
+FX_BOOL CXFA_FM2JSContext::HValueIsNull(FXJSE_HOBJECT hThis, FXJSE_HVALUE arg) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  FX_BOOL isNull = FALSE;
+  if (FXJSE_Value_IsNull(arg)) {
+    isNull = TRUE;
+  } else if (FXJSE_Value_IsArray(arg)) {
+    int32_t iLength = hvalue_get_array_length(hThis, arg);
+    if (iLength > 2) {
+      FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+      FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectPropByIdx(arg, 1, propertyValue);
+      FXJSE_Value_GetObjectPropByIdx(arg, 2, jsObjectValue);
+      if (FXJSE_Value_IsNull(propertyValue)) {
+        FXJSE_HVALUE defaultValue = FXJSE_Value_Create(hruntime);
+        GetObjectDefaultValue(jsObjectValue, defaultValue);
+        if (FXJSE_Value_IsNull(defaultValue)) {
+          isNull = TRUE;
+        }
+        FXJSE_Value_Release(defaultValue);
+      } else {
+        CFX_ByteString propertyStr;
+        FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+        FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+        FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr, newPropertyValue);
+        if (FXJSE_Value_IsNull(newPropertyValue)) {
+          isNull = TRUE;
+        }
+        FXJSE_Value_Release(newPropertyValue);
+      }
+      FXJSE_Value_Release(propertyValue);
+      FXJSE_Value_Release(jsObjectValue);
+    } else {
+      isNull = TRUE;
+    }
+  } else if (FXJSE_Value_IsObject(arg)) {
+    FXJSE_HVALUE defaultValue = FXJSE_Value_Create(hruntime);
+    GetObjectDefaultValue(arg, defaultValue);
+    if (FXJSE_Value_IsNull(defaultValue)) {
+      isNull = TRUE;
+    }
+    FXJSE_Value_Release(defaultValue);
+  }
+  return isNull;
+}
+int32_t CXFA_FM2JSContext::hvalue_get_array_length(FXJSE_HOBJECT hThis,
+                                                   FXJSE_HVALUE arg) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  int32_t iLength = 0;
+  if (FXJSE_Value_IsArray(arg)) {
+    FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+    FXJSE_Value_GetObjectProp(arg, "length", lengthValue);
+    iLength = FXJSE_Value_ToInteger(lengthValue);
+    FXJSE_Value_Release(lengthValue);
+  }
+  return iLength;
+}
+FX_BOOL CXFA_FM2JSContext::simpleValueCompare(FXJSE_HOBJECT hThis,
+                                              FXJSE_HVALUE firstValue,
+                                              FXJSE_HVALUE secondValue) {
+  FX_BOOL bReturn = FALSE;
+  if (FXJSE_Value_IsUTF8String(firstValue)) {
+    CFX_ByteString firstString, secondString;
+    HValueToUTF8String(firstValue, firstString);
+    HValueToUTF8String(secondValue, secondString);
+    bReturn = firstString.Equal(secondString);
+  } else if (FXJSE_Value_IsNumber(firstValue)) {
+    FX_FLOAT first = HValueToFloat(hThis, firstValue);
+    FX_FLOAT second = HValueToFloat(hThis, secondValue);
+    bReturn = (first == second);
+  } else if (FXJSE_Value_IsBoolean(firstValue)) {
+    bReturn = (FXJSE_Value_ToBoolean(firstValue) ==
+               FXJSE_Value_ToBoolean(secondValue));
+  } else if (FXJSE_Value_IsNull(firstValue) &&
+             FXJSE_Value_IsNull(secondValue)) {
+    bReturn = TRUE;
+  }
+  return bReturn;
+}
+void CXFA_FM2JSContext::unfoldArgs(FXJSE_HOBJECT hThis,
+                                   CFXJSE_Arguments& args,
+                                   FXJSE_HVALUE*& resultValues,
+                                   int32_t& iCount,
+                                   int32_t iStart) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  iCount = 0;
+  int32_t argc = args.GetLength();
+  FXJSE_HVALUE* argsValue = FX_Alloc(FXJSE_HVALUE, argc);
+  for (int32_t i = iStart; i < argc; i++) {
+    argsValue[i] = args.GetValue(i);
+    if (FXJSE_Value_IsArray(argsValue[i])) {
+      FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectProp(argsValue[i], "length", lengthValue);
+      int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
+      FXJSE_Value_Release(lengthValue);
+      iCount += ((iLength > 2) ? (iLength - 2) : 0);
+    } else {
+      iCount += 1;
+    }
+  }
+  resultValues = FX_Alloc(FXJSE_HVALUE, iCount);
+  for (int32_t i = 0; i < iCount; i++) {
+    resultValues[i] = FXJSE_Value_Create(hruntime);
+  }
+  int32_t index = 0;
+  for (int32_t i = iStart; i < argc; i++) {
+    if (FXJSE_Value_IsArray(argsValue[i])) {
+      FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+      FXJSE_Value_GetObjectProp(argsValue[i], "length", lengthValue);
+      int32_t iLength = FXJSE_Value_ToInteger(lengthValue);
+      FXJSE_Value_Release(lengthValue);
+      if (iLength > 2) {
+        FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+        FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+        FXJSE_Value_GetObjectPropByIdx(argsValue[i], 1, propertyValue);
+        if (FXJSE_Value_IsNull(propertyValue)) {
+          for (int32_t j = 2; j < iLength; j++) {
+            FXJSE_Value_GetObjectPropByIdx(argsValue[i], j, jsObjectValue);
+            GetObjectDefaultValue(jsObjectValue, resultValues[index]);
+            index++;
+          }
+        } else {
+          CFX_ByteString propertyString;
+          FXJSE_Value_ToUTF8String(propertyValue, propertyString);
+          for (int32_t j = 2; j < iLength; j++) {
+            FXJSE_Value_GetObjectPropByIdx(argsValue[i], j, jsObjectValue);
+            FXJSE_Value_GetObjectProp(jsObjectValue, propertyString,
+                                      resultValues[index]);
+            index++;
+          }
+        }
+        FXJSE_Value_Release(propertyValue);
+        FXJSE_Value_Release(jsObjectValue);
+      }
+    } else if (FXJSE_Value_IsObject(argsValue[i])) {
+      GetObjectDefaultValue(argsValue[i], resultValues[index]);
+      index++;
+    } else {
+      FXJSE_Value_Set(resultValues[index], argsValue[i]);
+      index++;
+    }
+  }
+  for (int32_t i = iStart; i < argc; i++) {
+    FXJSE_Value_Release(argsValue[i]);
+  }
+  FX_Free(argsValue);
+}
+void CXFA_FM2JSContext::GetObjectDefaultValue(FXJSE_HVALUE hObjectValue,
+                                              FXJSE_HVALUE hDefaultValue) {
+  CXFA_Node* pNode =
+      ToNode((CXFA_Object*)FXJSE_Value_ToObject(hObjectValue, NULL));
+  if (pNode) {
+    pNode->Script_Som_DefaultValue(hDefaultValue, FALSE, (XFA_ATTRIBUTE)-1);
+  } else {
+    FXJSE_Value_SetNull(hDefaultValue);
+  }
+}
+FX_BOOL CXFA_FM2JSContext::SetObjectDefaultValue(FXJSE_HVALUE hObjectValue,
+                                                 FXJSE_HVALUE hNewValue) {
+  CXFA_Node* pNode =
+      ToNode((CXFA_Object*)FXJSE_Value_ToObject(hObjectValue, NULL));
+  if (pNode) {
+    pNode->Script_Som_DefaultValue(hNewValue, TRUE, (XFA_ATTRIBUTE)-1);
+    return TRUE;
+  }
+  return FALSE;
+}
+void CXFA_FM2JSContext::GenerateSomExpression(const CFX_ByteStringC& szName,
+                                              int32_t iIndexFlags,
+                                              int32_t iIndexValue,
+                                              FX_BOOL bIsStar,
+                                              CFX_ByteString& szSomExp) {
+  if (bIsStar) {
+    szSomExp = szName + "[*]";
+    return;
+  }
+  if (iIndexFlags == 0) {
+    szSomExp = szName;
+    return;
+  }
+  if (iIndexFlags == 1 || iIndexValue == 0) {
+    szSomExp = szName + "[" +
+               CFX_ByteString::FormatInteger(iIndexValue, FXFORMAT_SIGNED) +
+               "]";
+  } else if (iIndexFlags == 2) {
+    szSomExp = (iIndexValue < 0) ? (szName + "[-") : (szName + "[+");
+    iIndexValue = (iIndexValue < 0) ? (0 - iIndexValue) : iIndexValue;
+    szSomExp += CFX_ByteString::FormatInteger(iIndexValue);
+    szSomExp += "]";
+  } else {
+    szSomExp = (iIndexValue < 0) ? (szName + "[") : (szName + "[-");
+    iIndexValue = (iIndexValue < 0) ? (0 - iIndexValue) : iIndexValue;
+    szSomExp += CFX_ByteString::FormatInteger(iIndexValue);
+    szSomExp += "]";
+  }
+}
+FX_BOOL CXFA_FM2JSContext::GetObjectByName(
+    FXJSE_HOBJECT hThis,
+    FXJSE_HVALUE accessorValue,
+    const CFX_ByteStringC& szAccessorName) {
+  FX_BOOL bFlags = FALSE;
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  CXFA_Document* pDoc = pContext->GetDocument();
+  if (!pDoc) {
+    return bFlags;
+  }
+  IXFA_ScriptContext* pScriptContext = pDoc->GetScriptContext();
+  XFA_RESOLVENODE_RS resoveNodeRS;
+  FX_DWORD dwFlags = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
+                     XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent;
+  int32_t iRet = pScriptContext->ResolveObjects(
+      pScriptContext->GetThisObject(),
+      CFX_WideString::FromUTF8(szAccessorName.GetCStr(),
+                               szAccessorName.GetLength()),
+      resoveNodeRS, dwFlags);
+  if (iRet >= 1 && resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
+    FXJSE_Value_Set(accessorValue, pScriptContext->GetJSValueFromMap(
+                                       resoveNodeRS.nodes.GetAt(0)));
+    bFlags = TRUE;
+  }
+  return bFlags;
+}
+int32_t CXFA_FM2JSContext::ResolveObjects(FXJSE_HOBJECT hThis,
+                                          FXJSE_HVALUE hRefValue,
+                                          const CFX_ByteStringC& bsSomExp,
+                                          XFA_RESOLVENODE_RS& resoveNodeRS,
+                                          FX_BOOL bdotAccessor,
+                                          FX_BOOL bHasNoResolveName) {
+  CFX_WideString wsSomExpression =
+      CFX_WideString::FromUTF8(bsSomExp.GetCStr(), bsSomExp.GetLength());
+  int32_t iRet = -1;
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  CXFA_Document* pDoc = pContext->GetDocument();
+  if (!pDoc) {
+    return iRet;
+  }
+  IXFA_ScriptContext* pScriptContext = pDoc->GetScriptContext();
+  CXFA_Object* pNode = NULL;
+  FX_DWORD dFlags = 0UL;
+  if (bdotAccessor) {
+    if (FXJSE_Value_IsNull(hRefValue)) {
+      pNode = pScriptContext->GetThisObject();
+      dFlags = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent;
+    } else {
+      pNode = (CXFA_Object*)FXJSE_Value_ToObject(hRefValue, NULL);
+      FXSYS_assert(pNode);
+      if (bHasNoResolveName) {
+        CFX_WideString wsName;
+        if (CXFA_Node* pXFANode = pNode->AsNode()) {
+          pXFANode->GetAttribute(XFA_ATTRIBUTE_Name, wsName, FALSE);
+        }
+        if (wsName.IsEmpty()) {
+          CFX_WideStringC className;
+          pNode->GetClassName(className);
+          wsName = FX_WSTRC(L"#") + className;
+        }
+        wsSomExpression = wsName + wsSomExpression;
+        dFlags = XFA_RESOLVENODE_Siblings;
+      } else {
+        dFlags = (bsSomExp == "*")
+                     ? (XFA_RESOLVENODE_Children)
+                     : (XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
+                        XFA_RESOLVENODE_Properties);
+      }
+    }
+  } else {
+    pNode = (CXFA_Object*)FXJSE_Value_ToObject(hRefValue, NULL);
+    dFlags = XFA_RESOLVENODE_AnyChild;
+  }
+  iRet = pScriptContext->ResolveObjects(pNode, wsSomExpression, resoveNodeRS,
+                                        dFlags);
+  return iRet;
+}
+void CXFA_FM2JSContext::ParseResolveResult(
+    FXJSE_HOBJECT hThis,
+    const XFA_RESOLVENODE_RS& resoveNodeRS,
+    FXJSE_HVALUE hParentValue,
+    FXJSE_HVALUE*& resultValues,
+    int32_t& iSize,
+    FX_BOOL& bAttribute) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hRuntime = pContext->GetScriptRuntime();
+  iSize = 0;
+  resultValues = NULL;
+  if (resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
+    bAttribute = FALSE;
+    iSize = resoveNodeRS.nodes.GetSize();
+    resultValues = FX_Alloc(FXJSE_HVALUE, iSize);
+    for (int32_t i = 0; i < iSize; i++) {
+      resultValues[i] = FXJSE_Value_Create(hRuntime);
+      FXJSE_Value_Set(
+          resultValues[i],
+          pContext->GetDocument()->GetScriptContext()->GetJSValueFromMap(
+              resoveNodeRS.nodes.GetAt(i)));
+    }
+  } else {
+    CXFA_HVALUEArray objectProperties(hRuntime);
+    int32_t iRet = resoveNodeRS.GetAttributeResult(objectProperties);
+    bAttribute = (iRet == 0);
+    if (bAttribute) {
+      if (FXJSE_Value_IsObject(hParentValue)) {
+        iSize = 1;
+        resultValues = FX_Alloc(FXJSE_HVALUE, 1);
+        resultValues[0] = FXJSE_Value_Create(hRuntime);
+        FXJSE_Value_Set(resultValues[0], hParentValue);
+      }
+    } else {
+      iSize = iRet;
+      resultValues = FX_Alloc(FXJSE_HVALUE, iSize);
+      for (int32_t i = 0; i < iSize; i++) {
+        resultValues[i] = FXJSE_Value_Create(hRuntime);
+        FXJSE_Value_Set(resultValues[i], objectProperties[i]);
+      }
+    }
+  }
+}
+int32_t CXFA_FM2JSContext::HValueToInteger(FXJSE_HOBJECT hThis,
+                                           FXJSE_HVALUE hValue) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  int32_t iValue = 0;
+  if (FXJSE_Value_IsArray(hValue)) {
+    FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+    FXJSE_HVALUE jsobjectValue = FXJSE_Value_Create(hruntime);
+    FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
+    FXJSE_Value_GetObjectPropByIdx(hValue, 1, propertyValue);
+    FXJSE_Value_GetObjectPropByIdx(hValue, 2, jsobjectValue);
+    if (FXJSE_Value_IsNull(propertyValue)) {
+      GetObjectDefaultValue(jsobjectValue, newProperty);
+    } else {
+      CFX_ByteString propertyStr;
+      FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+      FXJSE_Value_GetObjectProp(jsobjectValue, propertyStr, newProperty);
+    }
+    iValue = HValueToInteger(hThis, newProperty);
+    FXJSE_Value_Release(newProperty);
+    FXJSE_Value_Release(jsobjectValue);
+    FXJSE_Value_Release(propertyValue);
+    return iValue;
+  } else if (FXJSE_Value_IsObject(hValue)) {
+    FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
+    GetObjectDefaultValue(hValue, newProperty);
+    iValue = HValueToInteger(hThis, newProperty);
+    FXJSE_Value_Release(newProperty);
+    return iValue;
+  } else if (FXJSE_Value_IsUTF8String(hValue)) {
+    CFX_ByteString szValue;
+    FXJSE_Value_ToUTF8String(hValue, szValue);
+    iValue = FXSYS_atoi(szValue);
+  } else {
+    iValue = FXJSE_Value_ToInteger(hValue);
+  }
+  return iValue;
+}
+FX_DOUBLE CXFA_FM2JSContext::StringToDouble(
+    const CFX_ByteStringC& szStringVal) {
+  return XFA_ByteStringToDouble(szStringVal);
+}
+FX_FLOAT CXFA_FM2JSContext::HValueToFloat(FXJSE_HOBJECT hThis,
+                                          FXJSE_HVALUE arg) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  FX_FLOAT fRet = 0.0f;
+  if (FXJSE_Value_IsArray(arg)) {
+    FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+    FXJSE_HVALUE jsobjectValue = FXJSE_Value_Create(hruntime);
+    FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
+    FXJSE_Value_GetObjectPropByIdx(arg, 1, propertyValue);
+    FXJSE_Value_GetObjectPropByIdx(arg, 2, jsobjectValue);
+    if (FXJSE_Value_IsNull(propertyValue)) {
+      GetObjectDefaultValue(jsobjectValue, newProperty);
+    } else {
+      CFX_ByteString propertyStr;
+      FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+      FXJSE_Value_GetObjectProp(jsobjectValue, propertyStr, newProperty);
+    }
+    fRet = HValueToFloat(hThis, newProperty);
+    FXJSE_Value_Release(newProperty);
+    FXJSE_Value_Release(jsobjectValue);
+    FXJSE_Value_Release(propertyValue);
+  } else if (FXJSE_Value_IsObject(arg)) {
+    FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
+    GetObjectDefaultValue(arg, newProperty);
+    fRet = HValueToFloat(hThis, newProperty);
+    FXJSE_Value_Release(newProperty);
+  } else if (FXJSE_Value_IsUTF8String(arg)) {
+    CFX_ByteString bsOutput;
+    FXJSE_Value_ToUTF8String(arg, bsOutput);
+    fRet = (FX_FLOAT)StringToDouble(bsOutput);
+  } else if (FXJSE_Value_IsUndefined(arg)) {
+    fRet = 0;
+  } else {
+    fRet = FXJSE_Value_ToFloat(arg);
+  }
+  return fRet;
+}
+FX_DOUBLE CXFA_FM2JSContext::HValueToDouble(FXJSE_HOBJECT hThis,
+                                            FXJSE_HVALUE arg) {
+  CXFA_FM2JSContext* pContext =
+      (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+  FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+  FX_DOUBLE dRet = 0;
+  if (FXJSE_Value_IsArray(arg)) {
+    FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+    FXJSE_HVALUE jsobjectValue = FXJSE_Value_Create(hruntime);
+    FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
+    FXJSE_Value_GetObjectPropByIdx(arg, 1, propertyValue);
+    FXJSE_Value_GetObjectPropByIdx(arg, 2, jsobjectValue);
+    if (FXJSE_Value_IsNull(propertyValue)) {
+      GetObjectDefaultValue(jsobjectValue, newProperty);
+    } else {
+      CFX_ByteString propertyStr;
+      FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+      FXJSE_Value_GetObjectProp(jsobjectValue, propertyStr, newProperty);
+    }
+    dRet = HValueToDouble(hThis, newProperty);
+    FXJSE_Value_Release(newProperty);
+    FXJSE_Value_Release(jsobjectValue);
+    FXJSE_Value_Release(propertyValue);
+  } else if (FXJSE_Value_IsObject(arg)) {
+    FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
+    GetObjectDefaultValue(arg, newProperty);
+    dRet = HValueToDouble(hThis, newProperty);
+    FXJSE_Value_Release(newProperty);
+  } else if (FXJSE_Value_IsUTF8String(arg)) {
+    CFX_ByteString bsOutput;
+    FXJSE_Value_ToUTF8String(arg, bsOutput);
+    dRet = StringToDouble(bsOutput);
+  } else if (FXJSE_Value_IsUndefined(arg)) {
+    dRet = 0;
+  } else {
+    dRet = FXJSE_Value_ToDouble(arg);
+  }
+  return dRet;
+}
+void CXFA_FM2JSContext::HValueToUTF8String(FXJSE_HVALUE arg,
+                                           CFX_ByteString& szOutputString) {
+  if (FXJSE_Value_IsNull(arg) || FXJSE_Value_IsUndefined(arg)) {
+    szOutputString = "";
+  } else if (FXJSE_Value_IsBoolean(arg)) {
+    szOutputString = FXJSE_Value_ToBoolean(arg) ? "1" : "0";
+  } else {
+    szOutputString = "";
+    FXJSE_Value_ToUTF8String(arg, szOutputString);
+  }
+}
+static FXJSE_FUNCTION formcalc_fm2js_functions[] = {
+    {"Abs", CXFA_FM2JSContext::Abs},
+    {"Avg", CXFA_FM2JSContext::Avg},
+    {"Ceil", CXFA_FM2JSContext::Ceil},
+    {"Count", CXFA_FM2JSContext::Count},
+    {"Floor", CXFA_FM2JSContext::Floor},
+    {"Max", CXFA_FM2JSContext::Max},
+    {"Min", CXFA_FM2JSContext::Min},
+    {"Mod", CXFA_FM2JSContext::Mod},
+    {"Round", CXFA_FM2JSContext::Round},
+    {"Sum", CXFA_FM2JSContext::Sum},
+    {"Date", CXFA_FM2JSContext::Date},
+    {"Date2Num", CXFA_FM2JSContext::Date2Num},
+    {"DateFmt", CXFA_FM2JSContext::DateFmt},
+    {"IsoDate2Num", CXFA_FM2JSContext::IsoDate2Num},
+    {"IsoTime2Num", CXFA_FM2JSContext::IsoTime2Num},
+    {"LocalDateFmt", CXFA_FM2JSContext::LocalDateFmt},
+    {"LocalTimeFmt", CXFA_FM2JSContext::LocalTimeFmt},
+    {"Num2Date", CXFA_FM2JSContext::Num2Date},
+    {"Num2GMTime", CXFA_FM2JSContext::Num2GMTime},
+    {"Num2Time", CXFA_FM2JSContext::Num2Time},
+    {"Time", CXFA_FM2JSContext::Time},
+    {"Time2Num", CXFA_FM2JSContext::Time2Num},
+    {"TimeFmt", CXFA_FM2JSContext::TimeFmt},
+    {"Apr", CXFA_FM2JSContext::Apr},
+    {"Cterm", CXFA_FM2JSContext::CTerm},
+    {"FV", CXFA_FM2JSContext::FV},
+    {"Ipmt", CXFA_FM2JSContext::IPmt},
+    {"NPV", CXFA_FM2JSContext::NPV},
+    {"Pmt", CXFA_FM2JSContext::Pmt},
+    {"PPmt", CXFA_FM2JSContext::PPmt},
+    {"PV", CXFA_FM2JSContext::PV},
+    {"Rate", CXFA_FM2JSContext::Rate},
+    {"Term", CXFA_FM2JSContext::Term},
+    {"Choose", CXFA_FM2JSContext::Choose},
+    {"Exists", CXFA_FM2JSContext::Exists},
+    {"HasValue", CXFA_FM2JSContext::HasValue},
+    {"Oneof", CXFA_FM2JSContext::Oneof},
+    {"Within", CXFA_FM2JSContext::Within},
+    {"If", CXFA_FM2JSContext::If},
+    {"Eval", CXFA_FM2JSContext::Eval},
+    {"Translate", CXFA_FM2JSContext::eval_translation},
+    {"Ref", CXFA_FM2JSContext::Ref},
+    {"UnitType", CXFA_FM2JSContext::UnitType},
+    {"UnitValue", CXFA_FM2JSContext::UnitValue},
+    {"At", CXFA_FM2JSContext::At},
+    {"Concat", CXFA_FM2JSContext::Concat},
+    {"Decode", CXFA_FM2JSContext::Decode},
+    {"Encode", CXFA_FM2JSContext::Encode},
+    {"Format", CXFA_FM2JSContext::Format},
+    {"Left", CXFA_FM2JSContext::Left},
+    {"Len", CXFA_FM2JSContext::Len},
+    {"Lower", CXFA_FM2JSContext::Lower},
+    {"Ltrim", CXFA_FM2JSContext::Ltrim},
+    {"Parse", CXFA_FM2JSContext::Parse},
+    {"Replace", CXFA_FM2JSContext::Replace},
+    {"Right", CXFA_FM2JSContext::Right},
+    {"Rtrim", CXFA_FM2JSContext::Rtrim},
+    {"Space", CXFA_FM2JSContext::Space},
+    {"Str", CXFA_FM2JSContext::Str},
+    {"Stuff", CXFA_FM2JSContext::Stuff},
+    {"Substr", CXFA_FM2JSContext::Substr},
+    {"Uuid", CXFA_FM2JSContext::Uuid},
+    {"Upper", CXFA_FM2JSContext::Upper},
+    {"WordNum", CXFA_FM2JSContext::WordNum},
+    {"Get", CXFA_FM2JSContext::Get},
+    {"Post", CXFA_FM2JSContext::Post},
+    {"Put", CXFA_FM2JSContext::Put},
+    {"positive_operator", CXFA_FM2JSContext::positive_operator},
+    {"negative_operator", CXFA_FM2JSContext::negative_operator},
+    {"logical_or_operator", CXFA_FM2JSContext::logical_or_operator},
+    {"logical_and_operator", CXFA_FM2JSContext::logical_and_operator},
+    {"logical_not_operator", CXFA_FM2JSContext::logical_not_operator},
+    {"equality_operator", CXFA_FM2JSContext::equality_operator},
+    {"notequality_operator", CXFA_FM2JSContext::notequality_operator},
+    {"less_operator", CXFA_FM2JSContext::less_operator},
+    {"lessequal_operator", CXFA_FM2JSContext::lessequal_operator},
+    {"greater_operator", CXFA_FM2JSContext::greater_operator},
+    {"greaterequal_operator", CXFA_FM2JSContext::greaterequal_operator},
+    {"plus_operator", CXFA_FM2JSContext::plus_operator},
+    {"minus_operator", CXFA_FM2JSContext::minus_operator},
+    {"multiple_operator", CXFA_FM2JSContext::multiple_operator},
+    {"divide_operator", CXFA_FM2JSContext::divide_operator},
+    {"assign_value_operator", CXFA_FM2JSContext::assign_value_operator},
+    {"dot_accessor", CXFA_FM2JSContext::dot_accessor},
+    {"dotdot_accessor", CXFA_FM2JSContext::dotdot_accessor},
+    {"concat_fm_object", CXFA_FM2JSContext::concat_fm_object},
+    {"is_fm_object", CXFA_FM2JSContext::is_fm_object},
+    {"is_fm_array", CXFA_FM2JSContext::is_fm_array},
+    {"get_fm_value", CXFA_FM2JSContext::get_fm_value},
+    {"get_fm_jsobj", CXFA_FM2JSContext::get_fm_jsobj},
+    {"fm_var_filter", CXFA_FM2JSContext::fm_var_filter},
+};
+CXFA_FM2JSContext::CXFA_FM2JSContext()
+    : m_hFMClass(nullptr), m_pDocument(nullptr) {
+  FXSYS_memset(&m_fmClass, 0, sizeof(FXJSE_CLASS));
+}
+CXFA_FM2JSContext::~CXFA_FM2JSContext() {
+  m_pDocument = NULL;
+  if (m_hValue) {
+    FXJSE_Value_Release(m_hValue);
+    m_hValue = NULL;
+  }
+  m_hScriptRuntime = NULL;
+}
+CXFA_FM2JSContext* CXFA_FM2JSContext::Create() {
+  return new CXFA_FM2JSContext;
+}
+void CXFA_FM2JSContext::Initialize(FXJSE_HRUNTIME hScriptRuntime,
+                                   FXJSE_HCONTEXT hScriptContext,
+                                   CXFA_Document* pDoc) {
+  m_pDocument = pDoc;
+  m_hScriptRuntime = hScriptRuntime;
+  m_fmClass.name = "XFA_FM2JS_FormCalcClass";
+  m_fmClass.constructor = NULL;
+  m_fmClass.properties = NULL;
+  m_fmClass.methods = formcalc_fm2js_functions;
+  m_fmClass.propNum = 0;
+  m_fmClass.methNum =
+      sizeof(formcalc_fm2js_functions) / sizeof(formcalc_fm2js_functions[0]);
+  m_hFMClass = FXJSE_DefineClass(hScriptContext, &m_fmClass);
+  m_hValue = FXJSE_Value_Create(hScriptRuntime);
+  FXJSE_Value_SetNull(m_hValue);
+  FXJSE_Value_SetObject(m_hValue, this, m_hFMClass);
+}
+void CXFA_FM2JSContext::GlobalPropertyGetter(FXJSE_HVALUE hValue) {
+  FXJSE_Value_Set(hValue, m_hValue);
+}
+void CXFA_FM2JSContext::Release() {
+  delete this;
+}
+void CXFA_FM2JSContext::ThrowScriptErrorMessage(int32_t iStringID, ...) {
+  IXFA_AppProvider* pAppProvider = m_pDocument->GetNotify()->GetAppProvider();
+  FXSYS_assert(pAppProvider);
+  CFX_WideString wsFormat;
+  pAppProvider->LoadString(iStringID, wsFormat);
+  CFX_WideString wsMessage;
+  va_list arg_ptr;
+  va_start(arg_ptr, iStringID);
+  wsMessage.FormatV((const FX_WCHAR*)wsFormat, arg_ptr);
+  va_end(arg_ptr);
+  FXJSE_ThrowMessage("", FX_UTF8Encode(wsMessage, wsMessage.GetLength()));
+}
diff --git a/xfa/fxfa/fm2js/xfa_fm2jscontext.h b/xfa/fxfa/fm2js/xfa_fm2jscontext.h
new file mode 100644
index 0000000..c80d988
--- /dev/null
+++ b/xfa/fxfa/fm2js/xfa_fm2jscontext.h
@@ -0,0 +1,453 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_FM2JS_XFA_FM2JSCONTEXT_H_
+#define XFA_FXFA_FM2JS_XFA_FM2JSCONTEXT_H_
+
+#include "xfa/fxfa/parser/xfa_script.h"
+
+class CXFA_FM2JSContext {
+ public:
+  static void Abs(FXJSE_HOBJECT hThis,
+                  const CFX_ByteStringC& szFuncName,
+                  CFXJSE_Arguments& args);
+  static void Avg(FXJSE_HOBJECT hThis,
+                  const CFX_ByteStringC& szFuncName,
+                  CFXJSE_Arguments& args);
+  static void Ceil(FXJSE_HOBJECT hThis,
+                   const CFX_ByteStringC& szFuncName,
+                   CFXJSE_Arguments& args);
+  static void Count(FXJSE_HOBJECT hThis,
+                    const CFX_ByteStringC& szFuncName,
+                    CFXJSE_Arguments& args);
+  static void Floor(FXJSE_HOBJECT hThis,
+                    const CFX_ByteStringC& szFuncName,
+                    CFXJSE_Arguments& args);
+  static void Max(FXJSE_HOBJECT hThis,
+                  const CFX_ByteStringC& szFuncName,
+                  CFXJSE_Arguments& args);
+  static void Min(FXJSE_HOBJECT hThis,
+                  const CFX_ByteStringC& szFuncName,
+                  CFXJSE_Arguments& args);
+  static void Mod(FXJSE_HOBJECT hThis,
+                  const CFX_ByteStringC& szFuncName,
+                  CFXJSE_Arguments& args);
+  static void Round(FXJSE_HOBJECT hThis,
+                    const CFX_ByteStringC& szFuncName,
+                    CFXJSE_Arguments& args);
+  static void Sum(FXJSE_HOBJECT hThis,
+                  const CFX_ByteStringC& szFuncName,
+                  CFXJSE_Arguments& args);
+  static void Date(FXJSE_HOBJECT hThis,
+                   const CFX_ByteStringC& szFuncName,
+                   CFXJSE_Arguments& args);
+  static void Date2Num(FXJSE_HOBJECT hThis,
+                       const CFX_ByteStringC& szFuncName,
+                       CFXJSE_Arguments& args);
+  static void DateFmt(FXJSE_HOBJECT hThis,
+                      const CFX_ByteStringC& szFuncName,
+                      CFXJSE_Arguments& args);
+  static void IsoDate2Num(FXJSE_HOBJECT hThis,
+                          const CFX_ByteStringC& szFuncName,
+                          CFXJSE_Arguments& args);
+  static void IsoTime2Num(FXJSE_HOBJECT hThis,
+                          const CFX_ByteStringC& szFuncName,
+                          CFXJSE_Arguments& args);
+  static void LocalDateFmt(FXJSE_HOBJECT hThis,
+                           const CFX_ByteStringC& szFuncName,
+                           CFXJSE_Arguments& args);
+  static void LocalTimeFmt(FXJSE_HOBJECT hThis,
+                           const CFX_ByteStringC& szFuncName,
+                           CFXJSE_Arguments& args);
+  static void Num2Date(FXJSE_HOBJECT hThis,
+                       const CFX_ByteStringC& szFuncName,
+                       CFXJSE_Arguments& args);
+  static void Num2GMTime(FXJSE_HOBJECT hThis,
+                         const CFX_ByteStringC& szFuncName,
+                         CFXJSE_Arguments& args);
+  static void Num2Time(FXJSE_HOBJECT hThis,
+                       const CFX_ByteStringC& szFuncName,
+                       CFXJSE_Arguments& args);
+  static void Time(FXJSE_HOBJECT hThis,
+                   const CFX_ByteStringC& szFuncName,
+                   CFXJSE_Arguments& args);
+  static void Time2Num(FXJSE_HOBJECT hThis,
+                       const CFX_ByteStringC& szFuncName,
+                       CFXJSE_Arguments& args);
+  static void TimeFmt(FXJSE_HOBJECT hThis,
+                      const CFX_ByteStringC& szFuncName,
+                      CFXJSE_Arguments& args);
+
+  static FX_BOOL IsIsoDateFormat(const FX_CHAR* pData,
+                                 int32_t iLength,
+                                 int32_t& iStyle,
+                                 int32_t& iYear,
+                                 int32_t& iMonth,
+                                 int32_t& iDay);
+  static FX_BOOL IsIsoTimeFormat(const FX_CHAR* pData,
+                                 int32_t iLength,
+                                 int32_t& iHour,
+                                 int32_t& iMinute,
+                                 int32_t& iSecond,
+                                 int32_t& iMilliSecond,
+                                 int32_t& iZoneHour,
+                                 int32_t& iZoneMinute);
+  static FX_BOOL IsIsoDateTimeFormat(const FX_CHAR* pData,
+                                     int32_t iLength,
+                                     int32_t& iYear,
+                                     int32_t& iMonth,
+                                     int32_t& iDay,
+                                     int32_t& iHour,
+                                     int32_t& iMinute,
+                                     int32_t& iSecond,
+                                     int32_t& iMillionSecond,
+                                     int32_t& iZoneHour,
+                                     int32_t& iZoneMinute);
+  static FX_BOOL Local2IsoDate(FXJSE_HOBJECT hThis,
+                               const CFX_ByteStringC& szDate,
+                               const CFX_ByteStringC& szFormat,
+                               const CFX_ByteStringC& szLocale,
+                               CFX_ByteString& strIsoDate);
+  static FX_BOOL Local2IsoTime(FXJSE_HOBJECT hThis,
+                               const CFX_ByteStringC& szTime,
+                               const CFX_ByteStringC& szFormat,
+                               const CFX_ByteStringC& szLocale,
+                               CFX_ByteString& strIsoTime);
+  static FX_BOOL IsoDate2Local(FXJSE_HOBJECT hThis,
+                               const CFX_ByteStringC& szDate,
+                               const CFX_ByteStringC& szFormat,
+                               const CFX_ByteStringC& szLocale,
+                               CFX_ByteString& strLocalDate);
+  static FX_BOOL IsoTime2Local(FXJSE_HOBJECT hThis,
+                               const CFX_ByteStringC& szTime,
+                               const CFX_ByteStringC& szFormat,
+                               const CFX_ByteStringC& szLocale,
+                               CFX_ByteString& strLocalTime);
+  static FX_BOOL GetGMTTime(FXJSE_HOBJECT hThis,
+                            const CFX_ByteStringC& szTime,
+                            const CFX_ByteStringC& szFormat,
+                            const CFX_ByteStringC& szLocale,
+                            CFX_ByteString& strGMTTime);
+  static int32_t DateString2Num(const CFX_ByteStringC& szDateString);
+  static void GetLocalDateFormat(FXJSE_HOBJECT hThis,
+                                 int32_t iStyle,
+                                 const CFX_ByteStringC& szLocalStr,
+                                 CFX_ByteString& strFormat,
+                                 FX_BOOL bStandard);
+  static void GetLocalTimeFormat(FXJSE_HOBJECT hThis,
+                                 int32_t iStyle,
+                                 const CFX_ByteStringC& szLocalStr,
+                                 CFX_ByteString& strFormat,
+                                 FX_BOOL bStandard);
+  static void GetStandardDateFormat(FXJSE_HOBJECT hThis,
+                                    int32_t iStyle,
+                                    const CFX_ByteStringC& szLocalStr,
+                                    CFX_ByteString& strFormat);
+  static void GetStandardTimeFormat(FXJSE_HOBJECT hThis,
+                                    int32_t iStyle,
+                                    const CFX_ByteStringC& szLocalStr,
+                                    CFX_ByteString& strFormat);
+
+  static void Num2AllTime(FXJSE_HOBJECT hThis,
+                          int32_t iTime,
+                          const CFX_ByteStringC& szFormat,
+                          const CFX_ByteStringC& szLocale,
+                          FX_BOOL bGM,
+                          CFX_ByteString& strTime);
+  static void GetLocalTimeZone(int32_t& iHour, int32_t& iMin, int32_t& iSec);
+
+  static void Apr(FXJSE_HOBJECT hThis,
+                  const CFX_ByteStringC& szFuncName,
+                  CFXJSE_Arguments& args);
+  static void CTerm(FXJSE_HOBJECT hThis,
+                    const CFX_ByteStringC& szFuncName,
+                    CFXJSE_Arguments& args);
+  static void FV(FXJSE_HOBJECT hThis,
+                 const CFX_ByteStringC& szFuncName,
+                 CFXJSE_Arguments& args);
+  static void IPmt(FXJSE_HOBJECT hThis,
+                   const CFX_ByteStringC& szFuncName,
+                   CFXJSE_Arguments& args);
+  static void NPV(FXJSE_HOBJECT hThis,
+                  const CFX_ByteStringC& szFuncName,
+                  CFXJSE_Arguments& args);
+  static void Pmt(FXJSE_HOBJECT hThis,
+                  const CFX_ByteStringC& szFuncName,
+                  CFXJSE_Arguments& args);
+  static void PPmt(FXJSE_HOBJECT hThis,
+                   const CFX_ByteStringC& szFuncName,
+                   CFXJSE_Arguments& args);
+  static void PV(FXJSE_HOBJECT hThis,
+                 const CFX_ByteStringC& szFuncName,
+                 CFXJSE_Arguments& args);
+  static void Rate(FXJSE_HOBJECT hThis,
+                   const CFX_ByteStringC& szFuncName,
+                   CFXJSE_Arguments& args);
+  static void Term(FXJSE_HOBJECT hThis,
+                   const CFX_ByteStringC& szFuncName,
+                   CFXJSE_Arguments& args);
+  static void Choose(FXJSE_HOBJECT hThis,
+                     const CFX_ByteStringC& szFuncName,
+                     CFXJSE_Arguments& args);
+  static void Exists(FXJSE_HOBJECT hThis,
+                     const CFX_ByteStringC& szFuncName,
+                     CFXJSE_Arguments& args);
+  static void HasValue(FXJSE_HOBJECT hThis,
+                       const CFX_ByteStringC& szFuncName,
+                       CFXJSE_Arguments& args);
+  static void Oneof(FXJSE_HOBJECT hThis,
+                    const CFX_ByteStringC& szFuncName,
+                    CFXJSE_Arguments& args);
+  static void Within(FXJSE_HOBJECT hThis,
+                     const CFX_ByteStringC& szFuncName,
+                     CFXJSE_Arguments& args);
+  static void If(FXJSE_HOBJECT hThis,
+                 const CFX_ByteStringC& szFuncName,
+                 CFXJSE_Arguments& args);
+  static void Eval(FXJSE_HOBJECT hThis,
+                   const CFX_ByteStringC& szFuncName,
+                   CFXJSE_Arguments& args);
+  static void Ref(FXJSE_HOBJECT hThis,
+                  const CFX_ByteStringC& szFuncName,
+                  CFXJSE_Arguments& args);
+  static void UnitType(FXJSE_HOBJECT hThis,
+                       const CFX_ByteStringC& szFuncName,
+                       CFXJSE_Arguments& args);
+  static void UnitValue(FXJSE_HOBJECT hThis,
+                        const CFX_ByteStringC& szFuncName,
+                        CFXJSE_Arguments& args);
+
+  static void At(FXJSE_HOBJECT hThis,
+                 const CFX_ByteStringC& szFuncName,
+                 CFXJSE_Arguments& args);
+  static void Concat(FXJSE_HOBJECT hThis,
+                     const CFX_ByteStringC& szFuncName,
+                     CFXJSE_Arguments& args);
+  static void Decode(FXJSE_HOBJECT hThis,
+                     const CFX_ByteStringC& szFuncName,
+                     CFXJSE_Arguments& args);
+  static void DecodeURL(const CFX_ByteStringC& szURLString,
+                        CFX_ByteTextBuf& szResultBuf);
+  static void DecodeHTML(const CFX_ByteStringC& szHTMLString,
+                         CFX_ByteTextBuf& szResultBuf);
+  static void DecodeXML(const CFX_ByteStringC& szXMLString,
+                        CFX_ByteTextBuf& szResultBuf);
+  static void Encode(FXJSE_HOBJECT hThis,
+                     const CFX_ByteStringC& szFuncName,
+                     CFXJSE_Arguments& args);
+  static void EncodeURL(const CFX_ByteStringC& szURLString,
+                        CFX_ByteTextBuf& szResultBuf);
+  static void EncodeHTML(const CFX_ByteStringC& szHTMLString,
+                         CFX_ByteTextBuf& szResultBuf);
+  static void EncodeXML(const CFX_ByteStringC& szXMLString,
+                        CFX_ByteTextBuf& szResultBuf);
+  static FX_BOOL HTMLSTR2Code(const CFX_WideStringC& pData, uint32_t& iCode);
+  static FX_BOOL HTMLCode2STR(uint32_t iCode, CFX_WideString& wsHTMLReserve);
+  static void Format(FXJSE_HOBJECT hThis,
+                     const CFX_ByteStringC& szFuncName,
+                     CFXJSE_Arguments& args);
+  static void Left(FXJSE_HOBJECT hThis,
+                   const CFX_ByteStringC& szFuncName,
+                   CFXJSE_Arguments& args);
+  static void Len(FXJSE_HOBJECT hThis,
+                  const CFX_ByteStringC& szFuncName,
+                  CFXJSE_Arguments& args);
+  static void Lower(FXJSE_HOBJECT hThis,
+                    const CFX_ByteStringC& szFuncName,
+                    CFXJSE_Arguments& args);
+  static void Ltrim(FXJSE_HOBJECT hThis,
+                    const CFX_ByteStringC& szFuncName,
+                    CFXJSE_Arguments& args);
+  static void Parse(FXJSE_HOBJECT hThis,
+                    const CFX_ByteStringC& szFuncName,
+                    CFXJSE_Arguments& args);
+  static void Replace(FXJSE_HOBJECT hThis,
+                      const CFX_ByteStringC& szFuncName,
+                      CFXJSE_Arguments& args);
+  static void Right(FXJSE_HOBJECT hThis,
+                    const CFX_ByteStringC& szFuncName,
+                    CFXJSE_Arguments& args);
+  static void Rtrim(FXJSE_HOBJECT hThis,
+                    const CFX_ByteStringC& szFuncName,
+                    CFXJSE_Arguments& args);
+  static void Space(FXJSE_HOBJECT hThis,
+                    const CFX_ByteStringC& szFuncName,
+                    CFXJSE_Arguments& args);
+  static void Str(FXJSE_HOBJECT hThis,
+                  const CFX_ByteStringC& szFuncName,
+                  CFXJSE_Arguments& args);
+  static void Stuff(FXJSE_HOBJECT hThis,
+                    const CFX_ByteStringC& szFuncName,
+                    CFXJSE_Arguments& args);
+  static void Substr(FXJSE_HOBJECT hThis,
+                     const CFX_ByteStringC& szFuncName,
+                     CFXJSE_Arguments& args);
+  static void Uuid(FXJSE_HOBJECT hThis,
+                   const CFX_ByteStringC& szFuncName,
+                   CFXJSE_Arguments& args);
+  static void Upper(FXJSE_HOBJECT hThis,
+                    const CFX_ByteStringC& szFuncName,
+                    CFXJSE_Arguments& args);
+  static void WordNum(FXJSE_HOBJECT hThis,
+                      const CFX_ByteStringC& szFuncName,
+                      CFXJSE_Arguments& args);
+  static void TrillionUS(const CFX_ByteStringC& szData,
+                         CFX_ByteTextBuf& strBuf);
+  static void WordUS(const CFX_ByteStringC& szData,
+                     int32_t iStyle,
+                     CFX_ByteTextBuf& strBuf);
+
+  static void Get(FXJSE_HOBJECT hThis,
+                  const CFX_ByteStringC& szFuncName,
+                  CFXJSE_Arguments& args);
+  static void Post(FXJSE_HOBJECT hThis,
+                   const CFX_ByteStringC& szFuncName,
+                   CFXJSE_Arguments& args);
+  static void Put(FXJSE_HOBJECT hThis,
+                  const CFX_ByteStringC& szFuncName,
+                  CFXJSE_Arguments& args);
+  static void assign_value_operator(FXJSE_HOBJECT hThis,
+                                    const CFX_ByteStringC& szFuncName,
+                                    CFXJSE_Arguments& args);
+  static void logical_or_operator(FXJSE_HOBJECT hThis,
+                                  const CFX_ByteStringC& szFuncName,
+                                  CFXJSE_Arguments& args);
+  static void logical_and_operator(FXJSE_HOBJECT hThis,
+                                   const CFX_ByteStringC& szFuncName,
+                                   CFXJSE_Arguments& args);
+  static void equality_operator(FXJSE_HOBJECT hThis,
+                                const CFX_ByteStringC& szFuncName,
+                                CFXJSE_Arguments& args);
+  static void notequality_operator(FXJSE_HOBJECT hThis,
+                                   const CFX_ByteStringC& szFuncName,
+                                   CFXJSE_Arguments& args);
+  static FX_BOOL fm_ref_equal(FXJSE_HOBJECT hThis, CFXJSE_Arguments& args);
+  static void less_operator(FXJSE_HOBJECT hThis,
+                            const CFX_ByteStringC& szFuncName,
+                            CFXJSE_Arguments& args);
+  static void lessequal_operator(FXJSE_HOBJECT hThis,
+                                 const CFX_ByteStringC& szFuncName,
+                                 CFXJSE_Arguments& args);
+  static void greater_operator(FXJSE_HOBJECT hThis,
+                               const CFX_ByteStringC& szFuncName,
+                               CFXJSE_Arguments& args);
+  static void greaterequal_operator(FXJSE_HOBJECT hThis,
+                                    const CFX_ByteStringC& szFuncName,
+                                    CFXJSE_Arguments& args);
+  static void plus_operator(FXJSE_HOBJECT hThis,
+                            const CFX_ByteStringC& szFuncName,
+                            CFXJSE_Arguments& args);
+  static void minus_operator(FXJSE_HOBJECT hThis,
+                             const CFX_ByteStringC& szFuncName,
+                             CFXJSE_Arguments& args);
+  static void multiple_operator(FXJSE_HOBJECT hThis,
+                                const CFX_ByteStringC& szFuncName,
+                                CFXJSE_Arguments& args);
+  static void divide_operator(FXJSE_HOBJECT hThis,
+                              const CFX_ByteStringC& szFuncName,
+                              CFXJSE_Arguments& args);
+  static void positive_operator(FXJSE_HOBJECT hThis,
+                                const CFX_ByteStringC& szFuncName,
+                                CFXJSE_Arguments& args);
+  static void negative_operator(FXJSE_HOBJECT hThis,
+                                const CFX_ByteStringC& szFuncName,
+                                CFXJSE_Arguments& args);
+  static void logical_not_operator(FXJSE_HOBJECT hThis,
+                                   const CFX_ByteStringC& szFuncName,
+                                   CFXJSE_Arguments& args);
+  static void dot_accessor(FXJSE_HOBJECT hThis,
+                           const CFX_ByteStringC& szFuncName,
+                           CFXJSE_Arguments& args);
+  static void dotdot_accessor(FXJSE_HOBJECT hThis,
+                              const CFX_ByteStringC& szFuncName,
+                              CFXJSE_Arguments& args);
+  static void eval_translation(FXJSE_HOBJECT hThis,
+                               const CFX_ByteStringC& szFuncName,
+                               CFXJSE_Arguments& args);
+  static void is_fm_object(FXJSE_HOBJECT hThis,
+                           const CFX_ByteStringC& szFuncName,
+                           CFXJSE_Arguments& args);
+  static void is_fm_array(FXJSE_HOBJECT hThis,
+                          const CFX_ByteStringC& szFuncName,
+                          CFXJSE_Arguments& args);
+  static void get_fm_value(FXJSE_HOBJECT hThis,
+                           const CFX_ByteStringC& szFuncName,
+                           CFXJSE_Arguments& args);
+  static void get_fm_jsobj(FXJSE_HOBJECT hThis,
+                           const CFX_ByteStringC& szFuncName,
+                           CFXJSE_Arguments& args);
+  static void fm_var_filter(FXJSE_HOBJECT hThis,
+                            const CFX_ByteStringC& szFuncName,
+                            CFXJSE_Arguments& args);
+  static void concat_fm_object(FXJSE_HOBJECT hThis,
+                               const CFX_ByteStringC& szFuncName,
+                               CFXJSE_Arguments& args);
+
+  static int32_t hvalue_get_array_length(FXJSE_HOBJECT hThis, FXJSE_HVALUE arg);
+  static FX_BOOL simpleValueCompare(FXJSE_HOBJECT hThis,
+                                    FXJSE_HVALUE firstValue,
+                                    FXJSE_HVALUE secondValue);
+  static void unfoldArgs(FXJSE_HOBJECT hThis,
+                         CFXJSE_Arguments& args,
+                         FXJSE_HVALUE*& resultValues,
+                         int32_t& iCount,
+                         int32_t iStart = 0);
+  static void GetObjectDefaultValue(FXJSE_HVALUE hObjectValue,
+                                    FXJSE_HVALUE hDefaultValue);
+  static FX_BOOL SetObjectDefaultValue(FXJSE_HVALUE hObjectValue,
+                                       FXJSE_HVALUE hNewValue);
+  static void GenerateSomExpression(const CFX_ByteStringC& szName,
+                                    int32_t iIndexFlags,
+                                    int32_t iIndexValue,
+                                    FX_BOOL bIsStar,
+                                    CFX_ByteString& szSomExp);
+  static FX_BOOL GetObjectByName(FXJSE_HOBJECT hThis,
+                                 FXJSE_HVALUE accessorValue,
+                                 const CFX_ByteStringC& szAccessorName);
+  static int32_t ResolveObjects(FXJSE_HOBJECT hThis,
+                                FXJSE_HVALUE hParentValue,
+                                const CFX_ByteStringC& bsSomExp,
+                                XFA_RESOLVENODE_RS& resoveNodeRS,
+                                FX_BOOL bdotAccessor = TRUE,
+                                FX_BOOL bHasNoResolveName = FALSE);
+  static void ParseResolveResult(FXJSE_HOBJECT hThis,
+                                 const XFA_RESOLVENODE_RS& resoveNodeRS,
+                                 FXJSE_HVALUE hParentValue,
+                                 FXJSE_HVALUE*& resultValues,
+                                 int32_t& iSize,
+                                 FX_BOOL& bAttribute);
+
+  static FXJSE_HVALUE GetSimpleHValue(FXJSE_HOBJECT hThis,
+                                      CFXJSE_Arguments& args,
+                                      uint32_t index);
+  static FX_BOOL HValueIsNull(FXJSE_HOBJECT hThis, FXJSE_HVALUE hValue);
+  static int32_t HValueToInteger(FXJSE_HOBJECT hThis, FXJSE_HVALUE hValue);
+  static FX_DOUBLE StringToDouble(const CFX_ByteStringC& szStringVal);
+  static FX_FLOAT HValueToFloat(FXJSE_HOBJECT hThis, FXJSE_HVALUE hValue);
+  static FX_DOUBLE HValueToDouble(FXJSE_HOBJECT hThis, FXJSE_HVALUE hValue);
+  static void HValueToUTF8String(FXJSE_HVALUE hValue,
+                                 CFX_ByteString& outputValue);
+  CXFA_FM2JSContext();
+  ~CXFA_FM2JSContext();
+  static CXFA_FM2JSContext* Create();
+  void Initialize(FXJSE_HRUNTIME hScriptRuntime,
+                  FXJSE_HCONTEXT hScriptContext,
+                  CXFA_Document* pDoc);
+  void GlobalPropertyGetter(FXJSE_HVALUE hValue);
+  void Release();
+  FXJSE_HRUNTIME GetScriptRuntime() const { return m_hScriptRuntime; }
+  CXFA_Document* GetDocument() const { return m_pDocument; }
+  void ThrowScriptErrorMessage(int32_t iStringID, ...);
+
+ private:
+  FXJSE_HRUNTIME m_hScriptRuntime;
+  FXJSE_CLASS m_fmClass;
+  FXJSE_HCLASS m_hFMClass;
+  FXJSE_HVALUE m_hValue;
+  CXFA_Document* m_pDocument;
+};
+
+#endif  // XFA_FXFA_FM2JS_XFA_FM2JSCONTEXT_H_
diff --git a/xfa/fxfa/fm2js/xfa_fmparse.cpp b/xfa/fxfa/fm2js/xfa_fmparse.cpp
new file mode 100644
index 0000000..6e30d95
--- /dev/null
+++ b/xfa/fxfa/fm2js/xfa_fmparse.cpp
@@ -0,0 +1,1051 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/fm2js/xfa_fmparse.h"
+
+#include <memory>
+
+CXFA_FMParse::CXFA_FMParse() : m_pToken(nullptr), m_pErrorInfo(0) {}
+
+int32_t CXFA_FMParse::Init(const CFX_WideStringC& wsFormcalc,
+                           CXFA_FMErrorInfo* pErrorInfo) {
+  m_pErrorInfo = pErrorInfo;
+  m_lexer.reset(new CXFA_FMLexer(wsFormcalc, m_pErrorInfo));
+  return 0;
+}
+
+void CXFA_FMParse::NextToken() {
+  m_pToken = m_lexer->NextToken();
+  while (m_pToken->m_type == TOKreserver) {
+    if (m_lexer->HasError()) {
+      break;
+    }
+    m_pToken = m_lexer->NextToken();
+  }
+}
+
+void CXFA_FMParse::Check(XFA_FM_TOKEN op) {
+  if (m_pToken->m_type != op) {
+    CFX_WideString ws_TempString = m_pToken->m_wstring;
+    Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
+          XFA_FM_KeywordToString(op), ws_TempString.c_str());
+  }
+  NextToken();
+}
+
+void CXFA_FMParse::Error(FX_DWORD lineNum, XFA_FM_ERRMSG msg, ...) {
+  m_pErrorInfo->linenum = lineNum;
+  const FX_WCHAR* lpMessageInfo = XFA_FM_ErrorMsg(msg);
+  va_list ap;
+  va_start(ap, msg);
+  m_pErrorInfo->message.FormatV(lpMessageInfo, ap);
+  va_end(ap);
+}
+
+CFX_PtrArray* CXFA_FMParse::ParseTopExpression() {
+  std::unique_ptr<CXFA_FMExpression> e;
+  CFX_PtrArray* expression = new CFX_PtrArray();
+  while (1) {
+    if (m_pToken->m_type == TOKeof || m_pToken->m_type == TOKendfunc ||
+        m_pToken->m_type == TOKendif || m_pToken->m_type == TOKelseif ||
+        m_pToken->m_type == TOKelse || m_pToken->m_type == TOKreserver) {
+      return expression;
+    }
+
+    if (m_pToken->m_type == TOKfunc) {
+      e.reset(ParseFunction());
+      if (e) {
+        expression->Add(e.release());
+      } else {
+        break;
+      }
+    } else {
+      e.reset(ParseExpression());
+      if (e) {
+        expression->Add(e.release());
+      } else {
+        break;
+      }
+    }
+  }
+  return expression;
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseFunction() {
+  std::unique_ptr<CXFA_FMExpression> e;
+  CFX_WideStringC ident;
+  std::unique_ptr<CFX_WideStringCArray> pArguments;
+  std::unique_ptr<CFX_PtrArray> pExpressions;
+  FX_DWORD line = m_pToken->m_uLinenum;
+  NextToken();
+  if (m_pToken->m_type != TOKidentifier) {
+    CFX_WideString ws_TempString = m_pToken->m_wstring;
+    Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,
+          ws_TempString.c_str());
+  } else {
+    ident = m_pToken->m_wstring;
+    NextToken();
+  }
+  Check(TOKlparen);
+  if (m_pToken->m_type == TOKrparen) {
+    NextToken();
+  } else {
+    pArguments.reset(new CFX_WideStringCArray());
+    CFX_WideStringC p;
+    while (1) {
+      if (m_pToken->m_type == TOKidentifier) {
+        p = m_pToken->m_wstring;
+        pArguments->Add(p);
+        NextToken();
+        if (m_pToken->m_type == TOKcomma) {
+          NextToken();
+          continue;
+        } else if (m_pToken->m_type == TOKrparen) {
+          NextToken();
+          break;
+        } else {
+          Check(TOKrparen);
+          break;
+        }
+      } else {
+        CFX_WideString ws_TempString = m_pToken->m_wstring;
+        Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,
+              ws_TempString.c_str());
+        NextToken();
+        break;
+      }
+    }
+  }
+  Check(TOKdo);
+  if (m_pToken->m_type == TOKendfunc) {
+    NextToken();
+  } else {
+    pExpressions.reset(ParseTopExpression());
+    Check(TOKendfunc);
+  }
+  if (m_pErrorInfo->message.IsEmpty()) {
+    e.reset(new CXFA_FMFunctionDefinition(line, 0, ident, pArguments.release(),
+                                          pExpressions.release()));
+  } else {
+    if (pArguments)
+      pArguments->RemoveAll();
+    if (pExpressions) {
+      for (int i = 0; i < pExpressions->GetSize(); ++i)
+        delete static_cast<CXFA_FMExpression*>(pExpressions->GetAt(i));
+    }
+  }
+  return e.release();
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseExpression() {
+  std::unique_ptr<CXFA_FMExpression> e;
+  FX_DWORD line = m_pToken->m_uLinenum;
+  switch (m_pToken->m_type) {
+    case TOKvar:
+      e.reset(ParseVarExpression());
+      break;
+    case TOKnull:
+    case TOKnumber:
+    case TOKstring:
+    case TOKplus:
+    case TOKminus:
+    case TOKksnot:
+    case TOKidentifier:
+    case TOKlparen:
+      e.reset(ParseExpExpression());
+      break;
+    case TOKif:
+      e.reset(ParseIfExpression());
+      break;
+    case TOKwhile:
+      e.reset(ParseWhileExpression());
+      break;
+    case TOKfor:
+      e.reset(ParseForExpression());
+      break;
+    case TOKforeach:
+      e.reset(ParseForeachExpression());
+      break;
+    case TOKdo:
+      e.reset(ParseDoExpression());
+      break;
+    case TOKbreak:
+      e.reset(new CXFA_FMBreakExpression(line));
+      NextToken();
+      break;
+    case TOKcontinue:
+      e.reset(new CXFA_FMContinueExpression(line));
+      NextToken();
+      break;
+    default:
+      CFX_WideString ws_TempString = m_pToken->m_wstring;
+      Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION,
+            ws_TempString.c_str());
+      NextToken();
+      break;
+  }
+  return e.release();
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseVarExpression() {
+  std::unique_ptr<CXFA_FMExpression> e;
+  CFX_WideStringC ident;
+  FX_DWORD line = m_pToken->m_uLinenum;
+  NextToken();
+  if (m_pToken->m_type != TOKidentifier) {
+    CFX_WideString ws_TempString = m_pToken->m_wstring;
+    Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,
+          ws_TempString.c_str());
+  } else {
+    ident = m_pToken->m_wstring;
+    NextToken();
+  }
+  if (m_pToken->m_type == TOKassign) {
+    NextToken();
+    e.reset(ParseExpExpression());
+  }
+  if (m_pErrorInfo->message.IsEmpty()) {
+    e.reset(new CXFA_FMVarExpression(line, ident, e.release()));
+  } else {
+    e.reset();
+  }
+  return e.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseSimpleExpression() {
+  FX_DWORD line = m_pToken->m_uLinenum;
+  std::unique_ptr<CXFA_FMSimpleExpression> pExp1(ParseLogicalOrExpression());
+  while (m_pToken->m_type == TOKassign) {
+    NextToken();
+    std::unique_ptr<CXFA_FMSimpleExpression> pExp2(ParseLogicalOrExpression());
+    if (m_pErrorInfo->message.IsEmpty()) {
+      pExp1.reset(new CXFA_FMAssignExpression(line, TOKassign, pExp1.release(),
+                                              pExp2.release()));
+    } else {
+      pExp1.reset();
+    }
+  }
+  return pExp1.release();
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseExpExpression() {
+  FX_DWORD line = m_pToken->m_uLinenum;
+  std::unique_ptr<CXFA_FMSimpleExpression> pExp1(ParseSimpleExpression());
+  std::unique_ptr<CXFA_FMExpression> e;
+  if (m_pErrorInfo->message.IsEmpty()) {
+    e.reset(new CXFA_FMExpExpression(line, pExp1.release()));
+  } else {
+    e.reset();
+  }
+  return e.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseLogicalOrExpression() {
+  FX_DWORD line = m_pToken->m_uLinenum;
+  std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseLogicalAndExpression());
+  for (;;) {
+    switch (m_pToken->m_type) {
+      case TOKor:
+      case TOKksor: {
+        NextToken();
+        std::unique_ptr<CXFA_FMSimpleExpression> e2(
+            ParseLogicalAndExpression());
+        if (m_pErrorInfo->message.IsEmpty()) {
+          e1.reset(new CXFA_FMLogicalOrExpression(line, TOKor, e1.release(),
+                                                  e2.release()));
+        } else {
+          e1.reset();
+        }
+        continue;
+      }
+      default:
+        break;
+    }
+    break;
+  }
+  return e1.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseLogicalAndExpression() {
+  FX_DWORD line = m_pToken->m_uLinenum;
+  std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseEqualityExpression());
+  for (;;) {
+    switch (m_pToken->m_type) {
+      case TOKand:
+      case TOKksand: {
+        NextToken();
+        std::unique_ptr<CXFA_FMSimpleExpression> e2(ParseEqualityExpression());
+        if (m_pErrorInfo->message.IsEmpty()) {
+          e1.reset(new CXFA_FMLogicalAndExpression(line, TOKand, e1.release(),
+                                                   e2.release()));
+        } else {
+          e1.reset();
+        }
+        continue;
+      }
+      default:
+        break;
+    }
+    break;
+  }
+  return e1.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseEqualityExpression() {
+  FX_DWORD line = m_pToken->m_uLinenum;
+  std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseRelationalExpression());
+  for (;;) {
+    std::unique_ptr<CXFA_FMSimpleExpression> e2;
+    switch (m_pToken->m_type) {
+      case TOKeq:
+      case TOKkseq:
+        NextToken();
+        e2.reset(ParseRelationalExpression());
+        if (m_pErrorInfo->message.IsEmpty()) {
+          e1.reset(new CXFA_FMEqualityExpression(line, TOKeq, e1.release(),
+                                                 e2.release()));
+        } else {
+          e1.reset();
+        }
+        continue;
+      case TOKne:
+      case TOKksne:
+        NextToken();
+        e2.reset(ParseRelationalExpression());
+        if (m_pErrorInfo->message.IsEmpty()) {
+          e1.reset(new CXFA_FMEqualityExpression(line, TOKne, e1.release(),
+                                                 e2.release()));
+        } else {
+          e1.reset();
+        }
+        continue;
+      default:
+        break;
+    }
+    break;
+  }
+  return e1.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseRelationalExpression() {
+  FX_DWORD line = m_pToken->m_uLinenum;
+  std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseAddtiveExpression());
+  for (;;) {
+    std::unique_ptr<CXFA_FMSimpleExpression> e2;
+    switch (m_pToken->m_type) {
+      case TOKlt:
+      case TOKkslt:
+        NextToken();
+        e2.reset(ParseAddtiveExpression());
+        if (m_pErrorInfo->message.IsEmpty()) {
+          e1.reset(new CXFA_FMRelationalExpression(line, TOKlt, e1.release(),
+                                                   e2.release()));
+        } else {
+          e1.reset();
+        }
+        continue;
+      case TOKgt:
+      case TOKksgt:
+        NextToken();
+        e2.reset(ParseAddtiveExpression());
+        if (m_pErrorInfo->message.IsEmpty()) {
+          e1.reset(new CXFA_FMRelationalExpression(line, TOKgt, e1.release(),
+                                                   e2.release()));
+        } else {
+          e1.reset();
+        }
+        continue;
+      case TOKle:
+      case TOKksle:
+        NextToken();
+        e2.reset(ParseAddtiveExpression());
+        if (m_pErrorInfo->message.IsEmpty()) {
+          e1.reset(new CXFA_FMRelationalExpression(line, TOKle, e1.release(),
+                                                   e2.release()));
+        } else {
+          e1.reset();
+        }
+        continue;
+      case TOKge:
+      case TOKksge:
+        NextToken();
+        e2.reset(ParseAddtiveExpression());
+        if (m_pErrorInfo->message.IsEmpty()) {
+          e1.reset(new CXFA_FMRelationalExpression(line, TOKge, e1.release(),
+                                                   e2.release()));
+        } else {
+          e1.reset();
+        }
+        continue;
+      default:
+        break;
+    }
+    break;
+  }
+  return e1.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseAddtiveExpression() {
+  FX_DWORD line = m_pToken->m_uLinenum;
+  std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseMultiplicativeExpression());
+  for (;;) {
+    std::unique_ptr<CXFA_FMSimpleExpression> e2;
+    switch (m_pToken->m_type) {
+      case TOKplus:
+        NextToken();
+        e2.reset(ParseMultiplicativeExpression());
+        if (m_pErrorInfo->message.IsEmpty()) {
+          e1.reset(new CXFA_FMAdditiveExpression(line, TOKplus, e1.release(),
+                                                 e2.release()));
+        } else {
+          e1.reset();
+        }
+        continue;
+      case TOKminus:
+        NextToken();
+        e2.reset(ParseMultiplicativeExpression());
+        if (m_pErrorInfo->message.IsEmpty()) {
+          e1.reset(new CXFA_FMAdditiveExpression(line, TOKminus, e1.release(),
+                                                 e2.release()));
+        } else {
+          e1.reset();
+        }
+        continue;
+      default:
+        break;
+    }
+    break;
+  }
+  return e1.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseMultiplicativeExpression() {
+  FX_DWORD line = m_pToken->m_uLinenum;
+  std::unique_ptr<CXFA_FMSimpleExpression> e1(ParseUnaryExpression());
+  for (;;) {
+    std::unique_ptr<CXFA_FMSimpleExpression> e2;
+    switch (m_pToken->m_type) {
+      case TOKmul:
+        NextToken();
+        e2.reset(ParseUnaryExpression());
+        if (m_pErrorInfo->message.IsEmpty()) {
+          e1.reset(new CXFA_FMMultiplicativeExpression(
+              line, TOKmul, e1.release(), e2.release()));
+        } else {
+          e1.reset();
+        }
+        continue;
+      case TOKdiv:
+        NextToken();
+        e2.reset(ParseUnaryExpression());
+        if (m_pErrorInfo->message.IsEmpty()) {
+          e1.reset(new CXFA_FMMultiplicativeExpression(
+              line, TOKdiv, e1.release(), e2.release()));
+        } else {
+          e1.reset();
+        }
+        continue;
+      default:
+        break;
+    }
+    break;
+  }
+  return e1.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseUnaryExpression() {
+  std::unique_ptr<CXFA_FMSimpleExpression> e;
+  FX_DWORD line = m_pToken->m_uLinenum;
+  switch (m_pToken->m_type) {
+    case TOKplus:
+      NextToken();
+      e.reset(ParseUnaryExpression());
+      if (m_pErrorInfo->message.IsEmpty()) {
+        e.reset(new CXFA_FMPosExpression(line, e.release()));
+      } else {
+        e.reset();
+      }
+      break;
+    case TOKminus:
+      NextToken();
+      e.reset(ParseUnaryExpression());
+      if (m_pErrorInfo->message.IsEmpty()) {
+        e.reset(new CXFA_FMNegExpression(line, e.release()));
+      } else {
+        e.reset();
+      }
+      break;
+    case TOKksnot:
+      NextToken();
+      e.reset(ParseUnaryExpression());
+      if (m_pErrorInfo->message.IsEmpty()) {
+        e.reset(new CXFA_FMNotExpression(line, e.release()));
+      } else {
+        e.reset();
+      }
+      break;
+    default:
+      e.reset(ParsePrimaryExpression());
+      break;
+  }
+  return e.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParsePrimaryExpression() {
+  std::unique_ptr<CXFA_FMSimpleExpression> e;
+  FX_DWORD line = m_pToken->m_uLinenum;
+  switch (m_pToken->m_type) {
+    case TOKnumber:
+      e.reset(new CXFA_FMNumberExpression(line, m_pToken->m_wstring));
+      NextToken();
+      break;
+    case TOKstring:
+      e.reset(new CXFA_FMStringExpression(line, m_pToken->m_wstring));
+      NextToken();
+      break;
+    case TOKidentifier: {
+      CFX_WideStringC wsIdentifier(m_pToken->m_wstring);
+      NextToken();
+      if (m_pToken->m_type == TOKlbracket) {
+        CXFA_FMSimpleExpression* s = ParseIndexExpression();
+        if (s) {
+          e.reset(new CXFA_FMDotAccessorExpression(line, NULL, TOKdot,
+                                                   wsIdentifier, s));
+        }
+        NextToken();
+      } else {
+        e.reset(new CXFA_FMIdentifierExpressionn(line, wsIdentifier));
+      }
+    } break;
+    case TOKif:
+      e.reset(new CXFA_FMIdentifierExpressionn(line, m_pToken->m_wstring));
+      NextToken();
+      break;
+    case TOKnull:
+      e.reset(new CXFA_FMNullExpression(line));
+      NextToken();
+      break;
+    case TOKlparen:
+      e.reset(ParseParenExpression());
+      break;
+    default:
+      CFX_WideString ws_TempString = m_pToken->m_wstring;
+      Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION,
+            ws_TempString.c_str());
+      NextToken();
+      break;
+  }
+  e.reset(ParsePostExpression(e.release()));
+  if (!(m_pErrorInfo->message.IsEmpty()))
+    e.reset();
+  return e.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParsePostExpression(
+    CXFA_FMSimpleExpression* e) {
+  FX_DWORD line = m_pToken->m_uLinenum;
+  while (1) {
+    switch (m_pToken->m_type) {
+      case TOKlparen: {
+        NextToken();
+        std::unique_ptr<CFX_PtrArray> pArray;
+        if (m_pToken->m_type != TOKrparen) {
+          pArray.reset(new CFX_PtrArray());
+          while (m_pToken->m_type != TOKrparen) {
+            CXFA_FMSimpleExpression* e = ParseSimpleExpression();
+            if (e) {
+              pArray->Add(e);
+            }
+            if (m_pToken->m_type == TOKcomma) {
+              NextToken();
+            } else if (m_pToken->m_type == TOKeof ||
+                       m_pToken->m_type == TOKreserver) {
+              break;
+            }
+          }
+          if (m_pToken->m_type != TOKrparen) {
+            CFX_WideString ws_TempString = m_pToken->m_wstring;
+            Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
+                  XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());
+          }
+        }
+        if (m_pErrorInfo->message.IsEmpty()) {
+          e = new CXFA_FMCallExpression(line, e, pArray.release(), FALSE);
+          NextToken();
+          if (m_pToken->m_type != TOKlbracket) {
+            continue;
+          }
+          CXFA_FMSimpleExpression* s = ParseIndexExpression();
+          if (s) {
+            e = new CXFA_FMDotAccessorExpression(line, e, TOKcall,
+                                                 FX_WSTRC(L""), s);
+          } else {
+            delete e;
+            e = nullptr;
+          }
+        } else {
+          if (pArray) {
+            for (int32_t i = 0; i < pArray->GetSize(); ++i)
+              delete static_cast<CXFA_FMSimpleExpression*>(pArray->GetAt(i));
+          }
+          delete e;
+          e = nullptr;
+        }
+      } break;
+      case TOKdot:
+        NextToken();
+        if (m_pToken->m_type == TOKidentifier) {
+          CFX_WideStringC tempStr = m_pToken->m_wstring;
+          FX_DWORD tempLine = m_pToken->m_uLinenum;
+          NextToken();
+          if (m_pToken->m_type == TOKlparen) {
+            CXFA_FMSimpleExpression* pExpAccessor;
+            CXFA_FMSimpleExpression* pExpCall;
+            pExpAccessor = e;
+            NextToken();
+            std::unique_ptr<CFX_PtrArray> pArray;
+            if (m_pToken->m_type != TOKrparen) {
+              pArray.reset(new CFX_PtrArray());
+              while (m_pToken->m_type != TOKrparen) {
+                CXFA_FMSimpleExpression* exp = ParseSimpleExpression();
+                pArray->Add(exp);
+                if (m_pToken->m_type == TOKcomma) {
+                  NextToken();
+                } else if (m_pToken->m_type == TOKeof ||
+                           m_pToken->m_type == TOKreserver) {
+                  break;
+                }
+              }
+              if (m_pToken->m_type != TOKrparen) {
+                CFX_WideString ws_TempString = m_pToken->m_wstring;
+                Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
+                      XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());
+              }
+            }
+            if (m_pErrorInfo->message.IsEmpty()) {
+              CXFA_FMSimpleExpression* pIdentifier =
+                  new CXFA_FMIdentifierExpressionn(tempLine, tempStr);
+              pExpCall = new CXFA_FMCallExpression(line, pIdentifier,
+                                                   pArray.release(), TRUE);
+              e = new CXFA_FMMethodCallExpression(line, pExpAccessor, pExpCall);
+              NextToken();
+              if (m_pToken->m_type != TOKlbracket) {
+                continue;
+              }
+              CXFA_FMSimpleExpression* s = ParseIndexExpression();
+              if (s) {
+                e = new CXFA_FMDotAccessorExpression(line, e, TOKcall,
+                                                     FX_WSTRC(L""), s);
+              } else {
+                delete e;
+                e = nullptr;
+              }
+            } else {
+              if (pArray) {
+                for (int32_t i = 0; i < pArray->GetSize(); ++i) {
+                  delete static_cast<CXFA_FMSimpleExpression*>(
+                      pArray->GetAt(i));
+                }
+              }
+              delete e;
+              e = nullptr;
+            }
+          } else if (m_pToken->m_type == TOKlbracket) {
+            std::unique_ptr<CXFA_FMSimpleExpression> s(ParseIndexExpression());
+            if (!(m_pErrorInfo->message.IsEmpty())) {
+              delete e;
+              return nullptr;
+            }
+            e = new CXFA_FMDotAccessorExpression(tempLine, e, TOKdot, tempStr,
+                                                 s.release());
+          } else {
+            CXFA_FMSimpleExpression* s = new CXFA_FMIndexExpression(
+                tempLine, ACCESSOR_NO_INDEX, NULL, FALSE);
+            e = new CXFA_FMDotAccessorExpression(line, e, TOKdot, tempStr, s);
+            continue;
+          }
+        } else {
+          CFX_WideString ws_TempString = m_pToken->m_wstring;
+          Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,
+                ws_TempString.c_str());
+          return e;
+        }
+        break;
+      case TOKdotdot:
+        NextToken();
+        if (m_pToken->m_type == TOKidentifier) {
+          CFX_WideStringC tempStr = m_pToken->m_wstring;
+          FX_DWORD tempLine = m_pToken->m_uLinenum;
+          NextToken();
+          if (m_pToken->m_type == TOKlbracket) {
+            std::unique_ptr<CXFA_FMSimpleExpression> s(ParseIndexExpression());
+            if (!(m_pErrorInfo->message.IsEmpty())) {
+              delete e;
+              return nullptr;
+            }
+            e = new CXFA_FMDotDotAccessorExpression(tempLine, e, TOKdotdot,
+                                                    tempStr, s.release());
+          } else {
+            CXFA_FMSimpleExpression* s = new CXFA_FMIndexExpression(
+                tempLine, ACCESSOR_NO_INDEX, NULL, FALSE);
+            e = new CXFA_FMDotDotAccessorExpression(line, e, TOKdotdot, tempStr,
+                                                    s);
+            continue;
+          }
+        } else {
+          CFX_WideString ws_TempString = m_pToken->m_wstring;
+          Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,
+                ws_TempString.c_str());
+          return e;
+        }
+        break;
+      case TOKdotscream:
+        NextToken();
+        if (m_pToken->m_type == TOKidentifier) {
+          CFX_WideStringC tempStr = m_pToken->m_wstring;
+          FX_DWORD tempLine = m_pToken->m_uLinenum;
+          NextToken();
+          if (m_pToken->m_type == TOKlbracket) {
+            std::unique_ptr<CXFA_FMSimpleExpression> s(ParseIndexExpression());
+            if (!(m_pErrorInfo->message.IsEmpty())) {
+              delete e;
+              return nullptr;
+            }
+            e = new CXFA_FMDotAccessorExpression(tempLine, e, TOKdotscream,
+                                                 tempStr, s.release());
+          } else {
+            CXFA_FMSimpleExpression* s = new CXFA_FMIndexExpression(
+                tempLine, ACCESSOR_NO_INDEX, NULL, FALSE);
+            e = new CXFA_FMDotAccessorExpression(line, e, TOKdotscream, tempStr,
+                                                 s);
+            continue;
+          }
+        } else {
+          CFX_WideString ws_TempString = m_pToken->m_wstring;
+          Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER,
+                ws_TempString.c_str());
+          return e;
+        }
+        break;
+      case TOKdotstar: {
+        CXFA_FMSimpleExpression* s =
+            new CXFA_FMIndexExpression(line, ACCESSOR_NO_INDEX, NULL, FALSE);
+        e = new CXFA_FMDotAccessorExpression(line, e, TOKdotstar,
+                                             FX_WSTRC(L"*"), s);
+      } break;
+      default:
+        return e;
+    }
+    NextToken();
+  }
+  return e;
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseIndexExpression() {
+  std::unique_ptr<CXFA_FMSimpleExpression> pExp;
+  FX_DWORD line = m_pToken->m_uLinenum;
+  NextToken();
+  std::unique_ptr<CXFA_FMSimpleExpression> s;
+  XFA_FM_AccessorIndex accessorIndex = ACCESSOR_NO_RELATIVEINDEX;
+  if (m_pToken->m_type == TOKmul) {
+    pExp.reset(
+        new CXFA_FMIndexExpression(line, accessorIndex, s.release(), TRUE));
+    NextToken();
+    if (m_pToken->m_type != TOKrbracket) {
+      CFX_WideString ws_TempString = m_pToken->m_wstring;
+      Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
+            XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());
+      pExp.reset();
+    }
+    return pExp.release();
+  }
+  if (m_pToken->m_type == TOKplus) {
+    accessorIndex = ACCESSOR_POSITIVE_INDEX;
+    NextToken();
+  } else if (m_pToken->m_type == TOKminus) {
+    accessorIndex = ACCESSOR_NEGATIVE_INDEX;
+    NextToken();
+  }
+  s.reset(ParseSimpleExpression());
+  if (m_pToken->m_type != TOKrbracket) {
+    CFX_WideString ws_TempString = m_pToken->m_wstring;
+    Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
+          XFA_FM_KeywordToString(TOKrparen), ws_TempString.c_str());
+  } else {
+    pExp.reset(
+        new CXFA_FMIndexExpression(line, accessorIndex, s.release(), FALSE));
+  }
+  return pExp.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseParenExpression() {
+  Check(TOKlparen);
+
+  if (m_pToken->m_type == TOKrparen) {
+    Error(m_pToken->m_uLinenum, FMERR_EXPECTED_NON_EMPTY_EXPRESSION);
+    NextToken();
+    return nullptr;
+  }
+
+  FX_DWORD line = m_pToken->m_uLinenum;
+  std::unique_ptr<CXFA_FMSimpleExpression> pExp1(ParseLogicalOrExpression());
+
+  while (m_pToken->m_type == TOKassign) {
+    NextToken();
+    std::unique_ptr<CXFA_FMSimpleExpression> pExp2(ParseLogicalOrExpression());
+    if (m_pErrorInfo->message.IsEmpty()) {
+      pExp1.reset(new CXFA_FMAssignExpression(line, TOKassign, pExp1.release(),
+                                              pExp2.release()));
+    } else {
+      pExp1.reset();
+    }
+  }
+  Check(TOKrparen);
+  return pExp1.release();
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseBlockExpression() {
+  FX_DWORD line = m_pToken->m_uLinenum;
+  CXFA_FMExpression* e = nullptr;
+  std::unique_ptr<CFX_PtrArray> expression(new CFX_PtrArray());
+  while (1) {
+    switch (m_pToken->m_type) {
+      case TOKeof:
+      case TOKendif:
+      case TOKelseif:
+      case TOKelse:
+      case TOKendwhile:
+      case TOKendfor:
+      case TOKend:
+      case TOKendfunc:
+      case TOKreserver:
+        break;
+      case TOKfunc:
+        e = ParseFunction();
+        if (e) {
+          expression->Add(e);
+        }
+        continue;
+      default:
+        e = ParseExpression();
+        if (e) {
+          expression->Add(e);
+        }
+        continue;
+    }
+    break;
+  }
+  std::unique_ptr<CXFA_FMBlockExpression> pExp;
+  if (m_pErrorInfo->message.IsEmpty()) {
+    pExp.reset(new CXFA_FMBlockExpression(line, expression.release()));
+  } else {
+    for (int i = 0; i < expression->GetSize(); ++i)
+      delete static_cast<CXFA_FMExpression*>(expression->GetAt(i));
+  }
+  return pExp.release();
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseIfExpression() {
+  FX_DWORD line = m_pToken->m_uLinenum;
+  const FX_WCHAR* pStartPos = m_lexer->SavePos();
+  NextToken();
+  Check(TOKlparen);
+  std::unique_ptr<CXFA_FMSimpleExpression> pExpression;
+  while (m_pToken->m_type != TOKrparen) {
+    pExpression.reset(ParseSimpleExpression());
+    if (m_pToken->m_type != TOKcomma)
+      break;
+    NextToken();
+  }
+  Check(TOKrparen);
+  if (m_pToken->m_type != TOKthen) {
+    m_lexer->SetCurrentLine(line);
+    m_pToken = new CXFA_FMToken(line);
+    m_pToken->m_type = TOKidentifier;
+    m_pToken->m_wstring = FX_WSTRC(L"if");
+    m_lexer->SetToken(m_pToken);
+    m_lexer->RestorePos(pStartPos);
+    return ParseExpExpression();
+  }
+  Check(TOKthen);
+  std::unique_ptr<CXFA_FMExpression> pIfExpression(ParseBlockExpression());
+  std::unique_ptr<CXFA_FMExpression> pElseExpression;
+  switch (m_pToken->m_type) {
+    case TOKeof:
+    case TOKendif:
+      Check(TOKendif);
+      break;
+    case TOKif:
+      pElseExpression.reset(ParseIfExpression());
+      Check(TOKendif);
+      break;
+    case TOKelseif:
+      pElseExpression.reset(ParseIfExpression());
+      break;
+    case TOKelse:
+      NextToken();
+      pElseExpression.reset(ParseBlockExpression());
+      Check(TOKendif);
+      break;
+    default:
+      CFX_WideString ws_TempString = m_pToken->m_wstring;
+      Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IFEND, ws_TempString.c_str());
+      NextToken();
+      break;
+  }
+  std::unique_ptr<CXFA_FMIfExpression> pExp;
+  if (m_pErrorInfo->message.IsEmpty()) {
+    pExp.reset(new CXFA_FMIfExpression(line, pExpression.release(),
+                                       pIfExpression.release(),
+                                       pElseExpression.release()));
+  }
+  return pExp.release();
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseWhileExpression() {
+  FX_DWORD line = m_pToken->m_uLinenum;
+  NextToken();
+  std::unique_ptr<CXFA_FMSimpleExpression> pCondition(ParseParenExpression());
+  Check(TOKdo);
+  std::unique_ptr<CXFA_FMExpression> pExpression(ParseBlockExpression());
+  Check(TOKendwhile);
+  std::unique_ptr<CXFA_FMExpression> e;
+  if (m_pErrorInfo->message.IsEmpty()) {
+    e.reset(new CXFA_FMWhileExpression(line, pCondition.release(),
+                                       pExpression.release()));
+  }
+  return e.release();
+}
+
+CXFA_FMSimpleExpression* CXFA_FMParse::ParseSubassignmentInForExpression() {
+  std::unique_ptr<CXFA_FMSimpleExpression> e;
+  switch (m_pToken->m_type) {
+    case TOKidentifier:
+      e.reset(ParseSimpleExpression());
+      break;
+    default:
+      CFX_WideString ws_TempString = m_pToken->m_wstring;
+      Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION,
+            ws_TempString.c_str());
+      NextToken();
+      break;
+  }
+  return e.release();
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseForExpression() {
+  CFX_WideStringC wsVariant;
+  FX_DWORD line = m_pToken->m_uLinenum;
+  NextToken();
+  if (m_pToken->m_type != TOKidentifier) {
+    CFX_WideString ws_TempString = m_pToken->m_wstring;
+    Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
+          XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str());
+  }
+  wsVariant = m_pToken->m_wstring;
+  NextToken();
+  std::unique_ptr<CXFA_FMSimpleExpression> pAssignment;
+  if (m_pToken->m_type == TOKassign) {
+    NextToken();
+    pAssignment.reset(ParseSimpleExpression());
+  } else {
+    CFX_WideString ws_TempString = m_pToken->m_wstring;
+    Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
+          XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str());
+  }
+  int32_t iDirection = 0;
+  if (m_pToken->m_type == TOKupto) {
+    iDirection = 1;
+  } else if (m_pToken->m_type == TOKdownto) {
+    iDirection = -1;
+  } else {
+    CFX_WideString ws_TempString = m_pToken->m_wstring;
+    Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, L"upto or downto",
+          (const FX_WCHAR*)ws_TempString);
+  }
+  NextToken();
+  std::unique_ptr<CXFA_FMSimpleExpression> pAccessor(ParseSimpleExpression());
+  std::unique_ptr<CXFA_FMSimpleExpression> pStep;
+  if (m_pToken->m_type == TOKstep) {
+    NextToken();
+    pStep.reset(ParseSimpleExpression());
+  }
+  Check(TOKdo);
+  std::unique_ptr<CXFA_FMExpression> pList(ParseBlockExpression());
+  Check(TOKendfor);
+  std::unique_ptr<CXFA_FMExpression> e;
+  if (m_pErrorInfo->message.IsEmpty()) {
+    e.reset(new CXFA_FMForExpression(line, wsVariant, pAssignment.release(),
+                                     pAccessor.release(), iDirection,
+                                     pStep.release(), pList.release()));
+  }
+  return e.release();
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseForeachExpression() {
+  std::unique_ptr<CXFA_FMExpression> e;
+  CFX_WideStringC wsIdentifier;
+  std::unique_ptr<CFX_PtrArray> pAccessors;
+  std::unique_ptr<CXFA_FMExpression> pList;
+  FX_DWORD line = m_pToken->m_uLinenum;
+  NextToken();
+  if (m_pToken->m_type != TOKidentifier) {
+    CFX_WideString ws_TempString = m_pToken->m_wstring;
+    Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN,
+          XFA_FM_KeywordToString(m_pToken->m_type), ws_TempString.c_str());
+  }
+  wsIdentifier = m_pToken->m_wstring;
+  NextToken();
+  Check(TOKin);
+  Check(TOKlparen);
+  if (m_pToken->m_type == TOKrparen) {
+    CFX_WideString ws_TempString = m_pToken->m_wstring;
+    Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION,
+          ws_TempString.c_str());
+    NextToken();
+  } else {
+    pAccessors.reset(new CFX_PtrArray());
+    while (m_pToken->m_type != TOKrparen) {
+      CXFA_FMSimpleExpression* s = ParseSimpleExpression();
+      if (s) {
+        pAccessors->Add(s);
+      }
+      if (m_pToken->m_type == TOKcomma) {
+        NextToken();
+      } else {
+        break;
+      }
+    }
+    Check(TOKrparen);
+  }
+  Check(TOKdo);
+  pList.reset(ParseBlockExpression());
+  Check(TOKendfor);
+  if (m_pErrorInfo->message.IsEmpty()) {
+    e.reset(new CXFA_FMForeachExpression(
+        line, wsIdentifier, pAccessors.release(), pList.release()));
+  } else {
+    if (pAccessors) {
+      for (int i = 0; i < pAccessors->GetSize(); ++i)
+        delete static_cast<CXFA_FMSimpleExpression*>(pAccessors->GetAt(i));
+    }
+  }
+  return e.release();
+}
+
+CXFA_FMExpression* CXFA_FMParse::ParseDoExpression() {
+  std::unique_ptr<CXFA_FMExpression> e;
+  FX_DWORD line = m_pToken->m_uLinenum;
+  NextToken();
+  e.reset(ParseBlockExpression());
+  Check(TOKend);
+  if (m_pErrorInfo->message.IsEmpty()) {
+    e.reset(new CXFA_FMDoExpression(line, e.release()));
+  } else {
+    e.reset();
+  }
+  return e.release();
+}
diff --git a/xfa/fxfa/fm2js/xfa_fmparse.h b/xfa/fxfa/fm2js/xfa_fmparse.h
new file mode 100644
index 0000000..a8991b4
--- /dev/null
+++ b/xfa/fxfa/fm2js/xfa_fmparse.h
@@ -0,0 +1,53 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_FM2JS_XFA_FMPARSE_H_
+#define XFA_FXFA_FM2JS_XFA_FMPARSE_H_
+
+#include <memory>
+
+#include "xfa/fxfa/fm2js/xfa_expression.h"
+#include "xfa/fxfa/fm2js/xfa_lexer.h"
+
+class CXFA_FMParse {
+ public:
+  CXFA_FMParse();
+  int32_t Init(const CFX_WideStringC& wsFormcalc, CXFA_FMErrorInfo* pErrorInfo);
+  void NextToken();
+  void Check(XFA_FM_TOKEN op);
+  void Error(FX_DWORD lineNum, XFA_FM_ERRMSG msg, ...);
+  CFX_PtrArray* ParseTopExpression();
+  CXFA_FMExpression* ParseFunction();
+  CXFA_FMExpression* ParseExpression();
+  CXFA_FMExpression* ParseVarExpression();
+  CXFA_FMExpression* ParseExpExpression();
+  CXFA_FMExpression* ParseBlockExpression();
+  CXFA_FMExpression* ParseIfExpression();
+  CXFA_FMExpression* ParseWhileExpression();
+  CXFA_FMExpression* ParseForExpression();
+  CXFA_FMExpression* ParseForeachExpression();
+  CXFA_FMExpression* ParseDoExpression();
+  CXFA_FMSimpleExpression* ParseParenExpression();
+  CXFA_FMSimpleExpression* ParseSimpleExpression();
+  CXFA_FMSimpleExpression* ParseSubassignmentInForExpression();
+  CXFA_FMSimpleExpression* ParseLogicalOrExpression();
+  CXFA_FMSimpleExpression* ParseLogicalAndExpression();
+  CXFA_FMSimpleExpression* ParseEqualityExpression();
+  CXFA_FMSimpleExpression* ParseRelationalExpression();
+  CXFA_FMSimpleExpression* ParseAddtiveExpression();
+  CXFA_FMSimpleExpression* ParseMultiplicativeExpression();
+  CXFA_FMSimpleExpression* ParseUnaryExpression();
+  CXFA_FMSimpleExpression* ParsePrimaryExpression();
+  CXFA_FMSimpleExpression* ParsePostExpression(CXFA_FMSimpleExpression* e);
+  CXFA_FMSimpleExpression* ParseIndexExpression();
+
+ private:
+  std::unique_ptr<CXFA_FMLexer> m_lexer;
+  CXFA_FMToken* m_pToken;
+  CXFA_FMErrorInfo* m_pErrorInfo;
+};
+
+#endif  // XFA_FXFA_FM2JS_XFA_FMPARSE_H_
diff --git a/xfa/fxfa/fm2js/xfa_lexer.cpp b/xfa/fxfa/fm2js/xfa_lexer.cpp
new file mode 100644
index 0000000..d470390
--- /dev/null
+++ b/xfa/fxfa/fm2js/xfa_lexer.cpp
@@ -0,0 +1,552 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/fm2js/xfa_lexer.h"
+
+#include "core/include/fxcrt/fx_ext.h"
+
+namespace {
+
+struct XFA_FMDChar {
+  static const FX_WCHAR* inc(const FX_WCHAR*& p) {
+    ++p;
+    return p;
+  }
+  static const FX_WCHAR* dec(const FX_WCHAR*& p) {
+    --p;
+    return p;
+  }
+  static uint16_t get(const FX_WCHAR* p) { return *p; }
+  static FX_BOOL isWhiteSpace(const FX_WCHAR* p) {
+    return (*p) == 0x09 || (*p) == 0x0b || (*p) == 0x0c || (*p) == 0x20;
+  }
+  static FX_BOOL isLineTerminator(const FX_WCHAR* p) {
+    return *p == 0x0A || *p == 0x0D;
+  }
+  static FX_BOOL isBinary(const FX_WCHAR* p) {
+    return (*p) >= '0' && (*p) <= '1';
+  }
+  static FX_BOOL isOctal(const FX_WCHAR* p) {
+    return (*p) >= '0' && (*p) <= '7';
+  }
+  static FX_BOOL isDigital(const FX_WCHAR* p) {
+    return (*p) >= '0' && (*p) <= '9';
+  }
+  static FX_BOOL isHex(const FX_WCHAR* p) {
+    return isDigital(p) || ((*p) >= 'a' && (*p) <= 'f') ||
+           ((*p) >= 'A' && (*p) <= 'F');
+  }
+  static FX_BOOL isAlpha(const FX_WCHAR* p) {
+    return ((*p) <= 'z' && (*p) >= 'a') || ((*p) <= 'Z' && (*p) >= 'A');
+  }
+  static FX_BOOL isAvalid(const FX_WCHAR* p, FX_BOOL flag = 0);
+  static FX_BOOL string2number(const FX_WCHAR* s,
+                               FX_DOUBLE* pValue,
+                               const FX_WCHAR*& pEnd);
+  static FX_BOOL isUnicodeAlpha(uint16_t ch);
+};
+
+inline FX_BOOL XFA_FMDChar::isAvalid(const FX_WCHAR* p, FX_BOOL flag) {
+  if (*p == 0) {
+    return 1;
+  }
+  if ((*p <= 0x0A && *p >= 0x09) || *p == 0x0D ||
+      (*p <= 0xd7ff && *p >= 0x20) || (*p <= 0xfffd && *p >= 0xe000)) {
+    return 1;
+  }
+  if (!flag) {
+    if (*p == 0x0B || *p == 0x0C) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+inline FX_BOOL XFA_FMDChar::string2number(const FX_WCHAR* s,
+                                          FX_DOUBLE* pValue,
+                                          const FX_WCHAR*& pEnd) {
+  if (s) {
+    *pValue = wcstod((wchar_t*)s, (wchar_t**)&pEnd);
+  }
+  return 0;
+}
+
+inline FX_BOOL XFA_FMDChar::isUnicodeAlpha(uint16_t ch) {
+  if (ch == 0 || ch == 0x0A || ch == 0x0D || ch == 0x09 || ch == 0x0B ||
+      ch == 0x0C || ch == 0x20 || ch == '.' || ch == ';' || ch == '"' ||
+      ch == '=' || ch == '<' || ch == '>' || ch == ',' || ch == '(' ||
+      ch == ')' || ch == ']' || ch == '[' || ch == '&' || ch == '|' ||
+      ch == '+' || ch == '-' || ch == '*' || ch == '/') {
+    return FALSE;
+  }
+  return TRUE;
+}
+
+const XFA_FMKeyword keyWords[] = {
+    {TOKand, 0x00000026, L"&"},
+    {TOKlparen, 0x00000028, L"("},
+    {TOKrparen, 0x00000029, L")"},
+    {TOKmul, 0x0000002a, L"*"},
+    {TOKplus, 0x0000002b, L"+"},
+    {TOKcomma, 0x0000002c, L","},
+    {TOKminus, 0x0000002d, L"-"},
+    {TOKdot, 0x0000002e, L"."},
+    {TOKdiv, 0x0000002f, L"/"},
+    {TOKlt, 0x0000003c, L"<"},
+    {TOKassign, 0x0000003d, L"="},
+    {TOKgt, 0x0000003e, L">"},
+    {TOKlbracket, 0x0000005b, L"["},
+    {TOKrbracket, 0x0000005d, L"]"},
+    {TOKor, 0x0000007c, L"|"},
+    {TOKdotscream, 0x0000ec11, L".#"},
+    {TOKdotstar, 0x0000ec18, L".*"},
+    {TOKdotdot, 0x0000ec1c, L".."},
+    {TOKle, 0x000133f9, L"<="},
+    {TOKne, 0x000133fa, L"<>"},
+    {TOKeq, 0x0001391a, L"=="},
+    {TOKge, 0x00013e3b, L">="},
+    {TOKdo, 0x00020153, L"do"},
+    {TOKkseq, 0x00020676, L"eq"},
+    {TOKksge, 0x000210ac, L"ge"},
+    {TOKksgt, 0x000210bb, L"gt"},
+    {TOKif, 0x00021aef, L"if"},
+    {TOKin, 0x00021af7, L"in"},
+    {TOKksle, 0x00022a51, L"le"},
+    {TOKkslt, 0x00022a60, L"lt"},
+    {TOKksne, 0x00023493, L"ne"},
+    {TOKksor, 0x000239c1, L"or"},
+    {TOKnull, 0x052931bb, L"null"},
+    {TOKbreak, 0x05518c25, L"break"},
+    {TOKksand, 0x09f9db33, L"and"},
+    {TOKend, 0x0a631437, L"end"},
+    {TOKeof, 0x0a63195a, L"eof"},
+    {TOKfor, 0x0a7d67a7, L"for"},
+    {TOKnan, 0x0b4f91dd, L"nan"},
+    {TOKksnot, 0x0b4fd9b1, L"not"},
+    {TOKvar, 0x0c2203e9, L"var"},
+    {TOKthen, 0x2d5738cf, L"then"},
+    {TOKelse, 0x45f65ee9, L"else"},
+    {TOKexit, 0x4731d6ba, L"exit"},
+    {TOKdownto, 0x4caadc3b, L"downto"},
+    {TOKreturn, 0x4db8bd60, L"return"},
+    {TOKinfinity, 0x5c0a010a, L"infinity"},
+    {TOKendwhile, 0x5c64bff0, L"endwhile"},
+    {TOKforeach, 0x67e31f38, L"foreach"},
+    {TOKendfunc, 0x68f984a3, L"endfunc"},
+    {TOKelseif, 0x78253218, L"elseif"},
+    {TOKwhile, 0x84229259, L"while"},
+    {TOKendfor, 0x8ab49d7e, L"endfor"},
+    {TOKthrow, 0x8db05c94, L"throw"},
+    {TOKstep, 0xa7a7887c, L"step"},
+    {TOKupto, 0xb5155328, L"upto"},
+    {TOKcontinue, 0xc0340685, L"continue"},
+    {TOKfunc, 0xcdce60ec, L"func"},
+    {TOKendif, 0xe0e8fee6, L"endif"},
+};
+
+const XFA_FM_TOKEN KEYWORD_START = TOKdo;
+const XFA_FM_TOKEN KEYWORD_END = TOKendif;
+
+}  // namespace
+
+const FX_WCHAR* XFA_FM_KeywordToString(XFA_FM_TOKEN op) {
+  if (op < KEYWORD_START || op > KEYWORD_END)
+    return L"";
+  return keyWords[op].m_keyword;
+}
+
+CXFA_FMToken::CXFA_FMToken() : m_type(TOKreserver), m_uLinenum(1) {}
+
+CXFA_FMToken::CXFA_FMToken(FX_DWORD uLineNum)
+    : m_type(TOKreserver), m_uLinenum(uLineNum) {}
+
+CXFA_FMLexer::CXFA_FMLexer(const CFX_WideStringC& wsFormCalc,
+                           CXFA_FMErrorInfo* pErrorInfo)
+    : m_ptr(wsFormCalc.GetPtr()), m_uCurrentLine(1), m_pErrorInfo(pErrorInfo) {}
+
+CXFA_FMToken* CXFA_FMLexer::NextToken() {
+  m_pToken.reset(Scan());
+  return m_pToken.get();
+}
+
+CXFA_FMToken* CXFA_FMLexer::Scan() {
+  uint16_t ch = 0;
+  CXFA_FMToken* p = new CXFA_FMToken(m_uCurrentLine);
+  if (!XFA_FMDChar::isAvalid(m_ptr)) {
+    ch = XFA_FMDChar::get(m_ptr);
+    Error(FMERR_UNSUPPORTED_CHAR, ch);
+    return p;
+  }
+  int iRet = 0;
+  while (1) {
+    if (!XFA_FMDChar::isAvalid(m_ptr)) {
+      ch = XFA_FMDChar::get(m_ptr);
+      Error(FMERR_UNSUPPORTED_CHAR, ch);
+      return p;
+    }
+    ch = XFA_FMDChar::get(m_ptr);
+    switch (ch) {
+      case 0:
+        p->m_type = TOKeof;
+        return p;
+      case 0x0A:
+        ++m_uCurrentLine;
+        p->m_uLinenum = m_uCurrentLine;
+        XFA_FMDChar::inc(m_ptr);
+        break;
+      case 0x0D:
+        XFA_FMDChar::inc(m_ptr);
+        break;
+      case ';': {
+        const FX_WCHAR* pTemp = 0;
+        Comment(m_ptr, pTemp);
+        m_ptr = pTemp;
+      } break;
+      case '"': {
+        const FX_WCHAR* pTemp = 0;
+        p->m_type = TOKstring;
+        iRet = String(p, m_ptr, pTemp);
+        m_ptr = pTemp;
+      }
+        return p;
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9': {
+        p->m_type = TOKnumber;
+        const FX_WCHAR* pTemp = 0;
+        iRet = Number(p, m_ptr, pTemp);
+        m_ptr = pTemp;
+        if (iRet) {
+          Error(FMERR_BAD_SUFFIX_NUMBER);
+          return p;
+        }
+      }
+        return p;
+      case '=':
+        XFA_FMDChar::inc(m_ptr);
+        if (XFA_FMDChar::isAvalid(m_ptr)) {
+          ch = XFA_FMDChar::get(m_ptr);
+          if (ch == '=') {
+            p->m_type = TOKeq;
+            XFA_FMDChar::inc(m_ptr);
+            return p;
+          } else {
+            p->m_type = TOKassign;
+            return p;
+          }
+        } else {
+          ch = XFA_FMDChar::get(m_ptr);
+          Error(FMERR_UNSUPPORTED_CHAR, ch);
+          return p;
+        }
+        break;
+      case '<':
+        XFA_FMDChar::inc(m_ptr);
+        if (XFA_FMDChar::isAvalid(m_ptr)) {
+          ch = XFA_FMDChar::get(m_ptr);
+          if (ch == '=') {
+            p->m_type = TOKle;
+            XFA_FMDChar::inc(m_ptr);
+            return p;
+          } else if (ch == '>') {
+            p->m_type = TOKne;
+            XFA_FMDChar::inc(m_ptr);
+            return p;
+          } else {
+            p->m_type = TOKlt;
+            return p;
+          }
+        } else {
+          ch = XFA_FMDChar::get(m_ptr);
+          Error(FMERR_UNSUPPORTED_CHAR, ch);
+          return p;
+        }
+        break;
+      case '>':
+        XFA_FMDChar::inc(m_ptr);
+        if (XFA_FMDChar::isAvalid(m_ptr)) {
+          ch = XFA_FMDChar::get(m_ptr);
+          if (ch == '=') {
+            p->m_type = TOKge;
+            XFA_FMDChar::inc(m_ptr);
+            return p;
+          } else {
+            p->m_type = TOKgt;
+            return p;
+          }
+        } else {
+          ch = XFA_FMDChar::get(m_ptr);
+          Error(FMERR_UNSUPPORTED_CHAR, ch);
+          return p;
+        }
+        break;
+      case ',':
+        p->m_type = TOKcomma;
+        XFA_FMDChar::inc(m_ptr);
+        return p;
+      case '(':
+        p->m_type = TOKlparen;
+        XFA_FMDChar::inc(m_ptr);
+        return p;
+      case ')':
+        p->m_type = TOKrparen;
+        XFA_FMDChar::inc(m_ptr);
+        return p;
+      case '[':
+        p->m_type = TOKlbracket;
+        XFA_FMDChar::inc(m_ptr);
+        return p;
+      case ']':
+        p->m_type = TOKrbracket;
+        XFA_FMDChar::inc(m_ptr);
+        return p;
+      case '&':
+        XFA_FMDChar::inc(m_ptr);
+        p->m_type = TOKand;
+        return p;
+      case '|':
+        XFA_FMDChar::inc(m_ptr);
+        p->m_type = TOKor;
+        return p;
+      case '+':
+        XFA_FMDChar::inc(m_ptr);
+        p->m_type = TOKplus;
+        return p;
+      case '-':
+        XFA_FMDChar::inc(m_ptr);
+        p->m_type = TOKminus;
+        return p;
+      case '*':
+        XFA_FMDChar::inc(m_ptr);
+        p->m_type = TOKmul;
+        return p;
+      case '/':
+        XFA_FMDChar::inc(m_ptr);
+        if (XFA_FMDChar::isAvalid(m_ptr)) {
+          ch = XFA_FMDChar::get(m_ptr);
+          if (ch == '/') {
+            const FX_WCHAR* pTemp = 0;
+            Comment(m_ptr, pTemp);
+            m_ptr = pTemp;
+            break;
+          } else {
+            p->m_type = TOKdiv;
+            return p;
+          }
+        } else {
+          ch = XFA_FMDChar::get(m_ptr);
+          Error(FMERR_UNSUPPORTED_CHAR, ch);
+          return p;
+        }
+        break;
+      case '.':
+        XFA_FMDChar::inc(m_ptr);
+        if (XFA_FMDChar::isAvalid(m_ptr)) {
+          ch = XFA_FMDChar::get(m_ptr);
+          if (ch == '.') {
+            p->m_type = TOKdotdot;
+            XFA_FMDChar::inc(m_ptr);
+            return p;
+          } else if (ch == '*') {
+            p->m_type = TOKdotstar;
+            XFA_FMDChar::inc(m_ptr);
+            return p;
+          } else if (ch == '#') {
+            p->m_type = TOKdotscream;
+            XFA_FMDChar::inc(m_ptr);
+            return p;
+          } else if (ch <= '9' && ch >= '0') {
+            p->m_type = TOKnumber;
+            const FX_WCHAR* pTemp = 0;
+            XFA_FMDChar::dec(m_ptr);
+            iRet = Number(p, m_ptr, pTemp);
+            m_ptr = pTemp;
+            if (iRet) {
+              Error(FMERR_BAD_SUFFIX_NUMBER);
+            }
+            return p;
+          } else {
+            p->m_type = TOKdot;
+            return p;
+          }
+        } else {
+          ch = XFA_FMDChar::get(m_ptr);
+          Error(FMERR_UNSUPPORTED_CHAR, ch);
+          return p;
+        }
+      case 0x09:
+      case 0x0B:
+      case 0x0C:
+      case 0x20:
+        XFA_FMDChar::inc(m_ptr);
+        break;
+      default: {
+        const FX_WCHAR* pTemp = 0;
+        iRet = Identifiers(p, m_ptr, pTemp);
+        m_ptr = pTemp;
+        if (iRet) {
+          return p;
+        }
+        p->m_type = IsKeyword(p->m_wstring);
+      }
+        return p;
+    }
+  }
+}
+
+FX_DWORD CXFA_FMLexer::Number(CXFA_FMToken* t,
+                              const FX_WCHAR* p,
+                              const FX_WCHAR*& pEnd) {
+  FX_DOUBLE number = 0;
+  if (XFA_FMDChar::string2number(p, &number, pEnd)) {
+    return 1;
+  }
+  if (pEnd && XFA_FMDChar::isAlpha(pEnd)) {
+    return 1;
+  }
+  t->m_wstring = CFX_WideStringC(p, (pEnd - p));
+  return 0;
+}
+
+FX_DWORD CXFA_FMLexer::String(CXFA_FMToken* t,
+                              const FX_WCHAR* p,
+                              const FX_WCHAR*& pEnd) {
+  const FX_WCHAR* pStart = p;
+  uint16_t ch = 0;
+  XFA_FMDChar::inc(p);
+  ch = XFA_FMDChar::get(p);
+  while (ch) {
+    if (!XFA_FMDChar::isAvalid(p)) {
+      ch = XFA_FMDChar::get(p);
+      pEnd = p;
+      t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
+      Error(FMERR_UNSUPPORTED_CHAR, ch);
+      return 1;
+    }
+    if (ch == '"') {
+      XFA_FMDChar::inc(p);
+      if (!XFA_FMDChar::isAvalid(p)) {
+        ch = XFA_FMDChar::get(p);
+        pEnd = p;
+        t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
+        Error(FMERR_UNSUPPORTED_CHAR, ch);
+        return 1;
+      }
+      ch = XFA_FMDChar::get(p);
+      if (ch == '"') {
+        goto NEXT;
+      } else {
+        break;
+      }
+    }
+  NEXT:
+    XFA_FMDChar::inc(p);
+    ch = XFA_FMDChar::get(p);
+  }
+  pEnd = p;
+  t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
+  return 0;
+}
+
+FX_DWORD CXFA_FMLexer::Identifiers(CXFA_FMToken* t,
+                                   const FX_WCHAR* p,
+                                   const FX_WCHAR*& pEnd) {
+  const FX_WCHAR* pStart = p;
+  uint16_t ch = 0;
+  ch = XFA_FMDChar::get(p);
+  XFA_FMDChar::inc(p);
+  if (!XFA_FMDChar::isAvalid(p)) {
+    pEnd = p;
+    t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
+    Error(FMERR_UNSUPPORTED_CHAR, ch);
+    return 1;
+  }
+  ch = XFA_FMDChar::get(p);
+  while (ch) {
+    if (!XFA_FMDChar::isAvalid(p)) {
+      pEnd = p;
+      t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
+      Error(FMERR_UNSUPPORTED_CHAR, ch);
+      return 1;
+    }
+    ch = XFA_FMDChar::get(p);
+    if (XFA_FMDChar::isUnicodeAlpha(ch)) {
+      XFA_FMDChar::inc(p);
+    } else {
+      pEnd = p;
+      t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
+      return 0;
+    }
+  }
+  pEnd = p;
+  t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
+  return 0;
+}
+
+void CXFA_FMLexer::Comment(const FX_WCHAR* p, const FX_WCHAR*& pEnd) {
+  unsigned ch = 0;
+  XFA_FMDChar::inc(p);
+  ch = XFA_FMDChar::get(p);
+  while (ch) {
+    if (ch == 0x0D) {
+      XFA_FMDChar::inc(p);
+      pEnd = p;
+      return;
+    }
+    if (ch == 0x0A) {
+      ++m_uCurrentLine;
+      XFA_FMDChar::inc(p);
+      pEnd = p;
+      return;
+    }
+    XFA_FMDChar::inc(p);
+    ch = XFA_FMDChar::get(p);
+  }
+  pEnd = p;
+}
+
+XFA_FM_TOKEN CXFA_FMLexer::IsKeyword(const CFX_WideStringC& str) {
+  int32_t iLength = str.GetLength();
+  uint32_t uHash = FX_HashCode_String_GetW(str.GetPtr(), iLength, TRUE);
+  int32_t iStart = KEYWORD_START, iEnd = KEYWORD_END;
+  int32_t iMid = (iStart + iEnd) / 2;
+  XFA_FMKeyword keyword;
+  do {
+    iMid = (iStart + iEnd) / 2;
+    keyword = keyWords[iMid];
+    if (uHash == keyword.m_uHash) {
+      return keyword.m_type;
+    } else if (uHash < keyword.m_uHash) {
+      iEnd = iMid - 1;
+    } else {
+      iStart = iMid + 1;
+    }
+  } while (iStart <= iEnd);
+  return TOKidentifier;
+}
+
+void CXFA_FMLexer::Error(XFA_FM_ERRMSG msg, ...) {
+  m_pErrorInfo->linenum = m_uCurrentLine;
+  const FX_WCHAR* lpMessageInfo = XFA_FM_ErrorMsg(msg);
+  va_list ap;
+  va_start(ap, msg);
+  m_pErrorInfo->message.FormatV(lpMessageInfo, ap);
+  va_end(ap);
+}
+
+FX_BOOL CXFA_FMLexer::HasError() const {
+  if (m_pErrorInfo->message.IsEmpty()) {
+    return FALSE;
+  }
+  return TRUE;
+}
diff --git a/xfa/fxfa/fm2js/xfa_lexer.h b/xfa/fxfa/fm2js/xfa_lexer.h
new file mode 100644
index 0000000..b0d6069
--- /dev/null
+++ b/xfa/fxfa/fm2js/xfa_lexer.h
@@ -0,0 +1,134 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_FM2JS_XFA_LEXER_H_
+#define XFA_FXFA_FM2JS_XFA_LEXER_H_
+
+#include <memory>
+
+#include "core/include/fxcrt/fx_string.h"
+#include "xfa/fxfa/fm2js/xfa_error.h"
+
+enum XFA_FM_TOKEN {
+  TOKand,
+  TOKlparen,
+  TOKrparen,
+  TOKmul,
+  TOKplus,
+  TOKcomma,
+  TOKminus,
+  TOKdot,
+  TOKdiv,
+  TOKlt,
+  TOKassign,
+  TOKgt,
+  TOKlbracket,
+  TOKrbracket,
+  TOKor,
+  TOKdotscream,
+  TOKdotstar,
+  TOKdotdot,
+  TOKle,
+  TOKne,
+  TOKeq,
+  TOKge,
+  TOKdo,
+  TOKkseq,
+  TOKksge,
+  TOKksgt,
+  TOKif,
+  TOKin,
+  TOKksle,
+  TOKkslt,
+  TOKksne,
+  TOKksor,
+  TOKnull,
+  TOKbreak,
+  TOKksand,
+  TOKend,
+  TOKeof,
+  TOKfor,
+  TOKnan,
+  TOKksnot,
+  TOKvar,
+  TOKthen,
+  TOKelse,
+  TOKexit,
+  TOKdownto,
+  TOKreturn,
+  TOKinfinity,
+  TOKendwhile,
+  TOKforeach,
+  TOKendfunc,
+  TOKelseif,
+  TOKwhile,
+  TOKendfor,
+  TOKthrow,
+  TOKstep,
+  TOKupto,
+  TOKcontinue,
+  TOKfunc,
+  TOKendif,
+  TOKstar,
+  TOKidentifier,
+  TOKunderscore,
+  TOKdollar,
+  TOKexclamation,
+  TOKcall,
+  TOKstring,
+  TOKnumber,
+  TOKreserver
+};
+
+struct XFA_FMKeyword {
+  XFA_FM_TOKEN m_type;
+  uint32_t m_uHash;
+  const FX_WCHAR* m_keyword;
+};
+
+const FX_WCHAR* XFA_FM_KeywordToString(XFA_FM_TOKEN op);
+
+class CXFA_FMToken {
+ public:
+  CXFA_FMToken();
+  explicit CXFA_FMToken(FX_DWORD uLineNum);
+
+  CFX_WideStringC m_wstring;
+  XFA_FM_TOKEN m_type;
+  FX_DWORD m_uLinenum;
+};
+
+class CXFA_FMLexer {
+ public:
+  CXFA_FMLexer(const CFX_WideStringC& wsFormcalc, CXFA_FMErrorInfo* pErrorInfo);
+  CXFA_FMToken* NextToken();
+  FX_DWORD Number(CXFA_FMToken* t, const FX_WCHAR* p, const FX_WCHAR*& pEnd);
+  FX_DWORD String(CXFA_FMToken* t, const FX_WCHAR* p, const FX_WCHAR*& pEnd);
+  FX_DWORD Identifiers(CXFA_FMToken* t,
+                       const FX_WCHAR* p,
+                       const FX_WCHAR*& pEnd);
+  void Comment(const FX_WCHAR* p, const FX_WCHAR*& pEnd);
+  XFA_FM_TOKEN IsKeyword(const CFX_WideStringC& p);
+  void SetCurrentLine(FX_DWORD line) { m_uCurrentLine = line; }
+  void SetToken(CXFA_FMToken* pToken) {
+    if (m_pToken.get() != pToken)
+      m_pToken.reset(pToken);
+  }
+  const FX_WCHAR* SavePos() { return m_ptr; }
+  void RestorePos(const FX_WCHAR* pPos) { m_ptr = pPos; }
+  void Error(XFA_FM_ERRMSG msg, ...);
+  FX_BOOL HasError() const;
+
+ protected:
+  CXFA_FMToken* Scan();
+
+  const FX_WCHAR* m_ptr;
+  FX_DWORD m_uCurrentLine;
+  std::unique_ptr<CXFA_FMToken> m_pToken;
+  CXFA_FMErrorInfo* m_pErrorInfo;
+};
+
+#endif  // XFA_FXFA_FM2JS_XFA_LEXER_H_
diff --git a/xfa/fxfa/fm2js/xfa_program.cpp b/xfa/fxfa/fm2js/xfa_program.cpp
new file mode 100644
index 0000000..ef5efb2
--- /dev/null
+++ b/xfa/fxfa/fm2js/xfa_program.cpp
@@ -0,0 +1,45 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/fm2js/xfa_program.h"
+
+CXFA_FMProgram::CXFA_FMProgram() : m_globalFunction(0) {}
+CXFA_FMProgram::~CXFA_FMProgram() {
+  if (m_globalFunction != 0) {
+    delete m_globalFunction;
+    m_globalFunction = 0;
+  }
+}
+int32_t CXFA_FMProgram::Init(const CFX_WideStringC& wsFormcalc) {
+  return m_parse.Init(wsFormcalc, &m_pErrorInfo);
+}
+int32_t CXFA_FMProgram::ParseProgram() {
+  CFX_PtrArray* expressions = 0;
+  m_parse.NextToken();
+  if (!m_pErrorInfo.message.IsEmpty()) {
+    return -1;
+  }
+  expressions = m_parse.ParseTopExpression();
+  if (!m_pErrorInfo.message.IsEmpty()) {
+    CXFA_FMExpression* e = 0;
+    for (int32_t u = 0; u < expressions->GetSize(); ++u) {
+      e = (CXFA_FMExpression*)expressions->GetAt(u);
+      if (e) {
+        delete e;
+      }
+    }
+    delete expressions;
+    return -1;
+  }
+  m_globalFunction =
+      new CXFA_FMFunctionDefinition(1, 1, FX_WSTRC(L""), 0, expressions);
+  return 0;
+}
+int32_t CXFA_FMProgram::TranslateProgram(CFX_WideTextBuf& wsJavaScript) {
+  m_globalFunction->ToJavaScript(wsJavaScript);
+  wsJavaScript.AppendChar(0);
+  return 0;
+}
diff --git a/xfa/fxfa/fm2js/xfa_program.h b/xfa/fxfa/fm2js/xfa_program.h
new file mode 100644
index 0000000..2f6de5e
--- /dev/null
+++ b/xfa/fxfa/fm2js/xfa_program.h
@@ -0,0 +1,28 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_FM2JS_XFA_PROGRAM_H_
+#define XFA_FXFA_FM2JS_XFA_PROGRAM_H_
+
+#include "xfa/fxfa/fm2js/xfa_error.h"
+#include "xfa/fxfa/fm2js/xfa_fmparse.h"
+
+class CXFA_FMProgram {
+ public:
+  CXFA_FMProgram();
+  ~CXFA_FMProgram();
+  int32_t Init(const CFX_WideStringC& wsFormcalc);
+  int32_t ParseProgram();
+  int32_t TranslateProgram(CFX_WideTextBuf& wsJavaScript);
+  CXFA_FMErrorInfo& GetError() { return m_pErrorInfo; }
+
+ private:
+  CXFA_FMErrorInfo m_pErrorInfo;
+  CXFA_FMParse m_parse;
+  CXFA_FMFunctionDefinition* m_globalFunction;
+};
+
+#endif  // XFA_FXFA_FM2JS_XFA_PROGRAM_H_
diff --git a/xfa/fxfa/fm2js/xfa_simpleexpression.cpp b/xfa/fxfa/fm2js/xfa_simpleexpression.cpp
new file mode 100644
index 0000000..3e66573
--- /dev/null
+++ b/xfa/fxfa/fm2js/xfa_simpleexpression.cpp
@@ -0,0 +1,745 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/fm2js/xfa_simpleexpression.h"
+
+#include "core/include/fxcrt/fx_ext.h"
+
+namespace {
+
+const CFX_WideStringC gs_lpStrExpFuncName[] = {
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.assign_value_operator"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.logical_or_operator"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.logical_and_operator"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.equality_operator"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.notequality_operator"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.less_operator"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.lessequal_operator"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.greater_operator"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.greaterequal_operator"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.plus_operator"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.minus_operator"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.multiple_operator"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.divide_operator"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.positive_operator"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.negative_operator"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.logical_not_operator"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime."),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.dot_accessor"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.dotdot_accessor"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.concat_fm_object"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.is_fm_object"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.is_fm_array"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.get_fm_value"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.get_fm_jsobj"),
+    FX_WSTRC(L"foxit_xfa_formcalc_runtime.fm_var_filter"),
+};
+
+struct XFA_FMBuildInFunc {
+  uint32_t m_uHash;
+  const FX_WCHAR* m_buildinfunc;
+};
+const XFA_FMBuildInFunc g_BuildInFuncs[] = {
+    {0x0001f1f5, L"At"},           {0x00020b9c, L"FV"},
+    {0x00021aef, L"If"},           {0x00023ee6, L"PV"},
+    {0x04b5c9ee, L"Encode"},       {0x08e96685, L"DateFmt"},
+    {0x09f99db6, L"Abs"},          {0x09f9e583, L"Apr"},
+    {0x09fa043e, L"Avg"},          {0x0a9782a0, L"Get"},
+    {0x0b1b09df, L"Len"},          {0x0b3543a6, L"Max"},
+    {0x0b356ca4, L"Min"},          {0x0b358b60, L"Mod"},
+    {0x0b4fded4, L"NPV"},          {0x0b846bf1, L"Pmt"},
+    {0x0b8494f9, L"Put"},          {0x0bb8df5d, L"Ref"},
+    {0x0bd37a99, L"Str"},          {0x0bd37fb5, L"Sum"},
+    {0x1048469b, L"Cterm"},        {0x11e03660, L"Exists"},
+    {0x126236e6, L"Post"},         {0x127c6661, L"PPmt"},
+    {0x193ade3e, L"Right"},        {0x1ec8ab2c, L"Rate"},
+    {0x20e476dc, L"IsoTime2Num"},  {0x23eb6816, L"TimeFmt"},
+    {0x24fb17b0, L"LocalDateFmt"}, {0x28dee6e9, L"Format"},
+    {0x2d0890b8, L"Term"},         {0x2d71b00f, L"Time"},
+    {0x2f890fb1, L"Num2Time"},     {0x3767511d, L"Ceil"},
+    {0x3ffd1941, L"LocalTimeFmt"}, {0x442f68c8, L"Round"},
+    {0x46fd1128, L"Eval"},         {0x4d629440, L"Date2Num"},
+    {0x4dcf25f8, L"Concat"},       {0x4e00255d, L"UnitValue"},
+    {0x55a5cc29, L"Lower"},        {0x5e43e04c, L"WordNum"},
+    {0x620ce6ba, L"Ipmt"},         {0x6f544d49, L"Count"},
+    {0x7e241013, L"Within"},       {0x9b9a6e2b, L"IsoDate2Num"},
+    {0xb2c941c2, L"UnitType"},     {0xb598a1f7, L"Uuid"},
+    {0xbde9abde, L"Date"},         {0xc0010b80, L"Num2Date"},
+    {0xc1f6144c, L"Upper"},        {0xc44028f7, L"Oneof"},
+    {0xc62c1b2c, L"Space"},        {0xd0ff50f9, L"HasValue"},
+    {0xd1537042, L"Floor"},        {0xd2ac9cf1, L"Time2Num"},
+    {0xd907aee5, L"Num2GMTime"},   {0xdf24f7c4, L"Decode"},
+    {0xe2664803, L"Substr"},       {0xe3e7b528, L"Stuff"},
+    {0xe6792d4e, L"Rtrim"},        {0xe8c23f5b, L"Parse"},
+    {0xea18d121, L"Choose"},       {0xebfef69c, L"Replace"},
+    {0xf5ad782b, L"Left"},         {0xf7bb2248, L"Ltrim"},
+};
+
+struct XFA_FMSOMMethod {
+  uint32_t m_uHash;
+  const FX_WCHAR* m_wsSomMethodName;
+  FX_DWORD m_dParameters;
+};
+const XFA_FMSOMMethod gs_FMSomMethods[] = {
+    {0x00000068, L"h", 0x01},
+    {0x00000077, L"w", 0x01},
+    {0x00000078, L"x", 0x01},
+    {0x00000079, L"y", 0x01},
+    {0x05eb5b0f, L"pageSpan", 0x01},
+    {0x10f1b1bd, L"page", 0x01},
+    {0x3bf1c2a5, L"absPageSpan", 0x01},
+    {0x3c752495, L"verify", 0x0d},
+    {0x44c352ad, L"formNodes", 0x01},
+    {0x5775c2cc, L"absPageInBatch", 0x01},
+    {0x5ee00996, L"setElement", 0x01},
+    {0x7033bfd5, L"insert", 0x03},
+    {0x8c5feb32, L"sheetInBatch", 0x01},
+    {0x8f3a8379, L"sheet", 0x01},
+    {0x92dada4f, L"saveFilteredXML", 0x01},
+    {0x9cab7cae, L"remove", 0x01},
+    {0xa68635f1, L"sign", 0x61},
+    {0xaac241c8, L"isRecordGroup", 0x01},
+    {0xd8ed1467, L"clear", 0x01},
+    {0xda12e518, L"append", 0x01},
+    {0xe74f0653, L"absPage", 0x01},
+};
+
+}  // namespace
+
+CFX_WideStringC XFA_FM_EXPTypeToString(
+    XFA_FM_SimpleExpressionType simpleExpType) {
+  return gs_lpStrExpFuncName[simpleExpType];
+}
+
+CXFA_FMSimpleExpression::CXFA_FMSimpleExpression(FX_DWORD line, XFA_FM_TOKEN op)
+    : m_line(line), m_op(op) {}
+
+void CXFA_FMSimpleExpression::ToJavaScript(CFX_WideTextBuf& javascript) {}
+
+void CXFA_FMSimpleExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {}
+
+XFA_FM_TOKEN CXFA_FMSimpleExpression::GetOperatorToken() const {
+  return m_op;
+}
+
+CXFA_FMNullExpression::CXFA_FMNullExpression(FX_DWORD line)
+    : CXFA_FMSimpleExpression(line, TOKnull) {}
+
+void CXFA_FMNullExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  javascript << FX_WSTRC(L"null");
+}
+
+CXFA_FMNumberExpression::CXFA_FMNumberExpression(FX_DWORD line,
+                                                 CFX_WideStringC wsNumber)
+    : CXFA_FMSimpleExpression(line, TOKnumber), m_wsNumber(wsNumber) {}
+
+void CXFA_FMNumberExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  javascript << m_wsNumber;
+}
+
+CXFA_FMStringExpression::CXFA_FMStringExpression(FX_DWORD line,
+                                                 CFX_WideStringC wsString)
+    : CXFA_FMSimpleExpression(line, TOKstring), m_wsString(wsString) {}
+
+void CXFA_FMStringExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  CFX_WideString tempStr = m_wsString;
+  if (tempStr.GetLength() > 2) {
+    javascript.AppendChar(L'\"');
+    FX_WCHAR oneChar;
+    for (int16_t i = 1; i < tempStr.GetLength() - 1; i++) {
+      oneChar = tempStr[i];
+      switch (oneChar) {
+        case L'\"': {
+          i++;
+          javascript << FX_WSTRC(L"\\\"");
+        } break;
+        case 0x0d:
+          break;
+        case 0x0a: {
+          javascript << FX_WSTRC(L"\\n");
+        } break;
+        default: { javascript.AppendChar(oneChar); } break;
+      }
+    }
+    javascript.AppendChar(L'\"');
+  } else {
+    javascript << tempStr;
+  }
+}
+
+CXFA_FMIdentifierExpressionn::CXFA_FMIdentifierExpressionn(
+    FX_DWORD line,
+    CFX_WideStringC wsIdentifier)
+    : CXFA_FMSimpleExpression(line, TOKidentifier),
+      m_wsIdentifier(wsIdentifier) {}
+
+void CXFA_FMIdentifierExpressionn::ToJavaScript(CFX_WideTextBuf& javascript) {
+  CFX_WideString tempStr = m_wsIdentifier;
+  if (tempStr.Equal(FX_WSTRC(L"$"))) {
+    tempStr = FX_WSTRC(L"this");
+  } else if (tempStr.Equal(FX_WSTRC(L"!"))) {
+    tempStr = FX_WSTRC(L"xfa.datasets");
+  } else if (tempStr.Equal(FX_WSTRC(L"$data"))) {
+    tempStr = FX_WSTRC(L"xfa.datasets.data");
+  } else if (tempStr.Equal(FX_WSTRC(L"$event"))) {
+    tempStr = FX_WSTRC(L"xfa.event");
+  } else if (tempStr.Equal(FX_WSTRC(L"$form"))) {
+    tempStr = FX_WSTRC(L"xfa.form");
+  } else if (tempStr.Equal(FX_WSTRC(L"$host"))) {
+    tempStr = FX_WSTRC(L"xfa.host");
+  } else if (tempStr.Equal(FX_WSTRC(L"$layout"))) {
+    tempStr = FX_WSTRC(L"xfa.layout");
+  } else if (tempStr.Equal(FX_WSTRC(L"$template"))) {
+    tempStr = FX_WSTRC(L"xfa.template");
+  } else if (tempStr[0] == L'!') {
+    tempStr = EXCLAMATION_IN_IDENTIFIER + tempStr.Mid(1);
+  }
+  javascript << tempStr;
+}
+
+CXFA_FMUnaryExpression::CXFA_FMUnaryExpression(FX_DWORD line,
+                                               XFA_FM_TOKEN op,
+                                               CXFA_FMSimpleExpression* pExp)
+    : CXFA_FMSimpleExpression(line, op), m_pExp(pExp) {}
+
+void CXFA_FMUnaryExpression::ToJavaScript(CFX_WideTextBuf& javascript) {}
+
+CXFA_FMBinExpression::CXFA_FMBinExpression(FX_DWORD line,
+                                           XFA_FM_TOKEN op,
+                                           CXFA_FMSimpleExpression* pExp1,
+                                           CXFA_FMSimpleExpression* pExp2)
+    : CXFA_FMSimpleExpression(line, op), m_pExp1(pExp1), m_pExp2(pExp2) {}
+
+void CXFA_FMBinExpression::ToJavaScript(CFX_WideTextBuf& javascript) {}
+
+CXFA_FMAssignExpression::CXFA_FMAssignExpression(FX_DWORD line,
+                                                 XFA_FM_TOKEN op,
+                                                 CXFA_FMSimpleExpression* pExp1,
+                                                 CXFA_FMSimpleExpression* pExp2)
+    : CXFA_FMBinExpression(line, op, pExp1, pExp2) {}
+
+void CXFA_FMAssignExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  javascript << FX_WSTRC(L"if (");
+  javascript << gs_lpStrExpFuncName[ISFMOBJECT];
+  javascript << FX_WSTRC(L"(");
+  m_pExp1->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L"))\n{\n");
+  javascript << gs_lpStrExpFuncName[ASSIGN];
+  javascript << FX_WSTRC(L"(");
+  m_pExp1->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L", ");
+  m_pExp2->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L");\n}\n");
+  CFX_WideTextBuf tempExp1;
+  m_pExp1->ToJavaScript(tempExp1);
+  if (m_pExp1->GetOperatorToken() == TOKidentifier &&
+      tempExp1.GetWideString() != FX_WSTRC(L"this")) {
+    javascript << FX_WSTRC(L"else\n{\n");
+    javascript << tempExp1;
+    javascript << FX_WSTRC(L" = ");
+    javascript << gs_lpStrExpFuncName[ASSIGN];
+    javascript << FX_WSTRC(L"(");
+    m_pExp1->ToJavaScript(javascript);
+    javascript << FX_WSTRC(L", ");
+    m_pExp2->ToJavaScript(javascript);
+    javascript << FX_WSTRC(L");\n}\n");
+  }
+}
+
+void CXFA_FMAssignExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) {
+  javascript << FX_WSTRC(L"if (");
+  javascript << gs_lpStrExpFuncName[ISFMOBJECT];
+  javascript << FX_WSTRC(L"(");
+  m_pExp1->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L"))\n{\n");
+  javascript << RUNTIMEFUNCTIONRETURNVALUE;
+  javascript << FX_WSTRC(L" = ");
+  javascript << gs_lpStrExpFuncName[ASSIGN];
+  javascript << FX_WSTRC(L"(");
+  m_pExp1->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L", ");
+  m_pExp2->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L");\n}\n");
+  CFX_WideTextBuf tempExp1;
+  m_pExp1->ToJavaScript(tempExp1);
+  if (m_pExp1->GetOperatorToken() == TOKidentifier &&
+      tempExp1.GetWideString() != FX_WSTRC(L"this")) {
+    javascript << FX_WSTRC(L"else\n{\n");
+    javascript << RUNTIMEFUNCTIONRETURNVALUE;
+    javascript << FX_WSTRC(L" = ");
+    javascript << tempExp1;
+    javascript << FX_WSTRC(L" = ");
+    javascript << gs_lpStrExpFuncName[ASSIGN];
+    javascript << FX_WSTRC(L"(");
+    m_pExp1->ToJavaScript(javascript);
+    javascript << FX_WSTRC(L", ");
+    m_pExp2->ToJavaScript(javascript);
+    javascript << FX_WSTRC(L");\n}\n");
+  }
+}
+
+CXFA_FMLogicalOrExpression::CXFA_FMLogicalOrExpression(
+    FX_DWORD line,
+    XFA_FM_TOKEN op,
+    CXFA_FMSimpleExpression* pExp1,
+    CXFA_FMSimpleExpression* pExp2)
+    : CXFA_FMBinExpression(line, op, pExp1, pExp2) {}
+
+void CXFA_FMLogicalOrExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  javascript << gs_lpStrExpFuncName[LOGICALOR];
+  javascript << FX_WSTRC(L"(");
+  m_pExp1->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L", ");
+  m_pExp2->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L")");
+}
+
+CXFA_FMLogicalAndExpression::CXFA_FMLogicalAndExpression(
+    FX_DWORD line,
+    XFA_FM_TOKEN op,
+    CXFA_FMSimpleExpression* pExp1,
+    CXFA_FMSimpleExpression* pExp2)
+    : CXFA_FMBinExpression(line, op, pExp1, pExp2) {}
+
+void CXFA_FMLogicalAndExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  javascript << gs_lpStrExpFuncName[LOGICALAND];
+  javascript << FX_WSTRC(L"(");
+  m_pExp1->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L", ");
+  m_pExp2->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L")");
+}
+
+CXFA_FMEqualityExpression::CXFA_FMEqualityExpression(
+    FX_DWORD line,
+    XFA_FM_TOKEN op,
+    CXFA_FMSimpleExpression* pExp1,
+    CXFA_FMSimpleExpression* pExp2)
+    : CXFA_FMBinExpression(line, op, pExp1, pExp2) {}
+
+void CXFA_FMEqualityExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  switch (m_op) {
+    case TOKeq:
+    case TOKkseq:
+      javascript << gs_lpStrExpFuncName[EQUALITY];
+      break;
+    case TOKne:
+    case TOKksne:
+      javascript << gs_lpStrExpFuncName[NOTEQUALITY];
+      break;
+    default:
+      FXSYS_assert(FALSE);
+      break;
+  }
+  javascript << FX_WSTRC(L"(");
+  m_pExp1->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L", ");
+  m_pExp2->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L")");
+}
+
+CXFA_FMRelationalExpression::CXFA_FMRelationalExpression(
+    FX_DWORD line,
+    XFA_FM_TOKEN op,
+    CXFA_FMSimpleExpression* pExp1,
+    CXFA_FMSimpleExpression* pExp2)
+    : CXFA_FMBinExpression(line, op, pExp1, pExp2) {}
+
+void CXFA_FMRelationalExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  switch (m_op) {
+    case TOKlt:
+    case TOKkslt:
+      javascript << gs_lpStrExpFuncName[LESS];
+      break;
+    case TOKgt:
+    case TOKksgt:
+      javascript << gs_lpStrExpFuncName[GREATER];
+      break;
+    case TOKle:
+    case TOKksle:
+      javascript << gs_lpStrExpFuncName[LESSEQUAL];
+      break;
+    case TOKge:
+    case TOKksge:
+      javascript << gs_lpStrExpFuncName[GREATEREQUAL];
+      break;
+    default:
+      FXSYS_assert(FALSE);
+      break;
+  }
+  javascript << FX_WSTRC(L"(");
+  m_pExp1->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L", ");
+  m_pExp2->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L")");
+}
+
+CXFA_FMAdditiveExpression::CXFA_FMAdditiveExpression(
+    FX_DWORD line,
+    XFA_FM_TOKEN op,
+    CXFA_FMSimpleExpression* pExp1,
+    CXFA_FMSimpleExpression* pExp2)
+    : CXFA_FMBinExpression(line, op, pExp1, pExp2) {}
+
+void CXFA_FMAdditiveExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  switch (m_op) {
+    case TOKplus:
+      javascript << gs_lpStrExpFuncName[PLUS];
+      break;
+    case TOKminus:
+      javascript << gs_lpStrExpFuncName[MINUS];
+      break;
+    default:
+      FXSYS_assert(FALSE);
+      break;
+  }
+  javascript << FX_WSTRC(L"(");
+  m_pExp1->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L", ");
+  m_pExp2->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L")");
+}
+
+CXFA_FMMultiplicativeExpression::CXFA_FMMultiplicativeExpression(
+    FX_DWORD line,
+    XFA_FM_TOKEN op,
+    CXFA_FMSimpleExpression* pExp1,
+    CXFA_FMSimpleExpression* pExp2)
+    : CXFA_FMBinExpression(line, op, pExp1, pExp2) {}
+
+void CXFA_FMMultiplicativeExpression::ToJavaScript(
+    CFX_WideTextBuf& javascript) {
+  switch (m_op) {
+    case TOKmul:
+      javascript << gs_lpStrExpFuncName[MULTIPLE];
+      break;
+    case TOKdiv:
+      javascript << gs_lpStrExpFuncName[DIVIDE];
+      break;
+    default:
+      FXSYS_assert(FALSE);
+      break;
+  }
+  javascript << FX_WSTRC(L"(");
+  m_pExp1->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L", ");
+  m_pExp2->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L")");
+}
+
+CXFA_FMPosExpression::CXFA_FMPosExpression(FX_DWORD line,
+                                           CXFA_FMSimpleExpression* pExp)
+    : CXFA_FMUnaryExpression(line, TOKplus, pExp) {}
+
+void CXFA_FMPosExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  javascript << gs_lpStrExpFuncName[POSITIVE];
+  javascript << FX_WSTRC(L"(");
+  m_pExp->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L")");
+}
+
+CXFA_FMNegExpression::CXFA_FMNegExpression(FX_DWORD line,
+                                           CXFA_FMSimpleExpression* pExp)
+    : CXFA_FMUnaryExpression(line, TOKminus, pExp) {}
+
+void CXFA_FMNegExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  javascript << gs_lpStrExpFuncName[NEGATIVE];
+  javascript << FX_WSTRC(L"(");
+  m_pExp->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L")");
+}
+
+CXFA_FMNotExpression::CXFA_FMNotExpression(FX_DWORD line,
+                                           CXFA_FMSimpleExpression* pExp)
+    : CXFA_FMUnaryExpression(line, TOKksnot, pExp) {}
+
+void CXFA_FMNotExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  javascript << gs_lpStrExpFuncName[NOT];
+  javascript << FX_WSTRC(L"(");
+  m_pExp->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L")");
+}
+
+CXFA_FMCallExpression::CXFA_FMCallExpression(FX_DWORD line,
+                                             CXFA_FMSimpleExpression* pExp,
+                                             CFX_PtrArray* pArguments,
+                                             FX_BOOL bIsSomMethod)
+    : CXFA_FMUnaryExpression(line, TOKcall, pExp),
+      m_bIsSomMethod(bIsSomMethod),
+      m_pArguments(pArguments) {}
+
+CXFA_FMCallExpression::~CXFA_FMCallExpression() {
+  if (m_pArguments) {
+    for (int i = 0; i < m_pArguments->GetSize(); ++i) {
+      delete reinterpret_cast<CXFA_FMSimpleExpression*>(m_pArguments->GetAt(i));
+    }
+    m_pArguments->RemoveAll();
+    delete m_pArguments;
+  }
+}
+
+bool CXFA_FMCallExpression::IsBuildInFunc(CFX_WideTextBuf* funcName) {
+  uint32_t uHash = FX_HashCode_String_GetW(funcName->GetBuffer(),
+                                           funcName->GetLength(), TRUE);
+  const XFA_FMBuildInFunc* pEnd = g_BuildInFuncs + FX_ArraySize(g_BuildInFuncs);
+  const XFA_FMBuildInFunc* pFunc =
+      std::lower_bound(g_BuildInFuncs, pEnd, uHash,
+                       [](const XFA_FMBuildInFunc& func, uint32_t hash) {
+                         return func.m_uHash < hash;
+                       });
+  if (pFunc < pEnd && uHash == pFunc->m_uHash) {
+    funcName->Clear();
+    *funcName << pFunc->m_buildinfunc;
+    return true;
+  }
+  return false;
+}
+
+FX_DWORD CXFA_FMCallExpression::IsMethodWithObjParam(
+    const CFX_WideStringC& methodName) {
+  int32_t iLength = methodName.GetLength();
+  uint32_t uHash = FX_HashCode_String_GetW(methodName.GetPtr(), iLength);
+  XFA_FMSOMMethod somMethodWithObjPara;
+  FX_DWORD parameters = 0x00;
+  int32_t iStart = 0,
+          iEnd = (sizeof(gs_FMSomMethods) / sizeof(gs_FMSomMethods[0])) - 1;
+  int32_t iMid = (iStart + iEnd) / 2;
+  do {
+    iMid = (iStart + iEnd) / 2;
+    somMethodWithObjPara = gs_FMSomMethods[iMid];
+    if (uHash == somMethodWithObjPara.m_uHash) {
+      parameters = somMethodWithObjPara.m_dParameters;
+      break;
+    } else if (uHash < somMethodWithObjPara.m_uHash) {
+      iEnd = iMid - 1;
+    } else {
+      iStart = iMid + 1;
+    }
+  } while (iStart <= iEnd);
+  return parameters;
+}
+
+void CXFA_FMCallExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  CFX_WideTextBuf funcName;
+  m_pExp->ToJavaScript(funcName);
+  if (m_bIsSomMethod) {
+    javascript << funcName;
+    javascript << FX_WSTRC(L"(");
+    if (m_pArguments) {
+      FX_DWORD methodPara = IsMethodWithObjParam(funcName.GetWideString());
+      if (methodPara > 0) {
+        for (int i = 0; i < m_pArguments->GetSize(); ++i) {
+          if ((methodPara & (0x01 << i)) > 0) {
+            javascript << gs_lpStrExpFuncName[GETFMJSOBJ];
+          } else {
+            javascript << gs_lpStrExpFuncName[GETFMVALUE];
+          }
+          javascript << FX_WSTRC(L"(");
+          CXFA_FMSimpleExpression* e =
+              reinterpret_cast<CXFA_FMSimpleExpression*>(
+                  m_pArguments->GetAt(i));
+          e->ToJavaScript(javascript);
+          javascript << FX_WSTRC(L")");
+          if (i + 1 < m_pArguments->GetSize()) {
+            javascript << FX_WSTRC(L", ");
+          }
+        }
+      } else {
+        for (int i = 0; i < m_pArguments->GetSize(); ++i) {
+          javascript << gs_lpStrExpFuncName[GETFMVALUE];
+          javascript << FX_WSTRC(L"(");
+          CXFA_FMSimpleExpression* e =
+              reinterpret_cast<CXFA_FMSimpleExpression*>(
+                  m_pArguments->GetAt(i));
+          e->ToJavaScript(javascript);
+          javascript << FX_WSTRC(L")");
+          if (i + 1 < m_pArguments->GetSize()) {
+            javascript << FX_WSTRC(L", ");
+          }
+        }
+      }
+    }
+    javascript << FX_WSTRC(L")");
+  } else {
+    bool isEvalFunc = false;
+    bool isExistsFunc = false;
+    if (IsBuildInFunc(&funcName)) {
+      if (funcName.GetWideString() == FX_WSTRC(L"Eval")) {
+        isEvalFunc = true;
+        javascript << FX_WSTRC(L"eval.call(this, ");
+        javascript << gs_lpStrExpFuncName[CALL];
+        javascript << FX_WSTRC(L"Translate");
+      } else if (funcName.GetWideString() == FX_WSTRC(L"Exists")) {
+        isExistsFunc = true;
+        javascript << gs_lpStrExpFuncName[CALL];
+        javascript << funcName;
+      } else {
+        javascript << gs_lpStrExpFuncName[CALL];
+        javascript << funcName;
+      }
+    } else {
+      javascript << funcName;
+    }
+    javascript << FX_WSTRC(L"(");
+    if (isExistsFunc) {
+      javascript << FX_WSTRC(L"\n(\nfunction ()\n{\ntry\n{\n");
+      if (m_pArguments && m_pArguments->GetSize() > 0) {
+        CXFA_FMSimpleExpression* e =
+            reinterpret_cast<CXFA_FMSimpleExpression*>(m_pArguments->GetAt(0));
+        javascript << FX_WSTRC(L"return ");
+        e->ToJavaScript(javascript);
+        javascript << FX_WSTRC(L";\n}\n");
+      } else {
+        javascript << FX_WSTRC(L"return 0;\n}\n");
+      }
+      javascript << FX_WSTRC(
+          L"catch(accessExceptions)\n{\nreturn 0;\n}\n}\n).call(this)\n");
+    } else if (m_pArguments) {
+      for (int i = 0; i < m_pArguments->GetSize(); ++i) {
+        CXFA_FMSimpleExpression* e =
+            reinterpret_cast<CXFA_FMSimpleExpression*>(m_pArguments->GetAt(i));
+        e->ToJavaScript(javascript);
+        if (i + 1 < m_pArguments->GetSize()) {
+          javascript << FX_WSTRC(L", ");
+        }
+      }
+    }
+    javascript << FX_WSTRC(L")");
+    if (isEvalFunc) {
+      javascript << FX_WSTRC(L")");
+    }
+  }
+}
+
+CXFA_FMDotAccessorExpression::CXFA_FMDotAccessorExpression(
+    FX_DWORD line,
+    CXFA_FMSimpleExpression* pAccessor,
+    XFA_FM_TOKEN op,
+    CFX_WideStringC wsIdentifier,
+    CXFA_FMSimpleExpression* pIndexExp)
+    : CXFA_FMBinExpression(line, op, pAccessor, pIndexExp),
+      m_wsIdentifier(wsIdentifier) {}
+
+void CXFA_FMDotAccessorExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  javascript << gs_lpStrExpFuncName[DOT];
+  javascript << FX_WSTRC(L"(");
+  if (m_pExp1) {
+    m_pExp1->ToJavaScript(javascript);
+  } else {
+    javascript << FX_WSTRC(L"null");
+  }
+  javascript << FX_WSTRC(L", ");
+  javascript << FX_WSTRC(L"\"");
+  if (m_pExp1 && m_pExp1->GetOperatorToken() == TOKidentifier) {
+    m_pExp1->ToJavaScript(javascript);
+  }
+  javascript << FX_WSTRC(L"\", ");
+  if (m_op == TOKdotscream) {
+    javascript << FX_WSTRC(L"\"#");
+    javascript << m_wsIdentifier;
+    javascript << FX_WSTRC(L"\", ");
+  } else if (m_op == TOKdotstar) {
+    javascript << FX_WSTRC(L"\"*\", ");
+  } else if (m_op == TOKcall) {
+    javascript << FX_WSTRC(L"\"\", ");
+  } else {
+    javascript << FX_WSTRC(L"\"");
+    javascript << m_wsIdentifier;
+    javascript << FX_WSTRC(L"\", ");
+  }
+  m_pExp2->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L")");
+}
+
+CXFA_FMIndexExpression::CXFA_FMIndexExpression(
+    FX_DWORD line,
+    XFA_FM_AccessorIndex accessorIndex,
+    CXFA_FMSimpleExpression* pIndexExp,
+    FX_BOOL bIsStarIndex)
+    : CXFA_FMUnaryExpression(line, TOKlbracket, pIndexExp),
+      m_accessorIndex(accessorIndex),
+      m_bIsStarIndex(bIsStarIndex) {}
+
+void CXFA_FMIndexExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  switch (m_accessorIndex) {
+    case ACCESSOR_NO_INDEX:
+      javascript << FX_WSTRC(L"0");
+      break;
+    case ACCESSOR_NO_RELATIVEINDEX:
+      javascript << FX_WSTRC(L"1");
+      break;
+    case ACCESSOR_POSITIVE_INDEX:
+      javascript << FX_WSTRC(L"2");
+      break;
+    case ACCESSOR_NEGATIVE_INDEX:
+      javascript << FX_WSTRC(L"3");
+      break;
+    default:
+      javascript << FX_WSTRC(L"0");
+  }
+  if (!m_bIsStarIndex) {
+    javascript << FX_WSTRC(L", ");
+    if (m_pExp) {
+      m_pExp->ToJavaScript(javascript);
+    } else {
+      javascript << FX_WSTRC(L"0");
+    }
+  }
+}
+
+CXFA_FMDotDotAccessorExpression::CXFA_FMDotDotAccessorExpression(
+    FX_DWORD line,
+    CXFA_FMSimpleExpression* pAccessor,
+    XFA_FM_TOKEN op,
+    CFX_WideStringC wsIdentifier,
+    CXFA_FMSimpleExpression* pIndexExp)
+    : CXFA_FMBinExpression(line, op, pAccessor, pIndexExp),
+      m_wsIdentifier(wsIdentifier) {}
+
+void CXFA_FMDotDotAccessorExpression::ToJavaScript(
+    CFX_WideTextBuf& javascript) {
+  javascript << gs_lpStrExpFuncName[DOTDOT];
+  javascript << FX_WSTRC(L"(");
+  m_pExp1->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L", ");
+  javascript << FX_WSTRC(L"\"");
+  if (m_pExp1 && m_pExp1->GetOperatorToken() == TOKidentifier) {
+    m_pExp1->ToJavaScript(javascript);
+  }
+  javascript << FX_WSTRC(L"\", ");
+  javascript << FX_WSTRC(L"\"");
+  javascript << m_wsIdentifier;
+  javascript << FX_WSTRC(L"\", ");
+  m_pExp2->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L")");
+}
+
+CXFA_FMMethodCallExpression::CXFA_FMMethodCallExpression(
+    FX_DWORD line,
+    CXFA_FMSimpleExpression* pAccessorExp1,
+    CXFA_FMSimpleExpression* pCallExp)
+    : CXFA_FMBinExpression(line, TOKdot, pAccessorExp1, pCallExp) {}
+
+void CXFA_FMMethodCallExpression::ToJavaScript(CFX_WideTextBuf& javascript) {
+  javascript << FX_WSTRC(L"(\nfunction ()\n{\n");
+  javascript << FX_WSTRC(L"var method_return_value = null;\n");
+  javascript << FX_WSTRC(L"var accessor_object = ");
+  m_pExp1->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L";\n");
+  javascript << FX_WSTRC(L"if (");
+  javascript << gs_lpStrExpFuncName[ISFMARRAY];
+  javascript << FX_WSTRC(L"(accessor_object))\n{\n");
+  javascript << FX_WSTRC(
+      L"for(var index = accessor_object.length - 1; index > 1; index--)\n{\n");
+  javascript << FX_WSTRC(L"method_return_value = accessor_object[index].");
+  m_pExp2->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L";\n}\n}\n");
+  javascript << FX_WSTRC(L"else\n{\nmethod_return_value = accessor_object.");
+  m_pExp2->ToJavaScript(javascript);
+  javascript << FX_WSTRC(L";\n}\n");
+  javascript << FX_WSTRC(L"return method_return_value;\n");
+  javascript << FX_WSTRC(L"}\n).call(this)");
+}
diff --git a/xfa/fxfa/fm2js/xfa_simpleexpression.h b/xfa/fxfa/fm2js/xfa_simpleexpression.h
new file mode 100644
index 0000000..9098b39
--- /dev/null
+++ b/xfa/fxfa/fm2js/xfa_simpleexpression.h
@@ -0,0 +1,292 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_FM2JS_XFA_SIMPLEEXPRESSION_H_
+#define XFA_FXFA_FM2JS_XFA_SIMPLEEXPRESSION_H_
+
+#include <memory>
+
+#include "core/include/fxcrt/fx_basic.h"
+#include "xfa/fxfa/fm2js/xfa_lexer.h"
+
+#define RUNTIMEFUNCTIONRETURNVALUE \
+  (FX_WSTRC(L"foxit_xfa_formcalc_runtime_func_return_value"))
+#define EXCLAMATION_IN_IDENTIFIER \
+  (FX_WSTRC(L"foxit_xfa_formcalc__exclamation__"))
+
+enum XFA_FM_SimpleExpressionType {
+  ASSIGN,
+  LOGICALOR,
+  LOGICALAND,
+  EQUALITY,
+  NOTEQUALITY,
+  LESS,
+  LESSEQUAL,
+  GREATER,
+  GREATEREQUAL,
+  PLUS,
+  MINUS,
+  MULTIPLE,
+  DIVIDE,
+  POSITIVE,
+  NEGATIVE,
+  NOT,
+  CALL,
+  DOT,
+  DOTDOT,
+  CONCATFMOBJECT,
+  ISFMOBJECT,
+  ISFMARRAY,
+  GETFMVALUE,
+  GETFMJSOBJ,
+  VARFILTER
+};
+
+CFX_WideStringC XFA_FM_EXPTypeToString(
+    XFA_FM_SimpleExpressionType simpleExpType);
+
+enum XFA_FM_AccessorIndex {
+  ACCESSOR_NO_INDEX,
+  ACCESSOR_NO_RELATIVEINDEX,
+  ACCESSOR_POSITIVE_INDEX,
+  ACCESSOR_NEGATIVE_INDEX
+};
+
+class CXFA_FMSimpleExpression {
+ public:
+  CXFA_FMSimpleExpression(FX_DWORD line, XFA_FM_TOKEN op);
+  virtual ~CXFA_FMSimpleExpression() {}
+  virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+  virtual void ToImpliedReturnJS(CFX_WideTextBuf& javascript);
+
+  XFA_FM_TOKEN GetOperatorToken() const;
+
+ protected:
+  FX_DWORD m_line;
+  XFA_FM_TOKEN m_op;
+};
+
+class CXFA_FMNullExpression : public CXFA_FMSimpleExpression {
+ public:
+  explicit CXFA_FMNullExpression(FX_DWORD line);
+  ~CXFA_FMNullExpression() override {}
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+};
+
+class CXFA_FMNumberExpression : public CXFA_FMSimpleExpression {
+ public:
+  CXFA_FMNumberExpression(FX_DWORD line, CFX_WideStringC wsNumber);
+  ~CXFA_FMNumberExpression() override {}
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+
+ private:
+  CFX_WideStringC m_wsNumber;
+};
+
+class CXFA_FMStringExpression : public CXFA_FMSimpleExpression {
+ public:
+  CXFA_FMStringExpression(FX_DWORD line, CFX_WideStringC wsString);
+  ~CXFA_FMStringExpression() override {}
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+
+ private:
+  CFX_WideStringC m_wsString;
+};
+
+class CXFA_FMIdentifierExpressionn : public CXFA_FMSimpleExpression {
+ public:
+  CXFA_FMIdentifierExpressionn(FX_DWORD line, CFX_WideStringC wsIdentifier);
+  ~CXFA_FMIdentifierExpressionn() override {}
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+
+ private:
+  CFX_WideStringC m_wsIdentifier;
+};
+
+class CXFA_FMUnaryExpression : public CXFA_FMSimpleExpression {
+ public:
+  CXFA_FMUnaryExpression(FX_DWORD line,
+                         XFA_FM_TOKEN op,
+                         CXFA_FMSimpleExpression* pExp);
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+
+ protected:
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pExp;
+};
+
+class CXFA_FMBinExpression : public CXFA_FMSimpleExpression {
+ public:
+  CXFA_FMBinExpression(FX_DWORD line,
+                       XFA_FM_TOKEN op,
+                       CXFA_FMSimpleExpression* pExp1,
+                       CXFA_FMSimpleExpression* pExp2);
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+
+ protected:
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pExp1;
+  std::unique_ptr<CXFA_FMSimpleExpression> m_pExp2;
+};
+
+class CXFA_FMAssignExpression : public CXFA_FMBinExpression {
+ public:
+  CXFA_FMAssignExpression(FX_DWORD line,
+                          XFA_FM_TOKEN op,
+                          CXFA_FMSimpleExpression* pExp1,
+                          CXFA_FMSimpleExpression* pExp2);
+  ~CXFA_FMAssignExpression() override {}
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+  void ToImpliedReturnJS(CFX_WideTextBuf& javascript) override;
+};
+
+class CXFA_FMLogicalOrExpression : public CXFA_FMBinExpression {
+ public:
+  CXFA_FMLogicalOrExpression(FX_DWORD line,
+                             XFA_FM_TOKEN op,
+                             CXFA_FMSimpleExpression* pExp1,
+                             CXFA_FMSimpleExpression* pExp2);
+  ~CXFA_FMLogicalOrExpression() override {}
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+};
+
+class CXFA_FMLogicalAndExpression : public CXFA_FMBinExpression {
+ public:
+  CXFA_FMLogicalAndExpression(FX_DWORD line,
+                              XFA_FM_TOKEN op,
+                              CXFA_FMSimpleExpression* pExp1,
+                              CXFA_FMSimpleExpression* pExp2);
+  ~CXFA_FMLogicalAndExpression() override {}
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+};
+
+class CXFA_FMEqualityExpression : public CXFA_FMBinExpression {
+ public:
+  CXFA_FMEqualityExpression(FX_DWORD line,
+                            XFA_FM_TOKEN op,
+                            CXFA_FMSimpleExpression* pExp1,
+                            CXFA_FMSimpleExpression* pExp2);
+  ~CXFA_FMEqualityExpression() override {}
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+};
+
+class CXFA_FMRelationalExpression : public CXFA_FMBinExpression {
+ public:
+  CXFA_FMRelationalExpression(FX_DWORD line,
+                              XFA_FM_TOKEN op,
+                              CXFA_FMSimpleExpression* pExp1,
+                              CXFA_FMSimpleExpression* pExp2);
+  ~CXFA_FMRelationalExpression() override {}
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+};
+
+class CXFA_FMAdditiveExpression : public CXFA_FMBinExpression {
+ public:
+  CXFA_FMAdditiveExpression(FX_DWORD line,
+                            XFA_FM_TOKEN op,
+                            CXFA_FMSimpleExpression* pExp1,
+                            CXFA_FMSimpleExpression* pExp2);
+  ~CXFA_FMAdditiveExpression() override {}
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+};
+
+class CXFA_FMMultiplicativeExpression : public CXFA_FMBinExpression {
+ public:
+  CXFA_FMMultiplicativeExpression(FX_DWORD line,
+                                  XFA_FM_TOKEN op,
+                                  CXFA_FMSimpleExpression* pExp1,
+                                  CXFA_FMSimpleExpression* pExp2);
+  ~CXFA_FMMultiplicativeExpression() override {}
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+};
+
+class CXFA_FMPosExpression : public CXFA_FMUnaryExpression {
+ public:
+  CXFA_FMPosExpression(FX_DWORD line, CXFA_FMSimpleExpression* pExp);
+  ~CXFA_FMPosExpression() override {}
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+};
+
+class CXFA_FMNegExpression : public CXFA_FMUnaryExpression {
+ public:
+  CXFA_FMNegExpression(FX_DWORD line, CXFA_FMSimpleExpression* pExp);
+  ~CXFA_FMNegExpression() override {}
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+};
+
+class CXFA_FMNotExpression : public CXFA_FMUnaryExpression {
+ public:
+  CXFA_FMNotExpression(FX_DWORD line, CXFA_FMSimpleExpression* pExp);
+  ~CXFA_FMNotExpression() override {}
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+};
+
+class CXFA_FMCallExpression : public CXFA_FMUnaryExpression {
+ public:
+  CXFA_FMCallExpression(FX_DWORD line,
+                        CXFA_FMSimpleExpression* pExp,
+                        CFX_PtrArray* pArguments,
+                        FX_BOOL bIsSomMethod);
+  ~CXFA_FMCallExpression() override;
+  bool IsBuildInFunc(CFX_WideTextBuf* funcName);
+  FX_DWORD IsMethodWithObjParam(const CFX_WideStringC& methodName);
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+
+ private:
+  FX_BOOL m_bIsSomMethod;
+  CFX_PtrArray* m_pArguments;
+};
+
+class CXFA_FMDotAccessorExpression : public CXFA_FMBinExpression {
+ public:
+  CXFA_FMDotAccessorExpression(FX_DWORD line,
+                               CXFA_FMSimpleExpression* pAccessor,
+                               XFA_FM_TOKEN op,
+                               CFX_WideStringC wsIdentifier,
+                               CXFA_FMSimpleExpression* pIndexExp);
+  ~CXFA_FMDotAccessorExpression() override {}
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+
+ private:
+  CFX_WideStringC m_wsIdentifier;
+};
+
+class CXFA_FMIndexExpression : public CXFA_FMUnaryExpression {
+ public:
+  CXFA_FMIndexExpression(FX_DWORD line,
+                         XFA_FM_AccessorIndex accessorIndex,
+                         CXFA_FMSimpleExpression* pIndexExp,
+                         FX_BOOL bIsStarIndex);
+  ~CXFA_FMIndexExpression() override {}
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+
+ private:
+  XFA_FM_AccessorIndex m_accessorIndex;
+  FX_BOOL m_bIsStarIndex;
+};
+
+class CXFA_FMDotDotAccessorExpression : public CXFA_FMBinExpression {
+ public:
+  CXFA_FMDotDotAccessorExpression(FX_DWORD line,
+                                  CXFA_FMSimpleExpression* pAccessor,
+                                  XFA_FM_TOKEN op,
+                                  CFX_WideStringC wsIdentifier,
+                                  CXFA_FMSimpleExpression* pIndexExp);
+  ~CXFA_FMDotDotAccessorExpression() override {}
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+
+ private:
+  CFX_WideStringC m_wsIdentifier;
+};
+
+class CXFA_FMMethodCallExpression : public CXFA_FMBinExpression {
+ public:
+  CXFA_FMMethodCallExpression(FX_DWORD line,
+                              CXFA_FMSimpleExpression* pAccessorExp1,
+                              CXFA_FMSimpleExpression* pCallExp);
+  ~CXFA_FMMethodCallExpression() override {}
+  void ToJavaScript(CFX_WideTextBuf& javascript) override;
+};
+
+#endif  // XFA_FXFA_FM2JS_XFA_SIMPLEEXPRESSION_H_
diff --git a/xfa/fxfa/parser/xfa_basic_data.cpp b/xfa/fxfa/parser/xfa_basic_data.cpp
new file mode 100644
index 0000000..58e71de
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_basic_data.cpp
@@ -0,0 +1,7333 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_basic_data.h"
+
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_basic_imp.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_script_datawindow.h"
+#include "xfa/fxfa/parser/xfa_script_eventpseudomodel.h"
+#include "xfa/fxfa/parser/xfa_script_hostpseudomodel.h"
+#include "xfa/fxfa/parser/xfa_script_layoutpseudomodel.h"
+#include "xfa/fxfa/parser/xfa_script_logpseudomodel.h"
+#include "xfa/fxfa/parser/xfa_script_signaturepseudomodel.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+const XFA_ATTRIBUTEENUMINFO g_XFAEnumData[] = {
+    {0x2a, L"*", XFA_ATTRIBUTEENUM_Asterisk},
+    {0x2f, L"/", XFA_ATTRIBUTEENUM_Slash},
+    {0x5c, L"\\", XFA_ATTRIBUTEENUM_Backslash},
+    {0x239bd, L"on", XFA_ATTRIBUTEENUM_On},
+    {0x25356, L"tb", XFA_ATTRIBUTEENUM_Tb},
+    {0x25885, L"up", XFA_ATTRIBUTEENUM_Up},
+    {0x91b281, L"metaData", XFA_ATTRIBUTEENUM_MetaData},
+    {0x1f8dedb, L"delegate", XFA_ATTRIBUTEENUM_Delegate},
+    {0x2a6c55a, L"postSubmit", XFA_ATTRIBUTEENUM_PostSubmit},
+    {0x31b19c1, L"name", XFA_ATTRIBUTEENUM_Name},
+    {0x378a38a, L"cross", XFA_ATTRIBUTEENUM_Cross},
+    {0x3848b3f, L"next", XFA_ATTRIBUTEENUM_Next},
+    {0x48b6670, L"none", XFA_ATTRIBUTEENUM_None},
+    {0x51aafe5, L"shortEdge", XFA_ATTRIBUTEENUM_ShortEdge},
+    {0x55264c4, L"1mod10_1mod11", XFA_ATTRIBUTEENUM_1mod10_1mod11},
+    {0x5a5c519, L"height", XFA_ATTRIBUTEENUM_Height},
+    {0x89ce549, L"crossDiagonal", XFA_ATTRIBUTEENUM_CrossDiagonal},
+    {0x9f9d0f9, L"all", XFA_ATTRIBUTEENUM_All},
+    {0x9f9db48, L"any", XFA_ATTRIBUTEENUM_Any},
+    {0xa126261, L"toRight", XFA_ATTRIBUTEENUM_ToRight},
+    {0xa36de29, L"matchTemplate", XFA_ATTRIBUTEENUM_MatchTemplate},
+    {0xa48d040, L"dpl", XFA_ATTRIBUTEENUM_Dpl},
+    {0xa559c05, L"invisible", XFA_ATTRIBUTEENUM_Invisible},
+    {0xa7d48e3, L"fit", XFA_ATTRIBUTEENUM_Fit},
+    {0xa8a8f80, L"width", XFA_ATTRIBUTEENUM_Width},
+    {0xab466bb, L"preSubmit", XFA_ATTRIBUTEENUM_PreSubmit},
+    {0xacc5785, L"ipl", XFA_ATTRIBUTEENUM_Ipl},
+    {0xafab0f8, L"flateCompress", XFA_ATTRIBUTEENUM_FlateCompress},
+    {0xb355816, L"med", XFA_ATTRIBUTEENUM_Med},
+    {0xb69ef77, L"odd", XFA_ATTRIBUTEENUM_Odd},
+    {0xb69f9bb, L"off", XFA_ATTRIBUTEENUM_Off},
+    {0xb843dba, L"pdf", XFA_ATTRIBUTEENUM_Pdf},
+    {0xbb912b8, L"row", XFA_ATTRIBUTEENUM_Row},
+    {0xbedaf33, L"top", XFA_ATTRIBUTEENUM_Top},
+    {0xc56afcc, L"xdp", XFA_ATTRIBUTEENUM_Xdp},
+    {0xc56ba02, L"xfd", XFA_ATTRIBUTEENUM_Xfd},
+    {0xc56ddf1, L"xml", XFA_ATTRIBUTEENUM_Xml},
+    {0xc8b65f3, L"zip", XFA_ATTRIBUTEENUM_Zip},
+    {0xc8b89d6, L"zpl", XFA_ATTRIBUTEENUM_Zpl},
+    {0xf55d7ee, L"visible", XFA_ATTRIBUTEENUM_Visible},
+    {0xfe3596a, L"exclude", XFA_ATTRIBUTEENUM_Exclude},
+    {0x109d7ce7, L"mouseEnter", XFA_ATTRIBUTEENUM_MouseEnter},
+    {0x10f1bc0c, L"pair", XFA_ATTRIBUTEENUM_Pair},
+    {0x1154efe6, L"filter", XFA_ATTRIBUTEENUM_Filter},
+    {0x125bc94b, L"moveLast", XFA_ATTRIBUTEENUM_MoveLast},
+    {0x12e1f1f0, L"exportAndImport", XFA_ATTRIBUTEENUM_ExportAndImport},
+    {0x13000c60, L"push", XFA_ATTRIBUTEENUM_Push},
+    {0x138ee315, L"portrait", XFA_ATTRIBUTEENUM_Portrait},
+    {0x14da2125, L"default", XFA_ATTRIBUTEENUM_Default},
+    {0x157749a5, L"storedProc", XFA_ATTRIBUTEENUM_StoredProc},
+    {0x16641198, L"stayBOF", XFA_ATTRIBUTEENUM_StayBOF},
+    {0x16b2fc5b, L"stayEOF", XFA_ATTRIBUTEENUM_StayEOF},
+    {0x17fad373, L"postPrint", XFA_ATTRIBUTEENUM_PostPrint},
+    {0x193207d0, L"usCarrier", XFA_ATTRIBUTEENUM_UsCarrier},
+    {0x193ade3e, L"right", XFA_ATTRIBUTEENUM_Right},
+    {0x1bfc72d9, L"preOpen", XFA_ATTRIBUTEENUM_PreOpen},
+    {0x1cc9317a, L"actual", XFA_ATTRIBUTEENUM_Actual},
+    {0x1f31df1e, L"rest", XFA_ATTRIBUTEENUM_Rest},
+    {0x1fb1bf14, L"topCenter", XFA_ATTRIBUTEENUM_TopCenter},
+    {0x207de667, L"standardSymbol", XFA_ATTRIBUTEENUM_StandardSymbol},
+    {0x2196a452, L"initialize", XFA_ATTRIBUTEENUM_Initialize},
+    {0x23bd40c7, L"justifyAll", XFA_ATTRIBUTEENUM_JustifyAll},
+    {0x247cf3e9, L"normal", XFA_ATTRIBUTEENUM_Normal},
+    {0x25aa946b, L"landscape", XFA_ATTRIBUTEENUM_Landscape},
+    {0x2739b5c9, L"nonInteractive", XFA_ATTRIBUTEENUM_NonInteractive},
+    {0x27410f03, L"mouseExit", XFA_ATTRIBUTEENUM_MouseExit},
+    {0x2854e62c, L"minus", XFA_ATTRIBUTEENUM_Minus},
+    {0x287e936a, L"diagonalLeft", XFA_ATTRIBUTEENUM_DiagonalLeft},
+    {0x2972a98f, L"simplexPaginated", XFA_ATTRIBUTEENUM_SimplexPaginated},
+    {0x29d8225f, L"document", XFA_ATTRIBUTEENUM_Document},
+    {0x2a9d3016, L"warning", XFA_ATTRIBUTEENUM_Warning},
+    {0x2b35b6d9, L"auto", XFA_ATTRIBUTEENUM_Auto},
+    {0x2c1653d9, L"below", XFA_ATTRIBUTEENUM_Below},
+    {0x2c1f0540, L"bottomLeft", XFA_ATTRIBUTEENUM_BottomLeft},
+    {0x2c44e816, L"bottomCenter", XFA_ATTRIBUTEENUM_BottomCenter},
+    {0x2cd3e9f3, L"tcpl", XFA_ATTRIBUTEENUM_Tcpl},
+    {0x2d08af85, L"text", XFA_ATTRIBUTEENUM_Text},
+    {0x2dc478eb, L"grouping", XFA_ATTRIBUTEENUM_Grouping},
+    {0x2ef3afdd, L"secureSymbol", XFA_ATTRIBUTEENUM_SecureSymbol},
+    {0x2f2dd29a, L"preExecute", XFA_ATTRIBUTEENUM_PreExecute},
+    {0x33c43dec, L"docClose", XFA_ATTRIBUTEENUM_DocClose},
+    {0x33f25bb5, L"keyset", XFA_ATTRIBUTEENUM_Keyset},
+    {0x34e363da, L"vertical", XFA_ATTRIBUTEENUM_Vertical},
+    {0x361fa1b6, L"preSave", XFA_ATTRIBUTEENUM_PreSave},
+    {0x36f1c6d8, L"preSign", XFA_ATTRIBUTEENUM_PreSign},
+    {0x399f02b5, L"bottom", XFA_ATTRIBUTEENUM_Bottom},
+    {0x3b0ab096, L"toTop", XFA_ATTRIBUTEENUM_ToTop},
+    {0x3c752495, L"verify", XFA_ATTRIBUTEENUM_Verify},
+    {0x3ce05d68, L"first", XFA_ATTRIBUTEENUM_First},
+    {0x3ecead94, L"contentArea", XFA_ATTRIBUTEENUM_ContentArea},
+    {0x40623b5b, L"solid", XFA_ATTRIBUTEENUM_Solid},
+    {0x42c6cd8d, L"pessimistic", XFA_ATTRIBUTEENUM_Pessimistic},
+    {0x43ddc6bf, L"duplexPaginated", XFA_ATTRIBUTEENUM_DuplexPaginated},
+    {0x442f68c8, L"round", XFA_ATTRIBUTEENUM_Round},
+    {0x45efb847, L"remerge", XFA_ATTRIBUTEENUM_Remerge},
+    {0x46972265, L"ordered", XFA_ATTRIBUTEENUM_Ordered},
+    {0x46f95531, L"percent", XFA_ATTRIBUTEENUM_Percent},
+    {0x46fd25ae, L"even", XFA_ATTRIBUTEENUM_Even},
+    {0x4731d6ba, L"exit", XFA_ATTRIBUTEENUM_Exit},
+    {0x4977356b, L"toolTip", XFA_ATTRIBUTEENUM_ToolTip},
+    {0x49b980ee, L"orderedOccurrence", XFA_ATTRIBUTEENUM_OrderedOccurrence},
+    {0x4a7e2dfe, L"readOnly", XFA_ATTRIBUTEENUM_ReadOnly},
+    {0x4c4e8acb, L"currency", XFA_ATTRIBUTEENUM_Currency},
+    {0x4dcf25f8, L"concat", XFA_ATTRIBUTEENUM_Concat},
+    {0x4febb826, L"Thai", XFA_ATTRIBUTEENUM_Thai},
+    {0x50ef95b2, L"embossed", XFA_ATTRIBUTEENUM_Embossed},
+    {0x516e35ce, L"formdata", XFA_ATTRIBUTEENUM_Formdata},
+    {0x52fa6f0e, L"Greek", XFA_ATTRIBUTEENUM_Greek},
+    {0x54034c2f, L"decimal", XFA_ATTRIBUTEENUM_Decimal},
+    {0x542c7300, L"select", XFA_ATTRIBUTEENUM_Select},
+    {0x551f0ae5, L"longEdge", XFA_ATTRIBUTEENUM_LongEdge},
+    {0x55520a8a, L"protected", XFA_ATTRIBUTEENUM_Protected},
+    {0x559f76f3, L"bottomRight", XFA_ATTRIBUTEENUM_BottomRight},
+    {0x568cb500, L"zero", XFA_ATTRIBUTEENUM_Zero},
+    {0x56bcecb7, L"forwardOnly", XFA_ATTRIBUTEENUM_ForwardOnly},
+    {0x56bf456b, L"docReady", XFA_ATTRIBUTEENUM_DocReady},
+    {0x573cb40c, L"hidden", XFA_ATTRIBUTEENUM_Hidden},
+    {0x582e3424, L"include", XFA_ATTRIBUTEENUM_Include},
+    {0x58a3dd29, L"dashed", XFA_ATTRIBUTEENUM_Dashed},
+    {0x5955b22b, L"multiSelect", XFA_ATTRIBUTEENUM_MultiSelect},
+    {0x598d5c53, L"inactive", XFA_ATTRIBUTEENUM_Inactive},
+    {0x59c8f27d, L"embed", XFA_ATTRIBUTEENUM_Embed},
+    {0x5e7555e8, L"static", XFA_ATTRIBUTEENUM_Static},
+    {0x606d4def, L"onEntry", XFA_ATTRIBUTEENUM_OnEntry},
+    {0x6195eafb, L"Cyrillic", XFA_ATTRIBUTEENUM_Cyrillic},
+    {0x6491b0f3, L"nonBlank", XFA_ATTRIBUTEENUM_NonBlank},
+    {0x67bef031, L"topRight", XFA_ATTRIBUTEENUM_TopRight},
+    {0x67df5ebd, L"Hebrew", XFA_ATTRIBUTEENUM_Hebrew},
+    {0x6aea98be, L"topLeft", XFA_ATTRIBUTEENUM_TopLeft},
+    {0x6c51afc1, L"center", XFA_ATTRIBUTEENUM_Center},
+    {0x7145e6bf, L"moveFirst", XFA_ATTRIBUTEENUM_MoveFirst},
+    {0x7375465c, L"diamond", XFA_ATTRIBUTEENUM_Diamond},
+    {0x7461aef4, L"pageOdd", XFA_ATTRIBUTEENUM_PageOdd},
+    {0x75f8aeb2, L"1mod10", XFA_ATTRIBUTEENUM_1mod10},
+    {0x76d708e0, L"Korean", XFA_ATTRIBUTEENUM_Korean},
+    {0x789f14d7, L"aboveEmbedded", XFA_ATTRIBUTEENUM_AboveEmbedded},
+    {0x792ea39f, L"zipCompress", XFA_ATTRIBUTEENUM_ZipCompress},
+    {0x7a5b7193, L"numeric", XFA_ATTRIBUTEENUM_Numeric},
+    {0x7abec0d2, L"circle", XFA_ATTRIBUTEENUM_Circle},
+    {0x7afbba38, L"toBottom", XFA_ATTRIBUTEENUM_ToBottom},
+    {0x7b95e661, L"inverted", XFA_ATTRIBUTEENUM_Inverted},
+    {0x7baca2e3, L"update", XFA_ATTRIBUTEENUM_Update},
+    {0x7eb5da2c, L"isoname", XFA_ATTRIBUTEENUM_Isoname},
+    {0x7f6fd3d7, L"server", XFA_ATTRIBUTEENUM_Server},
+    {0x814f82b5, L"position", XFA_ATTRIBUTEENUM_Position},
+    {0x82deacf0, L"middleCenter", XFA_ATTRIBUTEENUM_MiddleCenter},
+    {0x83a49dc6, L"optional", XFA_ATTRIBUTEENUM_Optional},
+    {0x861a116f, L"usePrinterSetting", XFA_ATTRIBUTEENUM_UsePrinterSetting},
+    {0x86701ce0, L"outline", XFA_ATTRIBUTEENUM_Outline},
+    {0x8808385e, L"indexChange", XFA_ATTRIBUTEENUM_IndexChange},
+    {0x891f4606, L"change", XFA_ATTRIBUTEENUM_Change},
+    {0x89939f36, L"pageArea", XFA_ATTRIBUTEENUM_PageArea},
+    {0x8b5c3b25, L"once", XFA_ATTRIBUTEENUM_Once},
+    {0x8b5c6962, L"only", XFA_ATTRIBUTEENUM_Only},
+    {0x8b90e1f2, L"open", XFA_ATTRIBUTEENUM_Open},
+    {0x8bcfe96e, L"caption", XFA_ATTRIBUTEENUM_Caption},
+    {0x8ce83ef8, L"raised", XFA_ATTRIBUTEENUM_Raised},
+    {0x8d269cae, L"justify", XFA_ATTRIBUTEENUM_Justify},
+    {0x8fd520dc, L"refAndDescendants", XFA_ATTRIBUTEENUM_RefAndDescendants},
+    {0x9041d4b0, L"short", XFA_ATTRIBUTEENUM_Short},
+    {0x90c94426, L"pageFront", XFA_ATTRIBUTEENUM_PageFront},
+    {0x936beee5, L"monospace", XFA_ATTRIBUTEENUM_Monospace},
+    {0x947fa00f, L"middle", XFA_ATTRIBUTEENUM_Middle},
+    {0x9528a7b4, L"prePrint", XFA_ATTRIBUTEENUM_PrePrint},
+    {0x959ab231, L"always", XFA_ATTRIBUTEENUM_Always},
+    {0x96d61bf0, L"unknown", XFA_ATTRIBUTEENUM_Unknown},
+    {0x997194ee, L"toLeft", XFA_ATTRIBUTEENUM_ToLeft},
+    {0x9a83a3cd, L"above", XFA_ATTRIBUTEENUM_Above},
+    {0x9d0d71c7, L"dashDot", XFA_ATTRIBUTEENUM_DashDot},
+    {0x9df56f3e, L"gregorian", XFA_ATTRIBUTEENUM_Gregorian},
+    {0x9f6723fd, L"Roman", XFA_ATTRIBUTEENUM_Roman},
+    {0x9f693b21, L"mouseDown", XFA_ATTRIBUTEENUM_MouseDown},
+    {0xa1429b36, L"symbol", XFA_ATTRIBUTEENUM_Symbol},
+    {0xa5aa45cb, L"pageEven", XFA_ATTRIBUTEENUM_PageEven},
+    {0xa68635f1, L"sign", XFA_ATTRIBUTEENUM_Sign},
+    {0xa7315093, L"addNew", XFA_ATTRIBUTEENUM_AddNew},
+    {0xa7a773fa, L"star", XFA_ATTRIBUTEENUM_Star},
+    {0xa7d57b45, L"optimistic", XFA_ATTRIBUTEENUM_Optimistic},
+    {0xa8077321, L"rl-tb", XFA_ATTRIBUTEENUM_Rl_tb},
+    {0xa8f1468d, L"middleRight", XFA_ATTRIBUTEENUM_MiddleRight},
+    {0xaa84a1f1, L"maintain", XFA_ATTRIBUTEENUM_Maintain},
+    {0xab40b12c, L"package", XFA_ATTRIBUTEENUM_Package},
+    {0xac8b4d85, L"SimplifiedChinese", XFA_ATTRIBUTEENUM_SimplifiedChinese},
+    {0xadae6744, L"toCenter", XFA_ATTRIBUTEENUM_ToCenter},
+    {0xb0129df1, L"back", XFA_ATTRIBUTEENUM_Back},
+    {0xb0f088cf, L"unspecified", XFA_ATTRIBUTEENUM_Unspecified},
+    {0xb1271067, L"batchOptimistic", XFA_ATTRIBUTEENUM_BatchOptimistic},
+    {0xb18313a1, L"bold", XFA_ATTRIBUTEENUM_Bold},
+    {0xb1833cad, L"both", XFA_ATTRIBUTEENUM_Both},
+    {0xb221123f, L"butt", XFA_ATTRIBUTEENUM_Butt},
+    {0xb40c36bf, L"client", XFA_ATTRIBUTEENUM_Client},
+    {0xb56c7053, L"2mod10", XFA_ATTRIBUTEENUM_2mod10},
+    {0xb683a345, L"imageOnly", XFA_ATTRIBUTEENUM_ImageOnly},
+    {0xb7732dea, L"horizontal", XFA_ATTRIBUTEENUM_Horizontal},
+    {0xb88652a4, L"dotted", XFA_ATTRIBUTEENUM_Dotted},
+    {0xbb2f2880, L"userControl", XFA_ATTRIBUTEENUM_UserControl},
+    {0xbbb79c5d, L"diagonalRight", XFA_ATTRIBUTEENUM_DiagonalRight},
+    {0xbd077154, L"consumeData", XFA_ATTRIBUTEENUM_ConsumeData},
+    {0xbd3fb11e, L"check", XFA_ATTRIBUTEENUM_Check},
+    {0xbde9abda, L"data", XFA_ATTRIBUTEENUM_Data},
+    {0xbf5a02d8, L"down", XFA_ATTRIBUTEENUM_Down},
+    {0xbf7450ee, L"sansSerif", XFA_ATTRIBUTEENUM_SansSerif},
+    {0xc02d649f, L"inline", XFA_ATTRIBUTEENUM_Inline},
+    {0xc11a9e3a, L"TraditionalChinese", XFA_ATTRIBUTEENUM_TraditionalChinese},
+    {0xc16169d8, L"warn", XFA_ATTRIBUTEENUM_Warn},
+    {0xc16f071f, L"refOnly", XFA_ATTRIBUTEENUM_RefOnly},
+    {0xc27c8ba5, L"interactiveForms", XFA_ATTRIBUTEENUM_InteractiveForms},
+    {0xc2d1b15c, L"word", XFA_ATTRIBUTEENUM_Word},
+    {0xc3621288, L"unordered", XFA_ATTRIBUTEENUM_Unordered},
+    {0xc5251981, L"required", XFA_ATTRIBUTEENUM_Required},
+    {0xc7088e7d, L"importOnly", XFA_ATTRIBUTEENUM_ImportOnly},
+    {0xc72cf0e3, L"belowEmbedded", XFA_ATTRIBUTEENUM_BelowEmbedded},
+    {0xc819cf07, L"Japanese", XFA_ATTRIBUTEENUM_Japanese},
+    {0xcdce56b3, L"full", XFA_ATTRIBUTEENUM_Full},
+    {0xce0122e3, L"rl-row", XFA_ATTRIBUTEENUM_Rl_row},
+    {0xcf7d71f1, L"Vietnamese", XFA_ATTRIBUTEENUM_Vietnamese},
+    {0xcfde3e09, L"EastEuropeanRoman", XFA_ATTRIBUTEENUM_EastEuropeanRoman},
+    {0xd576d08e, L"mouseUp", XFA_ATTRIBUTEENUM_MouseUp},
+    {0xd7a92904, L"exportOnly", XFA_ATTRIBUTEENUM_ExportOnly},
+    {0xd8ed1467, L"clear", XFA_ATTRIBUTEENUM_Clear},
+    {0xd95657a6, L"click", XFA_ATTRIBUTEENUM_Click},
+    {0xd96c7de5, L"base64", XFA_ATTRIBUTEENUM_Base64},
+    {0xd9f47f36, L"close", XFA_ATTRIBUTEENUM_Close},
+    {0xdb075bde, L"host", XFA_ATTRIBUTEENUM_Host},
+    {0xdb103411, L"global", XFA_ATTRIBUTEENUM_Global},
+    {0xdb647188, L"blank", XFA_ATTRIBUTEENUM_Blank},
+    {0xdb9be968, L"table", XFA_ATTRIBUTEENUM_Table},
+    {0xdf590fbb, L"import", XFA_ATTRIBUTEENUM_Import},
+    {0xe0e573fb, L"custom", XFA_ATTRIBUTEENUM_Custom},
+    {0xe0ecc79a, L"middleLeft", XFA_ATTRIBUTEENUM_MiddleLeft},
+    {0xe1452019, L"postExecute", XFA_ATTRIBUTEENUM_PostExecute},
+    {0xe1911d98, L"radix", XFA_ATTRIBUTEENUM_Radix},
+    {0xe25fa7b8, L"postOpen", XFA_ATTRIBUTEENUM_PostOpen},
+    {0xe28dce7e, L"enter", XFA_ATTRIBUTEENUM_Enter},
+    {0xe2c44de4, L"ignore", XFA_ATTRIBUTEENUM_Ignore},
+    {0xe2cd8c61, L"lr-tb", XFA_ATTRIBUTEENUM_Lr_tb},
+    {0xe2da8336, L"fantasy", XFA_ATTRIBUTEENUM_Fantasy},
+    {0xe31d5396, L"italic", XFA_ATTRIBUTEENUM_Italic},
+    {0xe7ada113, L"author", XFA_ATTRIBUTEENUM_Author},
+    {0xe8e7cc18, L"toEdge", XFA_ATTRIBUTEENUM_ToEdge},
+    {0xe97aa98b, L"choice", XFA_ATTRIBUTEENUM_Choice},
+    {0xeafd2a38, L"disabled", XFA_ATTRIBUTEENUM_Disabled},
+    {0xeb2b7972, L"crossHatch", XFA_ATTRIBUTEENUM_CrossHatch},
+    {0xeb2db2d7, L"dataRef", XFA_ATTRIBUTEENUM_DataRef},
+    {0xec35dc6e, L"dashDotDot", XFA_ATTRIBUTEENUM_DashDotDot},
+    {0xef85d351, L"square", XFA_ATTRIBUTEENUM_Square},
+    {0xf2102445, L"dynamic", XFA_ATTRIBUTEENUM_Dynamic},
+    {0xf272c7be, L"manual", XFA_ATTRIBUTEENUM_Manual},
+    {0xf2bbb64d, L"etched", XFA_ATTRIBUTEENUM_Etched},
+    {0xf3b8fc6c, L"validationState", XFA_ATTRIBUTEENUM_ValidationState},
+    {0xf42f2b81, L"cursive", XFA_ATTRIBUTEENUM_Cursive},
+    {0xf54481d4, L"last", XFA_ATTRIBUTEENUM_Last},
+    {0xf5ad782b, L"left", XFA_ATTRIBUTEENUM_Left},
+    {0xf616da2e, L"link", XFA_ATTRIBUTEENUM_Link},
+    {0xf6b4afb0, L"long", XFA_ATTRIBUTEENUM_Long},
+    {0xf8636460, L"internationalCarrier",
+     XFA_ATTRIBUTEENUM_InternationalCarrier},
+    {0xf9fb37ac, L"PDF1.3", XFA_ATTRIBUTEENUM_PDF1_3},
+    {0xf9fb37af, L"PDF1.6", XFA_ATTRIBUTEENUM_PDF1_6},
+    {0xfbce7f19, L"serif", XFA_ATTRIBUTEENUM_Serif},
+    {0xfc82d695, L"postSave", XFA_ATTRIBUTEENUM_PostSave},
+    {0xfcef86b5, L"ready", XFA_ATTRIBUTEENUM_Ready},
+    {0xfd54fbb7, L"postSign", XFA_ATTRIBUTEENUM_PostSign},
+    {0xfdc0aae2, L"Arabic", XFA_ATTRIBUTEENUM_Arabic},
+    {0xfe06d2ca, L"error", XFA_ATTRIBUTEENUM_Error},
+    {0xfefc4885, L"urlencoded", XFA_ATTRIBUTEENUM_Urlencoded},
+    {0xff795ad2, L"lowered", XFA_ATTRIBUTEENUM_Lowered},
+};
+const int32_t g_iXFAEnumCount =
+    sizeof(g_XFAEnumData) / sizeof(XFA_ATTRIBUTEENUMINFO);
+static const CXFA_Measurement g_XFAMeasurementData[] = {
+    CXFA_Measurement(0, XFA_UNIT_In),
+    CXFA_Measurement(0, XFA_UNIT_Pt),
+    CXFA_Measurement(5, XFA_UNIT_Mm),
+    CXFA_Measurement(0.25, XFA_UNIT_Mm),
+    CXFA_Measurement(-1, XFA_UNIT_Unknown),
+    CXFA_Measurement(0, XFA_UNIT_Angle),
+    CXFA_Measurement(10, XFA_UNIT_Pt),
+    CXFA_Measurement(360, XFA_UNIT_Angle),
+    CXFA_Measurement(0.5, XFA_UNIT_Pt),
+};
+const XFA_ATTRIBUTEINFO g_XFAAttributeData[] = {
+    {0x68, L"h", XFA_ATTRIBUTE_H, XFA_ATTRIBUTETYPE_Measure,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x77, L"w", XFA_ATTRIBUTE_W, XFA_ATTRIBUTETYPE_Measure,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x78, L"x", XFA_ATTRIBUTE_X, XFA_ATTRIBUTETYPE_Measure,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x79, L"y", XFA_ATTRIBUTE_Y, XFA_ATTRIBUTETYPE_Measure,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x21aed, L"id", XFA_ATTRIBUTE_Id, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template |
+         XFA_XDPPACKET_ConnectionSet | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x25363, L"to", XFA_ATTRIBUTE_To, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Config, (void*)NULL},
+    {0xcb0ac9, L"lineThrough", XFA_ATTRIBUTE_LineThrough,
+     XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)0},
+    {0x2282c73, L"hAlign", XFA_ATTRIBUTE_HAlign, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Left},
+    {0x2c1c7f1, L"typeface", XFA_ATTRIBUTE_Typeface, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)L"Courier"},
+    {0x3106c3a, L"beforeTarget", XFA_ATTRIBUTE_BeforeTarget,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x31b19c1, L"name", XFA_ATTRIBUTE_Name, XFA_ATTRIBUTETYPE_NOTSURE,
+     XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Config | XFA_XDPPACKET_LocaleSet |
+         XFA_XDPPACKET_Template | XFA_XDPPACKET_Datasets | XFA_XDPPACKET_Form |
+         XFA_XDPPACKET_ConnectionSet | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x3848b3f, L"next", XFA_ATTRIBUTE_Next, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_None},
+    {0x43e349b, L"dataRowCount", XFA_ATTRIBUTE_DataRowCount,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x5518c25, L"break", XFA_ATTRIBUTE_Break, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Close},
+    {0x5ce6195, L"vScrollPolicy", XFA_ATTRIBUTE_VScrollPolicy,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Auto},
+    {0x8c74ae9, L"fontHorizontalScale", XFA_ATTRIBUTE_FontHorizontalScale,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)L"100%"},
+    {0x8d4f1c7, L"textIndent", XFA_ATTRIBUTE_TextIndent,
+     XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x97c1c65, L"context", XFA_ATTRIBUTE_Context, XFA_ATTRIBUTETYPE_Integer,
+     XFA_XDPPACKET_UNKNOWN, (void*)0},
+    {0x9876578, L"trayOut", XFA_ATTRIBUTE_TrayOut, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Auto},
+    {0xa2e3514, L"cap", XFA_ATTRIBUTE_Cap, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Square},
+    {0xb3543a6, L"max", XFA_ATTRIBUTE_Max, XFA_ATTRIBUTETYPE_NOTSURE,
+     XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0xb356ca4, L"min", XFA_ATTRIBUTE_Min, XFA_ATTRIBUTETYPE_Integer,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)1},
+    {0xbb8df5d, L"ref", XFA_ATTRIBUTE_Ref, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Config | XFA_XDPPACKET_Template |
+         XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0xbb8f3df, L"rid", XFA_ATTRIBUTE_Rid, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0xc080cd3, L"url", XFA_ATTRIBUTE_Url, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0xc0811ed, L"use", XFA_ATTRIBUTE_Use, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template |
+         XFA_XDPPACKET_ConnectionSet | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0xcfea02e, L"leftInset", XFA_ATTRIBUTE_LeftInset,
+     XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x1026c59d, L"widows", XFA_ATTRIBUTE_Widows, XFA_ATTRIBUTETYPE_Integer,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)0},
+    {0x1059ec18, L"level", XFA_ATTRIBUTE_Level, XFA_ATTRIBUTETYPE_Integer,
+     XFA_XDPPACKET_Config, (void*)0},
+    {0x1356caf8, L"bottomInset", XFA_ATTRIBUTE_BottomInset,
+     XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x13a08bdb, L"overflowTarget", XFA_ATTRIBUTE_OverflowTarget,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x1414d431, L"allowMacro", XFA_ATTRIBUTE_AllowMacro,
+     XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)0},
+    {0x14a32d52, L"pagePosition", XFA_ATTRIBUTE_PagePosition,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Any},
+    {0x1517dfa1, L"columnWidths", XFA_ATTRIBUTE_ColumnWidths,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x169134a1, L"overflowLeader", XFA_ATTRIBUTE_OverflowLeader,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x1b8dce3e, L"action", XFA_ATTRIBUTE_Action, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Include},
+    {0x1e459b8f, L"nonRepudiation", XFA_ATTRIBUTE_NonRepudiation,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x1ec8ab2c, L"rate", XFA_ATTRIBUTE_Rate, XFA_ATTRIBUTETYPE_Integer,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)50},
+    {0x1ef3a64a, L"allowRichText", XFA_ATTRIBUTE_AllowRichText,
+     XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)0},
+    {0x2038c9b2, L"role", XFA_ATTRIBUTE_Role, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0x20914367, L"overflowTrailer", XFA_ATTRIBUTE_OverflowTrailer,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x226ca8f1, L"operation", XFA_ATTRIBUTE_Operation,
+     XFA_ATTRIBUTETYPE_NOTSURE, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x24d85167, L"timeout", XFA_ATTRIBUTE_Timeout, XFA_ATTRIBUTETYPE_NOTSURE,
+     XFA_XDPPACKET_SourceSet, (void*)NULL},
+    {0x25764436, L"topInset", XFA_ATTRIBUTE_TopInset, XFA_ATTRIBUTETYPE_Measure,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x25839852, L"access", XFA_ATTRIBUTE_Access, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Open},
+    {0x268b7ec1, L"commandType", XFA_ATTRIBUTE_CommandType,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_SourceSet,
+     (void*)XFA_ATTRIBUTEENUM_Unknown},
+    {0x28dee6e9, L"format", XFA_ATTRIBUTE_Format, XFA_ATTRIBUTETYPE_NOTSURE,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x28e17e91, L"dataPrep", XFA_ATTRIBUTE_DataPrep, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_None},
+    {0x292b88fe, L"widgetData", XFA_ATTRIBUTE_WidgetData,
+     XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_UNKNOWN, (void*)0},
+    {0x29418bb7, L"abbr", XFA_ATTRIBUTE_Abbr, XFA_ATTRIBUTETYPE_Boolean,
+     XFA_XDPPACKET_LocaleSet, (void*)0},
+    {0x2a82d99c, L"marginRight", XFA_ATTRIBUTE_MarginRight,
+     XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x2b5df51e, L"dataDescription", XFA_ATTRIBUTE_DataDescription,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_ConnectionSet, (void*)NULL},
+    {0x2bb3f470, L"encipherOnly", XFA_ATTRIBUTE_EncipherOnly,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x2cd79033, L"kerningMode", XFA_ATTRIBUTE_KerningMode,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_None},
+    {0x2ee7678f, L"rotate", XFA_ATTRIBUTE_Rotate, XFA_ATTRIBUTETYPE_Measure,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 5)},
+    {0x2f105f72, L"wordCharacterCount", XFA_ATTRIBUTE_WordCharacterCount,
+     XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)7},
+    {0x2f16a382, L"type", XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_NOTSURE,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0x34ae103c, L"reserve", XFA_ATTRIBUTE_Reserve, XFA_ATTRIBUTETYPE_Measure,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 4)},
+    {0x3650557e, L"textLocation", XFA_ATTRIBUTE_TextLocation,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Below},
+    {0x39cdb0a2, L"priority", XFA_ATTRIBUTE_Priority, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Custom},
+    {0x3a0273a6, L"underline", XFA_ATTRIBUTE_Underline,
+     XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)0},
+    {0x3b582286, L"moduleWidth", XFA_ATTRIBUTE_ModuleWidth,
+     XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 3)},
+    {0x3d123c26, L"hyphenate", XFA_ATTRIBUTE_Hyphenate,
+     XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)0},
+    {0x3e7af94f, L"listen", XFA_ATTRIBUTE_Listen, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_RefOnly},
+    {0x4156ee3f, L"delimiter", XFA_ATTRIBUTE_Delimiter, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0x42fed1fd, L"contentType", XFA_ATTRIBUTE_ContentType,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template |
+                                  XFA_XDPPACKET_Datasets | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x453eaf38, L"startNew", XFA_ATTRIBUTE_StartNew, XFA_ATTRIBUTETYPE_Boolean,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)0},
+    {0x45a6daf8, L"eofAction", XFA_ATTRIBUTE_EofAction, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_SourceSet, (void*)XFA_ATTRIBUTEENUM_MoveLast},
+    {0x47cfa43a, L"allowNeutral", XFA_ATTRIBUTE_AllowNeutral,
+     XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)0},
+    {0x47d03490, L"connection", XFA_ATTRIBUTE_Connection,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x4873c601, L"baselineShift", XFA_ATTRIBUTE_BaselineShift,
+     XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x4b319767, L"overlinePeriod", XFA_ATTRIBUTE_OverlinePeriod,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_All},
+    {0x4b8bc840, L"fracDigits", XFA_ATTRIBUTE_FracDigits,
+     XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)2},
+    {0x4ef3d02c, L"orientation", XFA_ATTRIBUTE_Orientation,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Portrait},
+    {0x4fdc3454, L"timeStamp", XFA_ATTRIBUTE_TimeStamp, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_XDP, (void*)NULL},
+    {0x52666f1c, L"printCheckDigit", XFA_ATTRIBUTE_PrintCheckDigit,
+     XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)0},
+    {0x534729c9, L"marginLeft", XFA_ATTRIBUTE_MarginLeft,
+     XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x5392ea58, L"stroke", XFA_ATTRIBUTE_Stroke, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Solid},
+    {0x5404d6df, L"moduleHeight", XFA_ATTRIBUTE_ModuleHeight,
+     XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 2)},
+    {0x54fa722c, L"transferEncoding", XFA_ATTRIBUTE_TransferEncoding,
+     XFA_ATTRIBUTETYPE_NOTSURE,
+     XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x552d9ad5, L"usage", XFA_ATTRIBUTE_Usage, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_ExportAndImport},
+    {0x570ce835, L"presence", XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Visible},
+    {0x5739d1ff, L"radixOffset", XFA_ATTRIBUTE_RadixOffset,
+     XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x577682ac, L"preserve", XFA_ATTRIBUTE_Preserve, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0x58be2870, L"aliasNode", XFA_ATTRIBUTE_AliasNode,
+     XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_UNKNOWN, (void*)0},
+    {0x5a32e493, L"multiLine", XFA_ATTRIBUTE_MultiLine,
+     XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)0},
+    {0x5a50e9e6, L"version", XFA_ATTRIBUTE_Version, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0x5ab23b6c, L"startChar", XFA_ATTRIBUTE_StartChar, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0x5b707a35, L"scriptTest", XFA_ATTRIBUTE_ScriptTest,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Error},
+    {0x5c054755, L"startAngle", XFA_ATTRIBUTE_StartAngle,
+     XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 5)},
+    {0x5ec958c0, L"cursorType", XFA_ATTRIBUTE_CursorType,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_SourceSet,
+     (void*)XFA_ATTRIBUTEENUM_ForwardOnly},
+    {0x5f760b50, L"digitalSignature", XFA_ATTRIBUTE_DigitalSignature,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x60a61edd, L"codeType", XFA_ATTRIBUTE_CodeType, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0x60d4c8b1, L"output", XFA_ATTRIBUTE_Output, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_ConnectionSet, (void*)NULL},
+    {0x64110ab5, L"bookendTrailer", XFA_ATTRIBUTE_BookendTrailer,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x65e30c67, L"imagingBBox", XFA_ATTRIBUTE_ImagingBBox,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)L"none"},
+    {0x66539c48, L"excludeInitialCap", XFA_ATTRIBUTE_ExcludeInitialCap,
+     XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)0},
+    {0x66642f8f, L"force", XFA_ATTRIBUTE_Force, XFA_ATTRIBUTETYPE_Boolean,
+     XFA_XDPPACKET_Config, (void*)NULL},
+    {0x69aa2292, L"crlSign", XFA_ATTRIBUTE_CrlSign, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0x6a3405dd, L"previous", XFA_ATTRIBUTE_Previous, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_None},
+    {0x6a95c976, L"pushCharacterCount", XFA_ATTRIBUTE_PushCharacterCount,
+     XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)3},
+    {0x6b6ddcfb, L"nullTest", XFA_ATTRIBUTE_NullTest, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Disabled},
+    {0x6cfa828a, L"runAt", XFA_ATTRIBUTE_RunAt, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Client},
+    {0x731e0665, L"spaceBelow", XFA_ATTRIBUTE_SpaceBelow,
+     XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x74788f8b, L"sweepAngle", XFA_ATTRIBUTE_SweepAngle,
+     XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 7)},
+    {0x78bff531, L"numberOfCells", XFA_ATTRIBUTE_NumberOfCells,
+     XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)0},
+    {0x79543055, L"letterSpacing", XFA_ATTRIBUTE_LetterSpacing,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x79975f2b, L"lockType", XFA_ATTRIBUTE_LockType, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_SourceSet, (void*)XFA_ATTRIBUTEENUM_ReadOnly},
+    {0x7a0cc471, L"passwordChar", XFA_ATTRIBUTE_PasswordChar,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)L"*"},
+    {0x7a7cc341, L"vAlign", XFA_ATTRIBUTE_VAlign, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)XFA_ATTRIBUTEENUM_Top},
+    {0x7b29630a, L"sourceBelow", XFA_ATTRIBUTE_SourceBelow,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Config,
+     (void*)XFA_ATTRIBUTEENUM_Update},
+    {0x7b95e661, L"inverted", XFA_ATTRIBUTE_Inverted, XFA_ATTRIBUTETYPE_Boolean,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)0},
+    {0x7c2fd80b, L"mark", XFA_ATTRIBUTE_Mark, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Default},
+    {0x7c2ff6ae, L"maxH", XFA_ATTRIBUTE_MaxH, XFA_ATTRIBUTETYPE_Measure,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x7c2ff6bd, L"maxW", XFA_ATTRIBUTE_MaxW, XFA_ATTRIBUTETYPE_Measure,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x7c732a66, L"truncate", XFA_ATTRIBUTE_Truncate, XFA_ATTRIBUTETYPE_Boolean,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)0},
+    {0x7d02356c, L"minH", XFA_ATTRIBUTE_MinH, XFA_ATTRIBUTETYPE_Measure,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x7d02357b, L"minW", XFA_ATTRIBUTE_MinW, XFA_ATTRIBUTETYPE_Measure,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x7d0b5fca, L"initial", XFA_ATTRIBUTE_Initial, XFA_ATTRIBUTETYPE_Integer,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)1},
+    {0x7d9fd7c5, L"mode", XFA_ATTRIBUTE_Mode, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Config, (void*)XFA_ATTRIBUTEENUM_UsePrinterSetting},
+    {0x7e7e845e, L"layout", XFA_ATTRIBUTE_Layout, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Position},
+    {0x7f6fd3d7, L"server", XFA_ATTRIBUTE_Server, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0x824f21b7, L"embedPDF", XFA_ATTRIBUTE_EmbedPDF, XFA_ATTRIBUTETYPE_Boolean,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)0},
+    {0x8340ea66, L"oddOrEven", XFA_ATTRIBUTE_OddOrEven, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)XFA_ATTRIBUTEENUM_Any},
+    {0x836d4d7c, L"tabDefault", XFA_ATTRIBUTE_TabDefault,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x8855805f, L"contains", XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Datasets, (void*)XFA_ATTRIBUTEENUM_Data},
+    {0x8a692521, L"rightInset", XFA_ATTRIBUTE_RightInset,
+     XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x8af2e657, L"maxChars", XFA_ATTRIBUTE_MaxChars, XFA_ATTRIBUTETYPE_Integer,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)0},
+    {0x8b90e1f2, L"open", XFA_ATTRIBUTE_Open, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_UserControl},
+    {0x8c99377e, L"relation", XFA_ATTRIBUTE_Relation, XFA_ATTRIBUTETYPE_NOTSURE,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0x8d181d61, L"wideNarrowRatio", XFA_ATTRIBUTE_WideNarrowRatio,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)L"3:1"},
+    {0x8e1c2921, L"relevant", XFA_ATTRIBUTE_Relevant, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0x8e29d794, L"signatureType", XFA_ATTRIBUTE_SignatureType,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Filter},
+    {0x8ec6204c, L"lineThroughPeriod", XFA_ATTRIBUTE_LineThroughPeriod,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_All},
+    {0x8ed182d1, L"shape", XFA_ATTRIBUTE_Shape, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Square},
+    {0x8fa01790, L"tabStops", XFA_ATTRIBUTE_TabStops, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0x8fc36c0a, L"outputBelow", XFA_ATTRIBUTE_OutputBelow,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Config,
+     (void*)XFA_ATTRIBUTEENUM_Warn},
+    {0x9041d4b0, L"short", XFA_ATTRIBUTE_Short, XFA_ATTRIBUTETYPE_Measure,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0x907c7719, L"fontVerticalScale", XFA_ATTRIBUTE_FontVerticalScale,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)L"100%"},
+    {0x94446dcc, L"thickness", XFA_ATTRIBUTE_Thickness,
+     XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 8)},
+    {0x957fa006, L"commitOn", XFA_ATTRIBUTE_CommitOn, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Select},
+    {0x982bd892, L"remainCharacterCount", XFA_ATTRIBUTE_RemainCharacterCount,
+     XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)3},
+    {0x98fd4d81, L"keyAgreement", XFA_ATTRIBUTE_KeyAgreement,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x99800d7a, L"errorCorrectionLevel", XFA_ATTRIBUTE_ErrorCorrectionLevel,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0x9a63da3d, L"upsMode", XFA_ATTRIBUTE_UpsMode, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_UsCarrier},
+    {0x9cc17d75, L"mergeMode", XFA_ATTRIBUTE_MergeMode, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_ConsumeData},
+    {0x9d833d75, L"circular", XFA_ATTRIBUTE_Circular, XFA_ATTRIBUTETYPE_Boolean,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)0},
+    {0x9d8ee204, L"psName", XFA_ATTRIBUTE_PsName, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Config, (void*)NULL},
+    {0x9dcc3ab3, L"trailer", XFA_ATTRIBUTE_Trailer, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0xa0933954, L"unicodeRange", XFA_ATTRIBUTE_UnicodeRange,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Config, (void*)NULL},
+    {0xa1b0d2f5, L"executeType", XFA_ATTRIBUTE_ExecuteType,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Import},
+    {0xa25a883d, L"duplexImposition", XFA_ATTRIBUTE_DuplexImposition,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_LongEdge},
+    {0xa42ca1b7, L"trayIn", XFA_ATTRIBUTE_TrayIn, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Auto},
+    {0xa433f001, L"bindingNode", XFA_ATTRIBUTE_BindingNode,
+     XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_UNKNOWN, (void*)0},
+    {0xa5340ff5, L"bofAction", XFA_ATTRIBUTE_BofAction, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_SourceSet, (void*)XFA_ATTRIBUTEENUM_MoveFirst},
+    {0xa5b410cf, L"save", XFA_ATTRIBUTE_Save, XFA_ATTRIBUTETYPE_Boolean,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)0},
+    {0xa6118c89, L"targetType", XFA_ATTRIBUTE_TargetType,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Auto},
+    {0xa66404cb, L"keyEncipherment", XFA_ATTRIBUTE_KeyEncipherment,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0xa6710262, L"credentialServerPolicy",
+     XFA_ATTRIBUTE_CredentialServerPolicy, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Optional},
+    {0xa686975b, L"size", XFA_ATTRIBUTE_Size, XFA_ATTRIBUTETYPE_Measure,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 6)},
+    {0xa85e74f3, L"initialNumber", XFA_ATTRIBUTE_InitialNumber,
+     XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)1},
+    {0xabef37e3, L"slope", XFA_ATTRIBUTE_Slope, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Backslash},
+    {0xabfa6c4f, L"cSpace", XFA_ATTRIBUTE_CSpace, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)L"SRGB"},
+    {0xac06e2b0, L"colSpan", XFA_ATTRIBUTE_ColSpan, XFA_ATTRIBUTETYPE_Integer,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)1},
+    {0xadc4c77b, L"binding", XFA_ATTRIBUTE_Binding, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0xaf754613, L"checksum", XFA_ATTRIBUTE_Checksum, XFA_ATTRIBUTETYPE_NOTSURE,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0xb045fbc5, L"charEncoding", XFA_ATTRIBUTE_CharEncoding,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)L"UTF-8"},
+    {0xb0e5485d, L"bind", XFA_ATTRIBUTE_Bind, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_SourceSet, (void*)NULL},
+    {0xb12128b7, L"textEntry", XFA_ATTRIBUTE_TextEntry,
+     XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)0},
+    {0xb373a862, L"archive", XFA_ATTRIBUTE_Archive, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0xb598a1f7, L"uuid", XFA_ATTRIBUTE_Uuid, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_XDP, (void*)NULL},
+    {0xb5e49bf2, L"posture", XFA_ATTRIBUTE_Posture, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Normal},
+    {0xb6b44172, L"after", XFA_ATTRIBUTE_After, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Auto},
+    {0xb716467b, L"orphans", XFA_ATTRIBUTE_Orphans, XFA_ATTRIBUTETYPE_Integer,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)0},
+    {0xbc0c4695, L"qualifiedName", XFA_ATTRIBUTE_QualifiedName,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_UNKNOWN, (void*)NULL},
+    {0xbc254332, L"usehref", XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template |
+         XFA_XDPPACKET_ConnectionSet | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0xbc8fa350, L"locale", XFA_ATTRIBUTE_Locale, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0xbd6e1d88, L"weight", XFA_ATTRIBUTE_Weight, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Normal},
+    {0xbd96a0e9, L"underlinePeriod", XFA_ATTRIBUTE_UnderlinePeriod,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_All},
+    {0xbde9abda, L"data", XFA_ATTRIBUTE_Data, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Link},
+    {0xbe52dfbf, L"desc", XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_LocaleSet, (void*)NULL},
+    {0xbe9ba472, L"numbered", XFA_ATTRIBUTE_Numbered, XFA_ATTRIBUTETYPE_Integer,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)1},
+    {0xc035c6b1, L"dataColumnCount", XFA_ATTRIBUTE_DataColumnCount,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0xc0ec9fa4, L"overline", XFA_ATTRIBUTE_Overline, XFA_ATTRIBUTETYPE_Integer,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)0},
+    {0xc2ba0923, L"urlPolicy", XFA_ATTRIBUTE_UrlPolicy, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0xc2bd40fd, L"anchorType", XFA_ATTRIBUTE_AnchorType,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_TopLeft},
+    {0xc39a88bd, L"labelRef", XFA_ATTRIBUTE_LabelRef, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0xc3c1442f, L"bookendLeader", XFA_ATTRIBUTE_BookendLeader,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0xc4547a08, L"maxLength", XFA_ATTRIBUTE_MaxLength,
+     XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*) - 1},
+    {0xc4fed09b, L"accessKey", XFA_ATTRIBUTE_AccessKey, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0xc5762157, L"cursorLocation", XFA_ATTRIBUTE_CursorLocation,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_SourceSet,
+     (void*)XFA_ATTRIBUTEENUM_Client},
+    {0xc860f30a, L"delayedOpen", XFA_ATTRIBUTE_DelayedOpen,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_SourceSet, (void*)NULL},
+    {0xc8da4da7, L"target", XFA_ATTRIBUTE_Target, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0xca5dc27c, L"dataEncipherment", XFA_ATTRIBUTE_DataEncipherment,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0xcb150479, L"afterTarget", XFA_ATTRIBUTE_AfterTarget,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0xcbcaf66d, L"leader", XFA_ATTRIBUTE_Leader, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0xcca7897e, L"picker", XFA_ATTRIBUTE_Picker, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Host},
+    {0xcd7f7b54, L"from", XFA_ATTRIBUTE_From, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Config, (void*)NULL},
+    {0xcea5e62c, L"baseProfile", XFA_ATTRIBUTE_BaseProfile,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Full},
+    {0xd171b240, L"aspect", XFA_ATTRIBUTE_Aspect, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)XFA_ATTRIBUTEENUM_Fit},
+    {0xd3c84d25, L"rowColumnRatio", XFA_ATTRIBUTE_RowColumnRatio,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0xd4b01921, L"lineHeight", XFA_ATTRIBUTE_LineHeight,
+     XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 1)},
+    {0xd4cc53f8, L"highlight", XFA_ATTRIBUTE_Highlight, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Inverted},
+    {0xd50f903a, L"valueRef", XFA_ATTRIBUTE_ValueRef, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0xd52482e0, L"maxEntries", XFA_ATTRIBUTE_MaxEntries,
+     XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Config, (void*)5},
+    {0xd57c513c, L"dataLength", XFA_ATTRIBUTE_DataLength,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0xd6128d8d, L"activity", XFA_ATTRIBUTE_Activity, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Click},
+    {0xd6a39990, L"input", XFA_ATTRIBUTE_Input, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_ConnectionSet, (void*)NULL},
+    {0xd6e27f1d, L"value", XFA_ATTRIBUTE_Value, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Config | XFA_XDPPACKET_LocaleSet |
+         XFA_XDPPACKET_Template | XFA_XDPPACKET_Datasets |
+         XFA_XDPPACKET_ConnectionSet | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0xd70798c2, L"blankOrNotBlank", XFA_ATTRIBUTE_BlankOrNotBlank,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Any},
+    {0xd861f8af, L"addRevocationInfo", XFA_ATTRIBUTE_AddRevocationInfo,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0xd8f982bf, L"genericFamily", XFA_ATTRIBUTE_GenericFamily,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Config,
+     (void*)XFA_ATTRIBUTEENUM_Serif},
+    {0xd996fa9b, L"hand", XFA_ATTRIBUTE_Hand, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Even},
+    {0xdb55fec5, L"href", XFA_ATTRIBUTE_Href, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0xdc75676c, L"textEncoding", XFA_ATTRIBUTE_TextEncoding,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0xde7f92ba, L"leadDigits", XFA_ATTRIBUTE_LeadDigits,
+     XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*) - 1},
+    {0xe11a2cbc, L"permissions", XFA_ATTRIBUTE_Permissions,
+     XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)2},
+    {0xe18b5659, L"spaceAbove", XFA_ATTRIBUTE_SpaceAbove,
+     XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0xe1a26b56, L"codeBase", XFA_ATTRIBUTE_CodeBase, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0xe349d044, L"stock", XFA_ATTRIBUTE_Stock, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0xe372ae97, L"isNull", XFA_ATTRIBUTE_IsNull, XFA_ATTRIBUTETYPE_Boolean,
+     XFA_XDPPACKET_Datasets, (void*)0},
+    {0xe4c3a5e5, L"restoreState", XFA_ATTRIBUTE_RestoreState,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Manual},
+    {0xe5c96d6a, L"excludeAllCaps", XFA_ATTRIBUTE_ExcludeAllCaps,
+     XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)0},
+    {0xe64b1129, L"formatTest", XFA_ATTRIBUTE_FormatTest,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Warning},
+    {0xe6f99487, L"hScrollPolicy", XFA_ATTRIBUTE_HScrollPolicy,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Auto},
+    {0xe8dddf50, L"join", XFA_ATTRIBUTE_Join, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Square},
+    {0xe8f118a8, L"keyCertSign", XFA_ATTRIBUTE_KeyCertSign,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0xe948b9a8, L"radius", XFA_ATTRIBUTE_Radius, XFA_ATTRIBUTETYPE_Measure,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0xe996b2fe, L"sourceAbove", XFA_ATTRIBUTE_SourceAbove,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Config,
+     (void*)XFA_ATTRIBUTEENUM_Warn},
+    {0xea7090a0, L"override", XFA_ATTRIBUTE_Override, XFA_ATTRIBUTETYPE_NOTSURE,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0xeb091003, L"classId", XFA_ATTRIBUTE_ClassId, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0xeb511b54, L"disable", XFA_ATTRIBUTE_Disable, XFA_ATTRIBUTETYPE_Boolean,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)0},
+    {0xeda9017a, L"scope", XFA_ATTRIBUTE_Scope, XFA_ATTRIBUTETYPE_NOTSURE,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0xf197844d, L"match", XFA_ATTRIBUTE_Match, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Once},
+    {0xf2009339, L"placement", XFA_ATTRIBUTE_Placement, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Left},
+    {0xf4ffce73, L"before", XFA_ATTRIBUTE_Before, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_Auto},
+    {0xf531b059, L"writingScript", XFA_ATTRIBUTE_WritingScript,
+     XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Config,
+     (void*)XFA_ATTRIBUTEENUM_Asterisk},
+    {0xf575ca75, L"endChar", XFA_ATTRIBUTE_EndChar, XFA_ATTRIBUTETYPE_Cdata,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (void*)NULL},
+    {0xf6b47749, L"lock", XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTETYPE_Integer,
+     XFA_XDPPACKET_Config, (void*)0},
+    {0xf6b4afb0, L"long", XFA_ATTRIBUTE_Long, XFA_ATTRIBUTETYPE_Measure,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)(g_XFAMeasurementData + 0)},
+    {0xf6b59543, L"intact", XFA_ATTRIBUTE_Intact, XFA_ATTRIBUTETYPE_Enum,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)XFA_ATTRIBUTEENUM_None},
+    {0xf889e747, L"xdpContent", XFA_ATTRIBUTE_XdpContent,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+    {0xfea53ec6, L"decipherOnly", XFA_ATTRIBUTE_DecipherOnly,
+     XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     (void*)NULL},
+};
+const int32_t g_iXFAAttributeCount =
+    sizeof(g_XFAAttributeData) / sizeof(XFA_ATTRIBUTEINFO);
+const XFA_NOTSUREATTRIBUTE g_XFANotsureAttributes[] = {
+    {XFA_ELEMENT_SubformSet, XFA_ATTRIBUTE_Relation, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Ordered},
+    {XFA_ELEMENT_NumberPattern, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Numeric},
+    {XFA_ELEMENT_KeyUsage, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Optional},
+    {XFA_ELEMENT_LabelPrinter, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Zpl},
+    {XFA_ELEMENT_CalendarSymbols, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Gregorian},
+    {XFA_ELEMENT_Barcode, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Cdata,
+     (void*)NULL},
+    {XFA_ELEMENT_Barcode, XFA_ATTRIBUTE_Checksum, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_None},
+    {XFA_ELEMENT_TimePattern, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Med},
+    {XFA_ELEMENT_BatchOutput, XFA_ATTRIBUTE_Format, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_None},
+    {XFA_ELEMENT_SubjectDNs, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Optional},
+    {XFA_ELEMENT_Issuers, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Optional},
+    {XFA_ELEMENT_EncryptionMethods, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Optional},
+    {XFA_ELEMENT_Pattern, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_CrossHatch},
+    {XFA_ELEMENT_Compress, XFA_ATTRIBUTE_Scope, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_ImageOnly},
+    {XFA_ELEMENT_Image, XFA_ATTRIBUTE_TransferEncoding, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Base64},
+    {XFA_ELEMENT_TimeStamp, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Optional},
+    {XFA_ELEMENT_Subform, XFA_ATTRIBUTE_Scope, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Name},
+    {XFA_ELEMENT_Handler, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Optional},
+    {XFA_ELEMENT_Record, XFA_ATTRIBUTE_Max, XFA_ATTRIBUTETYPE_Integer,
+     (void*)0},
+    {XFA_ELEMENT_Command, XFA_ATTRIBUTE_Timeout, XFA_ATTRIBUTETYPE_Integer,
+     (void*)30},
+    {XFA_ELEMENT_DigestMethods, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Optional},
+    {XFA_ELEMENT_PageSet, XFA_ATTRIBUTE_Relation, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_OrderedOccurrence},
+    {XFA_ELEMENT_Equate, XFA_ATTRIBUTE_From, XFA_ATTRIBUTETYPE_Cdata,
+     (void*)NULL},
+    {XFA_ELEMENT_Equate, XFA_ATTRIBUTE_To, XFA_ATTRIBUTETYPE_Cdata,
+     (void*)NULL},
+    {XFA_ELEMENT_Traverse, XFA_ATTRIBUTE_Operation, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Next},
+    {XFA_ELEMENT_Encodings, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Optional},
+    {XFA_ELEMENT_Signing, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Optional},
+    {XFA_ELEMENT_Oids, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Optional},
+    {XFA_ELEMENT_Signature, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_PDF1_3},
+    {XFA_ELEMENT_ExData, XFA_ATTRIBUTE_TransferEncoding, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_None},
+    {XFA_ELEMENT_Linear, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_ToRight},
+    {XFA_ELEMENT_CurrencySymbol, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Symbol},
+    {XFA_ELEMENT_EquateRange, XFA_ATTRIBUTE_From, XFA_ATTRIBUTETYPE_Cdata,
+     (void*)NULL},
+    {XFA_ELEMENT_EquateRange, XFA_ATTRIBUTE_To, XFA_ATTRIBUTETYPE_Cdata,
+     (void*)NULL},
+    {XFA_ELEMENT_SignData, XFA_ATTRIBUTE_Operation, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Sign},
+    {XFA_ELEMENT_DatePattern, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Med},
+    {XFA_ELEMENT_Bind, XFA_ATTRIBUTE_TransferEncoding, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_None},
+    {XFA_ELEMENT_Reasons, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Optional},
+    {XFA_ELEMENT_AppearanceFilter, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Optional},
+    {XFA_ELEMENT_Form, XFA_ATTRIBUTE_Checksum, XFA_ATTRIBUTETYPE_Cdata,
+     (void*)NULL},
+    {XFA_ELEMENT_Value, XFA_ATTRIBUTE_Override, XFA_ATTRIBUTETYPE_Boolean,
+     (void*)0},
+    {XFA_ELEMENT_Calculate, XFA_ATTRIBUTE_Override, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Error},
+    {XFA_ELEMENT_Connect, XFA_ATTRIBUTE_Timeout, XFA_ATTRIBUTETYPE_Integer,
+     (void*)15},
+    {XFA_ELEMENT_Submit, XFA_ATTRIBUTE_Format, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Xdp},
+    {XFA_ELEMENT_Radial, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_ToEdge},
+    {XFA_ELEMENT_LockDocument, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Optional},
+    {XFA_ELEMENT_Occur, XFA_ATTRIBUTE_Max, XFA_ATTRIBUTETYPE_Integer, (void*)1},
+    {XFA_ELEMENT_NumberSymbol, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTETYPE_Enum,
+     (void*)XFA_ATTRIBUTEENUM_Decimal},
+};
+const int32_t g_iXFANotsureCount =
+    sizeof(g_XFANotsureAttributes) / sizeof(XFA_NOTSUREATTRIBUTE);
+const XFA_ELEMENTINFO g_XFAElementData[] = {
+    {0x23ee3, L"ps", XFA_ELEMENT_Ps, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+    {0x25363, L"to", XFA_ELEMENT_To, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x2587e, L"ui", XFA_ELEMENT_Ui,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x1c648b, L"recordSet", XFA_ELEMENT_RecordSet, XFA_XDPPACKET_SourceSet,
+     XFA_OBJECTTYPE_Node},
+    {0x171428f, L"subsetBelow", XFA_ELEMENT_SubsetBelow, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x1a0776a, L"subformSet", XFA_ELEMENT_SubformSet,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+    {0x2340d70, L"adobeExtensionLevel", XFA_ELEMENT_AdobeExtensionLevel,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0x2c1c7f1, L"typeface", XFA_ELEMENT_Typeface, XFA_XDPPACKET_LocaleSet,
+     XFA_OBJECTTYPE_Node},
+    {0x5518c25, L"break", XFA_ELEMENT_Break,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x5fff523, L"fontInfo", XFA_ELEMENT_FontInfo, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0x653a227, L"numberPattern", XFA_ELEMENT_NumberPattern,
+     XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_ContentNode},
+    {0x65b4a05, L"dynamicRender", XFA_ELEMENT_DynamicRender,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0x7e4362e, L"printScaling", XFA_ELEMENT_PrintScaling, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x7fe6d3a, L"checkButton", XFA_ELEMENT_CheckButton,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x80cf58f, L"datePatterns", XFA_ELEMENT_DatePatterns,
+     XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+    {0x811929d, L"sourceSet", XFA_ELEMENT_SourceSet, XFA_XDPPACKET_SourceSet,
+     XFA_OBJECTTYPE_ModelNode},
+    {0x9f9d612, L"amd", XFA_ELEMENT_Amd, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x9f9efb6, L"arc", XFA_ELEMENT_Arc,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xa48835e, L"day", XFA_ELEMENT_Day, XFA_XDPPACKET_LocaleSet,
+     XFA_OBJECTTYPE_ContentNode},
+    {0xa6328b8, L"era", XFA_ELEMENT_Era, XFA_XDPPACKET_LocaleSet,
+     XFA_OBJECTTYPE_ContentNode},
+    {0xae6a0a0, L"jog", XFA_ELEMENT_Jog, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0xb1b3d22, L"log", XFA_ELEMENT_Log, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xb35439e, L"map", XFA_ELEMENT_Map,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_SourceSet, XFA_OBJECTTYPE_Node},
+    {0xb355301, L"mdp", XFA_ELEMENT_Mdp,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xb420438, L"breakBefore", XFA_ELEMENT_BreakBefore,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xb6a091c, L"oid", XFA_ELEMENT_Oid,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_TextNode},
+    {0xb84389f, L"pcl", XFA_ELEMENT_Pcl, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xb843dba, L"pdf", XFA_ELEMENT_Pdf, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xbb8df5d, L"ref", XFA_ELEMENT_Ref,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_TextNode},
+    {0xc080cd0, L"uri", XFA_ELEMENT_Uri,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_ConnectionSet,
+     XFA_OBJECTTYPE_TextNode},
+    {0xc56afbf, L"xdc", XFA_ELEMENT_Xdc,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_Xdc, XFA_OBJECTTYPE_ModelNode},
+    {0xc56afcc, L"xdp", XFA_ELEMENT_Xdp, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xc56b9ff, L"xfa", XFA_ELEMENT_Xfa, XFA_XDPPACKET_XDP,
+     XFA_OBJECTTYPE_ModelNode},
+    {0xc56fcb7, L"xsl", XFA_ELEMENT_Xsl, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xc8b89d6, L"zpl", XFA_ELEMENT_Zpl, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xc9bae94, L"cache", XFA_ELEMENT_Cache, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xcb016be, L"margin", XFA_ELEMENT_Margin,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xe1378fe, L"keyUsage", XFA_ELEMENT_KeyUsage,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xfe3596a, L"exclude", XFA_ELEMENT_Exclude, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x10395ac7, L"choiceList", XFA_ELEMENT_ChoiceList,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x1059ec18, L"level", XFA_ELEMENT_Level, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x10874804, L"labelPrinter", XFA_ELEMENT_LabelPrinter,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+    {0x10c40e03, L"calendarSymbols", XFA_ELEMENT_CalendarSymbols,
+     XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+    {0x10f1ea24, L"para", XFA_ELEMENT_Para,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x10f1ea37, L"part", XFA_ELEMENT_Part, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x1140975b, L"pdfa", XFA_ELEMENT_Pdfa, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0x1154efe6, L"filter", XFA_ELEMENT_Filter,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x13f41de1, L"present", XFA_ELEMENT_Present, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0x1827e6ea, L"pagination", XFA_ELEMENT_Pagination, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x18463707, L"encoding", XFA_ELEMENT_Encoding,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_NodeC},
+    {0x185e41e2, L"event", XFA_ELEMENT_Event,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x1adb142d, L"whitespace", XFA_ELEMENT_Whitespace, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0x1f3f64c3, L"defaultUi", XFA_ELEMENT_DefaultUi,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x204e87cb, L"dataModel", XFA_ELEMENT_DataModel, XFA_XDPPACKET_Datasets,
+     XFA_OBJECTTYPE_ModelNode},
+    {0x2057b350, L"barcode", XFA_ELEMENT_Barcode,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x20596bad, L"timePattern", XFA_ELEMENT_TimePattern,
+     XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_ContentNode},
+    {0x210b74d3, L"batchOutput", XFA_ELEMENT_BatchOutput, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0x212ff0e2, L"enforce", XFA_ELEMENT_Enforce, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x21d351b4, L"currencySymbols", XFA_ELEMENT_CurrencySymbols,
+     XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+    {0x21db83c5, L"addSilentPrint", XFA_ELEMENT_AddSilentPrint,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0x22266258, L"rename", XFA_ELEMENT_Rename, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0x226ca8f1, L"operation", XFA_ELEMENT_Operation,
+     XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_TextNode},
+    {0x23e27b84, L"typefaces", XFA_ELEMENT_Typefaces, XFA_XDPPACKET_LocaleSet,
+     XFA_OBJECTTYPE_Node},
+    {0x23f4aa75, L"subjectDNs", XFA_ELEMENT_SubjectDNs,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x240d5e8e, L"issuers", XFA_ELEMENT_Issuers,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x2457a033, L"signaturePseudoModel", XFA_ELEMENT_SignaturePseudoModel,
+     XFA_XDPPACKET_XDP, XFA_OBJECTTYPE_OrdinaryObject},
+    {0x24a52f8a, L"wsdlConnection", XFA_ELEMENT_WsdlConnection,
+     XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_Node},
+    {0x254ebd07, L"debug", XFA_ELEMENT_Debug, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0x2655c66a, L"delta", XFA_ELEMENT_Delta, XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_OrdinaryObject},
+    {0x26c0daec, L"eraNames", XFA_ELEMENT_EraNames, XFA_XDPPACKET_LocaleSet,
+     XFA_OBJECTTYPE_Node},
+    {0x273ab03b, L"modifyAnnots", XFA_ELEMENT_ModifyAnnots,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0x27875bb4, L"startNode", XFA_ELEMENT_StartNode, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0x285d0dbc, L"button", XFA_ELEMENT_Button,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x28dee6e9, L"format", XFA_ELEMENT_Format,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x2a23349e, L"border", XFA_ELEMENT_Border,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x2ae67f19, L"area", XFA_ELEMENT_Area,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_ContainerNode},
+    {0x2c3c4c67, L"hyphenation", XFA_ELEMENT_Hyphenation,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x2d08af85, L"text", XFA_ELEMENT_Text,
+     XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x2d71b00f, L"time", XFA_ELEMENT_Time,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+    {0x2f16a382, L"type", XFA_ELEMENT_Type, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x2fe057e9, L"overprint", XFA_ELEMENT_Overprint, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x302aee16, L"certificates", XFA_ELEMENT_Certificates,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x30b227df, L"encryptionMethods", XFA_ELEMENT_EncryptionMethods,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x32b900d1, L"setProperty", XFA_ELEMENT_SetProperty,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x337d9e45, L"printerName", XFA_ELEMENT_PrinterName, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x33edda4b, L"startPage", XFA_ELEMENT_StartPage, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0x381943e4, L"pageOffset", XFA_ELEMENT_PageOffset, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0x382106cd, L"dateTime", XFA_ELEMENT_DateTime,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+    {0x386e7421, L"comb", XFA_ELEMENT_Comb,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x390acd9e, L"pattern", XFA_ELEMENT_Pattern,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x3942163e, L"ifEmpty", XFA_ELEMENT_IfEmpty, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0x39944a7b, L"suppressBanner", XFA_ELEMENT_SuppressBanner,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0x3b3c3dca, L"outputBin", XFA_ELEMENT_OutputBin, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x3b8a4024, L"field", XFA_ELEMENT_Field,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+    {0x3c15352f, L"agent", XFA_ELEMENT_Agent, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0x3d7e8668, L"outputXSL", XFA_ELEMENT_OutputXSL, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0x3e1c91c5, L"adjustData", XFA_ELEMENT_AdjustData, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0x3e7a9408, L"autoSave", XFA_ELEMENT_AutoSave, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0x3ecead94, L"contentArea", XFA_ELEMENT_ContentArea,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+    {0x3ef334e3, L"eventPseudoModel", XFA_ELEMENT_EventPseudoModel,
+     XFA_XDPPACKET_XDP, XFA_OBJECTTYPE_OrdinaryObject},
+    {0x3fadaec0, L"wsdlAddress", XFA_ELEMENT_WsdlAddress,
+     XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_TextNode},
+    {0x40623b5b, L"solid", XFA_ELEMENT_Solid,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x41f0bd76, L"dateTimeSymbols", XFA_ELEMENT_DateTimeSymbols,
+     XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_ContentNode},
+    {0x444e7523, L"encryptionLevel", XFA_ELEMENT_EncryptionLevel,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0x4523af55, L"edge", XFA_ELEMENT_Edge,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x45d5e3c1, L"stipple", XFA_ELEMENT_Stipple,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x475e4e87, L"attributes", XFA_ELEMENT_Attributes, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0x487a8c87, L"versionControl", XFA_ELEMENT_VersionControl,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+    {0x48e5248c, L"meridiem", XFA_ELEMENT_Meridiem, XFA_XDPPACKET_LocaleSet,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x48f36719, L"exclGroup", XFA_ELEMENT_ExclGroup,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+    {0x4977356b, L"toolTip", XFA_ELEMENT_ToolTip,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_TextNode},
+    {0x499afecc, L"compress", XFA_ELEMENT_Compress, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0x4a0c4948, L"reason", XFA_ELEMENT_Reason,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_TextNode},
+    {0x4bdcce13, L"execute", XFA_ELEMENT_Execute,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x4c56b216, L"contentCopy", XFA_ELEMENT_ContentCopy, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x4cc176d3, L"dateTimeEdit", XFA_ELEMENT_DateTimeEdit,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x4e1e39b6, L"config", XFA_ELEMENT_Config, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ModelNode},
+    {0x4e2d6083, L"image", XFA_ELEMENT_Image,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+    {0x4e814150, L"#xHTML", XFA_ELEMENT_SharpxHTML,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Config | XFA_XDPPACKET_LocaleSet |
+         XFA_XDPPACKET_ConnectionSet | XFA_XDPPACKET_SourceSet |
+         XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_NodeV},
+    {0x4f2388c1, L"numberOfCopies", XFA_ELEMENT_NumberOfCopies,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0x4f512e30, L"behaviorOverride", XFA_ELEMENT_BehaviorOverride,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0x4fdc3454, L"timeStamp", XFA_ELEMENT_TimeStamp,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x51d90546, L"month", XFA_ELEMENT_Month, XFA_XDPPACKET_LocaleSet,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x523437e4, L"viewerPreferences", XFA_ELEMENT_ViewerPreferences,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+    {0x53abc1c6, L"scriptModel", XFA_ELEMENT_ScriptModel, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x54034c2f, L"decimal", XFA_ELEMENT_Decimal,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+    {0x54202c9e, L"subform", XFA_ELEMENT_Subform,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+    {0x542c7300, L"select", XFA_ELEMENT_Select, XFA_XDPPACKET_SourceSet,
+     XFA_OBJECTTYPE_TextNode},
+    {0x5436d198, L"window", XFA_ELEMENT_Window, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0x5473b6dc, L"localeSet", XFA_ELEMENT_LocaleSet,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_ModelNode},
+    {0x56ae179e, L"handler", XFA_ELEMENT_Handler,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_TextNode},
+    {0x5700bd5f, L"hostPseudoModel", XFA_ELEMENT_HostPseudoModel,
+     XFA_XDPPACKET_XDP, XFA_OBJECTTYPE_OrdinaryObject},
+    {0x570ce835, L"presence", XFA_ELEMENT_Presence, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0x5779d65f, L"record", XFA_ELEMENT_Record, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0x59c8f27d, L"embed", XFA_ELEMENT_Embed, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x5a50e9e6, L"version", XFA_ELEMENT_Version, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x5b8383df, L"command", XFA_ELEMENT_Command, XFA_XDPPACKET_SourceSet,
+     XFA_OBJECTTYPE_Node},
+    {0x5c43c6c3, L"copies", XFA_ELEMENT_Copies, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x5e0c2c49, L"staple", XFA_ELEMENT_Staple, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0x5e5083dd, L"submitFormat", XFA_ELEMENT_SubmitFormat,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0x5e8c5d20, L"boolean", XFA_ELEMENT_Boolean,
+     XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x60490a85, L"message", XFA_ELEMENT_Message,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_Node},
+    {0x60d4c8b1, L"output", XFA_ELEMENT_Output, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0x61810081, L"psMap", XFA_ELEMENT_PsMap, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0x62bd904b, L"excludeNS", XFA_ELEMENT_ExcludeNS, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0x669d4f77, L"assist", XFA_ELEMENT_Assist,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x67334a1c, L"picture", XFA_ELEMENT_Picture,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x67fe7334, L"traversal", XFA_ELEMENT_Traversal,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x6894589c, L"silentPrint", XFA_ELEMENT_SilentPrint, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0x68a16bbd, L"webClient", XFA_ELEMENT_WebClient, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0x69f115df, L"layoutPseudoModel", XFA_ELEMENT_LayoutPseudoModel,
+     XFA_XDPPACKET_XDP, XFA_OBJECTTYPE_OrdinaryObject},
+    {0x6a4bc084, L"producer", XFA_ELEMENT_Producer, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x6a9e04c9, L"corner", XFA_ELEMENT_Corner,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x6ccd7274, L"msgId", XFA_ELEMENT_MsgId, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0x6e67921f, L"color", XFA_ELEMENT_Color,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x6ec217a5, L"keep", XFA_ELEMENT_Keep,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x6eef1116, L"query", XFA_ELEMENT_Query, XFA_XDPPACKET_SourceSet,
+     XFA_OBJECTTYPE_Node},
+    {0x7033bfd5, L"insert", XFA_ELEMENT_Insert, XFA_XDPPACKET_SourceSet,
+     XFA_OBJECTTYPE_TextNode},
+    {0x704af389, L"imageEdit", XFA_ELEMENT_ImageEdit,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x7233018a, L"validate", XFA_ELEMENT_Validate,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x72ba47b4, L"digestMethods", XFA_ELEMENT_DigestMethods,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x72f2aa7a, L"numberPatterns", XFA_ELEMENT_NumberPatterns,
+     XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+    {0x74caed29, L"pageSet", XFA_ELEMENT_PageSet,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+    {0x7568e6ae, L"integer", XFA_ELEMENT_Integer,
+     XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x76182db9, L"soapAddress", XFA_ELEMENT_SoapAddress,
+     XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_TextNode},
+    {0x773146c5, L"equate", XFA_ELEMENT_Equate, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0x77d449dd, L"formFieldFilling", XFA_ELEMENT_FormFieldFilling,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0x7889d68a, L"pageRange", XFA_ELEMENT_PageRange, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x7baca2e3, L"update", XFA_ELEMENT_Update, XFA_XDPPACKET_SourceSet,
+     XFA_OBJECTTYPE_TextNode},
+    {0x7ce89001, L"connectString", XFA_ELEMENT_ConnectString,
+     XFA_XDPPACKET_SourceSet, XFA_OBJECTTYPE_TextNode},
+    {0x7d9fd7c5, L"mode", XFA_ELEMENT_Mode, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x7e7e845e, L"layout", XFA_ELEMENT_Layout, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x7e845c34, L"#xml", XFA_ELEMENT_Sharpxml,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_NodeV},
+    {0x7fb341df, L"xsdConnection", XFA_ELEMENT_XsdConnection,
+     XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_Node},
+    {0x7ffb51cc, L"traverse", XFA_ELEMENT_Traverse,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x80203b5a, L"encodings", XFA_ELEMENT_Encodings,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x803550fc, L"template", XFA_ELEMENT_Template,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_ModelNode},
+    {0x803d5bbc, L"acrobat", XFA_ELEMENT_Acrobat, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0x821d6569, L"validationMessaging", XFA_ELEMENT_ValidationMessaging,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+    {0x830e688f, L"signing", XFA_ELEMENT_Signing,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x83a550d2, L"dataWindow", XFA_ELEMENT_DataWindow, XFA_XDPPACKET_Datasets,
+     XFA_OBJECTTYPE_OrdinaryObject},
+    {0x83dab9f5, L"script", XFA_ELEMENT_Script,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x8411ebcd, L"addViewerPreferences", XFA_ELEMENT_AddViewerPreferences,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0x8777642e, L"alwaysEmbed", XFA_ELEMENT_AlwaysEmbed, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0x877a6b39, L"passwordEdit", XFA_ELEMENT_PasswordEdit,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x87e84c99, L"numericEdit", XFA_ELEMENT_NumericEdit,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x8852cdec, L"encryptionMethod", XFA_ELEMENT_EncryptionMethod,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_NodeC},
+    {0x891f4606, L"change", XFA_ELEMENT_Change, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x89939f36, L"pageArea", XFA_ELEMENT_PageArea,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+    {0x8a9d6247, L"submitUrl", XFA_ELEMENT_SubmitUrl, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0x8ad8b90f, L"oids", XFA_ELEMENT_Oids,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x8b036f32, L"signature", XFA_ELEMENT_Signature,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x8b128efb, L"ADBE_JSConsole", XFA_ELEMENT_ADBE_JSConsole,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0x8bcfe96e, L"caption", XFA_ELEMENT_Caption,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x8e1c2921, L"relevant", XFA_ELEMENT_Relevant, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0x8e3f0a4b, L"flipLabel", XFA_ELEMENT_FlipLabel, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0x900280b7, L"exData", XFA_ELEMENT_ExData,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+    {0x91e80352, L"dayNames", XFA_ELEMENT_DayNames, XFA_XDPPACKET_LocaleSet,
+     XFA_OBJECTTYPE_Node},
+    {0x93113b11, L"soapAction", XFA_ELEMENT_SoapAction,
+     XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_TextNode},
+    {0x938b09f6, L"defaultTypeface", XFA_ELEMENT_DefaultTypeface,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+    {0x95b37897, L"manifest", XFA_ELEMENT_Manifest,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x97b76b54, L"overflow", XFA_ELEMENT_Overflow,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x9a57861b, L"linear", XFA_ELEMENT_Linear,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0x9ad5a821, L"currencySymbol", XFA_ELEMENT_CurrencySymbol,
+     XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_ContentNode},
+    {0x9c6471b3, L"delete", XFA_ELEMENT_Delete, XFA_XDPPACKET_SourceSet,
+     XFA_OBJECTTYPE_TextNode},
+    {0x9deea61d, L"deltas", XFA_ELEMENT_Deltas, XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_OrdinaryObject},
+    {0x9e67de21, L"digestMethod", XFA_ELEMENT_DigestMethod,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_NodeC},
+    {0x9f3e9510, L"instanceManager", XFA_ELEMENT_InstanceManager,
+     XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xa0799892, L"equateRange", XFA_ELEMENT_EquateRange, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0xa084a381, L"medium", XFA_ELEMENT_Medium,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xa1211b8b, L"textEdit", XFA_ELEMENT_TextEdit,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xa17008f0, L"templateCache", XFA_ELEMENT_TemplateCache,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+    {0xa4f7b88f, L"compressObjectStream", XFA_ELEMENT_CompressObjectStream,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0xa65f5d17, L"dataValue", XFA_ELEMENT_DataValue, XFA_XDPPACKET_Datasets,
+     XFA_OBJECTTYPE_Node},
+    {0xa6caaa89, L"accessibleContent", XFA_ELEMENT_AccessibleContent,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0xa8c7d5e2, L"nodeList", XFA_ELEMENT_NodeList, XFA_XDPPACKET_XDP,
+     XFA_OBJECTTYPE_NodeList},
+    {0xa94cc00b, L"includeXDPContent", XFA_ELEMENT_IncludeXDPContent,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0xa9b081a1, L"xmlConnection", XFA_ELEMENT_XmlConnection,
+     XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_Node},
+    {0xab2a3b74, L"validateApprovalSignatures",
+     XFA_ELEMENT_ValidateApprovalSignatures, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0xab8c5a2b, L"signData", XFA_ELEMENT_SignData,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xabaa2ceb, L"packets", XFA_ELEMENT_Packets, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0xadba359c, L"datePattern", XFA_ELEMENT_DatePattern,
+     XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_ContentNode},
+    {0xae222b2b, L"duplexOption", XFA_ELEMENT_DuplexOption,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0xb012effb, L"base", XFA_ELEMENT_Base, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0xb0e5485d, L"bind", XFA_ELEMENT_Bind,
+     XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_Node},
+    {0xb45d61b2, L"compression", XFA_ELEMENT_Compression, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xb563f0ff, L"user", XFA_ELEMENT_User, XFA_XDPPACKET_SourceSet,
+     XFA_OBJECTTYPE_TextNode},
+    {0xb5848ad5, L"rectangle", XFA_ELEMENT_Rectangle,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xb6dacb72, L"effectiveOutputPolicy", XFA_ELEMENT_EffectiveOutputPolicy,
+     XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_Node},
+    {0xb7d7654d, L"ADBE_JSDebugger", XFA_ELEMENT_ADBE_JSDebugger,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0xbab37f73, L"acrobat7", XFA_ELEMENT_Acrobat7, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xbc70081e, L"interactive", XFA_ELEMENT_Interactive, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0xbc8fa350, L"locale", XFA_ELEMENT_Locale,
+     XFA_XDPPACKET_Config | XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+    {0xbcd44940, L"currentPage", XFA_ELEMENT_CurrentPage, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0xbde9abda, L"data", XFA_ELEMENT_Data, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xbde9abde, L"date", XFA_ELEMENT_Date,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+    {0xbe52dfbf, L"desc", XFA_ELEMENT_Desc,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xbf4b6405, L"encrypt", XFA_ELEMENT_Encrypt,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Config | XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_ContentNode},
+    {0xbfa87cce, L"draw", XFA_ELEMENT_Draw,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+    {0xc181ff4b, L"encryption", XFA_ELEMENT_Encryption, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xc1970f40, L"meridiemNames", XFA_ELEMENT_MeridiemNames,
+     XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+    {0xc5ad9f5e, L"messaging", XFA_ELEMENT_Messaging, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xc69549f4, L"speak", XFA_ELEMENT_Speak,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_TextNode},
+    {0xc7743dc7, L"dataGroup", XFA_ELEMENT_DataGroup, XFA_XDPPACKET_Datasets,
+     XFA_OBJECTTYPE_Node},
+    {0xc7eb20e9, L"common", XFA_ELEMENT_Common, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xc85d4528, L"#text", XFA_ELEMENT_Sharptext,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Config | XFA_XDPPACKET_LocaleSet |
+         XFA_XDPPACKET_ConnectionSet | XFA_XDPPACKET_SourceSet |
+         XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_NodeV},
+    {0xc861556a, L"paginationOverride", XFA_ELEMENT_PaginationOverride,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0xc903dabb, L"reasons", XFA_ELEMENT_Reasons,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xc9a8127f, L"signatureProperties", XFA_ELEMENT_SignatureProperties,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xca010c2d, L"threshold", XFA_ELEMENT_Threshold, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0xcb4c5e96, L"appearanceFilter", XFA_ELEMENT_AppearanceFilter,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_NodeC},
+    {0xcc92aba7, L"fill", XFA_ELEMENT_Fill,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xcd308b77, L"font", XFA_ELEMENT_Font,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Config | XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_Node},
+    {0xcd309ff4, L"form", XFA_ELEMENT_Form, XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_ModelNode},
+    {0xcebcca2d, L"mediumInfo", XFA_ELEMENT_MediumInfo, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xcfe0d643, L"certificate", XFA_ELEMENT_Certificate,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_TextNode},
+    {0xd012c033, L"password", XFA_ELEMENT_Password, XFA_XDPPACKET_SourceSet,
+     XFA_OBJECTTYPE_TextNode},
+    {0xd01604bd, L"runScripts", XFA_ELEMENT_RunScripts, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0xd1227e6f, L"trace", XFA_ELEMENT_Trace, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xd1532876, L"float", XFA_ELEMENT_Float,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+    {0xd17a6c30, L"renderPolicy", XFA_ELEMENT_RenderPolicy,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0xd4bf6823, L"logPseudoModel", XFA_ELEMENT_LogPseudoModel,
+     XFA_XDPPACKET_XDP, XFA_OBJECTTYPE_OrdinaryObject},
+    {0xd58aa962, L"destination", XFA_ELEMENT_Destination, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0xd6e27f1d, L"value", XFA_ELEMENT_Value,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xd7a14462, L"bookend", XFA_ELEMENT_Bookend,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xd8c31254, L"exObject", XFA_ELEMENT_ExObject,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xda6a8590, L"openAction", XFA_ELEMENT_OpenAction, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xdab4fb7d, L"neverEmbed", XFA_ELEMENT_NeverEmbed, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0xdb98475f, L"bindItems", XFA_ELEMENT_BindItems,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xdbfbe02e, L"calculate", XFA_ELEMENT_Calculate,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xdd7676ed, L"print", XFA_ELEMENT_Print, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0xdde273d7, L"extras", XFA_ELEMENT_Extras,
+     XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_Node},
+    {0xde146b34, L"proto", XFA_ELEMENT_Proto,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xdf059321, L"dSigData", XFA_ELEMENT_DSigData,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xdfccf030, L"creator", XFA_ELEMENT_Creator, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0xdff78c6a, L"connect", XFA_ELEMENT_Connect,
+     XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form,
+     XFA_OBJECTTYPE_Node},
+    {0xe11a2cbc, L"permissions", XFA_ELEMENT_Permissions, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xe14c801c, L"connectionSet", XFA_ELEMENT_ConnectionSet,
+     XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_ModelNode},
+    {0xe1c83a14, L"submit", XFA_ELEMENT_Submit,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xe29821cd, L"range", XFA_ELEMENT_Range, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0xe38d83c7, L"linearized", XFA_ELEMENT_Linearized, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0xe3aa2578, L"packet", XFA_ELEMENT_Packet, XFA_XDPPACKET_XDP,
+     XFA_OBJECTTYPE_NodeC},
+    {0xe3aa860e, L"rootElement", XFA_ELEMENT_RootElement,
+     XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_TextNode},
+    {0xe3e553fa, L"plaintextMetadata", XFA_ELEMENT_PlaintextMetadata,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0xe3e6e4f2, L"numberSymbols", XFA_ELEMENT_NumberSymbols,
+     XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+    {0xe3f067f6, L"printHighQuality", XFA_ELEMENT_PrintHighQuality,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0xe3fd078c, L"driver", XFA_ELEMENT_Driver, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xe48b34f2, L"incrementalLoad", XFA_ELEMENT_IncrementalLoad,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+    {0xe550e7c2, L"subjectDN", XFA_ELEMENT_SubjectDN,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_NodeC},
+    {0xe6669a78, L"compressLogicalStructure",
+     XFA_ELEMENT_CompressLogicalStructure, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0xe7a7ea02, L"incrementalMerge", XFA_ELEMENT_IncrementalMerge,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0xe948530d, L"radial", XFA_ELEMENT_Radial,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xea8d6999, L"variables", XFA_ELEMENT_Variables,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+    {0xeaa142c0, L"timePatterns", XFA_ELEMENT_TimePatterns,
+     XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+    {0xeb943a71, L"effectiveInputPolicy", XFA_ELEMENT_EffectiveInputPolicy,
+     XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_Node},
+    {0xef04a2bc, L"nameAttr", XFA_ELEMENT_NameAttr, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0xf07222ab, L"conformance", XFA_ELEMENT_Conformance, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0xf0aaaadc, L"transform", XFA_ELEMENT_Transform, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_Node},
+    {0xf1433e88, L"lockDocument", XFA_ELEMENT_LockDocument,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+    {0xf54eb997, L"breakAfter", XFA_ELEMENT_BreakAfter,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xf616da28, L"line", XFA_ELEMENT_Line,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xf616f3dc, L"list", XFA_ELEMENT_List, XFA_XDPPACKET_XDP,
+     XFA_OBJECTTYPE_OrdinaryList},
+    {0xf7055fb1, L"source", XFA_ELEMENT_Source, XFA_XDPPACKET_SourceSet,
+     XFA_OBJECTTYPE_Node},
+    {0xf7eebe1c, L"occur", XFA_ELEMENT_Occur,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+    {0xf8d10d97, L"pickTrayByPDFSize", XFA_ELEMENT_PickTrayByPDFSize,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0xf8f19e3a, L"monthNames", XFA_ELEMENT_MonthNames, XFA_XDPPACKET_LocaleSet,
+     XFA_OBJECTTYPE_Node},
+    {0xf984149b, L"severity", XFA_ELEMENT_Severity, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0xf9bcb037, L"groupParent", XFA_ELEMENT_GroupParent, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_NodeV},
+    {0xfbc42fff, L"documentAssembly", XFA_ELEMENT_DocumentAssembly,
+     XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+    {0xfc78159f, L"numberSymbol", XFA_ELEMENT_NumberSymbol,
+     XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_ContentNode},
+    {0xfcbd606c, L"tagged", XFA_ELEMENT_Tagged, XFA_XDPPACKET_Config,
+     XFA_OBJECTTYPE_ContentNode},
+    {0xff063802, L"items", XFA_ELEMENT_Items,
+     XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+};
+const int32_t g_iXFAElementCount =
+    sizeof(g_XFAElementData) / sizeof(XFA_ELEMENTINFO);
+const XFA_ELEMENTHIERARCHY g_XFAElementPropertyIndex[] = {
+    {0, 8},    {8, 0},   {8, 14},   {22, 0},   {22, 0},   {22, 6},   {28, 0},
+    {28, 0},   {28, 1},  {29, 3},   {32, 0},   {32, 0},   {32, 0},   {32, 3},
+    {35, 1},   {36, 0},  {36, 0},   {36, 2},   {38, 0},   {38, 0},   {38, 0},
+    {38, 4},   {42, 0},  {42, 0},   {42, 1},   {43, 0},   {43, 8},   {51, 19},
+    {70, 0},   {70, 0},  {70, 2},   {72, 1},   {73, 0},   {73, 2},   {75, 4},
+    {79, 1},   {80, 1},  {81, 0},   {81, 0},   {81, 3},   {84, 0},   {84, 4},
+    {88, 4},   {92, 1},  {93, 0},   {93, 4},   {97, 9},   {106, 14}, {120, 0},
+    {120, 0},  {120, 5}, {125, 0},  {125, 1},  {126, 0},  {126, 0},  {126, 0},
+    {126, 0},  {126, 0}, {126, 1},  {127, 0},  {127, 0},  {127, 0},  {127, 0},
+    {127, 0},  {127, 0}, {127, 0},  {127, 6},  {133, 1},  {134, 0},  {134, 1},
+    {135, 0},  {135, 0}, {135, 1},  {136, 2},  {138, 5},  {143, 2},  {145, 0},
+    {145, 0},  {145, 0}, {145, 0},  {145, 0},  {145, 5},  {150, 0},  {150, 0},
+    {150, 0},  {150, 0}, {150, 0},  {150, 0},  {150, 0},  {150, 2},  {152, 0},
+    {152, 0},  {152, 0}, {152, 17}, {169, 0},  {169, 1},  {170, 0},  {170, 0},
+    {170, 2},  {172, 0}, {172, 0},  {172, 1},  {173, 0},  {173, 0},  {173, 2},
+    {175, 2},  {177, 0}, {177, 0},  {177, 0},  {177, 11}, {188, 0},  {188, 0},
+    {188, 0},  {188, 0}, {188, 0},  {188, 4},  {192, 3},  {195, 0},  {195, 0},
+    {195, 0},  {195, 0}, {195, 0},  {195, 0},  {195, 9},  {204, 0},  {204, 0},
+    {204, 17}, {221, 0}, {221, 0},  {221, 0},  {221, 0},  {221, 0},  {221, 0},
+    {221, 0},  {221, 0}, {221, 0},  {221, 4},  {225, 0},  {225, 0},  {225, 0},
+    {225, 0},  {225, 2}, {227, 3},  {230, 0},  {230, 0},  {230, 2},  {232, 0},
+    {232, 1},  {233, 2}, {235, 2},  {237, 0},  {237, 0},  {237, 2},  {239, 0},
+    {239, 1},  {240, 1}, {241, 2},  {243, 0},  {243, 3},  {246, 4},  {250, 0},
+    {250, 1},  {251, 2}, {253, 0},  {253, 0},  {253, 0},  {253, 0},  {253, 0},
+    {253, 0},  {253, 0}, {253, 0},  {253, 0},  {253, 0},  {253, 2},  {255, 2},
+    {257, 0},  {257, 6}, {263, 5},  {268, 0},  {268, 0},  {268, 0},  {268, 3},
+    {271, 0},  {271, 0}, {271, 3},  {274, 4},  {278, 0},  {278, 0},  {278, 4},
+    {282, 0},  {282, 0}, {282, 5},  {287, 0},  {287, 5},  {292, 0},  {292, 0},
+    {292, 0},  {292, 1}, {293, 0},  {293, 0},  {293, 1},  {294, 0},  {294, 2},
+    {296, 0},  {296, 0}, {296, 0},  {296, 0},  {296, 1},  {297, 0},  {297, 0},
+    {297, 4},  {301, 0}, {301, 0},  {301, 0},  {301, 0},  {301, 0},  {301, 0},
+    {301, 1},  {302, 0}, {302, 2},  {304, 0},  {304, 0},  {304, 0},  {304, 0},
+    {304, 1},  {305, 4}, {309, 0},  {309, 3},  {312, 0},  {312, 0},  {312, 1},
+    {313, 0},  {313, 8}, {321, 0},  {321, 10}, {331, 0},  {331, 10}, {341, 1},
+    {342, 12}, {354, 3}, {357, 1},  {358, 0},  {358, 0},  {358, 0},  {358, 8},
+    {366, 0},  {366, 0}, {366, 0},  {366, 0},  {366, 0},  {366, 0},  {366, 7},
+    {373, 2},  {375, 0}, {375, 1},  {376, 0},  {376, 0},  {376, 0},  {376, 0},
+    {376, 0},  {376, 0}, {376, 0},  {376, 0},  {376, 13}, {389, 0},  {389, 1},
+    {390, 1},  {391, 0}, {391, 0},  {391, 3},  {394, 0},  {394, 0},  {394, 0},
+    {394, 0},  {394, 0}, {394, 4},  {398, 9},  {407, 0},  {407, 1},  {408, 0},
+    {408, 0},  {408, 0}, {408, 0},  {408, 0},  {408, 1},  {409, 0},  {409, 2},
+    {411, 0},  {411, 0}, {411, 0},  {411, 0},  {411, 2},  {413, 0},  {413, 1},
+    {414, 0},  {414, 0}, {414, 0},  {414, 7},  {421, 0},  {421, 1},  {422, 1},
+    {423, 0},  {423, 1}, {424, 1},  {425, 0},  {425, 1},  {426, 0},  {426, 0},
+    {426, 0},  {426, 0}, {426, 0},  {426, 0},
+};
+const XFA_PROPERTY g_XFAElementPropertyData[] = {
+    {XFA_ELEMENT_FontInfo, 1, 0},
+    {XFA_ELEMENT_Jog, 1, 0},
+    {XFA_ELEMENT_Xdc, 1, 0},
+    {XFA_ELEMENT_BatchOutput, 1, 0},
+    {XFA_ELEMENT_OutputBin, 1, 0},
+    {XFA_ELEMENT_Compress, 1, 0},
+    {XFA_ELEMENT_Staple, 1, 0},
+    {XFA_ELEMENT_MediumInfo, 1, 0},
+    {XFA_ELEMENT_CheckButton, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_ChoiceList, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_DefaultUi, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Barcode, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Button, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_DateTimeEdit, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Picture, 1, 0},
+    {XFA_ELEMENT_ImageEdit, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_PasswordEdit, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_NumericEdit, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Signature, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_TextEdit, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_ExObject, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Break, 1, 0},
+    {XFA_ELEMENT_Overflow, 1, 0},
+    {XFA_ELEMENT_Desc, 1, 0},
+    {XFA_ELEMENT_Bookend, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Occur, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_SubsetBelow, 1, 0},
+    {XFA_ELEMENT_Map, 1, 0},
+    {XFA_ELEMENT_Embed, 1, 0},
+    {XFA_ELEMENT_Margin, 1, 0},
+    {XFA_ELEMENT_Border, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_DatePattern, 4, 0},
+    {XFA_ELEMENT_Edge, 1, 0},
+    {XFA_ELEMENT_Fill, 1, 0},
+    {XFA_ELEMENT_To, 1, 0},
+    {XFA_ELEMENT_Uri, 1, 0},
+    {XFA_ELEMENT_Mode, 1, 0},
+    {XFA_ELEMENT_Threshold, 1, 0},
+    {XFA_ELEMENT_Script, 1, 0},
+    {XFA_ELEMENT_FontInfo, 1, 0},
+    {XFA_ELEMENT_Jog, 1, 0},
+    {XFA_ELEMENT_Xdc, 1, 0},
+    {XFA_ELEMENT_BatchOutput, 1, 0},
+    {XFA_ELEMENT_PageOffset, 1, 0},
+    {XFA_ELEMENT_OutputBin, 1, 0},
+    {XFA_ELEMENT_Staple, 1, 0},
+    {XFA_ELEMENT_MediumInfo, 1, 0},
+    {XFA_ELEMENT_AdobeExtensionLevel, 1, 0},
+    {XFA_ELEMENT_FontInfo, 1, 0},
+    {XFA_ELEMENT_Xdc, 1, 0},
+    {XFA_ELEMENT_Pdfa, 1, 0},
+    {XFA_ELEMENT_BatchOutput, 1, 0},
+    {XFA_ELEMENT_ViewerPreferences, 1, 0},
+    {XFA_ELEMENT_ScriptModel, 1, 0},
+    {XFA_ELEMENT_Version, 1, 0},
+    {XFA_ELEMENT_SubmitFormat, 1, 0},
+    {XFA_ELEMENT_SilentPrint, 1, 0},
+    {XFA_ELEMENT_Producer, 1, 0},
+    {XFA_ELEMENT_Compression, 1, 0},
+    {XFA_ELEMENT_Interactive, 1, 0},
+    {XFA_ELEMENT_Encryption, 1, 0},
+    {XFA_ELEMENT_RenderPolicy, 1, 0},
+    {XFA_ELEMENT_OpenAction, 1, 0},
+    {XFA_ELEMENT_Creator, 1, 0},
+    {XFA_ELEMENT_Linearized, 1, 0},
+    {XFA_ELEMENT_Tagged, 1, 0},
+    {XFA_ELEMENT_Uri, 1, 0},
+    {XFA_ELEMENT_Xsl, 1, 0},
+    {XFA_ELEMENT_Packets, 1, 0},
+    {XFA_ELEMENT_Uri, 1, 0},
+    {XFA_ELEMENT_Debug, 1, 0},
+    {XFA_ELEMENT_FontInfo, 1, 0},
+    {XFA_ELEMENT_Xdc, 1, 0},
+    {XFA_ELEMENT_BatchOutput, 1, 0},
+    {XFA_ELEMENT_FlipLabel, 1, 0},
+    {XFA_ELEMENT_TemplateCache, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Margin, 1, 0},
+    {XFA_ELEMENT_Border, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_FontInfo, 1, 0},
+    {XFA_ELEMENT_Xdc, 1, 0},
+    {XFA_ELEMENT_BatchOutput, 1, 0},
+    {XFA_ELEMENT_FlipLabel, 1, 0},
+    {XFA_ELEMENT_EraNames, 1, 0},
+    {XFA_ELEMENT_DayNames, 2, 0},
+    {XFA_ELEMENT_MeridiemNames, 1, 0},
+    {XFA_ELEMENT_MonthNames, 2, 0},
+    {XFA_ELEMENT_Hyphenation, 1, 0},
+    {XFA_ELEMENT_Amd, 1, 0},
+    {XFA_ELEMENT_Part, 1, 0},
+    {XFA_ELEMENT_IncludeXDPContent, 1, 0},
+    {XFA_ELEMENT_Conformance, 1, 0},
+    {XFA_ELEMENT_Mdp, 1, 0},
+    {XFA_ELEMENT_Certificates, 1, 0},
+    {XFA_ELEMENT_TimeStamp, 1, 0},
+    {XFA_ELEMENT_Handler, 1, 0},
+    {XFA_ELEMENT_DigestMethods, 1, 0},
+    {XFA_ELEMENT_Encodings, 1, 0},
+    {XFA_ELEMENT_Reasons, 1, 0},
+    {XFA_ELEMENT_AppearanceFilter, 1, 0},
+    {XFA_ELEMENT_LockDocument, 1, 0},
+    {XFA_ELEMENT_Xdp, 1, 0},
+    {XFA_ELEMENT_Cache, 1, 0},
+    {XFA_ELEMENT_Pagination, 1, 0},
+    {XFA_ELEMENT_Overprint, 1, 0},
+    {XFA_ELEMENT_BehaviorOverride, 1, 0},
+    {XFA_ELEMENT_Copies, 1, 0},
+    {XFA_ELEMENT_Output, 1, 0},
+    {XFA_ELEMENT_Validate, 1, 0},
+    {XFA_ELEMENT_Layout, 1, 0},
+    {XFA_ELEMENT_Script, 1, 0},
+    {XFA_ELEMENT_Common, 1, 0},
+    {XFA_ELEMENT_PaginationOverride, 1, 0},
+    {XFA_ELEMENT_Destination, 1, 0},
+    {XFA_ELEMENT_IncrementalMerge, 1, 0},
+    {XFA_ELEMENT_Execute, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Script, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_SignData, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Submit, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_CurrencySymbol, 3, 0},
+    {XFA_ELEMENT_Operation, 1, 0},
+    {XFA_ELEMENT_WsdlAddress, 1, 0},
+    {XFA_ELEMENT_SoapAddress, 1, 0},
+    {XFA_ELEMENT_SoapAction, 1, 0},
+    {XFA_ELEMENT_EffectiveOutputPolicy, 1, 0},
+    {XFA_ELEMENT_EffectiveInputPolicy, 1, 0},
+    {XFA_ELEMENT_Uri, 1, 0},
+    {XFA_ELEMENT_Era, 2, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Picture, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Margin, 1, 0},
+    {XFA_ELEMENT_Edge, 4, 0},
+    {XFA_ELEMENT_Corner, 4, 0},
+    {XFA_ELEMENT_Fill, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Desc, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_KeyUsage, 1, 0},
+    {XFA_ELEMENT_SubjectDNs, 1, 0},
+    {XFA_ELEMENT_Issuers, 1, 0},
+    {XFA_ELEMENT_Signing, 1, 0},
+    {XFA_ELEMENT_Oids, 1, 0},
+    {XFA_ELEMENT_Color, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Ui, 1, 0},
+    {XFA_ELEMENT_Margin, 1, 0},
+    {XFA_ELEMENT_Para, 1, 0},
+    {XFA_ELEMENT_Format, 1, 0},
+    {XFA_ELEMENT_Border, 1, 0},
+    {XFA_ELEMENT_Assist, 1, 0},
+    {XFA_ELEMENT_Traversal, 1, 0},
+    {XFA_ELEMENT_Keep, 1, 0},
+    {XFA_ELEMENT_Validate, 1, 0},
+    {XFA_ELEMENT_Caption, 1, 0},
+    {XFA_ELEMENT_Bind, 1, 0},
+    {XFA_ELEMENT_Desc, 1, 0},
+    {XFA_ELEMENT_Font, 1, 0},
+    {XFA_ELEMENT_Value, 1, 0},
+    {XFA_ELEMENT_Calculate, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Items, 2, 0},
+    {XFA_ELEMENT_Uri, 1, 0},
+    {XFA_ELEMENT_Desc, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Color, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Color, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Margin, 1, 0},
+    {XFA_ELEMENT_Para, 1, 0},
+    {XFA_ELEMENT_Border, 1, 0},
+    {XFA_ELEMENT_Assist, 1, 0},
+    {XFA_ELEMENT_Traversal, 1, 0},
+    {XFA_ELEMENT_Validate, 1, 0},
+    {XFA_ELEMENT_Caption, 1, 0},
+    {XFA_ELEMENT_Bind, 1, 0},
+    {XFA_ELEMENT_Desc, 1, 0},
+    {XFA_ELEMENT_Calculate, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Margin, 1, 0},
+    {XFA_ELEMENT_Border, 1, 0},
+    {XFA_ELEMENT_Comb, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Present, 1, 0},
+    {XFA_ELEMENT_Acrobat, 1, 0},
+    {XFA_ELEMENT_Trace, 1, 0},
+    {XFA_ELEMENT_PrintScaling, 1, 0},
+    {XFA_ELEMENT_Enforce, 1, 0},
+    {XFA_ELEMENT_NumberOfCopies, 1, 0},
+    {XFA_ELEMENT_PageRange, 1, 0},
+    {XFA_ELEMENT_AddViewerPreferences, 1, 0},
+    {XFA_ELEMENT_ADBE_JSConsole, 1, 0},
+    {XFA_ELEMENT_DuplexOption, 1, 0},
+    {XFA_ELEMENT_ADBE_JSDebugger, 1, 0},
+    {XFA_ELEMENT_PickTrayByPDFSize, 1, 0},
+    {XFA_ELEMENT_Break, 1, 0},
+    {XFA_ELEMENT_Margin, 1, 0},
+    {XFA_ELEMENT_Para, 1, 0},
+    {XFA_ELEMENT_Border, 1, 0},
+    {XFA_ELEMENT_Assist, 1, 0},
+    {XFA_ELEMENT_Traversal, 1, 0},
+    {XFA_ELEMENT_Keep, 1, 0},
+    {XFA_ELEMENT_Validate, 1, 0},
+    {XFA_ELEMENT_PageSet, 1, 0},
+    {XFA_ELEMENT_Overflow, 1, 0},
+    {XFA_ELEMENT_Bind, 1, 0},
+    {XFA_ELEMENT_Desc, 1, 0},
+    {XFA_ELEMENT_Bookend, 1, 0},
+    {XFA_ELEMENT_Calculate, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Variables, 1, 0},
+    {XFA_ELEMENT_Occur, 1, 0},
+    {XFA_ELEMENT_Query, 1, 0},
+    {XFA_ELEMENT_Insert, 1, 0},
+    {XFA_ELEMENT_Update, 1, 0},
+    {XFA_ELEMENT_Delete, 1, 0},
+    {XFA_ELEMENT_MsgId, 1, 0},
+    {XFA_ELEMENT_Severity, 1, 0},
+    {XFA_ELEMENT_To, 1, 0},
+    {XFA_ELEMENT_Uri, 1, 0},
+    {XFA_ELEMENT_Type, 1, 0},
+    {XFA_ELEMENT_ToolTip, 1, 0},
+    {XFA_ELEMENT_Speak, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_AddSilentPrint, 1, 0},
+    {XFA_ELEMENT_PrinterName, 1, 0},
+    {XFA_ELEMENT_FontInfo, 1, 0},
+    {XFA_ELEMENT_Xdc, 1, 0},
+    {XFA_ELEMENT_Color, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_RecordSet, 1, 0},
+    {XFA_ELEMENT_Select, 1, 0},
+    {XFA_ELEMENT_Margin, 1, 0},
+    {XFA_ELEMENT_Border, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Message, 1, 0},
+    {XFA_ELEMENT_Picture, 1, 0},
+    {XFA_ELEMENT_Script, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_NumberPattern, 4, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Occur, 1, 0},
+    {XFA_ELEMENT_Uri, 1, 0},
+    {XFA_ELEMENT_RootElement, 1, 0},
+    {XFA_ELEMENT_Script, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Uri, 1, 0},
+    {XFA_ELEMENT_Xsl, 1, 0},
+    {XFA_ELEMENT_StartPage, 1, 0},
+    {XFA_ELEMENT_Relevant, 1, 0},
+    {XFA_ELEMENT_Base, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_AutoSave, 1, 0},
+    {XFA_ELEMENT_Validate, 1, 0},
+    {XFA_ELEMENT_ValidateApprovalSignatures, 1, 0},
+    {XFA_ELEMENT_Acrobat7, 1, 0},
+    {XFA_ELEMENT_Common, 1, 0},
+    {XFA_ELEMENT_Exclude, 1, 0},
+    {XFA_ELEMENT_CurrentPage, 1, 0},
+    {XFA_ELEMENT_RunScripts, 1, 0},
+    {XFA_ELEMENT_Margin, 1, 0},
+    {XFA_ELEMENT_Border, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Margin, 1, 0},
+    {XFA_ELEMENT_Border, 1, 0},
+    {XFA_ELEMENT_Comb, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Medium, 1, 0},
+    {XFA_ELEMENT_Desc, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Occur, 1, 0},
+    {XFA_ELEMENT_Margin, 1, 0},
+    {XFA_ELEMENT_Filter, 1, 0},
+    {XFA_ELEMENT_Border, 1, 0},
+    {XFA_ELEMENT_Manifest, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Margin, 1, 0},
+    {XFA_ELEMENT_Para, 1, 0},
+    {XFA_ELEMENT_Font, 1, 0},
+    {XFA_ELEMENT_Value, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Day, 7, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Color, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Occur, 1, 0},
+    {XFA_ELEMENT_Margin, 1, 0},
+    {XFA_ELEMENT_Border, 1, 0},
+    {XFA_ELEMENT_Comb, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Uri, 1, 0},
+    {XFA_ELEMENT_Filter, 1, 0},
+    {XFA_ELEMENT_Manifest, 1, 0},
+    {XFA_ELEMENT_Picture, 1, 0},
+    {XFA_ELEMENT_Level, 1, 0},
+    {XFA_ELEMENT_Type, 1, 0},
+    {XFA_ELEMENT_CompressObjectStream, 1, 0},
+    {XFA_ELEMENT_CompressLogicalStructure, 1, 0},
+    {XFA_ELEMENT_Edge, 4, 0},
+    {XFA_ELEMENT_Corner, 4, 0},
+    {XFA_ELEMENT_Fill, 1, 0},
+    {XFA_ELEMENT_DynamicRender, 1, 0},
+    {XFA_ELEMENT_DatePatterns, 1, 0},
+    {XFA_ELEMENT_CalendarSymbols, 1, 0},
+    {XFA_ELEMENT_CurrencySymbols, 1, 0},
+    {XFA_ELEMENT_Typefaces, 1, 0},
+    {XFA_ELEMENT_DateTimeSymbols, 1, 0},
+    {XFA_ELEMENT_NumberPatterns, 1, 0},
+    {XFA_ELEMENT_NumberSymbols, 1, 0},
+    {XFA_ELEMENT_TimePatterns, 1, 0},
+    {XFA_ELEMENT_Uri, 1, 0},
+    {XFA_ELEMENT_Xsl, 1, 0},
+    {XFA_ELEMENT_StartNode, 1, 0},
+    {XFA_ELEMENT_OutputXSL, 1, 0},
+    {XFA_ELEMENT_AdjustData, 1, 0},
+    {XFA_ELEMENT_Attributes, 1, 0},
+    {XFA_ELEMENT_Window, 1, 0},
+    {XFA_ELEMENT_Record, 1, 0},
+    {XFA_ELEMENT_Range, 1, 0},
+    {XFA_ELEMENT_IncrementalLoad, 1, 0},
+    {XFA_ELEMENT_Text, 1, 0},
+    {XFA_ELEMENT_Time, 1, 0},
+    {XFA_ELEMENT_DateTime, 1, 0},
+    {XFA_ELEMENT_Image, 1, 0},
+    {XFA_ELEMENT_Decimal, 1, 0},
+    {XFA_ELEMENT_Boolean, 1, 0},
+    {XFA_ELEMENT_Integer, 1, 0},
+    {XFA_ELEMENT_ExData, 1, 0},
+    {XFA_ELEMENT_Date, 1, 0},
+    {XFA_ELEMENT_Float, 1, 0},
+    {XFA_ELEMENT_Certificate, 1, 0},
+    {XFA_ELEMENT_Ui, 1, 0},
+    {XFA_ELEMENT_Margin, 1, 0},
+    {XFA_ELEMENT_Para, 1, 0},
+    {XFA_ELEMENT_Border, 1, 0},
+    {XFA_ELEMENT_Assist, 1, 0},
+    {XFA_ELEMENT_Traversal, 1, 0},
+    {XFA_ELEMENT_Keep, 1, 0},
+    {XFA_ELEMENT_Caption, 1, 0},
+    {XFA_ELEMENT_Desc, 1, 0},
+    {XFA_ELEMENT_Font, 1, 0},
+    {XFA_ELEMENT_Value, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_EncryptionLevel, 1, 0},
+    {XFA_ELEMENT_Encrypt, 1, 0},
+    {XFA_ELEMENT_Permissions, 1, 0},
+    {XFA_ELEMENT_Meridiem, 2, 0},
+    {XFA_ELEMENT_SuppressBanner, 1, 0},
+    {XFA_ELEMENT_VersionControl, 1, 0},
+    {XFA_ELEMENT_LocaleSet, 1, 0},
+    {XFA_ELEMENT_Template, 1, 0},
+    {XFA_ELEMENT_ValidationMessaging, 1, 0},
+    {XFA_ELEMENT_Locale, 1, 0},
+    {XFA_ELEMENT_Data, 1, 0},
+    {XFA_ELEMENT_Messaging, 1, 0},
+    {XFA_ELEMENT_Pattern, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Solid, 1,
+     XFA_PROPERTYFLAG_OneOf | XFA_PROPERTYFLAG_DefaultOneOf},
+    {XFA_ELEMENT_Stipple, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Color, 1, 0},
+    {XFA_ELEMENT_Linear, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Radial, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Fill, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Map, 1, 0},
+    {XFA_ELEMENT_Arc, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Text, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Time, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_DateTime, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Image, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Decimal, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Boolean, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Integer, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_ExData, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Rectangle, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Date, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Float, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Line, 1, XFA_PROPERTYFLAG_OneOf},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Destination, 1, 0},
+    {XFA_ELEMENT_Message, 1, 0},
+    {XFA_ELEMENT_Script, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Picture, 1, 0},
+    {XFA_ELEMENT_ConnectString, 1, 0},
+    {XFA_ELEMENT_User, 1, 0},
+    {XFA_ELEMENT_Password, 1, 0},
+    {XFA_ELEMENT_ModifyAnnots, 1, 0},
+    {XFA_ELEMENT_ContentCopy, 1, 0},
+    {XFA_ELEMENT_FormFieldFilling, 1, 0},
+    {XFA_ELEMENT_Change, 1, 0},
+    {XFA_ELEMENT_AccessibleContent, 1, 0},
+    {XFA_ELEMENT_Print, 1, 0},
+    {XFA_ELEMENT_PlaintextMetadata, 1, 0},
+    {XFA_ELEMENT_PrintHighQuality, 1, 0},
+    {XFA_ELEMENT_DocumentAssembly, 1, 0},
+    {XFA_ELEMENT_Encrypt, 1, 0},
+    {XFA_ELEMENT_NumberSymbol, 5, 0},
+    {XFA_ELEMENT_FontInfo, 1, 0},
+    {XFA_ELEMENT_Xdc, 1, 0},
+    {XFA_ELEMENT_Color, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_TimePattern, 4, 0},
+    {XFA_ELEMENT_Whitespace, 1, 0},
+    {XFA_ELEMENT_Rename, 1, 0},
+    {XFA_ELEMENT_IfEmpty, 1, 0},
+    {XFA_ELEMENT_Presence, 1, 0},
+    {XFA_ELEMENT_Picture, 1, 0},
+    {XFA_ELEMENT_NameAttr, 1, 0},
+    {XFA_ELEMENT_GroupParent, 1, 0},
+    {XFA_ELEMENT_Script, 1, 0},
+    {XFA_ELEMENT_Edge, 1, 0},
+    {XFA_ELEMENT_Connect, 1, 0},
+    {XFA_ELEMENT_Extras, 1, 0},
+    {XFA_ELEMENT_Month, 12, 0},
+};
+const XFA_ELEMENTHIERARCHY g_XFAElementChildrenIndex[] = {
+    {0, 0},   {0, 0},   {0, 0},   {0, 1},    {1, 0},   {1, 4},    {5, 0},
+    {5, 0},   {5, 0},   {5, 3},   {8, 0},    {8, 0},   {8, 0},    {8, 0},
+    {8, 0},   {8, 1},   {9, 0},   {9, 0},    {9, 0},   {9, 0},    {9, 0},
+    {9, 0},   {9, 2},   {11, 0},  {11, 0},   {11, 0},  {11, 0},   {11, 0},
+    {11, 0},  {11, 0},  {11, 0},  {11, 0},   {11, 0},  {11, 0},   {11, 0},
+    {11, 0},  {11, 0},  {11, 0},  {11, 0},   {11, 0},  {11, 0},   {11, 0},
+    {11, 0},  {11, 0},  {11, 0},  {11, 0},   {11, 0},  {11, 8},   {19, 0},
+    {19, 0},  {19, 0},  {19, 0},  {19, 0},   {19, 0},  {19, 0},   {19, 0},
+    {19, 0},  {19, 0},  {19, 0},  {19, 0},   {19, 0},  {19, 0},   {19, 1},
+    {20, 1},  {21, 1},  {22, 0},  {22, 0},   {22, 0},  {22, 0},   {22, 0},
+    {22, 0},  {22, 0},  {22, 0},  {22, 0},   {22, 0},  {22, 7},   {29, 0},
+    {29, 0},  {29, 0},  {29, 0},  {29, 0},   {29, 0},  {29, 1},   {30, 1},
+    {31, 0},  {31, 0},  {31, 0},  {31, 0},   {31, 0},  {31, 0},   {31, 0},
+    {31, 0},  {31, 0},  {31, 4},  {35, 2},   {37, 0},  {37, 0},   {37, 0},
+    {37, 0},  {37, 0},  {37, 0},  {37, 0},   {37, 0},  {37, 0},   {37, 0},
+    {37, 0},  {37, 0},  {37, 0},  {37, 0},   {37, 4},  {41, 0},   {41, 0},
+    {41, 0},  {41, 0},  {41, 0},  {41, 0},   {41, 2},  {43, 0},   {43, 0},
+    {43, 0},  {43, 0},  {43, 0},  {43, 0},   {43, 0},  {43, 0},   {43, 0},
+    {43, 13}, {56, 0},  {56, 0},  {56, 1},   {57, 0},  {57, 0},   {57, 0},
+    {57, 0},  {57, 0},  {57, 0},  {57, 0},   {57, 0},  {57, 0},   {57, 0},
+    {57, 0},  {57, 1},  {58, 0},  {58, 1},   {59, 0},  {59, 0},   {59, 0},
+    {59, 1},  {60, 0},  {60, 0},  {60, 0},   {60, 0},  {60, 0},   {60, 0},
+    {60, 0},  {60, 0},  {60, 1},  {61, 0},   {61, 0},  {61, 0},   {61, 1},
+    {62, 0},  {62, 2},  {64, 0},  {64, 0},   {64, 0},  {64, 0},   {64, 0},
+    {64, 0},  {64, 0},  {64, 0},  {64, 0},   {64, 0},  {64, 0},   {64, 0},
+    {64, 1},  {65, 1},  {66, 1},  {67, 0},   {67, 1},  {68, 0},   {68, 0},
+    {68, 0},  {68, 0},  {68, 0},  {68, 0},   {68, 0},  {68, 0},   {68, 6},
+    {74, 0},  {74, 1},  {75, 0},  {75, 0},   {75, 0},  {75, 0},   {75, 0},
+    {75, 0},  {75, 0},  {75, 0},  {75, 0},   {75, 1},  {76, 0},   {76, 0},
+    {76, 0},  {76, 0},  {76, 0},  {76, 0},   {76, 0},  {76, 0},   {76, 0},
+    {76, 0},  {76, 0},  {76, 0},  {76, 0},   {76, 0},  {76, 0},   {76, 0},
+    {76, 0},  {76, 0},  {76, 0},  {76, 0},   {76, 0},  {76, 0},   {76, 0},
+    {76, 0},  {76, 0},  {76, 0},  {76, 0},   {76, 0},  {76, 0},   {76, 0},
+    {76, 0},  {76, 0},  {76, 0},  {76, 2},   {78, 0},  {78, 0},   {78, 0},
+    {78, 1},  {79, 0},  {79, 0},  {79, 1},   {80, 0},  {80, 0},   {80, 1},
+    {81, 0},  {81, 0},  {81, 1},  {82, 0},   {82, 0},  {82, 0},   {82, 0},
+    {82, 0},  {82, 0},  {82, 0},  {82, 0},   {82, 0},  {82, 0},   {82, 1},
+    {83, 0},  {83, 0},  {83, 0},  {83, 0},   {83, 0},  {83, 0},   {83, 11},
+    {94, 0},  {94, 0},  {94, 0},  {94, 0},   {94, 0},  {94, 11},  {105, 106},
+    {211, 0}, {211, 0}, {211, 1}, {212, 0},  {212, 3}, {215, 1},  {216, 0},
+    {216, 0}, {216, 0}, {216, 0}, {216, 0},  {216, 0}, {216, 0},  {216, 0},
+    {216, 0}, {216, 0}, {216, 0}, {216, 0},  {216, 0}, {216, 12}, {228, 0},
+    {228, 0}, {228, 0}, {228, 0}, {228, 0},  {228, 0}, {228, 0},  {228, 0},
+    {228, 0}, {228, 2}, {230, 0}, {230, 0},  {230, 0}, {230, 0},  {230, 0},
+    {230, 0}, {230, 0}, {230, 0}, {230, 10},
+};
+const FX_WORD g_XFAElementChildrenData[] = {
+    XFA_ELEMENT_Extras,
+    XFA_ELEMENT_SubformSet,
+    XFA_ELEMENT_BreakBefore,
+    XFA_ELEMENT_Subform,
+    XFA_ELEMENT_BreakAfter,
+    XFA_ELEMENT_AlwaysEmbed,
+    XFA_ELEMENT_DefaultTypeface,
+    XFA_ELEMENT_NeverEmbed,
+    XFA_ELEMENT_Source,
+    XFA_ELEMENT_Equate,
+    XFA_ELEMENT_EquateRange,
+    XFA_ELEMENT_Ps,
+    XFA_ELEMENT_Pcl,
+    XFA_ELEMENT_Pdf,
+    XFA_ELEMENT_Zpl,
+    XFA_ELEMENT_LabelPrinter,
+    XFA_ELEMENT_WebClient,
+    XFA_ELEMENT_SubmitUrl,
+    XFA_ELEMENT_Driver,
+    XFA_ELEMENT_Typeface,
+    XFA_ELEMENT_SubjectDN,
+    XFA_ELEMENT_Certificate,
+    XFA_ELEMENT_SubformSet,
+    XFA_ELEMENT_Area,
+    XFA_ELEMENT_Field,
+    XFA_ELEMENT_ExclGroup,
+    XFA_ELEMENT_Subform,
+    XFA_ELEMENT_Draw,
+    XFA_ELEMENT_ExObject,
+    XFA_ELEMENT_EncryptionMethod,
+    XFA_ELEMENT_Ref,
+    XFA_ELEMENT_Event,
+    XFA_ELEMENT_SetProperty,
+    XFA_ELEMENT_BindItems,
+    XFA_ELEMENT_Connect,
+    XFA_ELEMENT_Pdf,
+    XFA_ELEMENT_Destination,
+    XFA_ELEMENT_Event,
+    XFA_ELEMENT_SetProperty,
+    XFA_ELEMENT_Field,
+    XFA_ELEMENT_Connect,
+    XFA_ELEMENT_Agent,
+    XFA_ELEMENT_PsMap,
+    XFA_ELEMENT_SubformSet,
+    XFA_ELEMENT_BreakBefore,
+    XFA_ELEMENT_Event,
+    XFA_ELEMENT_Area,
+    XFA_ELEMENT_SetProperty,
+    XFA_ELEMENT_Field,
+    XFA_ELEMENT_ExclGroup,
+    XFA_ELEMENT_Subform,
+    XFA_ELEMENT_Draw,
+    XFA_ELEMENT_ExObject,
+    XFA_ELEMENT_Proto,
+    XFA_ELEMENT_Connect,
+    XFA_ELEMENT_BreakAfter,
+    XFA_ELEMENT_Locale,
+    XFA_ELEMENT_Text,
+    XFA_ELEMENT_Font,
+    XFA_ELEMENT_Traverse,
+    XFA_ELEMENT_Map,
+    XFA_ELEMENT_DigestMethod,
+    XFA_ELEMENT_PageSet,
+    XFA_ELEMENT_PageArea,
+    XFA_ELEMENT_Encoding,
+    XFA_ELEMENT_Subform,
+    XFA_ELEMENT_SubmitUrl,
+    XFA_ELEMENT_Certificate,
+    XFA_ELEMENT_Area,
+    XFA_ELEMENT_Field,
+    XFA_ELEMENT_ContentArea,
+    XFA_ELEMENT_ExclGroup,
+    XFA_ELEMENT_Subform,
+    XFA_ELEMENT_Draw,
+    XFA_ELEMENT_Oid,
+    XFA_ELEMENT_Ref,
+    XFA_ELEMENT_ExcludeNS,
+    XFA_ELEMENT_Transform,
+    XFA_ELEMENT_SetProperty,
+    XFA_ELEMENT_Message,
+    XFA_ELEMENT_Log,
+    XFA_ELEMENT_Reason,
+    XFA_ELEMENT_Area,
+    XFA_ELEMENT_Text,
+    XFA_ELEMENT_Time,
+    XFA_ELEMENT_DateTime,
+    XFA_ELEMENT_Image,
+    XFA_ELEMENT_Decimal,
+    XFA_ELEMENT_Boolean,
+    XFA_ELEMENT_Integer,
+    XFA_ELEMENT_ExData,
+    XFA_ELEMENT_Date,
+    XFA_ELEMENT_Float,
+    XFA_ELEMENT_ExObject,
+    XFA_ELEMENT_Text,
+    XFA_ELEMENT_Time,
+    XFA_ELEMENT_DateTime,
+    XFA_ELEMENT_Image,
+    XFA_ELEMENT_Decimal,
+    XFA_ELEMENT_Boolean,
+    XFA_ELEMENT_Integer,
+    XFA_ELEMENT_ExData,
+    XFA_ELEMENT_Date,
+    XFA_ELEMENT_Float,
+    XFA_ELEMENT_Extras,
+    XFA_ELEMENT_Ui,
+    XFA_ELEMENT_SubformSet,
+    XFA_ELEMENT_Break,
+    XFA_ELEMENT_CheckButton,
+    XFA_ELEMENT_Arc,
+    XFA_ELEMENT_Mdp,
+    XFA_ELEMENT_BreakBefore,
+    XFA_ELEMENT_Oid,
+    XFA_ELEMENT_Ref,
+    XFA_ELEMENT_Margin,
+    XFA_ELEMENT_KeyUsage,
+    XFA_ELEMENT_ChoiceList,
+    XFA_ELEMENT_Para,
+    XFA_ELEMENT_Filter,
+    XFA_ELEMENT_Encoding,
+    XFA_ELEMENT_Event,
+    XFA_ELEMENT_DefaultUi,
+    XFA_ELEMENT_Barcode,
+    XFA_ELEMENT_SubjectDNs,
+    XFA_ELEMENT_Issuers,
+    XFA_ELEMENT_Button,
+    XFA_ELEMENT_Format,
+    XFA_ELEMENT_Border,
+    XFA_ELEMENT_Area,
+    XFA_ELEMENT_Hyphenation,
+    XFA_ELEMENT_Text,
+    XFA_ELEMENT_Time,
+    XFA_ELEMENT_Certificates,
+    XFA_ELEMENT_SetProperty,
+    XFA_ELEMENT_DateTime,
+    XFA_ELEMENT_Comb,
+    XFA_ELEMENT_Pattern,
+    XFA_ELEMENT_Field,
+    XFA_ELEMENT_ContentArea,
+    XFA_ELEMENT_Solid,
+    XFA_ELEMENT_Edge,
+    XFA_ELEMENT_Stipple,
+    XFA_ELEMENT_ExclGroup,
+    XFA_ELEMENT_ToolTip,
+    XFA_ELEMENT_Reason,
+    XFA_ELEMENT_Execute,
+    XFA_ELEMENT_DateTimeEdit,
+    XFA_ELEMENT_Image,
+    XFA_ELEMENT_TimeStamp,
+    XFA_ELEMENT_Decimal,
+    XFA_ELEMENT_Subform,
+    XFA_ELEMENT_Handler,
+    XFA_ELEMENT_Boolean,
+    XFA_ELEMENT_Message,
+    XFA_ELEMENT_Assist,
+    XFA_ELEMENT_Picture,
+    XFA_ELEMENT_Traversal,
+    XFA_ELEMENT_Corner,
+    XFA_ELEMENT_Color,
+    XFA_ELEMENT_Keep,
+    XFA_ELEMENT_ImageEdit,
+    XFA_ELEMENT_Validate,
+    XFA_ELEMENT_DigestMethods,
+    XFA_ELEMENT_PageSet,
+    XFA_ELEMENT_Integer,
+    XFA_ELEMENT_Traverse,
+    XFA_ELEMENT_Encodings,
+    XFA_ELEMENT_Signing,
+    XFA_ELEMENT_Script,
+    XFA_ELEMENT_PasswordEdit,
+    XFA_ELEMENT_NumericEdit,
+    XFA_ELEMENT_PageArea,
+    XFA_ELEMENT_Oids,
+    XFA_ELEMENT_Signature,
+    XFA_ELEMENT_Caption,
+    XFA_ELEMENT_ExData,
+    XFA_ELEMENT_Manifest,
+    XFA_ELEMENT_Overflow,
+    XFA_ELEMENT_Linear,
+    XFA_ELEMENT_DigestMethod,
+    XFA_ELEMENT_Medium,
+    XFA_ELEMENT_TextEdit,
+    XFA_ELEMENT_SignData,
+    XFA_ELEMENT_Rectangle,
+    XFA_ELEMENT_Date,
+    XFA_ELEMENT_Desc,
+    XFA_ELEMENT_Encrypt,
+    XFA_ELEMENT_Draw,
+    XFA_ELEMENT_Speak,
+    XFA_ELEMENT_Reasons,
+    XFA_ELEMENT_AppearanceFilter,
+    XFA_ELEMENT_Fill,
+    XFA_ELEMENT_Font,
+    XFA_ELEMENT_Certificate,
+    XFA_ELEMENT_Float,
+    XFA_ELEMENT_Value,
+    XFA_ELEMENT_Bookend,
+    XFA_ELEMENT_ExObject,
+    XFA_ELEMENT_BindItems,
+    XFA_ELEMENT_Calculate,
+    XFA_ELEMENT_Extras,
+    XFA_ELEMENT_Connect,
+    XFA_ELEMENT_Submit,
+    XFA_ELEMENT_SubjectDN,
+    XFA_ELEMENT_Radial,
+    XFA_ELEMENT_Variables,
+    XFA_ELEMENT_LockDocument,
+    XFA_ELEMENT_BreakAfter,
+    XFA_ELEMENT_Line,
+    XFA_ELEMENT_Occur,
+    XFA_ELEMENT_Items,
+    XFA_ELEMENT_Extras,
+    XFA_ELEMENT_WsdlConnection,
+    XFA_ELEMENT_XsdConnection,
+    XFA_ELEMENT_XmlConnection,
+    XFA_ELEMENT_SignData,
+    XFA_ELEMENT_Text,
+    XFA_ELEMENT_Time,
+    XFA_ELEMENT_DateTime,
+    XFA_ELEMENT_Image,
+    XFA_ELEMENT_Decimal,
+    XFA_ELEMENT_Boolean,
+    XFA_ELEMENT_Integer,
+    XFA_ELEMENT_Script,
+    XFA_ELEMENT_ExData,
+    XFA_ELEMENT_Manifest,
+    XFA_ELEMENT_Date,
+    XFA_ELEMENT_Float,
+    XFA_ELEMENT_Command,
+    XFA_ELEMENT_Bind,
+    XFA_ELEMENT_Text,
+    XFA_ELEMENT_Time,
+    XFA_ELEMENT_DateTime,
+    XFA_ELEMENT_Image,
+    XFA_ELEMENT_Decimal,
+    XFA_ELEMENT_Boolean,
+    XFA_ELEMENT_Integer,
+    XFA_ELEMENT_ExData,
+    XFA_ELEMENT_Date,
+    XFA_ELEMENT_Float,
+};
+const XFA_ELEMENTHIERARCHY g_XFAElementAttributeIndex[] = {
+    {0, 3},    {3, 2},    {5, 3},    {8, 10},   {18, 2},   {20, 6},   {26, 2},
+    {28, 1},   {29, 13},  {42, 2},   {44, 1},   {45, 2},   {47, 2},   {49, 7},
+    {56, 0},   {56, 4},   {60, 2},   {62, 7},   {69, 0},   {69, 0},   {69, 2},
+    {71, 2},   {73, 8},   {81, 5},   {86, 8},   {94, 4},   {98, 3},   {101, 3},
+    {104, 3},  {107, 6},  {113, 2},  {115, 2},  {117, 2},  {119, 2},  {121, 3},
+    {124, 2},  {126, 7},  {133, 13}, {146, 2},  {148, 6},  {154, 2},  {156, 3},
+    {159, 1},  {160, 17}, {177, 2},  {179, 2},  {181, 6},  {187, 2},  {189, 2},
+    {191, 3},  {194, 7},  {201, 2},  {203, 3},  {206, 0},  {206, 21}, {227, 1},
+    {228, 3},  {231, 2},  {233, 0},  {233, 2},  {235, 2},  {237, 6},  {243, 0},
+    {243, 4},  {247, 4},  {251, 0},  {251, 2},  {253, 2},  {255, 0},  {255, 0},
+    {255, 2},  {257, 2},  {259, 4},  {263, 3},  {266, 7},  {273, 10}, {283, 9},
+    {292, 6},  {298, 4},  {302, 2},  {304, 2},  {306, 6},  {312, 4},  {316, 3},
+    {319, 2},  {321, 2},  {323, 4},  {327, 4},  {331, 4},  {335, 4},  {339, 2},
+    {341, 2},  {343, 2},  {345, 22}, {367, 3},  {370, 2},  {372, 2},  {374, 2},
+    {376, 9},  {385, 0},  {385, 4},  {389, 3},  {392, 0},  {392, 2},  {394, 7},
+    {401, 4},  {405, 2},  {407, 4},  {411, 0},  {411, 21}, {432, 4},  {436, 3},
+    {439, 4},  {443, 6},  {449, 2},  {451, 5},  {456, 2},  {458, 8},  {466, 1},
+    {467, 2},  {469, 2},  {471, 5},  {476, 0},  {476, 2},  {478, 2},  {480, 6},
+    {486, 26}, {512, 4},  {516, 2},  {518, 2},  {520, 4},  {524, 0},  {524, 2},
+    {526, 2},  {528, 2},  {530, 2},  {532, 5},  {537, 2},  {539, 3},  {542, 2},
+    {544, 4},  {548, 5},  {553, 2},  {555, 0},  {555, 2},  {557, 4},  {561, 5},
+    {566, 3},  {569, 2},  {571, 3},  {574, 0},  {574, 2},  {576, 9},  {585, 2},
+    {587, 5},  {592, 6},  {598, 5},  {603, 4},  {607, 4},  {611, 8},  {619, 4},
+    {623, 0},  {623, 7},  {630, 4},  {634, 4},  {638, 5},  {643, 2},  {645, 2},
+    {647, 4},  {651, 4},  {655, 2},  {657, 2},  {659, 1},  {660, 2},  {662, 5},
+    {667, 4},  {671, 3},  {674, 2},  {676, 2},  {678, 4},  {682, 0},  {682, 9},
+    {691, 2},  {693, 2},  {695, 5},  {700, 4},  {704, 3},  {707, 2},  {709, 10},
+    {719, 2},  {721, 4},  {725, 4},  {729, 2},  {731, 6},  {737, 2},  {739, 2},
+    {741, 9},  {750, 1},  {751, 4},  {755, 3},  {758, 5},  {763, 6},  {769, 4},
+    {773, 1},  {774, 4},  {778, 0},  {778, 3},  {781, 1},  {782, 5},  {787, 10},
+    {797, 7},  {804, 3},  {807, 2},  {809, 5},  {814, 2},  {816, 0},  {816, 2},
+    {818, 2},  {820, 2},  {822, 6},  {828, 2},  {830, 1},  {831, 2},  {833, 2},
+    {835, 8},  {843, 2},  {845, 4},  {849, 4},  {853, 4},  {857, 2},  {859, 2},
+    {861, 2},  {863, 3},  {866, 2},  {868, 2},  {870, 4},  {874, 3},  {877, 5},
+    {882, 20}, {902, 2},  {904, 0},  {904, 2},  {906, 6},  {912, 1},  {913, 2},
+    {915, 1},  {916, 2},  {918, 4},  {922, 2},  {924, 2},  {926, 4},  {930, 4},
+    {934, 20}, {954, 1},  {955, 2},  {957, 4},  {961, 4},  {965, 2},  {967, 2},
+    {969, 4},  {973, 2},  {975, 0},  {975, 2},  {977, 5},  {982, 5},  {987, 8},
+    {995, 2},  {997, 2},  {999, 4},  {1003, 4}, {1007, 2}, {1009, 4}, {1013, 0},
+    {1013, 1}, {1014, 2}, {1016, 9}, {1025, 2}, {1027, 0}, {1027, 8}, {1035, 2},
+    {1037, 2}, {1039, 0}, {1039, 4}, {1043, 2}, {1045, 0}, {1045, 2}, {1047, 3},
+    {1050, 2}, {1052, 5}, {1057, 2}, {1059, 2}, {1061, 4}, {1065, 3}, {1068, 0},
+    {1068, 4}, {1072, 2}, {1074, 2}, {1076, 3}, {1079, 4}, {1083, 8}, {1091, 5},
+    {1096, 0}, {1096, 4}, {1100, 6}, {1106, 2}, {1108, 1}, {1109, 2}, {1111, 2},
+    {1113, 2}, {1115, 1}, {1116, 2}, {1118, 7},
+};
+const uint8_t g_XFAElementAttributeData[] = {
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Max,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_EofAction,
+    XFA_ATTRIBUTE_CursorType,
+    XFA_ATTRIBUTE_LockType,
+    XFA_ATTRIBUTE_BofAction,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_CursorLocation,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Relation,
+    XFA_ATTRIBUTE_Relevant,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_BeforeTarget,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_OverflowTarget,
+    XFA_ATTRIBUTE_OverflowLeader,
+    XFA_ATTRIBUTE_OverflowTrailer,
+    XFA_ATTRIBUTE_StartNew,
+    XFA_ATTRIBUTE_BookendTrailer,
+    XFA_ATTRIBUTE_After,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_BookendLeader,
+    XFA_ATTRIBUTE_AfterTarget,
+    XFA_ATTRIBUTE_Before,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_AllowNeutral,
+    XFA_ATTRIBUTE_Mark,
+    XFA_ATTRIBUTE_Shape,
+    XFA_ATTRIBUTE_Size,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_StartAngle,
+    XFA_ATTRIBUTE_SweepAngle,
+    XFA_ATTRIBUTE_Circular,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Hand,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Bind,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_From,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_SignatureType,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Permissions,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_StartNew,
+    XFA_ATTRIBUTE_Trailer,
+    XFA_ATTRIBUTE_TargetType,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Target,
+    XFA_ATTRIBUTE_Leader,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_TimeStamp,
+    XFA_ATTRIBUTE_Uuid,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_LeftInset,
+    XFA_ATTRIBUTE_BottomInset,
+    XFA_ATTRIBUTE_TopInset,
+    XFA_ATTRIBUTE_RightInset,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_NonRepudiation,
+    XFA_ATTRIBUTE_EncipherOnly,
+    XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTE_DigitalSignature,
+    XFA_ATTRIBUTE_CrlSign,
+    XFA_ATTRIBUTE_KeyAgreement,
+    XFA_ATTRIBUTE_KeyEncipherment,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_DataEncipherment,
+    XFA_ATTRIBUTE_KeyCertSign,
+    XFA_ATTRIBUTE_DecipherOnly,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Open,
+    XFA_ATTRIBUTE_CommitOn,
+    XFA_ATTRIBUTE_TextEntry,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_HAlign,
+    XFA_ATTRIBUTE_TextIndent,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Widows,
+    XFA_ATTRIBUTE_MarginRight,
+    XFA_ATTRIBUTE_MarginLeft,
+    XFA_ATTRIBUTE_RadixOffset,
+    XFA_ATTRIBUTE_Preserve,
+    XFA_ATTRIBUTE_SpaceBelow,
+    XFA_ATTRIBUTE_VAlign,
+    XFA_ATTRIBUTE_TabDefault,
+    XFA_ATTRIBUTE_TabStops,
+    XFA_ATTRIBUTE_Orphans,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_LineHeight,
+    XFA_ATTRIBUTE_SpaceAbove,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Version,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_AddRevocationInfo,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Ref,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Listen,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Activity,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_DataRowCount,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_DataPrep,
+    XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTE_TextLocation,
+    XFA_ATTRIBUTE_ModuleWidth,
+    XFA_ATTRIBUTE_PrintCheckDigit,
+    XFA_ATTRIBUTE_ModuleHeight,
+    XFA_ATTRIBUTE_StartChar,
+    XFA_ATTRIBUTE_Truncate,
+    XFA_ATTRIBUTE_WideNarrowRatio,
+    XFA_ATTRIBUTE_ErrorCorrectionLevel,
+    XFA_ATTRIBUTE_UpsMode,
+    XFA_ATTRIBUTE_Checksum,
+    XFA_ATTRIBUTE_CharEncoding,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_DataColumnCount,
+    XFA_ATTRIBUTE_RowColumnRatio,
+    XFA_ATTRIBUTE_DataLength,
+    XFA_ATTRIBUTE_EndChar,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Format,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Output,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Input,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_DataDescription,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Highlight,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Break,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Presence,
+    XFA_ATTRIBUTE_Relevant,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Hand,
+    XFA_ATTRIBUTE_X,
+    XFA_ATTRIBUTE_Y,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Level,
+    XFA_ATTRIBUTE_Relevant,
+    XFA_ATTRIBUTE_ColSpan,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_WordCharacterCount,
+    XFA_ATTRIBUTE_Hyphenate,
+    XFA_ATTRIBUTE_ExcludeInitialCap,
+    XFA_ATTRIBUTE_PushCharacterCount,
+    XFA_ATTRIBUTE_RemainCharacterCount,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_ExcludeAllCaps,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Rid,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_MaxChars,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Url,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_CredentialServerPolicy,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_UrlPolicy,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Ref,
+    XFA_ATTRIBUTE_Connection,
+    XFA_ATTRIBUTE_Target,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_X,
+    XFA_ATTRIBUTE_Y,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_NumberOfCells,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_H,
+    XFA_ATTRIBUTE_W,
+    XFA_ATTRIBUTE_X,
+    XFA_ATTRIBUTE_Y,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_HAlign,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Access,
+    XFA_ATTRIBUTE_Rotate,
+    XFA_ATTRIBUTE_Presence,
+    XFA_ATTRIBUTE_VAlign,
+    XFA_ATTRIBUTE_MaxH,
+    XFA_ATTRIBUTE_MaxW,
+    XFA_ATTRIBUTE_MinH,
+    XFA_ATTRIBUTE_MinW,
+    XFA_ATTRIBUTE_Relevant,
+    XFA_ATTRIBUTE_ColSpan,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Locale,
+    XFA_ATTRIBUTE_AnchorType,
+    XFA_ATTRIBUTE_AccessKey,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_H,
+    XFA_ATTRIBUTE_W,
+    XFA_ATTRIBUTE_X,
+    XFA_ATTRIBUTE_Y,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Relevant,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Cap,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Stroke,
+    XFA_ATTRIBUTE_Presence,
+    XFA_ATTRIBUTE_Thickness,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Rate,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_SourceBelow,
+    XFA_ATTRIBUTE_OutputBelow,
+    XFA_ATTRIBUTE_SourceAbove,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_H,
+    XFA_ATTRIBUTE_W,
+    XFA_ATTRIBUTE_X,
+    XFA_ATTRIBUTE_Y,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_HAlign,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Access,
+    XFA_ATTRIBUTE_Presence,
+    XFA_ATTRIBUTE_VAlign,
+    XFA_ATTRIBUTE_MaxH,
+    XFA_ATTRIBUTE_MaxW,
+    XFA_ATTRIBUTE_MinH,
+    XFA_ATTRIBUTE_MinW,
+    XFA_ATTRIBUTE_Layout,
+    XFA_ATTRIBUTE_Relevant,
+    XFA_ATTRIBUTE_ColSpan,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_AnchorType,
+    XFA_ATTRIBUTE_AccessKey,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Rid,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Scope,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Connection,
+    XFA_ATTRIBUTE_RunAt,
+    XFA_ATTRIBUTE_ExecuteType,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Picker,
+    XFA_ATTRIBUTE_HScrollPolicy,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_ContentType,
+    XFA_ATTRIBUTE_TransferEncoding,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Aspect,
+    XFA_ATTRIBUTE_Href,
+    XFA_ATTRIBUTE_Value,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTE_Server,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_FracDigits,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_LeadDigits,
+    XFA_ATTRIBUTE_H,
+    XFA_ATTRIBUTE_W,
+    XFA_ATTRIBUTE_X,
+    XFA_ATTRIBUTE_Y,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_HAlign,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_AllowMacro,
+    XFA_ATTRIBUTE_ColumnWidths,
+    XFA_ATTRIBUTE_Access,
+    XFA_ATTRIBUTE_Presence,
+    XFA_ATTRIBUTE_VAlign,
+    XFA_ATTRIBUTE_MaxH,
+    XFA_ATTRIBUTE_MaxW,
+    XFA_ATTRIBUTE_MinH,
+    XFA_ATTRIBUTE_MinW,
+    XFA_ATTRIBUTE_Layout,
+    XFA_ATTRIBUTE_Relevant,
+    XFA_ATTRIBUTE_MergeMode,
+    XFA_ATTRIBUTE_ColSpan,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Locale,
+    XFA_ATTRIBUTE_AnchorType,
+    XFA_ATTRIBUTE_RestoreState,
+    XFA_ATTRIBUTE_Scope,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Timeout,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Mode,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Role,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Stroke,
+    XFA_ATTRIBUTE_Presence,
+    XFA_ATTRIBUTE_Inverted,
+    XFA_ATTRIBUTE_Thickness,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Join,
+    XFA_ATTRIBUTE_Radius,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_CSpace,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Value,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Next,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Previous,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Intact,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_CommandType,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Data,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_ScriptTest,
+    XFA_ATTRIBUTE_NullTest,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_FormatTest,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Relation,
+    XFA_ATTRIBUTE_Relevant,
+    XFA_ATTRIBUTE_DuplexImposition,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_To,
+    XFA_ATTRIBUTE_Force,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_From,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Value,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_DataDescription,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Ref,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Operation,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_BaseProfile,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_ContentType,
+    XFA_ATTRIBUTE_RunAt,
+    XFA_ATTRIBUTE_Binding,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_PasswordChar,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_HScrollPolicy,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_HScrollPolicy,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_PagePosition,
+    XFA_ATTRIBUTE_OddOrEven,
+    XFA_ATTRIBUTE_Relevant,
+    XFA_ATTRIBUTE_InitialNumber,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Numbered,
+    XFA_ATTRIBUTE_BlankOrNotBlank,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Reserve,
+    XFA_ATTRIBUTE_Presence,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Placement,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Rid,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_ContentType,
+    XFA_ATTRIBUTE_TransferEncoding,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_MaxLength,
+    XFA_ATTRIBUTE_Href,
+    XFA_ATTRIBUTE_Abbr,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_WritingScript,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Action,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Trailer,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Target,
+    XFA_ATTRIBUTE_Leader,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_To,
+    XFA_ATTRIBUTE_UnicodeRange,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_From,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_TrayOut,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Orientation,
+    XFA_ATTRIBUTE_ImagingBBox,
+    XFA_ATTRIBUTE_Short,
+    XFA_ATTRIBUTE_TrayIn,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Stock,
+    XFA_ATTRIBUTE_Long,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_VScrollPolicy,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_AllowRichText,
+    XFA_ATTRIBUTE_MultiLine,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_HScrollPolicy,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_MaxEntries,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_ContentType,
+    XFA_ATTRIBUTE_Contains,
+    XFA_ATTRIBUTE_Value,
+    XFA_ATTRIBUTE_IsNull,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_DataDescription,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Ref,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Operation,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Target,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Ref,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_ContentType,
+    XFA_ATTRIBUTE_TransferEncoding,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Match,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Hand,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_H,
+    XFA_ATTRIBUTE_W,
+    XFA_ATTRIBUTE_X,
+    XFA_ATTRIBUTE_Y,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_HAlign,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Rotate,
+    XFA_ATTRIBUTE_Presence,
+    XFA_ATTRIBUTE_VAlign,
+    XFA_ATTRIBUTE_MaxH,
+    XFA_ATTRIBUTE_MaxW,
+    XFA_ATTRIBUTE_MinH,
+    XFA_ATTRIBUTE_MinW,
+    XFA_ATTRIBUTE_Relevant,
+    XFA_ATTRIBUTE_ColSpan,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Locale,
+    XFA_ATTRIBUTE_AnchorType,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Rid,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Priority,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Disable,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Value,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Presence,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_LineThrough,
+    XFA_ATTRIBUTE_Typeface,
+    XFA_ATTRIBUTE_FontHorizontalScale,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_KerningMode,
+    XFA_ATTRIBUTE_Underline,
+    XFA_ATTRIBUTE_BaselineShift,
+    XFA_ATTRIBUTE_OverlinePeriod,
+    XFA_ATTRIBUTE_LetterSpacing,
+    XFA_ATTRIBUTE_LineThroughPeriod,
+    XFA_ATTRIBUTE_FontVerticalScale,
+    XFA_ATTRIBUTE_PsName,
+    XFA_ATTRIBUTE_Size,
+    XFA_ATTRIBUTE_Posture,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Weight,
+    XFA_ATTRIBUTE_UnderlinePeriod,
+    XFA_ATTRIBUTE_Overline,
+    XFA_ATTRIBUTE_GenericFamily,
+    XFA_ATTRIBUTE_Checksum,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Relevant,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Override,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Trailer,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Leader,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_CodeType,
+    XFA_ATTRIBUTE_Archive,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_CodeBase,
+    XFA_ATTRIBUTE_ClassId,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Ref,
+    XFA_ATTRIBUTE_Connection,
+    XFA_ATTRIBUTE_LabelRef,
+    XFA_ATTRIBUTE_ValueRef,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Override,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Value,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Ref,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Timeout,
+    XFA_ATTRIBUTE_Connection,
+    XFA_ATTRIBUTE_Usage,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_DelayedOpen,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Format,
+    XFA_ATTRIBUTE_EmbedPDF,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Target,
+    XFA_ATTRIBUTE_TextEncoding,
+    XFA_ATTRIBUTE_XdpContent,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Delimiter,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Ref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_StartNew,
+    XFA_ATTRIBUTE_Trailer,
+    XFA_ATTRIBUTE_TargetType,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Target,
+    XFA_ATTRIBUTE_Leader,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Slope,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Hand,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Max,
+    XFA_ATTRIBUTE_Min,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Initial,
+    XFA_ATTRIBUTE_Usehref,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Abbr,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Desc,
+    XFA_ATTRIBUTE_Lock,
+    XFA_ATTRIBUTE_Id,
+    XFA_ATTRIBUTE_Name,
+    XFA_ATTRIBUTE_Ref,
+    XFA_ATTRIBUTE_Use,
+    XFA_ATTRIBUTE_Presence,
+    XFA_ATTRIBUTE_Save,
+    XFA_ATTRIBUTE_Usehref,
+};
+const XFA_PACKETINFO g_XFAPacketData[] = {
+    {0x0, NULL, XFA_XDPPACKET_USER, NULL,
+     XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTMANY},
+    {0x811929d, L"sourceSet", XFA_XDPPACKET_SourceSet,
+     L"http://www.xfa.org/schema/xfa-source-set/",
+     XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+    {0xb843dba, L"pdf", XFA_XDPPACKET_Pdf, L"http://ns.adobe.com/xdp/pdf/",
+     XFA_XDPPACKET_FLAGS_COMPLETEMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+    {0xc56afbf, L"xdc", XFA_XDPPACKET_Xdc, L"http://www.xfa.org/schema/xdc/",
+     XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+    {0xc56afcc, L"xdp", XFA_XDPPACKET_XDP, L"http://ns.adobe.com/xdp/",
+     XFA_XDPPACKET_FLAGS_COMPLETEMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+    {0x132a8fbc, L"xmpmeta", XFA_XDPPACKET_Xmpmeta,
+     L"http://ns.adobe.com/xmpmeta/",
+     XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTMANY},
+    {0x48d004a8, L"xfdf", XFA_XDPPACKET_Xfdf, L"http://ns.adobe.com/xfdf/",
+     XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+    {0x4e1e39b6, L"config", XFA_XDPPACKET_Config,
+     L"http://www.xfa.org/schema/xci/",
+     XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+    {0x5473b6dc, L"localeSet", XFA_XDPPACKET_LocaleSet,
+     L"http://www.xfa.org/schema/xfa-locale-set/",
+     XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+    {0x6038580a, L"stylesheet", XFA_XDPPACKET_Stylesheet,
+     L"http://www.w3.org/1999/XSL/Transform",
+     XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTMANY},
+    {0x803550fc, L"template", XFA_XDPPACKET_Template,
+     L"http://www.xfa.org/schema/xfa-template/",
+     XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+    {0x8b036f32, L"signature", XFA_XDPPACKET_Signature,
+     L"http://www.w3.org/2000/09/xmldsig#",
+     XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+    {0x99b95079, L"datasets", XFA_XDPPACKET_Datasets,
+     L"http://www.xfa.org/schema/xfa-data/",
+     XFA_XDPPACKET_FLAGS_PREFIXMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+    {0xcd309ff4, L"form", XFA_XDPPACKET_Form,
+     L"http://www.xfa.org/schema/xfa-form/",
+     XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+    {0xe14c801c, L"connectionSet", XFA_XDPPACKET_ConnectionSet,
+     L"http://www.xfa.org/schema/xfa-connection-set/",
+     XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+};
+const int32_t g_iXFAPacketCount =
+    sizeof(g_XFAPacketData) / sizeof(XFA_PACKETINFO);
+const XFA_SCRIPTHIERARCHY g_XFAScriptIndex[] = {
+    {0, 0, 0, 2, 316},      {0, 0, 2, 2, 316},       {0, 0, 4, 2, 316},
+    {0, 0, 6, 8, 316},      {0, 0, 14, 4, 316},      {0, 0, 18, 5, 317},
+    {0, 0, 23, 2, 316},     {0, 0, 25, 1, 316},      {0, 0, 26, 12, 316},
+    {0, 0, 38, 2, 316},     {0, 0, 40, 1, 316},      {0, 0, 41, 3, 316},
+    {0, 0, 44, 2, 316},     {0, 0, 46, 6, 316},      {0, 0, 52, 0, 316},
+    {0, 0, 52, 2, 319},     {0, 0, 54, 2, 316},      {0, 0, 56, 6, 316},
+    {0, 0, 62, 0, 316},     {0, 0, 62, 0, 316},      {0, 0, 62, 2, 316},
+    {0, 0, 64, 2, 316},     {0, 0, 66, 6, 316},      {0, 0, 72, 4, 316},
+    {0, 0, 76, 7, 316},     {0, 0, 83, 2, 320},      {0, 0, 85, 3, 316},
+    {0, 0, 88, 3, 316},     {0, 0, 91, 2, 320},      {0, 0, 93, 6, 320},
+    {0, 0, 99, 4, 316},     {0, 0, 103, 2, 316},     {0, 0, 105, 3, 319},
+    {0, 0, 108, 4, 316},    {0, 0, 112, 3, 316},     {0, 0, 115, 2, 316},
+    {0, 0, 117, 6, 316},    {0, 0, 123, 12, 316},    {0, 0, 135, 2, 316},
+    {0, 0, 137, 5, 316},    {0, 0, 142, 2, 316},     {0, 0, 144, 3, 316},
+    {0, 0, 147, 1, 316},    {0, 0, 148, 14, 316},    {0, 0, 162, 2, 316},
+    {0, 0, 164, 2, 316},    {0, 0, 166, 3, 316},     {0, 0, 169, 2, 316},
+    {0, 0, 171, 2, 316},    {0, 0, 173, 2, 316},     {0, 0, 175, 4, 316},
+    {0, 0, 179, 2, 316},    {0, 0, 181, 2, 316},     {0, 0, 183, 0, 319},
+    {0, 0, 183, 20, 316},   {0, 0, 203, 1, 316},     {0, 0, 204, 3, 316},
+    {0, 0, 207, 2, 316},    {0, 0, 209, 0, 316},     {0, 0, 209, 2, 316},
+    {0, 0, 211, 2, 316},    {0, 0, 213, 4, 320},     {0, 0, 217, 0, 316},
+    {0, 0, 217, 1, 316},    {0, 0, 218, 3, 316},     {0, 4, 221, 0, 312},
+    {4, 1, 221, 1, 316},    {5, 0, 222, 2, 316},     {5, 1, 224, 3, -1},
+    {6, 0, 227, 0, 316},    {6, 0, 227, 2, 316},     {6, 0, 229, 2, 316},
+    {6, 0, 231, 3, 316},    {6, 0, 234, 2, 316},     {6, 0, 236, 6, 316},
+    {6, 0, 242, 10, 317},   {6, 0, 252, 9, 316},     {6, 0, 261, 5, 318},
+    {6, 0, 266, 4, 318},    {6, 0, 270, 2, 316},     {6, 0, 272, 2, 316},
+    {6, 0, 274, 5, 316},    {6, 0, 279, 3, 316},     {6, 0, 282, 2, 316},
+    {6, 0, 284, 2, 316},    {6, 0, 286, 2, 316},     {6, 0, 288, 2, 316},
+    {6, 0, 290, 4, 316},    {6, 0, 294, 3, 316},     {6, 0, 297, 3, 316},
+    {6, 0, 300, 2, 316},    {6, 0, 302, 2, 316},     {6, 0, 304, 2, 316},
+    {6, 13, 306, 36, 317},  {19, 0, 342, 3, 316},    {19, 0, 345, 2, 316},
+    {19, 0, 347, 2, 316},   {19, 0, 349, 2, 316},    {19, 0, 351, 7, 317},
+    {19, 2, 358, 16, 312},  {21, 0, 374, 2, 320},    {21, 0, 376, 2, 316},
+    {21, 0, 378, 0, 316},   {21, 0, 378, 2, 316},    {21, 0, 380, 6, 316},
+    {21, 0, 386, 3, 316},   {21, 0, 389, 2, 316},    {21, 0, 391, 4, 316},
+    {21, 0, 395, 0, 316},   {21, 5, 395, 30, 316},   {26, 0, 425, 2, 320},
+    {26, 0, 427, 3, 316},   {26, 0, 430, 2, 320},    {26, 0, 432, 5, 316},
+    {26, 0, 437, 2, 316},   {26, 0, 439, 3, 316},    {26, 0, 442, 2, 316},
+    {26, 0, 444, 8, 316},   {26, 0, 452, 1, 316},    {26, 0, 453, 2, 316},
+    {26, 0, 455, 2, 316},   {26, 0, 457, 4, 316},    {26, 0, 461, 0, 316},
+    {26, 0, 461, 2, 316},   {26, 0, 463, 2, 316},    {26, 0, 465, 6, 318},
+    {26, 5, 471, 31, 317},  {31, 0, 502, 2, 320},    {31, 0, 504, 2, 316},
+    {31, 0, 506, 2, 316},   {31, 0, 508, 4, 320},    {31, 16, 512, 14, 312},
+    {47, 0, 526, 2, 316},   {47, 0, 528, 2, 316},    {47, 0, 530, 2, 316},
+    {47, 0, 532, 2, 316},   {47, 0, 534, 3, 316},    {47, 0, 537, 2, 316},
+    {47, 0, 539, 3, 316},   {47, 0, 542, 3, 316},    {47, 0, 545, 4, 318},
+    {47, 0, 549, 4, 316},   {47, 0, 553, 2, 316},    {47, 0, 555, 0, 316},
+    {47, 0, 555, 2, 316},   {47, 0, 557, 3, 316},    {47, 0, 560, 6, 316},
+    {47, 0, 566, 2, 316},   {47, 0, 568, 2, 316},    {47, 0, 570, 3, 316},
+    {47, 19, 573, 1, 312},  {66, 0, 574, 2, 316},    {66, 0, 576, 8, 316},
+    {66, 0, 584, 2, 316},   {66, 0, 586, 4, 316},    {66, 0, 590, 5, 316},
+    {66, 0, 595, 3, 316},   {66, 0, 598, 2, 320},    {66, 0, 600, 3, 316},
+    {66, 0, 603, 7, 316},   {66, 0, 610, 3, 316},    {66, 0, 613, 0, 316},
+    {66, 0, 613, 4, 317},   {66, 0, 617, 4, 318},    {66, 0, 621, 2, 320},
+    {66, 0, 623, 5, 316},   {66, 0, 628, 2, 316},    {66, 0, 630, 2, 316},
+    {66, 0, 632, 2, 320},   {66, 0, 634, 2, 320},    {66, 0, 636, 4, 316},
+    {66, 0, 640, 2, 316},   {66, 0, 642, 1, 316},    {66, 0, 643, 1, 316},
+    {66, 0, 644, 4, 316},   {66, 0, 648, 3, 316},    {66, 7, 651, 2, 319},
+    {73, 0, 653, 2, 316},   {73, 0, 655, 2, 316},    {73, 0, 657, 3, 316},
+    {73, 4, 660, 4, 312},   {77, 0, 664, 10, 316},   {77, 0, 674, 2, 316},
+    {77, 0, 676, 4, 316},   {77, 0, 680, 4, 316},    {77, 0, 684, 3, 316},
+    {77, 0, 687, 2, 316},   {77, 0, 689, 2, 316},    {77, 0, 691, 8, 317},
+    {77, 0, 699, 3, 316},   {77, 0, 702, 3, 316},    {77, 0, 705, 2, 316},
+    {77, 0, 707, 2, 316},   {77, 0, 709, 5, 316},    {77, 0, 714, 4, 316},
+    {77, 0, 718, 2, 316},   {77, 0, 720, 8, 318},    {77, 0, 728, 1, 316},
+    {77, 0, 729, 2, 320},   {77, 0, 731, 3, 316},    {77, 1, 734, 4, 316},
+    {78, 0, 738, 5, 316},   {78, 0, 743, 3, 316},    {78, 0, 746, 1, 316},
+    {78, 0, 747, 2, 320},   {78, 0, 749, 0, 313},    {78, 0, 749, 2, 316},
+    {78, 5, 751, 3, 316},   {83, 0, 754, 5, 316},    {83, 0, 759, 7, 316},
+    {83, 0, 766, 6, 316},   {83, 0, 772, 3, 316},    {83, 0, 775, 2, 316},
+    {83, 0, 777, 5, 316},   {83, 0, 782, 2, 316},    {83, 0, 784, 0, 314},
+    {83, 0, 784, 2, 316},   {83, 0, 786, 1, 316},    {83, 0, 787, 2, 316},
+    {83, 0, 789, 5, 316},   {83, 0, 794, 2, 316},    {83, 0, 796, 1, 316},
+    {83, 0, 797, 2, 316},   {83, 0, 799, 2, 316},    {83, 0, 801, 6, 316},
+    {83, 0, 807, 2, 316},   {83, 0, 809, 2, 320},    {83, 0, 811, 3, 316},
+    {83, 0, 814, 4, 316},   {83, 0, 818, 2, 316},    {83, 0, 820, 2, 316},
+    {83, 0, 822, 2, 316},   {83, 0, 824, 2, 316},    {83, 0, 826, 2, 316},
+    {83, 0, 828, 2, 316},   {83, 0, 830, 4, 318},    {83, 1, 834, 2, 316},
+    {84, 0, 836, 5, 316},   {84, 0, 841, 20, 317},   {84, 0, 861, 2, 316},
+    {84, 0, 863, 0, 316},   {84, 0, 863, 2, 316},    {84, 0, 865, 4, 320},
+    {84, 0, 869, 0, 316},   {84, 0, 869, 2, 316},    {84, 0, 871, 1, 316},
+    {84, 0, 872, 2, 316},   {84, 0, 874, 3, 316},    {84, 0, 877, 2, 316},
+    {84, 0, 879, 2, 316},   {84, 0, 881, 4, 316},    {84, 0, 885, 3, 316},
+    {84, 0, 888, 17, 316},  {84, 6, 905, 1, 319},    {90, 0, 906, 2, 316},
+    {90, 0, 908, 2, 320},   {90, 0, 910, 2, 320},    {90, 0, 912, 2, 316},
+    {90, 0, 914, 2, 316},   {90, 0, 916, 4, 318},    {90, 0, 920, 2, 316},
+    {90, 5, 922, 0, 312},   {95, 0, 922, 2, 316},    {95, 0, 924, 4, 316},
+    {95, 0, 928, 4, 316},   {95, 0, 932, 6, 316},    {95, 0, 938, 2, 316},
+    {95, 0, 940, 4, 316},   {95, 0, 944, 3, 316},    {95, 0, 947, 3, 316},
+    {95, 0, 950, 2, 316},   {95, 0, 952, 3, 316},    {95, 0, 955, 0, 316},
+    {95, 0, 955, 0, 316},   {95, 0, 955, 2, 316},    {95, 0, 957, 7, 316},
+    {95, 0, 964, 2, 316},   {95, 0, 966, 0, 319},    {95, 0, 966, 7, 316},
+    {95, 0, 973, 2, 316},   {95, 0, 975, 2, 316},    {95, 3, 977, 1, 316},
+    {98, 0, 978, 2, 320},   {98, 0, 980, 4, 316},    {98, 0, 984, 0, 316},
+    {98, 0, 984, 2, 316},   {98, 0, 986, 2, 316},    {98, 0, 988, 4, 316},
+    {98, 0, 992, 1, 316},   {98, 0, 993, 2, 316},    {98, 0, 995, 2, 316},
+    {98, 0, 997, 3, 316},   {98, 0, 1000, 2, 317},   {98, 0, 1002, 0, 316},
+    {98, 0, 1002, 4, 316},  {98, 0, 1006, 4, 316},   {98, 0, 1010, 2, 316},
+    {98, 0, 1012, 3, 316},  {98, 0, 1015, 4, 316},   {98, 0, 1019, 7, 316},
+    {98, 0, 1026, 4, 316},  {98, 0, 1030, 1, 313},   {98, 17, 1031, 3, 316},
+    {115, 0, 1034, 5, 316}, {115, 0, 1039, 2, 316},  {115, 0, 1041, 1, 316},
+    {115, 0, 1042, 4, 316}, {115, 0, 1046, 2, 316},  {115, 0, 1048, 2, 316},
+    {115, 0, 1050, 1, 316}, {115, 0, 1051, 2, 316},  {115, 0, 1053, 5, 316},
+    {115, 0, 1058, 1, -1},  {115, 4, 1059, 1, 312},  {119, 1, 1060, 0, 313},
+    {120, 2, 1060, 8, 312}, {122, 11, 1068, 6, 315}, {133, 2, 1074, 0, 316},
+    {135, 0, 1074, 0, 316}, {135, 3, 1074, 2, 316},  {138, 0, 1076, 2, 316},
+};
+const XFA_METHODINFO g_SomMethodData[] = {
+    {0x3c752495, L"verify", (XFA_METHOD_CALLBACK)&CScript_SignaturePseudoModel::
+                                Script_SignaturePseudoModel_Verify},
+    {0xa68635f1, L"sign", (XFA_METHOD_CALLBACK)&CScript_SignaturePseudoModel::
+                              Script_SignaturePseudoModel_Sign},
+    {0xa7f2c5e6, L"enumerate",
+     (XFA_METHOD_CALLBACK)&CScript_SignaturePseudoModel::
+         Script_SignaturePseudoModel_Enumerate},
+    {0xd8ed1467, L"clear", (XFA_METHOD_CALLBACK)&CScript_SignaturePseudoModel::
+                               Script_SignaturePseudoModel_Clear},
+    {0x4bdcce13, L"execute",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_WsdlConnection_Execute},
+    {0x1c296ba4, L"restore",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Delta_Restore},
+    {0x7d123a9, L"clearItems",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_ClearItems},
+    {0xfb0b007, L"execEvent",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_ExecEvent},
+    {0x6716ce97, L"execInitialize",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_ExecInitialize},
+    {0x7bb919c2, L"deleteItem",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_DeleteItem},
+    {0x9f053d5e, L"getSaveItem",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_GetSaveItem},
+    {0xbbd32747, L"boundItem",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_BoundItem},
+    {0xc492d950, L"getItemState",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_GetItemState},
+    {0xc6013cd3, L"execCalculate",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_ExecCalculate},
+    {0xd8930d0e, L"setItems",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_SetItems},
+    {0xe0f15045, L"getDisplayItem",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_GetDisplayItem},
+    {0xe23acddc, L"setItemState",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_SetItemState},
+    {0xe2dfb2f8, L"addItem",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_AddItem},
+    {0xef8ce48f, L"execValidate",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_ExecValidate},
+    {0x461079ef, L"emit", (XFA_METHOD_CALLBACK)&CScript_EventPseudoModel::
+                              Script_EventPseudoModel_Emit},
+    {0xfec90c63, L"reset", (XFA_METHOD_CALLBACK)&CScript_EventPseudoModel::
+                               Script_EventPseudoModel_Reset},
+    {0xfb0b007, L"execEvent",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ExclGroup_ExecEvent},
+    {0x3d832221, L"selectedMember",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ExclGroup_SelectedMember},
+    {0x6716ce97, L"execInitialize",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ExclGroup_ExecInitialize},
+    {0xc6013cd3, L"execCalculate",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ExclGroup_ExecCalculate},
+    {0xef8ce48f, L"execValidate",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ExclGroup_ExecValidate},
+    {0xfb0b007, L"execEvent",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Subform_ExecEvent},
+    {0x6716ce97, L"execInitialize",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Subform_ExecInitialize},
+    {0xc6013cd3, L"execCalculate",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Subform_ExecCalculate},
+    {0xd9b9b1f1, L"getInvalidObjects",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Subform_GetInvalidObjects},
+    {0xef8ce48f, L"execValidate",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Subform_ExecValidate},
+    {0xa366b7c, L"exportData", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::
+                                   Script_HostPseudoModel_ExportData},
+    {0x16cc226c, L"gotoURL", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::
+                                 Script_HostPseudoModel_GotoURL},
+    {0x1e0722f5, L"pageDown", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::
+                                  Script_HostPseudoModel_PageDown},
+    {0x3e66cb2c, L"setFocus", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::
+                                  Script_HostPseudoModel_SetFocus},
+    {0x4ac9faae, L"openList", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::
+                                  Script_HostPseudoModel_OpenList},
+    {0x7b89714f, L"response", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::
+                                  Script_HostPseudoModel_Response},
+    {0x7fd9fd58, L"documentInBatch",
+     (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::
+         Script_HostPseudoModel_DocumentInBatch},
+    {0xaf1d019d, L"resetData", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::
+                                   Script_HostPseudoModel_ResetData},
+    {0xb07be13c, L"beep", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::
+                              Script_HostPseudoModel_Beep},
+    {0xb1882ca0, L"getFocus", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::
+                                  Script_HostPseudoModel_GetFocus},
+    {0xbf4ba9ee, L"messageBox", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::
+                                    Script_HostPseudoModel_MessageBox},
+    {0xd6d4dbc1, L"documentCountInBatch",
+     (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::
+         Script_HostPseudoModel_DocumentCountInBatch},
+    {0xdd7676ed, L"print", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::
+                               Script_HostPseudoModel_Print},
+    {0xe2f863d0, L"currentDateTime",
+     (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::
+         Script_HostPseudoModel_CurrentDateTime},
+    {0xf995d0f5, L"importData", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::
+                                    Script_HostPseudoModel_ImportData},
+    {0xfeb96b62, L"pageUp", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::
+                                Script_HostPseudoModel_PageUp},
+    {0x68, L"h", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+                     Script_LayoutPseudoModel_H},
+    {0x77, L"w", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+                     Script_LayoutPseudoModel_W},
+    {0x78, L"x", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+                     Script_LayoutPseudoModel_X},
+    {0x79, L"y", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+                     Script_LayoutPseudoModel_Y},
+    {0x5460206, L"pageCount", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+                                  Script_LayoutPseudoModel_PageCount},
+    {0x5eb5b0f, L"pageSpan", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+                                 Script_LayoutPseudoModel_PageSpan},
+    {0x10f1b1bd, L"page", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+                              Script_LayoutPseudoModel_Page},
+    {0x1c1e6318, L"pageContent",
+     (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+         Script_LayoutPseudoModel_PageContent},
+    {0x1c1f4a5c, L"absPageCount",
+     (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+         Script_LayoutPseudoModel_AbsPageCount},
+    {0x1ec47db5, L"absPageCountInBatch",
+     (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+         Script_LayoutPseudoModel_AbsPageCountInBatch},
+    {0x2e4ecbdb, L"sheetCountInBatch",
+     (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+         Script_LayoutPseudoModel_SheetCountInBatch},
+    {0x2fcff4b5, L"relayout", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+                                  Script_LayoutPseudoModel_Relayout},
+    {0x3bf1c2a5, L"absPageSpan",
+     (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+         Script_LayoutPseudoModel_AbsPageSpan},
+    {0x5775c2cc, L"absPageInBatch",
+     (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+         Script_LayoutPseudoModel_AbsPageInBatch},
+    {0x8c5feb32, L"sheetInBatch",
+     (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+         Script_LayoutPseudoModel_SheetInBatch},
+    {0x8f3a8379, L"sheet", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+                               Script_LayoutPseudoModel_Sheet},
+    {0x96f3c4cb, L"relayoutPageArea",
+     (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+         Script_LayoutPseudoModel_RelayoutPageArea},
+    {0xd2a4a542, L"sheetCount",
+     (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+         Script_LayoutPseudoModel_SheetCount},
+    {0xe74f0653, L"absPage", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::
+                                 Script_LayoutPseudoModel_AbsPage},
+    {0x44c352ad, L"formNodes",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Template_FormNodes},
+    {0x45efb847, L"remerge",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Template_Remerge},
+    {0x6716ce97, L"execInitialize",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Template_ExecInitialize},
+    {0x712c6afa, L"createNode",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Template_CreateNode},
+    {0xa8a35e25, L"recalculate",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Template_Recalculate},
+    {0xc6013cd3, L"execCalculate",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Template_ExecCalculate},
+    {0xef8ce48f, L"execValidate",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Template_ExecValidate},
+    {0x4cc1c0f9, L"moveCurrentRecord",
+     (XFA_METHOD_CALLBACK)&CScript_DataWindow::
+         Script_DataWindow_MoveCurrentRecord},
+    {0x5779d65f, L"record",
+     (XFA_METHOD_CALLBACK)&CScript_DataWindow::Script_DataWindow_Record},
+    {0x8a476498, L"gotoRecord",
+     (XFA_METHOD_CALLBACK)&CScript_DataWindow::Script_DataWindow_GotoRecord},
+    {0xaac241c8, L"isRecordGroup",
+     (XFA_METHOD_CALLBACK)&CScript_DataWindow::Script_DataWindow_IsRecordGroup},
+    {0x1c6f4277, L"evaluate",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Manifest_Evaluate},
+    {0x2afec2cc, L"moveInstance",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_InstanceManager_MoveInstance},
+    {0x2bf94a63, L"removeInstance",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_InstanceManager_RemoveInstance},
+    {0x303adaf4, L"setInstances",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_InstanceManager_SetInstances},
+    {0x4d76b89e, L"addInstance",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_InstanceManager_AddInstance},
+    {0xc660dc8a, L"insertInstance",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_InstanceManager_InsertInstance},
+    {0xddfd1ea1, L"metadata",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Desc_Metadata},
+    {0x44c352ad, L"formNodes",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Form_FormNodes},
+    {0x45efb847, L"remerge",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Form_Remerge},
+    {0x6716ce97, L"execInitialize",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Form_ExecInitialize},
+    {0xa8a35e25, L"recalculate",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Form_Recalculate},
+    {0xc6013cd3, L"execCalculate",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Form_ExecCalculate},
+    {0xef8ce48f, L"execValidate",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Form_ExecValidate},
+    {0x60490a85, L"message", (XFA_METHOD_CALLBACK)&CScript_LogPseudoModel::
+                                 Script_LogPseudoModel_Message},
+    {0x60ecfcc9, L"traceDeactivate",
+     (XFA_METHOD_CALLBACK)&CScript_LogPseudoModel::
+         Script_LogPseudoModel_TraceDeactivate},
+    {0x86a0f4c0, L"traceActivate",
+     (XFA_METHOD_CALLBACK)&CScript_LogPseudoModel::
+         Script_LogPseudoModel_TraceActivate},
+    {0x93eac39a, L"traceEnabled", (XFA_METHOD_CALLBACK)&CScript_LogPseudoModel::
+                                      Script_LogPseudoModel_TraceEnabled},
+    {0xd1227e6f, L"trace",
+     (XFA_METHOD_CALLBACK)&CScript_LogPseudoModel::Script_LogPseudoModel_Trace},
+    {0x36c0ee14, L"getAttribute",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Packet_GetAttribute},
+    {0x5468e2a0, L"setAttribute",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Packet_SetAttribute},
+    {0xadc48de2, L"removeAttribute",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Packet_RemoveAttribute},
+    {0x3848b3f, L"next", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Next},
+    {0x14e25bc8, L"cancelBatch",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_CancelBatch},
+    {0x3ce05d68, L"first",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_First},
+    {0x649e1e65, L"updateBatch",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_UpdateBatch},
+    {0x6a3405dd, L"previous",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Previous},
+    {0x74818fb3, L"isBOF",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_IsBOF},
+    {0x74d07a76, L"isEOF",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_IsEOF},
+    {0x7613cb66, L"cancel",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Cancel},
+    {0x7baca2e3, L"update",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Update},
+    {0x8b90e1f2, L"open", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Open},
+    {0x9c6471b3, L"delete",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Delete},
+    {0xa7315093, L"addNew",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_AddNew},
+    {0xa7ce5f8d, L"requery",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Requery},
+    {0xc7368674, L"resync",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Resync},
+    {0xd9f47f36, L"close",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Close},
+    {0xf54481d4, L"last", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Last},
+    {0xf7965460, L"hasDataChanged",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_HasDataChanged},
+    {0x6275f6af, L"item",
+     (XFA_METHOD_CALLBACK)&CXFA_NodeList::Script_ListClass_Item},
+    {0x7033bfd5, L"insert",
+     (XFA_METHOD_CALLBACK)&CXFA_NodeList::Script_ListClass_Insert},
+    {0x9cab7cae, L"remove",
+     (XFA_METHOD_CALLBACK)&CXFA_NodeList::Script_ListClass_Remove},
+    {0xda12e518, L"append",
+     (XFA_METHOD_CALLBACK)&CXFA_NodeList::Script_ListClass_Append},
+    {0xd892a054, L"namedItem",
+     (XFA_METHOD_CALLBACK)&CXFA_NodeList::Script_TreelistClass_NamedItem},
+    {0xba2dd386, L"resolveNode",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_TreeClass_ResolveNode},
+    {0xe509e2b9, L"resolveNodes",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_TreeClass_ResolveNodes},
+    {0x1bca1ebd, L"applyXSL",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_ApplyXSL},
+    {0x36c0ee14, L"getAttribute",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_GetAttribute},
+    {0x5468e2a0, L"setAttribute",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_SetAttribute},
+    {0x5ee00996, L"setElement",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_SetElement},
+    {0x92dada4f, L"saveFilteredXML",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_SaveFilteredXML},
+    {0x9c456500, L"saveXML",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_SaveXML},
+    {0xabd3200a, L"getElement",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_GetElement},
+    {0xb269c60d, L"isPropertySpecified",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_IsPropertySpecified},
+    {0xb528be91, L"loadXML",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_LoadXML},
+    {0xd9f46591, L"clone",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_Clone},
+    {0xe006a76b, L"assignNode",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_AssignNode},
+    {0x7303fcea, L"getDelta",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ContainerClass_GetDelta},
+    {0xe7742c9d, L"getDeltas",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ContainerClass_GetDeltas},
+    {0x30ff6aad, L"clearErrorList",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ModelClass_ClearErrorList},
+    {0x712c6afa, L"createNode",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ModelClass_CreateNode},
+    {0x83a6411d, L"isCompatibleNS",
+     (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ModelClass_IsCompatibleNS},
+};
+const int32_t g_iSomMethodCount =
+    sizeof(g_SomMethodData) / sizeof(XFA_METHODINFO);
+const XFA_SCRIPTATTRIBUTEINFO g_SomAttributeData[] = {
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xb3543a6, L"max",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Max, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x45a6daf8, L"eofAction",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_EofAction, XFA_SCRIPT_Basic},
+    {0x5ec958c0, L"cursorType",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_CursorType, XFA_SCRIPT_Basic},
+    {0x79975f2b, L"lockType",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_LockType, XFA_SCRIPT_Basic},
+    {0xa5340ff5, L"bofAction",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_BofAction, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc5762157, L"cursorLocation",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_CursorLocation, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x1ee2d24d, L"instanceIndex",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_InstanceIndex, -1,
+     XFA_SCRIPT_Basic},
+    {0x8c99377e, L"relation",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Relation, XFA_SCRIPT_Basic},
+    {0x8e1c2921, L"relevant",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+    {0x3106c3a, L"beforeTarget",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_BeforeTarget, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x13a08bdb, L"overflowTarget",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_OverflowTarget, XFA_SCRIPT_Basic},
+    {0x169134a1, L"overflowLeader",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_OverflowLeader, XFA_SCRIPT_Basic},
+    {0x20914367, L"overflowTrailer",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_OverflowTrailer, XFA_SCRIPT_Basic},
+    {0x453eaf38, L"startNew",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_StartNew, XFA_SCRIPT_Basic},
+    {0x64110ab5, L"bookendTrailer",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_BookendTrailer, XFA_SCRIPT_Basic},
+    {0xb6b44172, L"after",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_After, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc3c1442f, L"bookendLeader",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_BookendLeader, XFA_SCRIPT_Basic},
+    {0xcb150479, L"afterTarget",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_AfterTarget, XFA_SCRIPT_Basic},
+    {0xf4ffce73, L"before",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Before, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue_Read, -1,
+     XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x47cfa43a, L"allowNeutral",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_AllowNeutral, XFA_SCRIPT_Basic},
+    {0x7c2fd80b, L"mark",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Mark, XFA_SCRIPT_Basic},
+    {0x8ed182d1, L"shape",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Shape, XFA_SCRIPT_Basic},
+    {0xa686975b, L"size",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Size, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x5c054755, L"startAngle",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_StartAngle, XFA_SCRIPT_Basic},
+    {0x74788f8b, L"sweepAngle",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_SweepAngle, XFA_SCRIPT_Basic},
+    {0x9d833d75, L"circular",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Circular, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd996fa9b, L"hand",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Hand, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xb0e5485d, L"bind",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Bind, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xcd7f7b54, L"from",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_From, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x8e29d794, L"signatureType",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_SignatureType, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xe11a2cbc, L"permissions",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Permissions, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x453eaf38, L"startNew",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_StartNew, XFA_SCRIPT_Basic},
+    {0x9dcc3ab3, L"trailer",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Trailer, XFA_SCRIPT_Basic},
+    {0xa6118c89, L"targetType",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_TargetType, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc8da4da7, L"target",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Target, XFA_SCRIPT_Basic},
+    {0xcbcaf66d, L"leader",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Leader, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x2d574d58, L"this", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Xfa_This,
+     -1, XFA_SCRIPT_Object},
+    {0x4fdc3454, L"timeStamp",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_TimeStamp, XFA_SCRIPT_Basic},
+    {0xb598a1f7, L"uuid",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Uuid, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xcfea02e, L"leftInset",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_LeftInset, XFA_SCRIPT_Basic},
+    {0x1356caf8, L"bottomInset",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_BottomInset, XFA_SCRIPT_Basic},
+    {0x25764436, L"topInset",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_TopInset, XFA_SCRIPT_Basic},
+    {0x8a692521, L"rightInset",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_RightInset, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x1e459b8f, L"nonRepudiation",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_NonRepudiation, XFA_SCRIPT_Basic},
+    {0x2bb3f470, L"encipherOnly",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_EncipherOnly, XFA_SCRIPT_Basic},
+    {0x2f16a382, L"type",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+    {0x5f760b50, L"digitalSignature",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_DigitalSignature, XFA_SCRIPT_Basic},
+    {0x69aa2292, L"crlSign",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_CrlSign, XFA_SCRIPT_Basic},
+    {0x98fd4d81, L"keyAgreement",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_KeyAgreement, XFA_SCRIPT_Basic},
+    {0xa66404cb, L"keyEncipherment",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_KeyEncipherment, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xca5dc27c, L"dataEncipherment",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_DataEncipherment, XFA_SCRIPT_Basic},
+    {0xe8f118a8, L"keyCertSign",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_KeyCertSign, XFA_SCRIPT_Basic},
+    {0xfea53ec6, L"decipherOnly",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_DecipherOnly, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x8b90e1f2, L"open",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Open, XFA_SCRIPT_Basic},
+    {0x957fa006, L"commitOn",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_CommitOn, XFA_SCRIPT_Basic},
+    {0xb12128b7, L"textEntry",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_TextEntry, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+    {0x2282c73, L"hAlign",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_HAlign, XFA_SCRIPT_Basic},
+    {0x8d4f1c7, L"textIndent",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_TextIndent, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2a82d99c, L"marginRight",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MarginRight, XFA_SCRIPT_Basic},
+    {0x534729c9, L"marginLeft",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MarginLeft, XFA_SCRIPT_Basic},
+    {0x5739d1ff, L"radixOffset",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_RadixOffset, XFA_SCRIPT_Basic},
+    {0x577682ac, L"preserve",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Preserve, XFA_SCRIPT_Basic},
+    {0x731e0665, L"spaceBelow",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_SpaceBelow, XFA_SCRIPT_Basic},
+    {0x7a7cc341, L"vAlign",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_VAlign, XFA_SCRIPT_Basic},
+    {0x836d4d7c, L"tabDefault",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_TabDefault, XFA_SCRIPT_Basic},
+    {0x8fa01790, L"tabStops",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_TabStops, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd4b01921, L"lineHeight",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_LineHeight, XFA_SCRIPT_Basic},
+    {0xe18b5659, L"spaceAbove",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_SpaceAbove, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd861f8af, L"addRevocationInfo",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_AddRevocationInfo, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbb8df5d, L"ref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Ref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd6128d8d, L"activity",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Activity, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0x43e349b, L"dataRowCount",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_DataRowCount, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x28e17e91, L"dataPrep",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_DataPrep, XFA_SCRIPT_Basic},
+    {0x2f16a382, L"type",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+    {0x3650557e, L"textLocation",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_TextLocation, XFA_SCRIPT_Basic},
+    {0x3b582286, L"moduleWidth",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ModuleWidth, XFA_SCRIPT_Basic},
+    {0x52666f1c, L"printCheckDigit",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_PrintCheckDigit, XFA_SCRIPT_Basic},
+    {0x5404d6df, L"moduleHeight",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ModuleHeight, XFA_SCRIPT_Basic},
+    {0x5ab23b6c, L"startChar",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_StartChar, XFA_SCRIPT_Basic},
+    {0x7c732a66, L"truncate",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Truncate, XFA_SCRIPT_Basic},
+    {0x8d181d61, L"wideNarrowRatio",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_WideNarrowRatio, XFA_SCRIPT_Basic},
+    {0x99800d7a, L"errorCorrectionLevel",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ErrorCorrectionLevel, XFA_SCRIPT_Basic},
+    {0x9a63da3d, L"upsMode",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_UpsMode, XFA_SCRIPT_Basic},
+    {0xaf754613, L"checksum",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Checksum, XFA_SCRIPT_Basic},
+    {0xb045fbc5, L"charEncoding",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_CharEncoding, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc035c6b1, L"dataColumnCount",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_DataColumnCount, XFA_SCRIPT_Basic},
+    {0xd3c84d25, L"rowColumnRatio",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_RowColumnRatio, XFA_SCRIPT_Basic},
+    {0xd57c513c, L"dataLength",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_DataLength, XFA_SCRIPT_Basic},
+    {0xf575ca75, L"endChar",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_EndChar, XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+    {0x28dee6e9, L"format",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Format, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x60d4c8b1, L"output",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Output, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd6a39990, L"input",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Input, XFA_SCRIPT_Basic},
+    {0x2f16a382, L"type",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2f16a382, L"type",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0x2b5df51e, L"dataDescription",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_DataDescription, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x6c0d9600, L"currentValue",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Delta_CurrentValue, -1,
+     XFA_SCRIPT_Basic},
+    {0x942643f0, L"savedValue",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Delta_SavedValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xc8da4da7, L"target",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Delta_Target, -1,
+     XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd4cc53f8, L"highlight",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Highlight, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0x5518c25, L"break",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Break, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x570ce835, L"presence",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic},
+    {0x8e1c2921, L"relevant",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd996fa9b, L"hand",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Hand, XFA_SCRIPT_Basic},
+    {0x78, L"x", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_X, XFA_SCRIPT_Basic},
+    {0x79, L"y", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Y, XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x1059ec18, L"level",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_Integer,
+     XFA_ATTRIBUTE_Level, XFA_SCRIPT_Basic},
+    {0x8e1c2921, L"relevant",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic},
+    {0xac06e2b0, L"colSpan",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ColSpan, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x21aed, L"id",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Id, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2f105f72, L"wordCharacterCount",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_WordCharacterCount, XFA_SCRIPT_Basic},
+    {0x3d123c26, L"hyphenate",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Hyphenate, XFA_SCRIPT_Basic},
+    {0x66539c48, L"excludeInitialCap",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ExcludeInitialCap, XFA_SCRIPT_Basic},
+    {0x6a95c976, L"pushCharacterCount",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_PushCharacterCount, XFA_SCRIPT_Basic},
+    {0x982bd892, L"remainCharacterCount",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_RemainCharacterCount, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xe5c96d6a, L"excludeAllCaps",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ExcludeAllCaps, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x8af2e657, L"maxChars",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MaxChars, XFA_SCRIPT_Basic},
+    {0xa52682bd, L"{default}",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xa52682bd, L"{default}",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc080cd3, L"url",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Url, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xa6710262, L"credentialServerPolicy",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_CredentialServerPolicy, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc2ba0923, L"urlPolicy",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_UrlPolicy, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2f16a382, L"type",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0x47d03490, L"connection",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Connection, XFA_SCRIPT_Basic},
+    {0xc8da4da7, L"target",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Target, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xa52682bd, L"{default}",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x78bff531, L"numberOfCells",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_Integer,
+     XFA_ATTRIBUTE_NumberOfCells, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2f16a382, L"type",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x68, L"h", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_H, XFA_SCRIPT_Basic},
+    {0x77, L"w", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_W, XFA_SCRIPT_Basic},
+    {0x78, L"x", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_X, XFA_SCRIPT_Basic},
+    {0x79, L"y", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Y, XFA_SCRIPT_Basic},
+    {0x2282c73, L"hAlign",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_HAlign, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x1abbd7e0, L"dataNode",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DataNode, -1,
+     XFA_SCRIPT_Object},
+    {0x25839852, L"access",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Access, XFA_SCRIPT_Basic},
+    {0x2ee7678f, L"rotate",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Rotate, XFA_SCRIPT_Basic},
+    {0x3b1ddd06, L"fillColor",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_FillColor, -1,
+     XFA_SCRIPT_Basic},
+    {0x54c399e3, L"formattedValue",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Field_FormattedValue, -1,
+     XFA_SCRIPT_Basic},
+    {0x570ce835, L"presence",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic},
+    {0x5a3b375d, L"borderColor",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_BorderColor, -1,
+     XFA_SCRIPT_Basic},
+    {0x5e936ed6, L"fontColor",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_FontColor, -1,
+     XFA_SCRIPT_Basic},
+    {0x6826c408, L"parentSubform",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Field_ParentSubform, -1,
+     XFA_SCRIPT_Basic},
+    {0x79b67434, L"mandatoryMessage",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_MandatoryMessage, -1,
+     XFA_SCRIPT_Basic},
+    {0x7a7cc341, L"vAlign",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_VAlign, XFA_SCRIPT_Basic},
+    {0x7c2ff6ae, L"maxH",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MaxH, XFA_SCRIPT_Basic},
+    {0x7c2ff6bd, L"maxW",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MaxW, XFA_SCRIPT_Basic},
+    {0x7d02356c, L"minH",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MinH, XFA_SCRIPT_Basic},
+    {0x7d02357b, L"minW",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MinW, XFA_SCRIPT_Basic},
+    {0x85fd6faf, L"mandatory",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_Mandatory, -1,
+     XFA_SCRIPT_Basic},
+    {0x8e1c2921, L"relevant",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic},
+    {0x964fb42e, L"formatMessage",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Field_FormatMessage, -1,
+     XFA_SCRIPT_Basic},
+    {0xa03cf627, L"rawValue",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xa52682bd, L"{default}",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xa60dd202, L"length",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Field_Length, -1,
+     XFA_SCRIPT_Basic},
+    {0xac06e2b0, L"colSpan",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ColSpan, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbc8fa350, L"locale",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Locale, XFA_SCRIPT_Basic},
+    {0xc2bd40fd, L"anchorType",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_AnchorType, XFA_SCRIPT_Basic},
+    {0xc4fed09b, L"accessKey",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_AccessKey, XFA_SCRIPT_Basic},
+    {0xcabfa3d0, L"validationMessage",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_ValidationMessage, -1,
+     XFA_SCRIPT_Basic},
+    {0xdcecd663, L"editValue",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Field_EditValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xe07e5061, L"selectedIndex",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Field_SelectedIndex, -1,
+     XFA_SCRIPT_Basic},
+    {0xf65e34be, L"borderWidth",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_BorderWidth, -1,
+     XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x68, L"h", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_H, XFA_SCRIPT_Basic},
+    {0x77, L"w", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_W, XFA_SCRIPT_Basic},
+    {0x78, L"x", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_X, XFA_SCRIPT_Basic},
+    {0x79, L"y", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Y, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x8e1c2921, L"relevant",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd843798, L"fullText", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::
+                                 Script_EventPseudoModel_FullText,
+     -1, XFA_SCRIPT_Basic},
+    {0x1b6d1cf5, L"reenter", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::
+                                 Script_EventPseudoModel_Reenter,
+     -1, XFA_SCRIPT_Basic},
+    {0x1e6ffa9a, L"prevContentType",
+     (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::
+         Script_EventPseudoModel_PrevContentType,
+     -1, XFA_SCRIPT_Basic},
+    {0x25a3c206, L"soapFaultString",
+     (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::
+         Script_EventPseudoModel_SoapFaultString,
+     -1, XFA_SCRIPT_Basic},
+    {0x2e00c007, L"newContentType",
+     (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::
+         Script_EventPseudoModel_NewContentType,
+     -1, XFA_SCRIPT_Basic},
+    {0x4570500f, L"modifier",
+     (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::
+         Script_EventPseudoModel_Modifier,
+     -1, XFA_SCRIPT_Basic},
+    {0x50e2e33b, L"selEnd", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::
+                                Script_EventPseudoModel_SelEnd,
+     -1, XFA_SCRIPT_Basic},
+    {0x57de87c2, L"prevText",
+     (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::
+         Script_EventPseudoModel_PrevText,
+     -1, XFA_SCRIPT_Basic},
+    {0x6ea04e0a, L"soapFaultCode",
+     (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::
+         Script_EventPseudoModel_SoapFaultCode,
+     -1, XFA_SCRIPT_Basic},
+    {0x6f6556cf, L"newText", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::
+                                 Script_EventPseudoModel_NewText,
+     -1, XFA_SCRIPT_Basic},
+    {0x891f4606, L"change", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::
+                                Script_EventPseudoModel_Change,
+     -1, XFA_SCRIPT_Basic},
+    {0x8fa3c19e, L"shift", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::
+                               Script_EventPseudoModel_Shift,
+     -1, XFA_SCRIPT_Basic},
+    {0xa9d9b2e1, L"keyDown", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::
+                                 Script_EventPseudoModel_KeyDown,
+     -1, XFA_SCRIPT_Basic},
+    {0xbfc89db2, L"selStart",
+     (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::
+         Script_EventPseudoModel_SelStart,
+     -1, XFA_SCRIPT_Basic},
+    {0xc32a5812, L"commitKey",
+     (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::
+         Script_EventPseudoModel_CommitKey,
+     -1, XFA_SCRIPT_Basic},
+    {0xc8da4da7, L"target", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::
+                                Script_EventPseudoModel_Target,
+     -1, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xa2e3514, L"cap",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Cap, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x5392ea58, L"stroke",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Stroke, XFA_SCRIPT_Basic},
+    {0x570ce835, L"presence",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic},
+    {0x94446dcc, L"thickness",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Thickness, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x1ec8ab2c, L"rate",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Rate, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x7b29630a, L"sourceBelow",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_SourceBelow, XFA_SCRIPT_Basic},
+    {0x8fc36c0a, L"outputBelow",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_OutputBelow, XFA_SCRIPT_Basic},
+    {0xe996b2fe, L"sourceAbove",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_SourceAbove, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x68, L"h", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_H, XFA_SCRIPT_Basic},
+    {0x77, L"w", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_W, XFA_SCRIPT_Basic},
+    {0x78, L"x", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_X, XFA_SCRIPT_Basic},
+    {0x79, L"y", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Y, XFA_SCRIPT_Basic},
+    {0x2282c73, L"hAlign",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_HAlign, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xf23332f, L"errorText",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_ExclGroup_ErrorText, -1,
+     XFA_SCRIPT_Basic},
+    {0x1abbd7e0, L"dataNode",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DataNode, -1,
+     XFA_SCRIPT_Object},
+    {0x25839852, L"access",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Access, XFA_SCRIPT_Basic},
+    {0x3b1ddd06, L"fillColor",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_FillColor, -1,
+     XFA_SCRIPT_Basic},
+    {0x570ce835, L"presence",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic},
+    {0x5a3b375d, L"borderColor",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_BorderColor, -1,
+     XFA_SCRIPT_Basic},
+    {0x79b67434, L"mandatoryMessage",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_MandatoryMessage, -1,
+     XFA_SCRIPT_Basic},
+    {0x7a7cc341, L"vAlign",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_VAlign, XFA_SCRIPT_Basic},
+    {0x7c2ff6ae, L"maxH",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MaxH, XFA_SCRIPT_Basic},
+    {0x7c2ff6bd, L"maxW",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MaxW, XFA_SCRIPT_Basic},
+    {0x7d02356c, L"minH",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MinH, XFA_SCRIPT_Basic},
+    {0x7d02357b, L"minW",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MinW, XFA_SCRIPT_Basic},
+    {0x7e7e845e, L"layout",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Layout, XFA_SCRIPT_Basic},
+    {0x846599f8, L"transient",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_ExclGroup_Transient, -1,
+     XFA_SCRIPT_Basic},
+    {0x85fd6faf, L"mandatory",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_Mandatory, -1,
+     XFA_SCRIPT_Basic},
+    {0x8e1c2921, L"relevant",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic},
+    {0xa03cf627, L"rawValue",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_ExclGroup_DefaultAndRawValue,
+     -1, XFA_SCRIPT_Basic},
+    {0xa52682bd, L"{default}",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_ExclGroup_DefaultAndRawValue,
+     -1, XFA_SCRIPT_Basic},
+    {0xac06e2b0, L"colSpan",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ColSpan, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc2bd40fd, L"anchorType",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_AnchorType, XFA_SCRIPT_Basic},
+    {0xc4fed09b, L"accessKey",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_AccessKey, XFA_SCRIPT_Basic},
+    {0xcabfa3d0, L"validationMessage",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_ValidationMessage, -1,
+     XFA_SCRIPT_Basic},
+    {0xf65e34be, L"borderWidth",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_BorderWidth, -1,
+     XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xeda9017a, L"scope",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Scope, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x47d03490, L"connection",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Connection, XFA_SCRIPT_Basic},
+    {0x6cfa828a, L"runAt",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_RunAt, XFA_SCRIPT_Basic},
+    {0xa1b0d2f5, L"executeType",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ExecuteType, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xe6f99487, L"hScrollPolicy",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_HScrollPolicy, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x42fed1fd, L"contentType",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ContentType, XFA_SCRIPT_Basic},
+    {0x54fa722c, L"transferEncoding",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_TransferEncoding, XFA_SCRIPT_Basic},
+    {0xa52682bd, L"{default}",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue_Read, -1,
+     XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd171b240, L"aspect",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Aspect, XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue_Read, -1,
+     XFA_SCRIPT_Basic},
+    {0xdb55fec5, L"href",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Href, XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Value, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2f16a382, L"type",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+    {0x7f6fd3d7, L"server",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Server, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x4b8bc840, L"fracDigits",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_FracDigits, XFA_SCRIPT_Basic},
+    {0xa52682bd, L"{default}",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xde7f92ba, L"leadDigits",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_LeadDigits, XFA_SCRIPT_Basic},
+    {0x68, L"h", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_H, XFA_SCRIPT_Basic},
+    {0x77, L"w", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_W, XFA_SCRIPT_Basic},
+    {0x78, L"x", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_X, XFA_SCRIPT_Basic},
+    {0x79, L"y", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Y, XFA_SCRIPT_Basic},
+    {0x2282c73, L"hAlign",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_HAlign, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x1414d431, L"allowMacro",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_AllowMacro, XFA_SCRIPT_Basic},
+    {0x1517dfa1, L"columnWidths",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ColumnWidths, XFA_SCRIPT_Basic},
+    {0x1abbd7e0, L"dataNode",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DataNode, -1,
+     XFA_SCRIPT_Object},
+    {0x1ee2d24d, L"instanceIndex",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_InstanceIndex, -1,
+     XFA_SCRIPT_Basic},
+    {0x25839852, L"access",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Access, XFA_SCRIPT_Basic},
+    {0x3b1ddd06, L"fillColor",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_FillColor, -1,
+     XFA_SCRIPT_Basic},
+    {0x570ce835, L"presence",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic},
+    {0x5a3b375d, L"borderColor",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_BorderColor, -1,
+     XFA_SCRIPT_Basic},
+    {0x7a7cc341, L"vAlign",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_VAlign, XFA_SCRIPT_Basic},
+    {0x7c2ff6ae, L"maxH",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MaxH, XFA_SCRIPT_Basic},
+    {0x7c2ff6bd, L"maxW",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MaxW, XFA_SCRIPT_Basic},
+    {0x7d02356c, L"minH",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MinH, XFA_SCRIPT_Basic},
+    {0x7d02357b, L"minW",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MinW, XFA_SCRIPT_Basic},
+    {0x7e7e845e, L"layout",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Layout, XFA_SCRIPT_Basic},
+    {0x8e1c2921, L"relevant",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic},
+    {0x9cc17d75, L"mergeMode",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MergeMode, XFA_SCRIPT_Basic},
+    {0x9f3e9510, L"instanceManager",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Subform_InstanceManager, -1,
+     XFA_SCRIPT_Object},
+    {0xac06e2b0, L"colSpan",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ColSpan, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbc8fa350, L"locale",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Subform_Locale, -1,
+     XFA_SCRIPT_Basic},
+    {0xc2bd40fd, L"anchorType",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_AnchorType, XFA_SCRIPT_Basic},
+    {0xcabfa3d0, L"validationMessage",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_ValidationMessage, -1,
+     XFA_SCRIPT_Basic},
+    {0xe4c3a5e5, L"restoreState",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_RestoreState, XFA_SCRIPT_Basic},
+    {0xeda9017a, L"scope",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Scope, XFA_SCRIPT_Basic},
+    {0xf65e34be, L"borderWidth",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_BorderWidth, -1,
+     XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2f16a382, L"type",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+    {0x5a50e9e6, L"version",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Handler_Version, -1,
+     XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0x4107ed, L"foxitAppType",
+     (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::
+         Script_HostPseudoModel_FoxitAppType,
+     -1, XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::
+                             Script_HostPseudoModel_Name,
+     -1, XFA_SCRIPT_Basic},
+    {0x66c1ae9, L"validationsEnabled",
+     (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::
+         Script_HostPseudoModel_ValidationsEnabled,
+     -1, XFA_SCRIPT_Basic},
+    {0x14d04502, L"title", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::
+                               Script_HostPseudoModel_Title,
+     -1, XFA_SCRIPT_Basic},
+    {0x193afe8b, L"foxitName",
+     (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::
+         Script_HostPseudoModel_FoxitName,
+     -1, XFA_SCRIPT_Basic},
+    {0x392ae445, L"platform", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::
+                                  Script_HostPseudoModel_Platform,
+     -1, XFA_SCRIPT_Basic},
+    {0x5a50e9e6, L"version", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::
+                                 Script_HostPseudoModel_Version,
+     -1, XFA_SCRIPT_Basic},
+    {0x66cb1eed, L"variation",
+     (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::
+         Script_HostPseudoModel_Variation,
+     -1, XFA_SCRIPT_Basic},
+    {0x7717cbc4, L"language", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::
+                                  Script_HostPseudoModel_Language,
+     -1, XFA_SCRIPT_Basic},
+    {0x86698963, L"appType", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::
+                                 Script_HostPseudoModel_AppType,
+     -1, XFA_SCRIPT_Basic},
+    {0x94ff9e8d, L"calculationsEnabled",
+     (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::
+         Script_HostPseudoModel_CalculationsEnabled,
+     -1, XFA_SCRIPT_Basic},
+    {0xbcd44940, L"currentPage",
+     (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::
+         Script_HostPseudoModel_CurrentPage,
+     -1, XFA_SCRIPT_Basic},
+    {0xd4286870, L"foxitVersion",
+     (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::
+         Script_HostPseudoModel_FoxitVersion,
+     -1, XFA_SCRIPT_Basic},
+    {0xd592b920, L"numPages", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::
+                                  Script_HostPseudoModel_NumPages,
+     -1, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x24d85167, L"timeout",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Timeout, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x7d9fd7c5, L"mode",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Mode, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x7d9fd7c5, L"mode",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_SubmitFormat_Mode, -1,
+     XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xa52682bd, L"{default}",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2038c9b2, L"role",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Role, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xa52682bd, L"{default}",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xfcef86b5, L"ready", (XFA_ATTRIBUTE_CALLBACK)&CScript_LayoutPseudoModel::
+                               Script_LayoutPseudoModel_Ready,
+     -1, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x5392ea58, L"stroke",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Stroke, XFA_SCRIPT_Basic},
+    {0x570ce835, L"presence",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic},
+    {0x7b95e661, L"inverted",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Inverted, XFA_SCRIPT_Basic},
+    {0x94446dcc, L"thickness",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Thickness, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xe8dddf50, L"join",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Join, XFA_SCRIPT_Basic},
+    {0xe948b9a8, L"radius",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Radius, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xabfa6c4f, L"cSpace",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_CSpace, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Value, XFA_SCRIPT_Basic},
+    {0x3848b3f, L"next",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Next, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x6a3405dd, L"previous",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Previous, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xf6b59543, L"intact",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Intact, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x268b7ec1, L"commandType",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_CommandType, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbde9abda, L"data",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Data, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x5b707a35, L"scriptTest",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ScriptTest, XFA_SCRIPT_Basic},
+    {0x6b6ddcfb, L"nullTest",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_NullTest, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xe64b1129, L"formatTest",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_FormatTest, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2f16a382, L"type",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x8c99377e, L"relation",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Relation, XFA_SCRIPT_Basic},
+    {0x8e1c2921, L"relevant",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xa52682bd, L"{default}",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0x25363, L"to",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_To, XFA_SCRIPT_Basic},
+    {0x66642f8f, L"force",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Force, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xcd7f7b54, L"from",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_From, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Value, XFA_SCRIPT_Basic},
+    {0x2b5df51e, L"dataDescription",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_DataDescription, XFA_SCRIPT_Basic},
+    {0xbb8df5d, L"ref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Ref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x226ca8f1, L"operation",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Operation, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2f16a382, L"type",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2f16a382, L"type",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xfb67185, L"recordsBefore", (XFA_ATTRIBUTE_CALLBACK)&CScript_DataWindow::
+                                      Script_DataWindow_RecordsBefore,
+     -1, XFA_SCRIPT_Basic},
+    {0x21d5dfcb, L"currentRecordNumber",
+     (XFA_ATTRIBUTE_CALLBACK)&CScript_DataWindow::
+         Script_DataWindow_CurrentRecordNumber,
+     -1, XFA_SCRIPT_Basic},
+    {0x312af044, L"recordsAfter", (XFA_ATTRIBUTE_CALLBACK)&CScript_DataWindow::
+                                      Script_DataWindow_RecordsAfter,
+     -1, XFA_SCRIPT_Basic},
+    {0x6aab37cb, L"isDefined",
+     (XFA_ATTRIBUTE_CALLBACK)&CScript_DataWindow::Script_DataWindow_IsDefined,
+     -1, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x42fed1fd, L"contentType",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ContentType, XFA_SCRIPT_Basic},
+    {0x6cfa828a, L"runAt",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_RunAt, XFA_SCRIPT_Basic},
+    {0xa021b738, L"stateless",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Script_Stateless, -1,
+     XFA_SCRIPT_Basic},
+    {0xa52682bd, L"{default}",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xadc4c77b, L"binding",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Binding, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x7a0cc471, L"passwordChar",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_PasswordChar, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xe6f99487, L"hScrollPolicy",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_HScrollPolicy, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xe6f99487, L"hScrollPolicy",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_HScrollPolicy, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x14a32d52, L"pagePosition",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_PagePosition, XFA_SCRIPT_Basic},
+    {0x8340ea66, L"oddOrEven",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_OddOrEven, XFA_SCRIPT_Basic},
+    {0x8e1c2921, L"relevant",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic},
+    {0xa85e74f3, L"initialNumber",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_InitialNumber, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe9ba472, L"numbered",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Numbered, XFA_SCRIPT_Basic},
+    {0xd70798c2, L"blankOrNotBlank",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_BlankOrNotBlank, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2f16a382, L"type",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x34ae103c, L"reserve",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Reserve, XFA_SCRIPT_Basic},
+    {0x570ce835, L"presence",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xf2009339, L"placement",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Placement, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x42fed1fd, L"contentType",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ContentType, XFA_SCRIPT_Basic},
+    {0x54fa722c, L"transferEncoding",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_TransferEncoding, XFA_SCRIPT_Basic},
+    {0xa52682bd, L"{default}",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc4547a08, L"maxLength",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MaxLength, XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xdb55fec5, L"href",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Href, XFA_SCRIPT_Basic},
+    {0x29418bb7, L"abbr",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Abbr, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf531b059, L"writingScript",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_WritingScript, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x1b8dce3e, L"action",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Action, XFA_SCRIPT_Basic},
+    {0xa52682bd, L"{default}",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x9dcc3ab3, L"trailer",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Trailer, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc8da4da7, L"target",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Target, XFA_SCRIPT_Basic},
+    {0xcbcaf66d, L"leader",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Leader, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2f16a382, L"type",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xb3543a6, L"max",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_InstanceManager_Max, -1,
+     XFA_SCRIPT_Basic},
+    {0xb356ca4, L"min",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_InstanceManager_Min, -1,
+     XFA_SCRIPT_Basic},
+    {0x6f544d49, L"count",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_InstanceManager_Count, -1,
+     XFA_SCRIPT_Basic},
+    {0x25363, L"to",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_To, XFA_SCRIPT_Basic},
+    {0xa0933954, L"unicodeRange",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_UnicodeRange, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xcd7f7b54, L"from",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_From, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x4ef3d02c, L"orientation",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Orientation, XFA_SCRIPT_Basic},
+    {0x65e30c67, L"imagingBBox",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ImagingBBox, XFA_SCRIPT_Basic},
+    {0x9041d4b0, L"short",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Short, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xe349d044, L"stock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Stock, XFA_SCRIPT_Basic},
+    {0xf6b4afb0, L"long",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Long, XFA_SCRIPT_Basic},
+    {0x5ce6195, L"vScrollPolicy",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_VScrollPolicy, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x1ef3a64a, L"allowRichText",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_AllowRichText, XFA_SCRIPT_Basic},
+    {0x5a32e493, L"multiLine",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MultiLine, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xe6f99487, L"hScrollPolicy",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_HScrollPolicy, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xd52482e0, L"maxEntries",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MaxEntries, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x42fed1fd, L"contentType",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ContentType, XFA_SCRIPT_Basic},
+    {0x8855805f, L"contains",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Contains, XFA_SCRIPT_Basic},
+    {0xa52682bd, L"{default}",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xe372ae97, L"isNull",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_IsNull, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x2b5df51e, L"dataDescription",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_DataDescription, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbb8df5d, L"ref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Ref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x226ca8f1, L"operation",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Operation, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc8da4da7, L"target",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Target, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbb8df5d, L"ref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Ref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x42fed1fd, L"contentType",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ContentType, XFA_SCRIPT_Basic},
+    {0x54fa722c, L"transferEncoding",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_TransferEncoding, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xf197844d, L"match",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Match, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd996fa9b, L"hand",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Hand, XFA_SCRIPT_Basic},
+    {0x21aed, L"id",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Id, XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xa52682bd, L"{default}",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x28dee6e9, L"format",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Encrypt_Format, -1,
+     XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x68, L"h", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_H, XFA_SCRIPT_Basic},
+    {0x77, L"w", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_W, XFA_SCRIPT_Basic},
+    {0x78, L"x", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_X, XFA_SCRIPT_Basic},
+    {0x79, L"y", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Y, XFA_SCRIPT_Basic},
+    {0x2282c73, L"hAlign",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_HAlign, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2ee7678f, L"rotate",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Rotate, XFA_SCRIPT_Basic},
+    {0x570ce835, L"presence",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic},
+    {0x7a7cc341, L"vAlign",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_VAlign, XFA_SCRIPT_Basic},
+    {0x7c2ff6ae, L"maxH",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MaxH, XFA_SCRIPT_Basic},
+    {0x7c2ff6bd, L"maxW",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MaxW, XFA_SCRIPT_Basic},
+    {0x7d02356c, L"minH",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MinH, XFA_SCRIPT_Basic},
+    {0x7d02357b, L"minW",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_MinW, XFA_SCRIPT_Basic},
+    {0x8e1c2921, L"relevant",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic},
+    {0xa03cf627, L"rawValue",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xa52682bd, L"{default}",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xac06e2b0, L"colSpan",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ColSpan, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbc8fa350, L"locale",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Locale, XFA_SCRIPT_Basic},
+    {0xc2bd40fd, L"anchorType",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_AnchorType, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x39cdb0a2, L"priority",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Priority, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xeb511b54, L"disable",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Disable, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Value, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2f16a382, L"type",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x21aed, L"id",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Id, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2f16a382, L"type",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x570ce835, L"presence",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xcb0ac9, L"lineThrough",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_LineThrough, XFA_SCRIPT_Basic},
+    {0x2c1c7f1, L"typeface",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Typeface, XFA_SCRIPT_Basic},
+    {0x8c74ae9, L"fontHorizontalScale",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_FontHorizontalScale, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2cd79033, L"kerningMode",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_KerningMode, XFA_SCRIPT_Basic},
+    {0x3a0273a6, L"underline",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Underline, XFA_SCRIPT_Basic},
+    {0x4873c601, L"baselineShift",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_BaselineShift, XFA_SCRIPT_Basic},
+    {0x4b319767, L"overlinePeriod",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_OverlinePeriod, XFA_SCRIPT_Basic},
+    {0x79543055, L"letterSpacing",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_LetterSpacing, XFA_SCRIPT_Basic},
+    {0x8ec6204c, L"lineThroughPeriod",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_LineThroughPeriod, XFA_SCRIPT_Basic},
+    {0x907c7719, L"fontVerticalScale",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_FontVerticalScale, XFA_SCRIPT_Basic},
+    {0xa686975b, L"size",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Size, XFA_SCRIPT_Basic},
+    {0xb5e49bf2, L"posture",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Posture, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbd6e1d88, L"weight",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Weight, XFA_SCRIPT_Basic},
+    {0xbd96a0e9, L"underlinePeriod",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_UnderlinePeriod, XFA_SCRIPT_Basic},
+    {0xc0ec9fa4, L"overline",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Overline, XFA_SCRIPT_Basic},
+    {0xaf754613, L"checksum",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Form_Checksum, -1,
+     XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xa52682bd, L"{default}",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x8e1c2921, L"relevant",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xea7090a0, L"override",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Override, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x9dcc3ab3, L"trailer",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Trailer, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xcbcaf66d, L"leader",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Leader, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x60a61edd, L"codeType",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_CodeType, XFA_SCRIPT_Basic},
+    {0xb373a862, L"archive",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Archive, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xe1a26b56, L"codeBase",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_CodeBase, XFA_SCRIPT_Basic},
+    {0xeb091003, L"classId",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ClassId, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x47d03490, L"connection",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Connection, XFA_SCRIPT_Basic},
+    {0xc39a88bd, L"labelRef",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_LabelRef, XFA_SCRIPT_Basic},
+    {0xd50f903a, L"valueRef",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_ValueRef, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xea7090a0, L"override",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Override, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2f16a382, L"type",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Extras_Type, -1,
+     XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbb8df5d, L"ref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Ref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x24d85167, L"timeout",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Timeout, XFA_SCRIPT_Basic},
+    {0x47d03490, L"connection",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Connection, XFA_SCRIPT_Basic},
+    {0x552d9ad5, L"usage",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usage, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc860f30a, L"delayedOpen",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_DelayedOpen, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x28dee6e9, L"format",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Format, XFA_SCRIPT_Basic},
+    {0x824f21b7, L"embedPDF",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_EmbedPDF, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc8da4da7, L"target",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Target, XFA_SCRIPT_Basic},
+    {0xdc75676c, L"textEncoding",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_TextEncoding, XFA_SCRIPT_Basic},
+    {0xf889e747, L"xdpContent",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_XdpContent, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x97be91b, L"content",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Packet_Content, -1,
+     XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x4156ee3f, L"delimiter",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Delimiter, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2f16a382, L"type",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0x21aed, L"id",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Id, XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbb8df5d, L"ref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Ref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x21aed, L"id",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Id, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x2f16a382, L"type",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x453eaf38, L"startNew",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_StartNew, XFA_SCRIPT_Basic},
+    {0x9dcc3ab3, L"trailer",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Trailer, XFA_SCRIPT_Basic},
+    {0xa6118c89, L"targetType",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_TargetType, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xc8da4da7, L"target",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Target, XFA_SCRIPT_Basic},
+    {0xcbcaf66d, L"leader",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Leader, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xabef37e3, L"slope",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Slope, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xd996fa9b, L"hand",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Hand, XFA_SCRIPT_Basic},
+    {0xa60dd202, L"length",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_NodeList::Script_ListClass_Length, -1,
+     XFA_SCRIPT_Basic},
+    {0x20146, L"db", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Source_Db, -1,
+     XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xb3543a6, L"max", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Occur_Max,
+     -1, XFA_SCRIPT_Basic},
+    {0xb356ca4, L"min", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Occur_Min,
+     -1, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x7d0b5fca, L"initial",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Initial, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x29418bb7, L"abbr",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Abbr, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+    {0xbe52dfbf, L"desc",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+    {0xf6b47749, L"lock",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL,
+     XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+    {0xbb8df5d, L"ref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Ref, XFA_SCRIPT_Basic},
+    {0xc0811ed, L"use",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+    {0x570ce835, L"presence",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic},
+    {0xa5b410cf, L"save",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Save, XFA_SCRIPT_Basic},
+    {0xbc254332, L"usehref",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+    {0xb2c80857, L"className",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Object::Script_ObjectClass_ClassName, -1,
+     XFA_SCRIPT_Basic},
+    {0xa60dd202, L"length",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_NodeList::Script_ListClass_Length, -1,
+     XFA_SCRIPT_Basic},
+    {0x31b19c1, L"name",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+    {0x9f9d0f9, L"all",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_TreeClass_All, -1,
+     XFA_SCRIPT_Object},
+    {0x4df15659, L"nodes",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_TreeClass_Nodes, -1,
+     XFA_SCRIPT_Object},
+    {0x78a8d6cf, L"classAll",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_TreeClass_ClassAll, -1,
+     XFA_SCRIPT_Object},
+    {0xcad6d8ca, L"parent",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_TreeClass_Parent, -1,
+     XFA_SCRIPT_Object},
+    {0xd5679c78, L"index",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_TreeClass_Index, -1,
+     XFA_SCRIPT_Basic},
+    {0xdb5b4bce, L"classIndex",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_TreeClass_ClassIndex, -1,
+     XFA_SCRIPT_Basic},
+    {0xe4989adf, L"somExpression",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_TreeClass_SomExpression, -1,
+     XFA_SCRIPT_Basic},
+    {0x21aed, L"id",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String,
+     XFA_ATTRIBUTE_Id, XFA_SCRIPT_Basic},
+    {0x234a1, L"ns", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_NodeClass_Ns,
+     -1, XFA_SCRIPT_Basic},
+    {0x50d1a9d1, L"model",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_NodeClass_Model, -1,
+     XFA_SCRIPT_Object},
+    {0xacb4823f, L"isContainer",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_NodeClass_IsContainer, -1,
+     XFA_SCRIPT_Basic},
+    {0xe372ae97, L"isNull",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_NodeClass_IsNull, -1,
+     XFA_SCRIPT_Basic},
+    {0xfe612a5b, L"oneOfChild",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_NodeClass_OneOfChild, -1,
+     XFA_SCRIPT_Object},
+    {0x97c1c65, L"context",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_ModelClass_Context, -1,
+     XFA_SCRIPT_Object},
+    {0x58be2870, L"aliasNode",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_ModelClass_AliasNode, -1,
+     XFA_SCRIPT_Object},
+    {0xa52682bd, L"{default}",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+    {0xd6e27f1d, L"value",
+     (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1,
+     XFA_SCRIPT_Basic},
+};
+const int32_t g_iSomAttributeCount =
+    sizeof(g_SomAttributeData) / sizeof(XFA_ATTRIBUTEINFO);
diff --git a/xfa/fxfa/parser/xfa_basic_data.h b/xfa/fxfa/parser/xfa_basic_data.h
new file mode 100644
index 0000000..8d36650
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_basic_data.h
@@ -0,0 +1,48 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_BASIC_DATA_H_
+#define XFA_FXFA_PARSER_XFA_BASIC_DATA_H_
+
+#include "xfa/fxfa/parser/xfa_basic_imp.h"
+#include "xfa/include/fxfa/fxfa_basic.h"
+
+extern const XFA_PACKETINFO g_XFAPacketData[];
+extern const int32_t g_iXFAPacketCount;
+
+extern const XFA_ATTRIBUTEENUMINFO g_XFAEnumData[];
+extern const int32_t g_iXFAEnumCount;
+
+extern const XFA_ATTRIBUTEINFO g_XFAAttributeData[];
+extern const int32_t g_iXFAAttributeCount;
+
+extern const XFA_NOTSUREATTRIBUTE g_XFANotsureAttributes[];
+extern const int32_t g_iXFANotsureCount;
+
+extern const XFA_ELEMENTINFO g_XFAElementData[];
+extern const int32_t g_iXFAElementCount;
+
+extern const XFA_ELEMENTHIERARCHY g_XFAElementChildrenIndex[];
+extern const FX_WORD g_XFAElementChildrenData[];
+
+extern const XFA_ELEMENTHIERARCHY g_XFAElementAttributeIndex[];
+extern const uint8_t g_XFAElementAttributeData[];
+
+extern const XFA_ELEMENTHIERARCHY g_XFAElementPropertyIndex[];
+extern const XFA_PROPERTY g_XFAElementPropertyData[];
+
+extern const XFA_SCRIPTHIERARCHY g_XFAScriptIndex[];
+
+extern const XFA_NOTSUREATTRIBUTE g_XFANotsureAttributes[];
+extern const int32_t g_iXFANotsureCount;
+
+extern const XFA_METHODINFO g_SomMethodData[];
+extern const int32_t g_iSomMethodCount;
+
+extern const XFA_SCRIPTATTRIBUTEINFO g_SomAttributeData[];
+extern const int32_t g_iSomAttributeCount;
+
+#endif  // XFA_FXFA_PARSER_XFA_BASIC_DATA_H_
diff --git a/xfa/fxfa/parser/xfa_basic_imp.cpp b/xfa/fxfa/parser/xfa_basic_imp.cpp
new file mode 100644
index 0000000..a6d4fc0
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_basic_imp.cpp
@@ -0,0 +1,612 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_basic_imp.h"
+
+#include "core/include/fxcrt/fx_ext.h"
+#include "xfa/fgas/crt/fgas_algorithm.h"
+#include "xfa/fgas/crt/fgas_codepage.h"
+#include "xfa/fgas/crt/fgas_system.h"
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_basic_data.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+const XFA_PACKETINFO* XFA_GetPacketByName(const CFX_WideStringC& wsName) {
+  int32_t iLength = wsName.GetLength();
+  if (iLength == 0) {
+    return NULL;
+  }
+  uint32_t uHash = FX_HashCode_String_GetW(wsName.GetPtr(), iLength);
+  int32_t iStart = 0, iEnd = g_iXFAPacketCount - 1;
+  do {
+    int32_t iMid = (iStart + iEnd) / 2;
+    const XFA_PACKETINFO* pInfo = g_XFAPacketData + iMid;
+    if (uHash == pInfo->uHash) {
+      return pInfo;
+    } else if (uHash < pInfo->uHash) {
+      iEnd = iMid - 1;
+    } else {
+      iStart = iMid + 1;
+    }
+  } while (iStart <= iEnd);
+  return NULL;
+}
+
+const XFA_PACKETINFO* XFA_GetPacketByID(FX_DWORD dwPacket) {
+  int32_t iStart = 0, iEnd = g_iXFAPacketCount - 1;
+  do {
+    int32_t iMid = (iStart + iEnd) / 2;
+    FX_DWORD dwFind = (g_XFAPacketData + iMid)->eName;
+    if (dwPacket == dwFind) {
+      return g_XFAPacketData + iMid;
+    } else if (dwPacket < dwFind) {
+      iEnd = iMid - 1;
+    } else {
+      iStart = iMid + 1;
+    }
+  } while (iStart <= iEnd);
+  return NULL;
+}
+
+const XFA_PACKETINFO* XFA_GetPacketByIndex(XFA_PACKET ePacket) {
+  return g_XFAPacketData + ePacket;
+}
+
+const XFA_ATTRIBUTEENUMINFO* XFA_GetAttributeEnumByName(
+    const CFX_WideStringC& wsName) {
+  int32_t iLength = wsName.GetLength();
+  if (iLength == 0) {
+    return NULL;
+  }
+  uint32_t uHash = FX_HashCode_String_GetW(wsName.GetPtr(), iLength);
+  int32_t iStart = 0, iEnd = g_iXFAEnumCount - 1;
+  do {
+    int32_t iMid = (iStart + iEnd) / 2;
+    const XFA_ATTRIBUTEENUMINFO* pInfo = g_XFAEnumData + iMid;
+    if (uHash == pInfo->uHash) {
+      return pInfo;
+    } else if (uHash < pInfo->uHash) {
+      iEnd = iMid - 1;
+    } else {
+      iStart = iMid + 1;
+    }
+  } while (iStart <= iEnd);
+  return NULL;
+}
+const XFA_ATTRIBUTEENUMINFO* XFA_GetAttributeEnumByID(XFA_ATTRIBUTEENUM eName) {
+  return g_XFAEnumData + eName;
+}
+int32_t XFA_GetAttributeCount() {
+  return g_iXFAAttributeCount;
+}
+const XFA_ATTRIBUTEINFO* XFA_GetAttributeByName(const CFX_WideStringC& wsName) {
+  int32_t iLength = wsName.GetLength();
+  if (iLength == 0) {
+    return NULL;
+  }
+  uint32_t uHash = FX_HashCode_String_GetW(wsName.GetPtr(), iLength);
+  int32_t iStart = 0, iEnd = g_iXFAAttributeCount - 1;
+  do {
+    int32_t iMid = (iStart + iEnd) / 2;
+    const XFA_ATTRIBUTEINFO* pInfo = g_XFAAttributeData + iMid;
+    if (uHash == pInfo->uHash) {
+      return pInfo;
+    } else if (uHash < pInfo->uHash) {
+      iEnd = iMid - 1;
+    } else {
+      iStart = iMid + 1;
+    }
+  } while (iStart <= iEnd);
+  return NULL;
+}
+const XFA_ATTRIBUTEINFO* XFA_GetAttributeByID(XFA_ATTRIBUTE eName) {
+  return (eName < g_iXFAAttributeCount) ? (g_XFAAttributeData + eName) : NULL;
+}
+FX_BOOL XFA_GetAttributeDefaultValue(void*& pValue,
+                                     XFA_ELEMENT eElement,
+                                     XFA_ATTRIBUTE eAttribute,
+                                     XFA_ATTRIBUTETYPE eType,
+                                     FX_DWORD dwPacket) {
+  const XFA_ATTRIBUTEINFO* pInfo = XFA_GetAttributeByID(eAttribute);
+  if (pInfo == NULL) {
+    return FALSE;
+  }
+  if (dwPacket && (dwPacket & pInfo->dwPackets) == 0) {
+    return FALSE;
+  }
+  if (pInfo->eType == eType) {
+    pValue = pInfo->pDefValue;
+    return TRUE;
+  } else if (pInfo->eType == XFA_ATTRIBUTETYPE_NOTSURE) {
+    const XFA_NOTSUREATTRIBUTE* pAttr =
+        XFA_GetNotsureAttribute(eElement, eAttribute, eType);
+    if (pAttr) {
+      pValue = pAttr->pValue;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+XFA_ATTRIBUTEENUM XFA_GetAttributeDefaultValue_Enum(XFA_ELEMENT eElement,
+                                                    XFA_ATTRIBUTE eAttribute,
+                                                    FX_DWORD dwPacket) {
+  void* pValue;
+  if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
+                                   XFA_ATTRIBUTETYPE_Enum, dwPacket)) {
+    return (XFA_ATTRIBUTEENUM)(uintptr_t)pValue;
+  }
+  return XFA_ATTRIBUTEENUM_Unknown;
+}
+CFX_WideStringC XFA_GetAttributeDefaultValue_Cdata(XFA_ELEMENT eElement,
+                                                   XFA_ATTRIBUTE eAttribute,
+                                                   FX_DWORD dwPacket) {
+  void* pValue;
+  if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
+                                   XFA_ATTRIBUTETYPE_Cdata, dwPacket)) {
+    return (const FX_WCHAR*)pValue;
+  }
+  return NULL;
+}
+FX_BOOL XFA_GetAttributeDefaultValue_Boolean(XFA_ELEMENT eElement,
+                                             XFA_ATTRIBUTE eAttribute,
+                                             FX_DWORD dwPacket) {
+  void* pValue;
+  if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
+                                   XFA_ATTRIBUTETYPE_Boolean, dwPacket)) {
+    return (FX_BOOL)(uintptr_t)pValue;
+  }
+  return FALSE;
+}
+int32_t XFA_GetAttributeDefaultValue_Integer(XFA_ELEMENT eElement,
+                                             XFA_ATTRIBUTE eAttribute,
+                                             FX_DWORD dwPacket) {
+  void* pValue;
+  if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
+                                   XFA_ATTRIBUTETYPE_Integer, dwPacket)) {
+    return (int32_t)(uintptr_t)pValue;
+  }
+  return 0;
+}
+CXFA_Measurement XFA_GetAttributeDefaultValue_Measure(XFA_ELEMENT eElement,
+                                                      XFA_ATTRIBUTE eAttribute,
+                                                      FX_DWORD dwPacket) {
+  void* pValue;
+  if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute,
+                                   XFA_ATTRIBUTETYPE_Measure, dwPacket)) {
+    return *(CXFA_Measurement*)pValue;
+  }
+  return CXFA_Measurement();
+}
+int32_t XFA_GetElementCount() {
+  return g_iXFAElementCount;
+}
+const XFA_ELEMENTINFO* XFA_GetElementByName(const CFX_WideStringC& wsName) {
+  int32_t iLength = wsName.GetLength();
+  if (iLength == 0) {
+    return NULL;
+  }
+  uint32_t uHash = FX_HashCode_String_GetW(wsName.GetPtr(), iLength);
+  int32_t iStart = 0, iEnd = g_iXFAElementCount - 1;
+  do {
+    int32_t iMid = (iStart + iEnd) / 2;
+    const XFA_ELEMENTINFO* pInfo = g_XFAElementData + iMid;
+    if (uHash == pInfo->uHash) {
+      return pInfo;
+    } else if (uHash < pInfo->uHash) {
+      iEnd = iMid - 1;
+    } else {
+      iStart = iMid + 1;
+    }
+  } while (iStart <= iEnd);
+  return NULL;
+}
+const XFA_ELEMENTINFO* XFA_GetElementByID(XFA_ELEMENT eName) {
+  return (eName < g_iXFAElementCount) ? (g_XFAElementData + eName) : NULL;
+}
+const FX_WORD* XFA_GetElementChildren(XFA_ELEMENT eElement, int32_t& iCount) {
+  if (eElement >= g_iXFAElementCount) {
+    return NULL;
+  }
+  const XFA_ELEMENTHIERARCHY* pElement = g_XFAElementChildrenIndex + eElement;
+  iCount = pElement->wCount;
+  return g_XFAElementChildrenData + pElement->wStart;
+}
+const uint8_t* XFA_GetElementAttributes(XFA_ELEMENT eElement, int32_t& iCount) {
+  if (eElement >= g_iXFAElementCount) {
+    return NULL;
+  }
+  const XFA_ELEMENTHIERARCHY* pElement = g_XFAElementAttributeIndex + eElement;
+  iCount = pElement->wCount;
+  return g_XFAElementAttributeData + pElement->wStart;
+}
+const XFA_ATTRIBUTEINFO* XFA_GetAttributeOfElement(XFA_ELEMENT eElement,
+                                                   XFA_ATTRIBUTE eAttribute,
+                                                   FX_DWORD dwPacket) {
+  int32_t iCount = 0;
+  const uint8_t* pAttr = XFA_GetElementAttributes(eElement, iCount);
+  if (pAttr == NULL || iCount < 1) {
+    return NULL;
+  }
+  CFX_DSPATemplate<uint8_t> search;
+  int32_t index = search.Lookup(eAttribute, pAttr, iCount);
+  if (index < 0) {
+    return NULL;
+  }
+  const XFA_ATTRIBUTEINFO* pInfo = XFA_GetAttributeByID(eAttribute);
+  ASSERT(pInfo);
+  if (dwPacket == XFA_XDPPACKET_UNKNOWN)
+    return pInfo;
+  return (dwPacket & pInfo->dwPackets) ? pInfo : NULL;
+}
+const XFA_ELEMENTINFO* XFA_GetChildOfElement(XFA_ELEMENT eElement,
+                                             XFA_ELEMENT eChild,
+                                             FX_DWORD dwPacket) {
+  int32_t iCount = 0;
+  const FX_WORD* pChild = XFA_GetElementChildren(eElement, iCount);
+  if (pChild == NULL || iCount < 1) {
+    return NULL;
+  }
+  CFX_DSPATemplate<FX_WORD> search;
+  int32_t index = search.Lookup(eChild, pChild, iCount);
+  if (index < 0) {
+    return NULL;
+  }
+  const XFA_ELEMENTINFO* pInfo = XFA_GetElementByID(eChild);
+  ASSERT(pInfo);
+  if (dwPacket == XFA_XDPPACKET_UNKNOWN)
+    return pInfo;
+  return (dwPacket & pInfo->dwPackets) ? pInfo : NULL;
+}
+const XFA_PROPERTY* XFA_GetElementProperties(XFA_ELEMENT eElement,
+                                             int32_t& iCount) {
+  if (eElement >= g_iXFAElementCount) {
+    return NULL;
+  }
+  const XFA_ELEMENTHIERARCHY* pElement = g_XFAElementPropertyIndex + eElement;
+  iCount = pElement->wCount;
+  return g_XFAElementPropertyData + pElement->wStart;
+}
+const XFA_PROPERTY* XFA_GetPropertyOfElement(XFA_ELEMENT eElement,
+                                             XFA_ELEMENT eProperty,
+                                             FX_DWORD dwPacket) {
+  int32_t iCount = 0;
+  const XFA_PROPERTY* pProperty = XFA_GetElementProperties(eElement, iCount);
+  if (pProperty == NULL || iCount < 1) {
+    return NULL;
+  }
+  int32_t iStart = 0, iEnd = iCount - 1, iMid;
+  do {
+    iMid = (iStart + iEnd) / 2;
+    XFA_ELEMENT eName = (XFA_ELEMENT)pProperty[iMid].eName;
+    if (eProperty == eName) {
+      break;
+    } else if (eProperty < eName) {
+      iEnd = iMid - 1;
+    } else {
+      iStart = iMid + 1;
+    }
+  } while (iStart <= iEnd);
+  if (iStart > iEnd) {
+    return NULL;
+  }
+  const XFA_ELEMENTINFO* pInfo = XFA_GetElementByID(eProperty);
+  ASSERT(pInfo);
+  if (dwPacket == XFA_XDPPACKET_UNKNOWN)
+    return pProperty + iMid;
+  return (dwPacket & pInfo->dwPackets) ? (pProperty + iMid) : NULL;
+}
+const XFA_NOTSUREATTRIBUTE* XFA_GetNotsureAttribute(XFA_ELEMENT eElement,
+                                                    XFA_ATTRIBUTE eAttribute,
+                                                    XFA_ATTRIBUTETYPE eType) {
+  int32_t iStart = 0, iEnd = g_iXFANotsureCount - 1;
+  do {
+    int32_t iMid = (iStart + iEnd) / 2;
+    const XFA_NOTSUREATTRIBUTE* pAttr = g_XFANotsureAttributes + iMid;
+    if (eElement == pAttr->eElement) {
+      if (pAttr->eAttribute == eAttribute) {
+        if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType) {
+          return pAttr;
+        }
+        return NULL;
+      } else {
+        int32_t iBefore = iMid - 1;
+        if (iBefore >= 0) {
+          pAttr = g_XFANotsureAttributes + iBefore;
+          while (eElement == pAttr->eElement) {
+            if (pAttr->eAttribute == eAttribute) {
+              if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType) {
+                return pAttr;
+              }
+              return NULL;
+            }
+            iBefore--;
+            if (iBefore < 0) {
+              break;
+            }
+            pAttr = g_XFANotsureAttributes + iBefore;
+          }
+        }
+        int32_t iAfter = iMid + 1;
+        if (iAfter <= g_iXFANotsureCount - 1) {
+          pAttr = g_XFANotsureAttributes + iAfter;
+          while (eElement == pAttr->eElement) {
+            if (pAttr->eAttribute == eAttribute) {
+              if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType) {
+                return pAttr;
+              }
+              return NULL;
+            }
+            iAfter++;
+            if (iAfter > g_iXFANotsureCount - 1) {
+              break;
+            }
+            pAttr = g_XFANotsureAttributes + iAfter;
+          }
+        }
+        return NULL;
+      }
+    } else if (eElement < pAttr->eElement) {
+      iEnd = iMid - 1;
+    } else {
+      iStart = iMid + 1;
+    }
+  } while (iStart <= iEnd);
+  return NULL;
+}
+int32_t XFA_GetMethodCount() {
+  return g_iSomMethodCount;
+}
+const XFA_METHODINFO* XFA_GetMethodByName(XFA_ELEMENT eElement,
+                                          const CFX_WideStringC& wsMethodName) {
+  int32_t iLength = wsMethodName.GetLength();
+  if (iLength == 0) {
+    return NULL;
+  }
+  int32_t iElementIndex = eElement;
+  while (iElementIndex != -1) {
+    XFA_LPCSCRIPTHIERARCHY scriptIndex = g_XFAScriptIndex + iElementIndex;
+    int32_t icount = scriptIndex->wMethodCount;
+    if (icount == 0) {
+      iElementIndex = scriptIndex->wParentIndex;
+      continue;
+    }
+    uint32_t uHash = FX_HashCode_String_GetW(wsMethodName.GetPtr(), iLength);
+    int32_t iStart = scriptIndex->wMethodStart, iEnd = iStart + icount - 1;
+    do {
+      int32_t iMid = (iStart + iEnd) / 2;
+      const XFA_METHODINFO* pInfo = g_SomMethodData + iMid;
+      if (uHash == pInfo->uHash) {
+        return pInfo;
+      } else if (uHash < pInfo->uHash) {
+        iEnd = iMid - 1;
+      } else {
+        iStart = iMid + 1;
+      }
+    } while (iStart <= iEnd);
+    iElementIndex = scriptIndex->wParentIndex;
+  }
+  return NULL;
+}
+const XFA_SCRIPTATTRIBUTEINFO* XFA_GetScriptAttributeByName(
+    XFA_ELEMENT eElement,
+    const CFX_WideStringC& wsAttributeName) {
+  int32_t iLength = wsAttributeName.GetLength();
+  if (iLength == 0) {
+    return NULL;
+  }
+  int32_t iElementIndex = eElement;
+  while (iElementIndex != -1) {
+    XFA_LPCSCRIPTHIERARCHY scriptIndex = g_XFAScriptIndex + iElementIndex;
+    int32_t icount = scriptIndex->wAttributeCount;
+    if (icount == 0) {
+      iElementIndex = scriptIndex->wParentIndex;
+      continue;
+    }
+    uint32_t uHash = FX_HashCode_String_GetW(wsAttributeName.GetPtr(), iLength);
+    int32_t iStart = scriptIndex->wAttributeStart, iEnd = iStart + icount - 1;
+    do {
+      int32_t iMid = (iStart + iEnd) / 2;
+      const XFA_SCRIPTATTRIBUTEINFO* pInfo = g_SomAttributeData + iMid;
+      if (uHash == pInfo->uHash) {
+        return pInfo;
+      } else if (uHash < pInfo->uHash) {
+        iEnd = iMid - 1;
+      } else {
+        iStart = iMid + 1;
+      }
+    } while (iStart <= iEnd);
+    iElementIndex = scriptIndex->wParentIndex;
+  }
+  return NULL;
+}
+void CXFA_Measurement::Set(const CFX_WideStringC& wsMeasure) {
+  if (wsMeasure.IsEmpty()) {
+    m_fValue = 0;
+    m_eUnit = XFA_UNIT_Unknown;
+    return;
+  }
+  int32_t iUsedLen = 0;
+  int32_t iOffset = (wsMeasure.GetAt(0) == L'=') ? 1 : 0;
+  FX_FLOAT fValue = FX_wcstof(wsMeasure.GetPtr() + iOffset,
+                              wsMeasure.GetLength() - iOffset, &iUsedLen);
+  XFA_UNIT eUnit = GetUnit(wsMeasure.Mid(iOffset + iUsedLen));
+  Set(fValue, eUnit);
+}
+FX_BOOL CXFA_Measurement::ToString(CFX_WideString& wsMeasure) const {
+  switch (GetUnit()) {
+    case XFA_UNIT_Mm:
+      wsMeasure.Format(L"%.8gmm", GetValue());
+      return TRUE;
+    case XFA_UNIT_Pt:
+      wsMeasure.Format(L"%.8gpt", GetValue());
+      return TRUE;
+    case XFA_UNIT_In:
+      wsMeasure.Format(L"%.8gin", GetValue());
+      return TRUE;
+    case XFA_UNIT_Cm:
+      wsMeasure.Format(L"%.8gcm", GetValue());
+      return TRUE;
+    case XFA_UNIT_Mp:
+      wsMeasure.Format(L"%.8gmp", GetValue());
+      return TRUE;
+    case XFA_UNIT_Pc:
+      wsMeasure.Format(L"%.8gpc", GetValue());
+      return TRUE;
+    case XFA_UNIT_Em:
+      wsMeasure.Format(L"%.8gem", GetValue());
+      return TRUE;
+    case XFA_UNIT_Percent:
+      wsMeasure.Format(L"%.8g%%", GetValue());
+      return TRUE;
+    default:
+      wsMeasure.Format(L"%.8g", GetValue());
+      return FALSE;
+  }
+}
+FX_BOOL CXFA_Measurement::ToUnit(XFA_UNIT eUnit, FX_FLOAT& fValue) const {
+  fValue = GetValue();
+  XFA_UNIT eFrom = GetUnit();
+  if (eFrom == eUnit) {
+    return TRUE;
+  }
+  switch (eFrom) {
+    case XFA_UNIT_Pt:
+      break;
+    case XFA_UNIT_Mm:
+      fValue *= 72 / 2.54f / 10;
+      break;
+    case XFA_UNIT_In:
+      fValue *= 72;
+      break;
+    case XFA_UNIT_Cm:
+      fValue *= 72 / 2.54f;
+      break;
+    case XFA_UNIT_Mp:
+      fValue *= 0.001f;
+      break;
+    case XFA_UNIT_Pc:
+      fValue *= 12.0f;
+      break;
+    default:
+      fValue = 0;
+      return FALSE;
+  }
+  switch (eUnit) {
+    case XFA_UNIT_Pt:
+      return TRUE;
+    case XFA_UNIT_Mm:
+      fValue /= 72 / 2.54f / 10;
+      return TRUE;
+    case XFA_UNIT_In:
+      fValue /= 72;
+      return TRUE;
+    case XFA_UNIT_Cm:
+      fValue /= 72 / 2.54f;
+      return TRUE;
+    case XFA_UNIT_Mp:
+      fValue /= 0.001f;
+      return TRUE;
+    case XFA_UNIT_Pc:
+      fValue /= 12.0f;
+      return TRUE;
+    default:
+      fValue = 0;
+      return FALSE;
+  }
+  return FALSE;
+}
+XFA_UNIT CXFA_Measurement::GetUnit(const CFX_WideStringC& wsUnit) {
+  if (wsUnit == FX_WSTRC(L"mm")) {
+    return XFA_UNIT_Mm;
+  } else if (wsUnit == FX_WSTRC(L"pt")) {
+    return XFA_UNIT_Pt;
+  } else if (wsUnit == FX_WSTRC(L"in")) {
+    return XFA_UNIT_In;
+  } else if (wsUnit == FX_WSTRC(L"cm")) {
+    return XFA_UNIT_Cm;
+  } else if (wsUnit == FX_WSTRC(L"pc")) {
+    return XFA_UNIT_Pc;
+  } else if (wsUnit == FX_WSTRC(L"mp")) {
+    return XFA_UNIT_Mp;
+  } else if (wsUnit == FX_WSTRC(L"em")) {
+    return XFA_UNIT_Em;
+  } else if (wsUnit == FX_WSTRC(L"%")) {
+    return XFA_UNIT_Percent;
+  } else {
+    return XFA_UNIT_Unknown;
+  }
+}
+IFX_Stream* XFA_CreateWideTextRead(const CFX_WideString& wsBuffer) {
+  return new CXFA_WideTextRead(wsBuffer);
+}
+CXFA_WideTextRead::CXFA_WideTextRead(const CFX_WideString& wsBuffer)
+    : m_wsBuffer(wsBuffer), m_iPosition(0), m_iRefCount(1) {}
+void CXFA_WideTextRead::Release() {
+  if (--m_iRefCount < 1) {
+    delete this;
+  }
+}
+IFX_Stream* CXFA_WideTextRead::Retain() {
+  m_iRefCount++;
+  return this;
+}
+FX_DWORD CXFA_WideTextRead::GetAccessModes() const {
+  return FX_STREAMACCESS_Read | FX_STREAMACCESS_Text;
+}
+int32_t CXFA_WideTextRead::GetLength() const {
+  return m_wsBuffer.GetLength() * sizeof(FX_WCHAR);
+}
+int32_t CXFA_WideTextRead::Seek(FX_STREAMSEEK eSeek, int32_t iOffset) {
+  switch (eSeek) {
+    case FX_STREAMSEEK_Begin:
+      m_iPosition = iOffset;
+      break;
+    case FX_STREAMSEEK_Current:
+      m_iPosition += iOffset;
+      break;
+    case FX_STREAMSEEK_End:
+      m_iPosition = m_wsBuffer.GetLength() + iOffset;
+      break;
+  }
+  if (m_iPosition < 0) {
+    m_iPosition = 0;
+  }
+  if (m_iPosition > m_wsBuffer.GetLength()) {
+    m_iPosition = m_wsBuffer.GetLength();
+  }
+  return GetPosition();
+}
+int32_t CXFA_WideTextRead::GetPosition() {
+  return m_iPosition * sizeof(FX_WCHAR);
+}
+FX_BOOL CXFA_WideTextRead::IsEOF() const {
+  return m_iPosition >= m_wsBuffer.GetLength();
+}
+int32_t CXFA_WideTextRead::ReadString(FX_WCHAR* pStr,
+                                      int32_t iMaxLength,
+                                      FX_BOOL& bEOS,
+                                      int32_t const* pByteSize) {
+  if (iMaxLength > m_wsBuffer.GetLength() - m_iPosition) {
+    iMaxLength = m_wsBuffer.GetLength() - m_iPosition;
+  }
+  FXSYS_wcsncpy(pStr, (const FX_WCHAR*)m_wsBuffer + m_iPosition, iMaxLength);
+  m_iPosition += iMaxLength;
+  bEOS = IsEOF();
+  return iMaxLength;
+}
+FX_WORD CXFA_WideTextRead::GetCodePage() const {
+  return (sizeof(FX_WCHAR) == 2) ? FX_CODEPAGE_UTF16LE : FX_CODEPAGE_UTF32LE;
+}
+FX_WORD CXFA_WideTextRead::SetCodePage(FX_WORD wCodePage) {
+  return GetCodePage();
+}
diff --git a/xfa/fxfa/parser/xfa_basic_imp.h b/xfa/fxfa/parser/xfa_basic_imp.h
new file mode 100644
index 0000000..7e67d2b
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_basic_imp.h
@@ -0,0 +1,71 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_BASIC_IMP_H_
+#define XFA_FXFA_PARSER_XFA_BASIC_IMP_H_
+
+#include "xfa/fgas/crt/fgas_stream.h"
+#include "xfa/include/fxfa/fxfa_basic.h"
+
+struct XFA_NOTSUREATTRIBUTE {
+  XFA_ELEMENT eElement;
+  XFA_ATTRIBUTE eAttribute;
+  XFA_ATTRIBUTETYPE eType;
+  void* pValue;
+};
+const XFA_NOTSUREATTRIBUTE* XFA_GetNotsureAttribute(
+    XFA_ELEMENT eElement,
+    XFA_ATTRIBUTE eAttribute,
+    XFA_ATTRIBUTETYPE eType = XFA_ATTRIBUTETYPE_NOTSURE);
+
+class CXFA_WideTextRead : public IFX_Stream {
+ public:
+  CXFA_WideTextRead(const CFX_WideString& wsBuffer);
+  virtual void Release();
+  virtual IFX_Stream* Retain();
+
+  virtual FX_DWORD GetAccessModes() const;
+  virtual int32_t GetLength() const;
+  virtual int32_t Seek(FX_STREAMSEEK eSeek, int32_t iOffset);
+  virtual int32_t GetPosition();
+  virtual FX_BOOL IsEOF() const;
+
+  virtual int32_t ReadData(uint8_t* pBuffer, int32_t iBufferSize) { return 0; }
+  virtual int32_t ReadString(FX_WCHAR* pStr,
+                             int32_t iMaxLength,
+                             FX_BOOL& bEOS,
+                             int32_t const* pByteSize = NULL);
+  virtual int32_t WriteData(const uint8_t* pBuffer, int32_t iBufferSize) {
+    return 0;
+  }
+  virtual int32_t WriteString(const FX_WCHAR* pStr, int32_t iLength) {
+    return 0;
+  }
+  virtual void Flush() {}
+  virtual FX_BOOL SetLength(int32_t iLength) { return FALSE; }
+
+  virtual int32_t GetBOM(uint8_t bom[4]) const { return 0; }
+  virtual FX_WORD GetCodePage() const;
+  virtual FX_WORD SetCodePage(FX_WORD wCodePage);
+
+  virtual void Lock() {}
+  virtual void Unlock() {}
+
+  virtual IFX_Stream* CreateSharedStream(FX_DWORD dwAccess,
+                                         int32_t iOffset,
+                                         int32_t iLength) {
+    return NULL;
+  }
+
+  CFX_WideString GetSrcText() const { return m_wsBuffer; }
+
+ protected:
+  CFX_WideString m_wsBuffer;
+  int32_t m_iPosition;
+  int32_t m_iRefCount;
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_BASIC_IMP_H_
diff --git a/xfa/fxfa/parser/xfa_docdata.h b/xfa/fxfa/parser/xfa_docdata.h
new file mode 100644
index 0000000..b3c3edd
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_docdata.h
@@ -0,0 +1,36 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_DOCDATA_H_
+#define XFA_FXFA_PARSER_XFA_DOCDATA_H_
+
+#include "xfa/fxfa/parser/xfa_document.h"
+
+enum XFA_DATAFORMAT {
+  XFA_DATAFORMAT_XDP,
+};
+
+class IXFA_PacketExport {
+ public:
+  static IXFA_PacketExport* Create(CXFA_Document* pDocument,
+                                   XFA_DATAFORMAT eFormat = XFA_DATAFORMAT_XDP);
+  virtual ~IXFA_PacketExport() {}
+  virtual void Release() = 0;
+  virtual FX_BOOL Export(IFX_FileWrite* pWrite) = 0;
+  virtual FX_BOOL Export(IFX_FileWrite* pWrite,
+                         CXFA_Node* pNode,
+                         FX_DWORD dwFlag = 0,
+                         const FX_CHAR* pChecksum = NULL) = 0;
+};
+class IXFA_PacketImport {
+ public:
+  static IXFA_PacketImport* Create(CXFA_Document* pDstDoc);
+  virtual ~IXFA_PacketImport() {}
+  virtual void Release() = 0;
+  virtual FX_BOOL ImportData(IFX_FileRead* pDataDocument) = 0;
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_DOCDATA_H_
diff --git a/xfa/fxfa/parser/xfa_doclayout.h b/xfa/fxfa/parser/xfa_doclayout.h
new file mode 100644
index 0000000..bb44868
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_doclayout.h
@@ -0,0 +1,136 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_DOCLAYOUT_H_
+#define XFA_FXFA_PARSER_XFA_DOCLAYOUT_H_
+
+#include "xfa/fxfa/parser/xfa_document.h"
+
+class CXFA_ContainerLayoutItem;
+class CXFA_ContentLayoutItem;
+class IXFA_DocLayout;
+
+class IXFA_LayoutPage {
+ public:
+  virtual ~IXFA_LayoutPage() {}
+  virtual IXFA_DocLayout* GetLayout() const = 0;
+  virtual int32_t GetPageIndex() const = 0;
+  virtual void GetPageSize(CFX_SizeF& size) = 0;
+  virtual CXFA_Node* GetMasterPage() const = 0;
+};
+
+class CXFA_LayoutItem {
+ public:
+  virtual ~CXFA_LayoutItem();
+
+  FX_BOOL IsContainerLayoutItem() const { return !m_bIsContentLayoutItem; }
+  FX_BOOL IsContentLayoutItem() const { return m_bIsContentLayoutItem; }
+  inline CXFA_ContainerLayoutItem* AsContainerLayoutItem();
+  inline CXFA_ContentLayoutItem* AsContentLayoutItem();
+
+  IXFA_LayoutPage* GetPage() const;
+  CXFA_Node* GetFormNode() const;
+  void GetRect(CFX_RectF& rtLayout, FX_BOOL bRelative = FALSE) const;
+  int32_t GetIndex() const;
+  int32_t GetCount() const;
+  CXFA_LayoutItem* GetParent() const;
+  const CXFA_LayoutItem* GetFirst() const;
+  CXFA_LayoutItem* GetFirst();
+  const CXFA_LayoutItem* GetLast() const;
+  CXFA_LayoutItem* GetLast();
+  CXFA_LayoutItem* GetPrev() const;
+  CXFA_LayoutItem* GetNext() const;
+
+  void AddChild(CXFA_LayoutItem* pChildItem);
+  void AddHeadChild(CXFA_LayoutItem* pChildItem);
+  void RemoveChild(CXFA_LayoutItem* pChildItem);
+  void InsertChild(CXFA_LayoutItem* pBeforeItem, CXFA_LayoutItem* pChildItem);
+
+  CXFA_Node* m_pFormNode;
+  CXFA_LayoutItem* m_pParent;
+  CXFA_LayoutItem* m_pNextSibling;
+  CXFA_LayoutItem* m_pFirstChild;
+
+ protected:
+  CXFA_LayoutItem(CXFA_Node* pNode, FX_BOOL bIsContentLayoutItem);
+
+  FX_BOOL m_bIsContentLayoutItem;
+};
+
+class CXFA_ContainerLayoutItem : public CXFA_LayoutItem,
+                                 public IXFA_LayoutPage {
+ public:
+  CXFA_ContainerLayoutItem(CXFA_Node* pNode);
+
+  // IXFA_LayoutPage:
+  IXFA_DocLayout* GetLayout() const override;
+  int32_t GetPageIndex() const override;
+  void GetPageSize(CFX_SizeF& size) override;
+  CXFA_Node* GetMasterPage() const override;
+
+  CXFA_Node* m_pOldSubform;
+};
+
+#define XFA_WIDGETSTATUS_Access 0x80000000
+#define XFA_WIDGETSTATUS_Disabled 0x40000000
+#define XFA_WIDGETSTATUS_RectCached 0x20000000
+#define XFA_WIDGETSTATUS_ButtonDown 0x10000000
+#define XFA_WIDGETSTATUS_Highlight 0x08000000
+#define XFA_WIDGETSTATUS_TextEditValueChanged 0x04000000
+
+class CXFA_ContentLayoutItem : public CXFA_LayoutItem {
+ public:
+  CXFA_ContentLayoutItem(CXFA_Node* pNode);
+  virtual ~CXFA_ContentLayoutItem();
+
+  CXFA_ContentLayoutItem* m_pPrev;
+  CXFA_ContentLayoutItem* m_pNext;
+  CFX_PointF m_sPos;
+  CFX_SizeF m_sSize;
+  FX_DWORD m_dwStatus;
+};
+
+CXFA_ContainerLayoutItem* CXFA_LayoutItem::AsContainerLayoutItem() {
+  return IsContainerLayoutItem() ? static_cast<CXFA_ContainerLayoutItem*>(this)
+                                 : nullptr;
+}
+CXFA_ContentLayoutItem* CXFA_LayoutItem::AsContentLayoutItem() {
+  return IsContentLayoutItem() ? static_cast<CXFA_ContentLayoutItem*>(this)
+                               : nullptr;
+}
+inline CXFA_ContainerLayoutItem* ToContainerLayoutItem(CXFA_LayoutItem* pItem) {
+  return pItem ? pItem->AsContainerLayoutItem() : nullptr;
+}
+inline CXFA_ContentLayoutItem* ToContentLayoutItem(CXFA_LayoutItem* pItem) {
+  return pItem ? pItem->AsContentLayoutItem() : nullptr;
+}
+
+class CXFA_TraverseStrategy_LayoutItem {
+ public:
+  static inline CXFA_LayoutItem* GetFirstChild(CXFA_LayoutItem* pLayoutItem) {
+    return pLayoutItem->m_pFirstChild;
+  }
+  static inline CXFA_LayoutItem* GetNextSibling(CXFA_LayoutItem* pLayoutItem) {
+    return pLayoutItem->m_pNextSibling;
+  }
+  static inline CXFA_LayoutItem* GetParent(CXFA_LayoutItem* pLayoutItem) {
+    return pLayoutItem->m_pParent;
+  }
+};
+
+class IXFA_DocLayout {
+ public:
+  virtual ~IXFA_DocLayout() {}
+  virtual CXFA_Document* GetDocument() const = 0;
+  virtual int32_t StartLayout(FX_BOOL bForceRestart = FALSE) = 0;
+  virtual int32_t DoLayout(IFX_Pause* pPause = NULL) = 0;
+  virtual FX_BOOL IncrementLayout() = 0;
+  virtual int32_t CountPages() const = 0;
+  virtual IXFA_LayoutPage* GetPage(int32_t index) const = 0;
+  virtual CXFA_LayoutItem* GetLayoutItem(CXFA_Node* pFormItem) = 0;
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_DOCLAYOUT_H_
diff --git a/xfa/fxfa/parser/xfa_document.h b/xfa/fxfa/parser/xfa_document.h
new file mode 100644
index 0000000..affe400
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_document.h
@@ -0,0 +1,201 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_DOCUMENT_H_
+#define XFA_FXFA_PARSER_XFA_DOCUMENT_H_
+
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/include/fxfa/fxfa.h"
+
+class CXFA_Document;
+class CXFA_LayoutItem;
+class CXFA_LayoutProcessor;
+class CXFA_Node;
+class IXFA_DocLayout;
+class IXFA_DocParser;
+class IXFA_LayoutPage;
+class IXFA_Notify;
+class IXFA_ObjFactory;
+class IXFA_ScriptContext;
+
+enum XFA_VERSION {
+  XFA_VERSION_UNKNOWN = 0,
+  XFA_VERSION_200 = 200,
+  XFA_VERSION_202 = 202,
+  XFA_VERSION_204 = 204,
+  XFA_VERSION_205 = 205,
+  XFA_VERSION_206 = 206,
+  XFA_VERSION_207 = 207,
+  XFA_VERSION_208 = 208,
+  XFA_VERSION_300 = 300,
+  XFA_VERSION_301 = 301,
+  XFA_VERSION_303 = 303,
+  XFA_VERSION_306 = 306,
+  XFA_VERSION_DEFAULT = XFA_VERSION_303,
+  XFA_VERSION_MIN = 200,
+  XFA_VERSION_MAX = 400,
+};
+
+#define XFA_LAYOUTSTATUS_Visible 0x0001
+#define XFA_LAYOUTSTATUS_Viewable 0x0010
+#define XFA_LAYOUTSTATUS_Printable 0x0020
+enum XFA_NODEEVENT {
+  XFA_NODEEVENT_Ready,
+  XFA_NODEEVENT_ValueChanging,
+  XFA_NODEEVENT_ValueChanged,
+  XFA_NODEEVENT_ChildAdded,
+  XFA_NODEEVENT_ChildRemoved,
+};
+enum XFA_PAGEEVENT {
+  XFA_PAGEEVENT_PageAdded,
+  XFA_PAGEEVENT_PageRemoved,
+};
+enum XFA_LAYOUTEVENT {
+  XFA_LAYOUTEVENT_ItemAdded,
+  XFA_LAYOUTEVENT_ItemRemoving,
+  XFA_LAYOUTEVENT_RectChanged,
+  XFA_LAYOUTEVENT_StatusChanged,
+};
+enum XFA_LAYOUTRESULT {
+  XFA_LAYOUTRESULT_Continue,
+  XFA_LAYOUTRESULT_Done,
+  XFA_LAYOUTRESULT_NextContent,
+};
+#define XFA_LAYOUTNOTIFY_StrictHeight 0x0001
+#define XFA_LAYOUTNOTIFY_NoParentBreak 0x0002
+
+class IXFA_Notify {
+ public:
+  virtual ~IXFA_Notify() {}
+  virtual void OnPageEvent(IXFA_LayoutPage* pSender,
+                           XFA_PAGEEVENT eEvent,
+                           void* pParam = NULL) = 0;
+
+  virtual void OnNodeEvent(CXFA_Node* pSender,
+                           XFA_NODEEVENT eEvent,
+                           void* pParam = NULL,
+                           void* pParam2 = NULL,
+                           void* pParam3 = NULL,
+                           void* pParam4 = NULL) = 0;
+  virtual void OnWidgetDataEvent(CXFA_WidgetData* pSender,
+                                 FX_DWORD dwEvent,
+                                 void* pParam = NULL,
+                                 void* pAdditional = NULL,
+                                 void* pAdditional2 = NULL) = 0;
+
+  virtual CXFA_LayoutItem* OnCreateLayoutItem(CXFA_Node* pNode) = 0;
+  virtual void OnLayoutEvent(IXFA_DocLayout* pLayout,
+                             CXFA_LayoutItem* pSender,
+                             XFA_LAYOUTEVENT eEvent,
+                             void* pParam = NULL,
+                             void* pParam2 = NULL) = 0;
+  virtual void StartFieldDrawLayout(CXFA_Node* pItem,
+                                    FX_FLOAT& fCalcWidth,
+                                    FX_FLOAT& fCalcHeight) = 0;
+  virtual FX_BOOL FindSplitPos(CXFA_Node* pItem,
+                               int32_t iBlockIndex,
+                               FX_FLOAT& fCalcHeightPos) = 0;
+  virtual FX_BOOL RunScript(CXFA_Node* pScript, CXFA_Node* pFormItem) = 0;
+  virtual int32_t ExecEventByDeepFirst(CXFA_Node* pFormNode,
+                                       XFA_EVENTTYPE eEventType,
+                                       FX_BOOL bIsFormReady = FALSE,
+                                       FX_BOOL bRecursive = TRUE,
+                                       CXFA_WidgetAcc* pExclude = NULL) = 0;
+  virtual void AddCalcValidate(CXFA_Node* pNode) = 0;
+  virtual IXFA_Doc* GetHDOC() = 0;
+  virtual IXFA_DocProvider* GetDocProvider() = 0;
+  virtual IXFA_AppProvider* GetAppProvider() = 0;
+  virtual IXFA_WidgetHandler* GetWidgetHandler() = 0;
+  virtual IXFA_Widget* GetHWidget(CXFA_LayoutItem* pLayoutItem) = 0;
+  virtual void OpenDropDownList(IXFA_Widget* hWidget) = 0;
+  virtual CFX_WideString GetCurrentDateTime() = 0;
+  virtual void ResetData(CXFA_WidgetData* pWidgetData = NULL) = 0;
+  virtual int32_t GetLayoutStatus() = 0;
+  virtual void RunNodeInitialize(CXFA_Node* pNode) = 0;
+  virtual void RunSubformIndexChange(CXFA_Node* pSubformNode) = 0;
+  virtual CXFA_Node* GetFocusWidgetNode() = 0;
+  virtual void SetFocusWidgetNode(CXFA_Node* pNode) = 0;
+};
+class IXFA_ObjFactory {
+ public:
+  virtual ~IXFA_ObjFactory() {}
+  virtual CXFA_Node* CreateNode(FX_DWORD dwPacket, XFA_ELEMENT eElement) = 0;
+  virtual CXFA_Node* CreateNode(const XFA_PACKETINFO* pPacket,
+                                XFA_ELEMENT eElement) = 0;
+};
+#define XFA_DOCFLAG_StrictScoping 0x0001
+#define XFA_DOCFLAG_HasInteractive 0x0002
+#define XFA_DOCFLAG_Interactive 0x0004
+#define XFA_DOCFLAG_Scripting 0x0008
+class CScript_DataWindow;
+class CScript_EventPseudoModel;
+class CScript_HostPseudoModel;
+class CScript_LogPseudoModel;
+class CScript_LayoutPseudoModel;
+class CScript_SignaturePseudoModel;
+class CXFA_Document : public IXFA_ObjFactory {
+ public:
+  CXFA_Document(IXFA_DocParser* pParser);
+  ~CXFA_Document();
+  CXFA_Node* GetRoot() const { return m_pRootNode; }
+  IXFA_DocParser* GetParser() const { return m_pParser; }
+  IXFA_Notify* GetNotify() const;
+  void SetRoot(CXFA_Node* pNewRoot);
+  CXFA_Object* GetXFAObject(const CFX_WideStringC& wsNodeName);
+  CXFA_Object* GetXFAObject(FX_DWORD wsNodeNameHash);
+  void AddPurgeNode(CXFA_Node* pNode);
+  FX_BOOL RemovePurgeNode(CXFA_Node* pNode);
+  void PurgeNodes();
+  bool HasFlag(FX_DWORD dwFlag) { return (m_dwDocFlags & dwFlag) == dwFlag; }
+  void SetFlag(FX_DWORD dwFlag, FX_BOOL bOn = TRUE);
+  FX_BOOL IsInteractive();
+  XFA_VERSION GetCurVersionMode() { return m_eCurVersionMode; }
+  XFA_VERSION RecognizeXFAVersionNumber(CFX_WideString& wsTemplateNS);
+  CXFA_LocaleMgr* GetLocalMgr();
+  virtual CXFA_Node* CreateNode(FX_DWORD dwPacket, XFA_ELEMENT eElement);
+  virtual CXFA_Node* CreateNode(const XFA_PACKETINFO* pPacket,
+                                XFA_ELEMENT eElement);
+  void DoProtoMerge();
+  CXFA_Node* GetNodeByID(CXFA_Node* pRoot, const CFX_WideStringC& wsID);
+  void DoDataMerge();
+  void DoDataRemerge(FX_BOOL bDoDataMerge);
+  CXFA_Node* DataMerge_CopyContainer(CXFA_Node* pTemplateNode,
+                                     CXFA_Node* pFormNode,
+                                     CXFA_Node* pDataScope,
+                                     FX_BOOL bOneInstance = FALSE,
+                                     FX_BOOL bDataMerge = TRUE,
+                                     FX_BOOL bUpLevel = TRUE);
+  void DataMerge_UpdateBindingRelations(CXFA_Node* pFormUpdateRoot);
+  CXFA_Node* GetNotBindNode(CXFA_ObjArray& arrayNodes);
+  CXFA_LayoutProcessor* GetLayoutProcessor();
+  IXFA_DocLayout* GetDocLayout();
+  IXFA_ScriptContext* InitScriptContext(FXJSE_HRUNTIME hRuntime);
+  IXFA_ScriptContext* GetScriptContext();
+  void ClearLayoutData();
+
+  CFX_MapPtrTemplate<FX_DWORD, CXFA_Node*> m_rgGlobalBinding;
+  CXFA_NodeArray m_pPendingPageSet;
+
+ protected:
+  IXFA_DocParser* m_pParser;
+  IXFA_ScriptContext* m_pScriptContext;
+  CXFA_LayoutProcessor* m_pLayoutProcessor;
+  CXFA_Node* m_pRootNode;
+  CXFA_LocaleMgr* m_pLocalMgr;
+  CScript_DataWindow* m_pScriptDataWindow;
+  CScript_EventPseudoModel* m_pScriptEvent;
+  CScript_HostPseudoModel* m_pScriptHost;
+  CScript_LogPseudoModel* m_pScriptLog;
+  CScript_LayoutPseudoModel* m_pScriptLayout;
+  CScript_SignaturePseudoModel* m_pScriptSignature;
+  CXFA_NodeSet m_rgPurgeNodes;
+  XFA_VERSION m_eCurVersionMode;
+  FX_DWORD m_dwDocFlags;
+  friend class CXFA_SimpleParser;
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_DOCUMENT_H_
diff --git a/xfa/fxfa/parser/xfa_document_datadescription_imp.cpp b/xfa/fxfa/parser/xfa_document_datadescription_imp.cpp
new file mode 100644
index 0000000..8cc8d01
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_document_datadescription_imp.cpp
@@ -0,0 +1,126 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+#define XFA_HASHCODE_Group 0xf7f75fcd
+
+class CXFA_TraverseStrategy_DDGroup {
+ public:
+  static inline CXFA_Node* GetFirstChild(CXFA_Node* pDDGroupNode) {
+    return pDDGroupNode->GetFirstChildByName(XFA_HASHCODE_Group);
+  }
+  static inline CXFA_Node* GetNextSibling(CXFA_Node* pDDGroupNode) {
+    return pDDGroupNode->GetNextSameNameSibling(XFA_HASHCODE_Group);
+  }
+  static inline CXFA_Node* GetParent(CXFA_Node* pDDGroupNode) {
+    return pDDGroupNode->GetNodeItem(XFA_NODEITEM_Parent);
+  }
+};
+void XFA_DataDescription_UpdateDataRelation(CXFA_Node* pDataNode,
+                                            CXFA_Node* pDataDescriptionNode) {
+  FXSYS_assert(pDataDescriptionNode);
+  for (CXFA_Node* pDataChild = pDataNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+       pDataChild;
+       pDataChild = pDataChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    FX_DWORD dwNameHash = pDataChild->GetNameHash();
+    XFA_ELEMENT eType = pDataChild->GetClassID();
+    if (!dwNameHash) {
+      continue;
+    }
+    CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_DDGroup>
+        sIterator(pDataDescriptionNode);
+    for (CXFA_Node* pDDGroupNode = sIterator.GetCurrent(); pDDGroupNode;
+         pDDGroupNode = sIterator.MoveToNext()) {
+      if (pDDGroupNode != pDataDescriptionNode) {
+        if (pDDGroupNode->GetClassID() != XFA_ELEMENT_DataGroup) {
+          continue;
+        }
+        CFX_WideString wsNamespace;
+        if (!pDDGroupNode->TryNamespace(wsNamespace) ||
+            wsNamespace != FX_WSTRC(L"http://ns.adobe.com/data-description/")) {
+          continue;
+        }
+      }
+      CXFA_Node* pDDNode = pDDGroupNode->GetFirstChildByName(dwNameHash);
+      if (!pDDNode) {
+        continue;
+      }
+      if (pDDNode->GetClassID() != eType) {
+        break;
+      }
+      pDataChild->SetDataDescriptionNode(pDDNode);
+      XFA_DataDescription_UpdateDataRelation(pDataChild, pDDNode);
+      break;
+    }
+  }
+}
+CXFA_Node* XFA_DataDescription_MaybeCreateDataNode(
+    CXFA_Document* pDocument,
+    CXFA_Node* pDataParent,
+    XFA_ELEMENT eNodeType,
+    const CFX_WideStringC& wsName) {
+  if (!pDataParent) {
+    return NULL;
+  }
+  CXFA_Node* pParentDDNode = pDataParent->GetDataDescriptionNode();
+  if (!pParentDDNode) {
+    CXFA_Node* pDataNode =
+        pDocument->CreateNode(XFA_XDPPACKET_Datasets, eNodeType);
+    FXSYS_assert(pDataNode);
+    pDataNode->SetCData(XFA_ATTRIBUTE_Name, wsName);
+    pDataNode->CreateXMLMappingNode();
+    pDataParent->InsertChild(pDataNode);
+    pDataNode->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+    return pDataNode;
+  } else {
+    CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_DDGroup>
+        sIterator(pParentDDNode);
+    for (CXFA_Node* pDDGroupNode = sIterator.GetCurrent(); pDDGroupNode;
+         pDDGroupNode = sIterator.MoveToNext()) {
+      if (pDDGroupNode != pParentDDNode) {
+        if (pDDGroupNode->GetClassID() != XFA_ELEMENT_DataGroup) {
+          continue;
+        }
+        CFX_WideString wsNamespace;
+        if (!pDDGroupNode->TryNamespace(wsNamespace) ||
+            wsNamespace != FX_WSTRC(L"http://ns.adobe.com/data-description/")) {
+          continue;
+        }
+      }
+      CXFA_Node* pDDNode = pDDGroupNode->GetFirstChildByName(wsName);
+      if (!pDDNode) {
+        continue;
+      }
+      if (pDDNode->GetClassID() != eNodeType) {
+        break;
+      }
+      CXFA_Node* pDataNode =
+          pDocument->CreateNode(XFA_XDPPACKET_Datasets, eNodeType);
+      FXSYS_assert(pDataNode);
+      pDataNode->SetCData(XFA_ATTRIBUTE_Name, wsName);
+      pDataNode->CreateXMLMappingNode();
+      if (eNodeType == XFA_ELEMENT_DataValue &&
+          pDDNode->GetEnum(XFA_ATTRIBUTE_Contains) ==
+              XFA_ATTRIBUTEENUM_MetaData) {
+        pDataNode->SetEnum(XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTEENUM_MetaData);
+      }
+      pDataParent->InsertChild(pDataNode);
+      pDataNode->SetDataDescriptionNode(pDDNode);
+      pDataNode->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+      return pDataNode;
+    }
+    return NULL;
+  }
+}
diff --git a/xfa/fxfa/parser/xfa_document_datadescription_imp.h b/xfa/fxfa/parser/xfa_document_datadescription_imp.h
new file mode 100644
index 0000000..f7c626d
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_document_datadescription_imp.h
@@ -0,0 +1,18 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_DOCUMENT_DATADESCRIPTION_IMP_H_
+#define XFA_FXFA_PARSER_XFA_DOCUMENT_DATADESCRIPTION_IMP_H_
+
+void XFA_DataDescription_UpdateDataRelation(CXFA_Node* pDataNode,
+                                            CXFA_Node* pDataDescriptionNode);
+CXFA_Node* XFA_DataDescription_MaybeCreateDataNode(
+    CXFA_Document* pDocument,
+    CXFA_Node* pDataParent,
+    XFA_ELEMENT eNodeType,
+    const CFX_WideStringC& wsName);
+
+#endif  // XFA_FXFA_PARSER_XFA_DOCUMENT_DATADESCRIPTION_IMP_H_
diff --git a/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp b/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp
new file mode 100644
index 0000000..0dc087a
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp
@@ -0,0 +1,1429 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_document_datamerger_imp.h"
+
+#include "core/include/fxcrt/fx_ext.h"
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_basic_imp.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_document_datadescription_imp.h"
+#include "xfa/fxfa/parser/xfa_document_layout_imp.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+static FX_BOOL XFA_GetOccurInfo(CXFA_Node* pOccurNode,
+                                int32_t& iMin,
+                                int32_t& iMax,
+                                int32_t& iInit) {
+  if (!pOccurNode) {
+    return FALSE;
+  }
+  CXFA_Occur occur(pOccurNode);
+  return occur.GetOccurInfo(iMin, iMax, iInit);
+}
+struct XFA_DataMerge_RecurseRecord {
+  CXFA_Node* pTemplateChild;
+  CXFA_Node* pDataChild;
+};
+static CXFA_Node* XFA_DataMerge_FormValueNode_CreateChild(
+    CXFA_Node* pValueNode,
+    XFA_ELEMENT iType = XFA_ELEMENT_UNKNOWN) {
+  CXFA_Node* pChildNode = pValueNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+  if (!pChildNode) {
+    if (iType == XFA_ELEMENT_UNKNOWN) {
+      return FALSE;
+    }
+    pChildNode = pValueNode->GetProperty(0, iType);
+  }
+  return pChildNode;
+}
+static void XFA_DataMerge_FormValueNode_MatchNoneCreateChild(
+    CXFA_Node* pFormNode) {
+  CXFA_WidgetData* pWidgetData = pFormNode->GetWidgetData();
+  FXSYS_assert(pWidgetData);
+  pWidgetData->GetUIType();
+}
+static FX_BOOL XFA_DataMerge_FormValueNode_SetChildContent(
+    CXFA_Node* pValueNode,
+    const CFX_WideString& wsContent,
+    XFA_ELEMENT iType = XFA_ELEMENT_UNKNOWN) {
+  if (!pValueNode) {
+    return FALSE;
+  }
+  FXSYS_assert(pValueNode->GetPacketID() == XFA_XDPPACKET_Form);
+  CXFA_Node* pChildNode =
+      XFA_DataMerge_FormValueNode_CreateChild(pValueNode, iType);
+  if (!pChildNode) {
+    return FALSE;
+  }
+  XFA_OBJECTTYPE objectType = pChildNode->GetObjectType();
+  switch (objectType) {
+    case XFA_OBJECTTYPE_ContentNode: {
+      CXFA_Node* pContentRawDataNode =
+          pChildNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+      if (!pContentRawDataNode) {
+        XFA_ELEMENT element = XFA_ELEMENT_Sharptext;
+        if (pChildNode->GetClassID() == XFA_ELEMENT_ExData) {
+          CFX_WideString wsContentType;
+          pChildNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType,
+                                   FALSE);
+          if (wsContentType.Equal(FX_WSTRC(L"text/html"))) {
+            element = XFA_ELEMENT_SharpxHTML;
+          } else if (wsContentType.Equal(FX_WSTRC(L"text/xml"))) {
+            element = XFA_ELEMENT_Sharpxml;
+          }
+        }
+        pContentRawDataNode = pChildNode->CreateSamePacketNode(element);
+        pChildNode->InsertChild(pContentRawDataNode);
+      }
+      pContentRawDataNode->SetCData(XFA_ATTRIBUTE_Value, wsContent);
+    } break;
+    case XFA_OBJECTTYPE_NodeC:
+    case XFA_OBJECTTYPE_TextNode:
+    case XFA_OBJECTTYPE_NodeV: {
+      pChildNode->SetCData(XFA_ATTRIBUTE_Value, wsContent);
+    } break;
+    default:
+      FXSYS_assert(FALSE);
+      break;
+  }
+  return TRUE;
+}
+static void XFA_DataMerge_CreateDataBinding(CXFA_Node* pFormNode,
+                                            CXFA_Node* pDataNode,
+                                            FX_BOOL bDataToForm = TRUE) {
+  pFormNode->SetObject(XFA_ATTRIBUTE_BindingNode, pDataNode);
+  pDataNode->AddBindItem(pFormNode);
+  XFA_ELEMENT eClass = pFormNode->GetClassID();
+  if (eClass != XFA_ELEMENT_Field && eClass != XFA_ELEMENT_ExclGroup) {
+    return;
+  }
+  CXFA_WidgetData* pWidgetData = pFormNode->GetWidgetData();
+  FXSYS_assert(pWidgetData);
+  FX_BOOL bNotify = FALSE;
+  XFA_ELEMENT eUIType = pWidgetData->GetUIType();
+  CXFA_Value defValue(pFormNode->GetProperty(0, XFA_ELEMENT_Value));
+  if (!bDataToForm) {
+    CFX_WideString wsValue;
+    CFX_WideString wsFormatedValue;
+    switch (eUIType) {
+      case XFA_ELEMENT_ImageEdit: {
+        CXFA_Image image = defValue.GetImage();
+        CFX_WideString wsContentType;
+        CFX_WideString wsHref;
+        if (image) {
+          image.GetContent(wsValue);
+          image.GetContentType(wsContentType);
+          image.GetHref(wsHref);
+        }
+        IFDE_XMLElement* pXMLDataElement =
+            (IFDE_XMLElement*)(pDataNode->GetXMLMappingNode());
+        FXSYS_assert(pXMLDataElement);
+        pWidgetData->GetFormatDataValue(wsValue, wsFormatedValue);
+        pDataNode->SetAttributeValue(wsValue, wsFormatedValue);
+        pDataNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
+        if (!wsHref.IsEmpty()) {
+          pXMLDataElement->SetString(FX_WSTRC(L"href"), wsHref);
+        }
+      } break;
+      case XFA_ELEMENT_ChoiceList:
+        defValue.GetChildValueContent(wsValue);
+        if (pWidgetData->GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
+          CFX_WideStringArray wsSelTextArray;
+          pWidgetData->GetSelectedItemsValue(wsSelTextArray);
+          int32_t iSize = wsSelTextArray.GetSize();
+          if (iSize >= 1) {
+            CXFA_Node* pValue = NULL;
+            for (int32_t i = 0; i < iSize; i++) {
+              pValue = pDataNode->CreateSamePacketNode(XFA_ELEMENT_DataValue);
+              pValue->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L"value"));
+              pValue->CreateXMLMappingNode();
+              pDataNode->InsertChild(pValue);
+              pValue->SetCData(XFA_ATTRIBUTE_Value, wsSelTextArray[i]);
+            }
+          } else {
+            IFDE_XMLNode* pXMLNode = pDataNode->GetXMLMappingNode();
+            FXSYS_assert(pXMLNode->GetType() == FDE_XMLNODE_Element);
+            ((IFDE_XMLElement*)pXMLNode)
+                ->SetString(FX_WSTRC(L"xfa:dataNode"), FX_WSTRC(L"dataGroup"));
+          }
+        } else if (!wsValue.IsEmpty()) {
+          pWidgetData->GetFormatDataValue(wsValue, wsFormatedValue);
+          pDataNode->SetAttributeValue(wsValue, wsFormatedValue);
+        }
+        break;
+      case XFA_ELEMENT_CheckButton:
+        defValue.GetChildValueContent(wsValue);
+        if (wsValue.IsEmpty()) {
+          break;
+        }
+        pWidgetData->GetFormatDataValue(wsValue, wsFormatedValue);
+        pDataNode->SetAttributeValue(wsValue, wsFormatedValue);
+        break;
+      case XFA_ELEMENT_ExclGroup: {
+        CXFA_Node* pChecked = NULL;
+        CXFA_Node* pChild = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+        for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+          if (pChild->GetClassID() != XFA_ELEMENT_Field) {
+            continue;
+          }
+          CXFA_Node* pValue = pChild->GetChild(0, XFA_ELEMENT_Value);
+          if (!pValue) {
+            continue;
+          }
+          CXFA_Value valueChild(pValue);
+          valueChild.GetChildValueContent(wsValue);
+          if (wsValue.IsEmpty()) {
+            continue;
+          }
+          CXFA_Node* pItems = pChild->GetChild(0, XFA_ELEMENT_Items);
+          if (!pItems) {
+            continue;
+          }
+          CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+          if (!pText) {
+            continue;
+          }
+          CFX_WideString wsContent;
+          if (pText->TryContent(wsContent) && (wsContent == wsValue)) {
+            pChecked = pChild;
+            wsFormatedValue = wsValue;
+            pDataNode->SetAttributeValue(wsValue, wsFormatedValue);
+            pFormNode->SetCData(XFA_ATTRIBUTE_Value, wsContent);
+            break;
+          }
+        }
+        if (!pChecked) {
+          break;
+        }
+        pChild = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+        for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+          if (pChild == pChecked) {
+            continue;
+          }
+          if (pChild->GetClassID() != XFA_ELEMENT_Field) {
+            continue;
+          }
+          CXFA_Node* pValue = pChild->GetProperty(0, XFA_ELEMENT_Value);
+          CXFA_Node* pItems = pChild->GetChild(0, XFA_ELEMENT_Items);
+          CXFA_Node* pText =
+              pItems ? pItems->GetNodeItem(XFA_NODEITEM_FirstChild) : NULL;
+          if (pText) {
+            pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
+          }
+          CFX_WideString wsContent;
+          if (pText) {
+            pText->TryContent(wsContent);
+          }
+          XFA_DataMerge_FormValueNode_SetChildContent(pValue, wsContent,
+                                                      XFA_ELEMENT_Text);
+        }
+      } break;
+      case XFA_ELEMENT_NumericEdit: {
+        defValue.GetChildValueContent(wsValue);
+        if (wsValue.IsEmpty()) {
+          break;
+        }
+        CFX_WideString wsOutput;
+        pWidgetData->NormalizeNumStr(wsValue, wsOutput);
+        wsValue = wsOutput;
+        pWidgetData->GetFormatDataValue(wsValue, wsFormatedValue);
+        pDataNode->SetAttributeValue(wsValue, wsFormatedValue);
+        CXFA_Node* pValue = pFormNode->GetProperty(0, XFA_ELEMENT_Value);
+        XFA_DataMerge_FormValueNode_SetChildContent(pValue, wsValue,
+                                                    XFA_ELEMENT_Float);
+      } break;
+      default:
+        defValue.GetChildValueContent(wsValue);
+        if (wsValue.IsEmpty()) {
+          break;
+        }
+        pWidgetData->GetFormatDataValue(wsValue, wsFormatedValue);
+        pDataNode->SetAttributeValue(wsValue, wsFormatedValue);
+        break;
+    }
+  } else {
+    CFX_WideString wsXMLValue;
+    pDataNode->TryContent(wsXMLValue);
+    CFX_WideString wsNormailizeValue;
+    pWidgetData->GetNormalizeDataValue(wsXMLValue, wsNormailizeValue);
+    pDataNode->SetAttributeValue(wsNormailizeValue, wsXMLValue);
+    switch (eUIType) {
+      case XFA_ELEMENT_ImageEdit: {
+        XFA_DataMerge_FormValueNode_SetChildContent(
+            defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_Image);
+        CXFA_Image image = defValue.GetImage();
+        if (image) {
+          IFDE_XMLElement* pXMLDataElement =
+              (IFDE_XMLElement*)(pDataNode->GetXMLMappingNode());
+          FXSYS_assert(pXMLDataElement);
+          CFX_WideString wsContentType;
+          CFX_WideString wsHref;
+          pXMLDataElement->GetString(L"xfa:contentType", wsContentType);
+          if (!wsContentType.IsEmpty()) {
+            pDataNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
+            image.SetContentType(wsContentType);
+          }
+          pXMLDataElement->GetString(L"href", wsHref);
+          if (!wsHref.IsEmpty()) {
+            image.SetHref(wsHref);
+          }
+        }
+      } break;
+      case XFA_ELEMENT_ChoiceList:
+        if (pWidgetData->GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
+          CXFA_NodeArray items;
+          pDataNode->GetNodeList(items);
+          int32_t iCounts = items.GetSize();
+          if (iCounts > 0) {
+            wsNormailizeValue.Empty();
+            CFX_WideString wsItem;
+            for (int32_t i = 0; i < iCounts; i++) {
+              items[i]->TryContent(wsItem);
+              wsItem = (iCounts == 1) ? wsItem : wsItem + FX_WSTRC(L"\n");
+              wsNormailizeValue += wsItem;
+            }
+            CXFA_ExData exData = defValue.GetExData();
+            FXSYS_assert(exData);
+            exData.SetContentType((iCounts == 1) ? FX_WSTRC(L"text/plain")
+                                                 : FX_WSTRC(L"text/xml"));
+          }
+          XFA_DataMerge_FormValueNode_SetChildContent(
+              defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_ExData);
+        } else {
+          XFA_DataMerge_FormValueNode_SetChildContent(
+              defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_Text);
+        }
+        break;
+      case XFA_ELEMENT_CheckButton:
+        XFA_DataMerge_FormValueNode_SetChildContent(
+            defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_Text);
+        break;
+      case XFA_ELEMENT_ExclGroup: {
+        pWidgetData->SetSelectedMemberByValue(wsNormailizeValue, bNotify, FALSE,
+                                              FALSE);
+      } break;
+      case XFA_ELEMENT_DateTimeEdit:
+        XFA_DataMerge_FormValueNode_SetChildContent(
+            defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_DateTime);
+        break;
+      case XFA_ELEMENT_NumericEdit: {
+        CFX_WideString wsPicture;
+        pWidgetData->GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind);
+        if (wsPicture.IsEmpty()) {
+          CFX_WideString wsOutput;
+          pWidgetData->NormalizeNumStr(wsNormailizeValue, wsOutput);
+          wsNormailizeValue = wsOutput;
+        }
+        XFA_DataMerge_FormValueNode_SetChildContent(
+            defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_Float);
+      } break;
+      case XFA_ELEMENT_Barcode:
+      case XFA_ELEMENT_Button:
+      case XFA_ELEMENT_PasswordEdit:
+      case XFA_ELEMENT_Signature:
+      case XFA_ELEMENT_TextEdit:
+      default:
+        XFA_DataMerge_FormValueNode_SetChildContent(
+            defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_Text);
+        break;
+    }
+  }
+}
+static CXFA_Node* XFA_DataMerge_GetGlobalBinding(CXFA_Document* pDocument,
+                                                 FX_DWORD dwNameHash) {
+  CXFA_Node* pNode = NULL;
+  pDocument->m_rgGlobalBinding.Lookup(dwNameHash, pNode);
+  return pNode;
+}
+static void XFA_DataMerge_RegisterGlobalBinding(CXFA_Document* pDocument,
+                                                FX_DWORD dwNameHash,
+                                                CXFA_Node* pDataNode) {
+  pDocument->m_rgGlobalBinding.SetAt(dwNameHash, pDataNode);
+}
+static void XFA_DataMerge_ClearGlobalBinding(CXFA_Document* pDocument) {
+  pDocument->m_rgGlobalBinding.RemoveAll();
+}
+static CXFA_Node* XFA_DataMerge_ScopeMatchGlobalBinding(
+    CXFA_Node* pDataScope,
+    FX_DWORD dwNameHash,
+    XFA_ELEMENT eMatchDataNodeType,
+    FX_BOOL bUpLevel = TRUE) {
+  for (CXFA_Node *pCurDataScope = pDataScope, *pLastDataScope = NULL;
+       pCurDataScope && pCurDataScope->GetPacketID() == XFA_XDPPACKET_Datasets;
+       pLastDataScope = pCurDataScope,
+                 pCurDataScope =
+                     pCurDataScope->GetNodeItem(XFA_NODEITEM_Parent)) {
+    for (CXFA_Node* pDataChild = pCurDataScope->GetFirstChildByName(dwNameHash);
+         pDataChild;
+         pDataChild = pDataChild->GetNextSameNameSibling(dwNameHash)) {
+      if (pDataChild == pLastDataScope ||
+          (eMatchDataNodeType != XFA_ELEMENT_DataModel &&
+           pDataChild->GetClassID() != eMatchDataNodeType) ||
+          pDataChild->HasBindItem()) {
+        continue;
+      }
+      return pDataChild;
+    }
+    for (CXFA_Node* pDataChild =
+             pCurDataScope->GetFirstChildByClass(XFA_ELEMENT_DataGroup);
+         pDataChild; pDataChild = pDataChild->GetNextSameClassSibling(
+                         XFA_ELEMENT_DataGroup)) {
+      CXFA_Node* pDataNode = XFA_DataMerge_ScopeMatchGlobalBinding(
+          pDataChild, dwNameHash, eMatchDataNodeType, FALSE);
+      if (pDataNode) {
+        return pDataNode;
+      }
+    }
+    if (!bUpLevel) {
+      break;
+    }
+  }
+  return NULL;
+}
+static CXFA_Node* XFA_DataMerge_FindGlobalDataNode(CXFA_Document* pDocument,
+                                                   CFX_WideStringC wsName,
+                                                   CXFA_Node* pDataScope,
+                                                   XFA_ELEMENT eMatchNodeType) {
+  FX_DWORD dwNameHash =
+      wsName.IsEmpty() ? 0 : FX_HashCode_String_GetW(wsName.GetPtr(),
+                                                     wsName.GetLength());
+  if (dwNameHash != 0) {
+    CXFA_Node* pBounded = XFA_DataMerge_GetGlobalBinding(pDocument, dwNameHash);
+    if (!pBounded) {
+      pBounded = XFA_DataMerge_ScopeMatchGlobalBinding(pDataScope, dwNameHash,
+                                                       eMatchNodeType);
+      if (pBounded) {
+        XFA_DataMerge_RegisterGlobalBinding(pDocument, dwNameHash, pBounded);
+      }
+    }
+    return pBounded;
+  }
+  return NULL;
+}
+static CXFA_Node* XFA_DataMerge_FindOnceDataNode(CXFA_Document* pDocument,
+                                                 CFX_WideStringC wsName,
+                                                 CXFA_Node* pDataScope,
+                                                 XFA_ELEMENT eMatchNodeType) {
+  FX_DWORD dwNameHash =
+      wsName.IsEmpty() ? 0 : FX_HashCode_String_GetW(wsName.GetPtr(),
+                                                     wsName.GetLength());
+  if (dwNameHash != 0) {
+    for (CXFA_Node *pCurDataScope = pDataScope, *pLastDataScope = NULL;
+         pCurDataScope &&
+         pCurDataScope->GetPacketID() == XFA_XDPPACKET_Datasets;
+         pLastDataScope = pCurDataScope,
+                   pCurDataScope =
+                       pCurDataScope->GetNodeItem(XFA_NODEITEM_Parent)) {
+      for (CXFA_Node* pDataChild =
+               pCurDataScope->GetFirstChildByName(dwNameHash);
+           pDataChild;
+           pDataChild = pDataChild->GetNextSameNameSibling(dwNameHash)) {
+        if (pDataChild == pLastDataScope ||
+            (eMatchNodeType != XFA_ELEMENT_DataModel &&
+             pDataChild->GetClassID() != eMatchNodeType) ||
+            pDataChild->HasBindItem()) {
+          continue;
+        }
+        return pDataChild;
+      }
+    }
+  }
+  return NULL;
+}
+static CXFA_Node* XFA_DataMerge_FindDataRefDataNode(CXFA_Document* pDocument,
+                                                    CFX_WideStringC wsRef,
+                                                    CXFA_Node* pDataScope,
+                                                    XFA_ELEMENT eMatchNodeType,
+                                                    CXFA_Node* pTemplateNode,
+                                                    FX_BOOL bForceBind,
+                                                    FX_BOOL bUpLevel = TRUE) {
+  FX_DWORD dFlags = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_BindNew;
+  if (bUpLevel || wsRef != FX_WSTRC(L"name")) {
+    dFlags |= (XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings);
+  }
+  XFA_RESOLVENODE_RS rs;
+  pDocument->GetScriptContext()->ResolveObjects(pDataScope, wsRef, rs, dFlags,
+                                                pTemplateNode);
+  if (rs.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeAll ||
+      rs.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeMidAll ||
+      rs.nodes.GetSize() > 1) {
+    return pDocument->GetNotBindNode(rs.nodes);
+  }
+  if (rs.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeOne) {
+    CXFA_Object* pObject = (rs.nodes.GetSize() > 0) ? rs.nodes[0] : NULL;
+    CXFA_Node* pNode = ToNode(pObject);
+    if (!bForceBind && pNode && pNode->HasBindItem()) {
+      pNode = NULL;
+    }
+    return pNode;
+  }
+  return NULL;
+}
+CXFA_Node* XFA_DataMerge_FindFormDOMInstance(CXFA_Document* pDocument,
+                                             XFA_ELEMENT eClassID,
+                                             FX_DWORD dwNameHash,
+                                             CXFA_Node* pFormParent) {
+  CXFA_Node* pFormChild = pFormParent->GetNodeItem(XFA_NODEITEM_FirstChild);
+  for (; pFormChild;
+       pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pFormChild->GetClassID() == eClassID &&
+        pFormChild->GetNameHash() == dwNameHash &&
+        pFormChild->HasFlag(XFA_NODEFLAG_UnusedNode)) {
+      return pFormChild;
+    }
+  }
+  return NULL;
+}
+static FX_BOOL XFA_NeedGenerateForm(CXFA_Node* pTemplateChild,
+                                    FX_BOOL bUseInstanceManager = TRUE) {
+  XFA_ELEMENT eType = pTemplateChild->GetClassID();
+  if (eType == XFA_ELEMENT_Variables) {
+    return TRUE;
+  }
+  if (pTemplateChild->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {
+    return FALSE;
+  }
+  if (eType == XFA_ELEMENT_Proto ||
+      (bUseInstanceManager && eType == XFA_ELEMENT_Occur)) {
+    return FALSE;
+  }
+  return TRUE;
+}
+CXFA_Node* XFA_NodeMerge_CloneOrMergeContainer(CXFA_Document* pDocument,
+                                               CXFA_Node* pFormParent,
+                                               CXFA_Node* pTemplateNode,
+                                               FX_BOOL bRecursive,
+                                               CXFA_NodeArray* pSubformArray) {
+  CXFA_Node* pExistingNode = NULL;
+  if (pSubformArray == NULL) {
+    pExistingNode = XFA_DataMerge_FindFormDOMInstance(
+        pDocument, pTemplateNode->GetClassID(), pTemplateNode->GetNameHash(),
+        pFormParent);
+  } else if (pSubformArray->GetSize() > 0) {
+    pExistingNode = pSubformArray->GetAt(0);
+    pSubformArray->RemoveAt(0);
+  }
+  if (pExistingNode) {
+    if (pSubformArray) {
+      pFormParent->InsertChild(pExistingNode);
+    } else if (pExistingNode->IsContainerNode()) {
+      pFormParent->RemoveChild(pExistingNode);
+      pFormParent->InsertChild(pExistingNode);
+    }
+    pExistingNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);
+    pExistingNode->SetTemplateNode(pTemplateNode);
+    if (bRecursive && pExistingNode->GetClassID() != XFA_ELEMENT_Items) {
+      for (CXFA_Node* pTemplateChild =
+               pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+           pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
+                               XFA_NODEITEM_NextSibling)) {
+        if (XFA_NeedGenerateForm(pTemplateChild)) {
+          XFA_NodeMerge_CloneOrMergeContainer(pDocument, pExistingNode,
+                                              pTemplateChild, bRecursive);
+        }
+      }
+    }
+    pExistingNode->SetFlag(XFA_NODEFLAG_Initialized);
+    return pExistingNode;
+  }
+  CXFA_Node* pNewNode = pTemplateNode->CloneTemplateToForm(FALSE);
+  pFormParent->InsertChild(pNewNode, NULL);
+  if (bRecursive) {
+    for (CXFA_Node* pTemplateChild =
+             pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+         pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
+                             XFA_NODEITEM_NextSibling)) {
+      if (XFA_NeedGenerateForm(pTemplateChild)) {
+        CXFA_Node* pNewChild = pTemplateChild->CloneTemplateToForm(TRUE);
+        pNewNode->InsertChild(pNewChild, NULL);
+      }
+    }
+  }
+  return pNewNode;
+}
+static CXFA_Node* XFA_NodeMerge_CloneOrMergeInstanceManager(
+    CXFA_Document* pDocument,
+    CXFA_Node* pFormParent,
+    CXFA_Node* pTemplateNode,
+    CXFA_NodeArray& subforms) {
+  CFX_WideStringC wsSubformName = pTemplateNode->GetCData(XFA_ATTRIBUTE_Name);
+  CFX_WideString wsInstMgrNodeName = FX_WSTRC(L"_") + wsSubformName;
+  FX_DWORD dwInstNameHash =
+      FX_HashCode_String_GetW(wsInstMgrNodeName, wsInstMgrNodeName.GetLength());
+  CXFA_Node* pExistingNode = XFA_DataMerge_FindFormDOMInstance(
+      pDocument, XFA_ELEMENT_InstanceManager, dwInstNameHash, pFormParent);
+  if (pExistingNode) {
+    FX_DWORD dwNameHash = pTemplateNode->GetNameHash();
+    for (CXFA_Node* pNode =
+             pExistingNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+         pNode;) {
+      XFA_ELEMENT eCurType = pNode->GetClassID();
+      if (eCurType == XFA_ELEMENT_InstanceManager) {
+        break;
+      }
+      if ((eCurType != XFA_ELEMENT_Subform) &&
+          (eCurType != XFA_ELEMENT_SubformSet)) {
+        pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+        continue;
+      }
+      if (dwNameHash != pNode->GetNameHash()) {
+        break;
+      }
+      CXFA_Node* pNextNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+      pFormParent->RemoveChild(pNode);
+      subforms.Add(pNode);
+      pNode = pNextNode;
+    }
+    pFormParent->RemoveChild(pExistingNode);
+    pFormParent->InsertChild(pExistingNode);
+    pExistingNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);
+    pExistingNode->SetTemplateNode(pTemplateNode);
+    return pExistingNode;
+  }
+  CXFA_Node* pNewNode = pDocument->GetParser()->GetFactory()->CreateNode(
+      XFA_XDPPACKET_Form, XFA_ELEMENT_InstanceManager);
+  FXSYS_assert(pNewNode);
+  wsInstMgrNodeName =
+      FX_WSTRC(L"_") + pTemplateNode->GetCData(XFA_ATTRIBUTE_Name);
+  pNewNode->SetCData(XFA_ATTRIBUTE_Name, wsInstMgrNodeName);
+  pFormParent->InsertChild(pNewNode, NULL);
+  pNewNode->SetTemplateNode(pTemplateNode);
+  return pNewNode;
+}
+static CXFA_Node* XFA_DataMerge_FindMatchingDataNode(
+    CXFA_Document* pDocument,
+    CXFA_Node* pTemplateNode,
+    CXFA_Node* pDataScope,
+    FX_BOOL& bAccessedDataDOM,
+    FX_BOOL bForceBind,
+    CXFA_NodeIteratorTemplate<CXFA_Node,
+                              CXFA_TraverseStrategy_XFAContainerNode>*
+        pIterator,
+    FX_BOOL& bSelfMatch,
+    XFA_ATTRIBUTEENUM& eBindMatch,
+    FX_BOOL bUpLevel = TRUE) {
+  FX_BOOL bOwnIterator = FALSE;
+  if (!pIterator) {
+    bOwnIterator = TRUE;
+    pIterator = new CXFA_NodeIteratorTemplate<
+        CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode>(pTemplateNode);
+  }
+  CXFA_Node* pResult = NULL;
+  for (CXFA_Node* pCurTemplateNode = pIterator->GetCurrent();
+       pCurTemplateNode;) {
+    XFA_ELEMENT eMatchNodeType;
+    switch (pCurTemplateNode->GetClassID()) {
+      case XFA_ELEMENT_Subform:
+        eMatchNodeType = XFA_ELEMENT_DataGroup;
+        break;
+      case XFA_ELEMENT_Field: {
+        eMatchNodeType = XFA_FieldIsMultiListBox(pCurTemplateNode)
+                             ? XFA_ELEMENT_DataGroup
+                             : XFA_ELEMENT_DataValue;
+      } break;
+      case XFA_ELEMENT_ExclGroup:
+        eMatchNodeType = XFA_ELEMENT_DataValue;
+        break;
+      default:
+        pCurTemplateNode = pIterator->MoveToNext();
+        continue;
+    }
+    CXFA_Node* pTemplateNodeOccur =
+        pCurTemplateNode->GetFirstChildByClass(XFA_ELEMENT_Occur);
+    int32_t iMin, iMax, iInit;
+    if (pTemplateNodeOccur &&
+        XFA_GetOccurInfo(pTemplateNodeOccur, iMin, iMax, iInit) && iMax == 0) {
+      pCurTemplateNode = pIterator->MoveToNext();
+      continue;
+    }
+    CXFA_Node* pTemplateNodeBind =
+        pCurTemplateNode->GetFirstChildByClass(XFA_ELEMENT_Bind);
+    XFA_ATTRIBUTEENUM eMatch =
+        pTemplateNodeBind ? pTemplateNodeBind->GetEnum(XFA_ATTRIBUTE_Match)
+                          : XFA_ATTRIBUTEENUM_Once;
+    eBindMatch = eMatch;
+    switch (eMatch) {
+      case XFA_ATTRIBUTEENUM_None:
+        pCurTemplateNode = pIterator->MoveToNext();
+        continue;
+      case XFA_ATTRIBUTEENUM_Global:
+        bAccessedDataDOM = TRUE;
+        if (!bForceBind) {
+          pCurTemplateNode = pIterator->MoveToNext();
+          continue;
+        }
+        if (eMatchNodeType == XFA_ELEMENT_DataValue ||
+            (eMatchNodeType == XFA_ELEMENT_DataGroup &&
+             XFA_FieldIsMultiListBox(pTemplateNodeBind))) {
+          CXFA_Node* pGlobalBindNode = XFA_DataMerge_FindGlobalDataNode(
+              pDocument, pCurTemplateNode->GetCData(XFA_ATTRIBUTE_Name),
+              pDataScope, eMatchNodeType);
+          if (!pGlobalBindNode) {
+            pCurTemplateNode = pIterator->MoveToNext();
+            continue;
+          }
+          pResult = pGlobalBindNode;
+          break;
+        }
+      case XFA_ATTRIBUTEENUM_Once: {
+        bAccessedDataDOM = TRUE;
+        CXFA_Node* pOnceBindNode = XFA_DataMerge_FindOnceDataNode(
+            pDocument, pCurTemplateNode->GetCData(XFA_ATTRIBUTE_Name),
+            pDataScope, eMatchNodeType);
+        if (!pOnceBindNode) {
+          pCurTemplateNode = pIterator->MoveToNext();
+          continue;
+        }
+        pResult = pOnceBindNode;
+      } break;
+      case XFA_ATTRIBUTEENUM_DataRef: {
+        bAccessedDataDOM = TRUE;
+        CXFA_Node* pDataRefBindNode = XFA_DataMerge_FindDataRefDataNode(
+            pDocument, pTemplateNodeBind->GetCData(XFA_ATTRIBUTE_Ref),
+            pDataScope, eMatchNodeType, pTemplateNode, bForceBind, bUpLevel);
+        if (pDataRefBindNode &&
+            pDataRefBindNode->GetClassID() == eMatchNodeType) {
+          pResult = pDataRefBindNode;
+        }
+        if (!pResult) {
+          pCurTemplateNode = pIterator->SkipChildrenAndMoveToNext();
+          continue;
+        }
+      } break;
+      default:
+        break;
+    }
+    if (pCurTemplateNode == pTemplateNode && pResult) {
+      bSelfMatch = TRUE;
+    }
+    break;
+  }
+  if (bOwnIterator) {
+    delete pIterator;
+  }
+  return pResult;
+}
+static void XFA_DataMerge_SortRecurseRecord(
+    CFX_ArrayTemplate<XFA_DataMerge_RecurseRecord>& rgRecords,
+    CXFA_Node* pDataScope,
+    FX_BOOL bChoiceMode = FALSE) {
+  int32_t iCount = rgRecords.GetSize();
+  CFX_ArrayTemplate<XFA_DataMerge_RecurseRecord> rgResultRecord;
+  for (CXFA_Node* pChildNode = pDataScope->GetNodeItem(XFA_NODEITEM_FirstChild);
+       pChildNode;
+       pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    for (int32_t i = 0; i < iCount; i++) {
+      CXFA_Node* pNode = rgRecords[i].pDataChild;
+      if (pChildNode == pNode) {
+        XFA_DataMerge_RecurseRecord sNewRecord = {rgRecords[i].pTemplateChild,
+                                                  pNode};
+        rgResultRecord.Add(sNewRecord);
+        rgRecords.RemoveAt(i);
+        iCount--;
+        break;
+      }
+    }
+    if (bChoiceMode && rgResultRecord.GetSize() > 0) {
+      break;
+    }
+  }
+  if (rgResultRecord.GetSize() > 0) {
+    if (!bChoiceMode) {
+      for (int32_t i = 0; i < iCount; i++) {
+        XFA_DataMerge_RecurseRecord sNewRecord = {rgRecords[i].pTemplateChild,
+                                                  rgRecords[i].pDataChild};
+        rgResultRecord.Add(sNewRecord);
+      }
+    }
+    rgRecords.RemoveAll();
+    rgRecords.Copy(rgResultRecord);
+  }
+}
+static CXFA_Node* XFA_DataMerge_CopyContainer_SubformSet(
+    CXFA_Document* pDocument,
+    CXFA_Node* pTemplateNode,
+    CXFA_Node* pFormParentNode,
+    CXFA_Node* pDataScope,
+    FX_BOOL bOneInstance,
+    FX_BOOL bDataMerge) {
+  XFA_ELEMENT eElement = pTemplateNode->GetClassID();
+  CXFA_Node* pOccurNode = NULL;
+  CXFA_Node* pFirstInstance = NULL;
+  FX_BOOL bUseInstanceManager =
+      pFormParentNode->GetClassID() != XFA_ELEMENT_Area;
+  CXFA_Node* pInstMgrNode = NULL;
+  CXFA_NodeArray subformArray;
+  CXFA_NodeArray* pSearchArray = NULL;
+  if (!bOneInstance &&
+      (eElement == XFA_ELEMENT_SubformSet || eElement == XFA_ELEMENT_Subform)) {
+    pInstMgrNode =
+        bUseInstanceManager
+            ? XFA_NodeMerge_CloneOrMergeInstanceManager(
+                  pDocument, pFormParentNode, pTemplateNode, subformArray)
+            : NULL;
+    if (CXFA_Node* pOccurTemplateNode =
+            pTemplateNode->GetFirstChildByClass(XFA_ELEMENT_Occur)) {
+      pOccurNode = pInstMgrNode
+                       ? XFA_NodeMerge_CloneOrMergeContainer(
+                             pDocument, pInstMgrNode, pOccurTemplateNode, FALSE)
+                       : pOccurTemplateNode;
+    } else if (pInstMgrNode) {
+      pOccurNode = pInstMgrNode->GetFirstChildByClass(XFA_ELEMENT_Occur);
+      if (pOccurNode) {
+        pOccurNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);
+      }
+    }
+    if (pInstMgrNode) {
+      pInstMgrNode->SetFlag(XFA_NODEFLAG_Initialized);
+      pSearchArray = &subformArray;
+      if (pFormParentNode->GetClassID() == XFA_ELEMENT_PageArea) {
+        bOneInstance = TRUE;
+        if (subformArray.GetSize() < 1) {
+          pSearchArray = NULL;
+        }
+      } else if ((pTemplateNode->GetNameHash() == 0) &&
+                 (subformArray.GetSize() < 1)) {
+        pSearchArray = NULL;
+      }
+    }
+  }
+  int32_t iMax = 1, iInit = 1, iMin = 1;
+  if (!bOneInstance) {
+    XFA_GetOccurInfo(pOccurNode, iMin, iMax, iInit);
+  }
+  XFA_ATTRIBUTEENUM eRelation =
+      eElement == XFA_ELEMENT_SubformSet
+          ? pTemplateNode->GetEnum(XFA_ATTRIBUTE_Relation)
+          : XFA_ATTRIBUTEENUM_Ordered;
+  int32_t iCurRepeatIndex = 0;
+  XFA_ATTRIBUTEENUM eParentBindMatch = XFA_ATTRIBUTEENUM_None;
+  if (bDataMerge) {
+    CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode>
+        sNodeIterator(pTemplateNode);
+    FX_BOOL bAccessedDataDOM = FALSE;
+    if (eElement == XFA_ELEMENT_SubformSet || eElement == XFA_ELEMENT_Area) {
+      sNodeIterator.MoveToNext();
+    } else {
+      CFX_MapPtrTemplate<CXFA_Node*, CXFA_Node*> subformMapArray;
+      CXFA_NodeArray subformArray;
+      for (; iMax < 0 || iCurRepeatIndex < iMax; iCurRepeatIndex++) {
+        FX_BOOL bSelfMatch = FALSE;
+        XFA_ATTRIBUTEENUM eBindMatch = XFA_ATTRIBUTEENUM_None;
+        CXFA_Node* pDataNode = XFA_DataMerge_FindMatchingDataNode(
+            pDocument, pTemplateNode, pDataScope, bAccessedDataDOM, FALSE,
+            &sNodeIterator, bSelfMatch, eBindMatch);
+        if (!pDataNode || sNodeIterator.GetCurrent() != pTemplateNode) {
+          break;
+        }
+        eParentBindMatch = eBindMatch;
+        CXFA_Node* pSubformNode = XFA_NodeMerge_CloneOrMergeContainer(
+            pDocument, pFormParentNode, pTemplateNode, FALSE, pSearchArray);
+        if (!pFirstInstance) {
+          pFirstInstance = pSubformNode;
+        }
+        XFA_DataMerge_CreateDataBinding(pSubformNode, pDataNode);
+        FXSYS_assert(pSubformNode);
+        subformMapArray.SetAt(pSubformNode, pDataNode);
+        subformArray.Add(pSubformNode);
+      }
+      subformMapArray.GetStartPosition();
+      for (int32_t iIndex = 0; iIndex < subformArray.GetSize(); iIndex++) {
+        CXFA_Node* pSubform = subformArray[iIndex];
+        CXFA_Node* pDataNode =
+            reinterpret_cast<CXFA_Node*>(subformMapArray.GetValueAt(pSubform));
+        for (CXFA_Node* pTemplateChild =
+                 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+             pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
+                                 XFA_NODEITEM_NextSibling)) {
+          if (XFA_NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
+            XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubform,
+                                                pTemplateChild, TRUE);
+          } else if (pTemplateChild->GetObjectType() ==
+                     XFA_OBJECTTYPE_ContainerNode) {
+            pDocument->DataMerge_CopyContainer(pTemplateChild, pSubform,
+                                               pDataNode, FALSE, TRUE, FALSE);
+          }
+        }
+      }
+      subformMapArray.RemoveAll();
+    }
+    for (; iMax < 0 || iCurRepeatIndex < iMax; iCurRepeatIndex++) {
+      FX_BOOL bSelfMatch = FALSE;
+      XFA_ATTRIBUTEENUM eBindMatch = XFA_ATTRIBUTEENUM_None;
+      if (!XFA_DataMerge_FindMatchingDataNode(
+              pDocument, pTemplateNode, pDataScope, bAccessedDataDOM, FALSE,
+              &sNodeIterator, bSelfMatch, eBindMatch)) {
+        break;
+      }
+      if (eBindMatch == XFA_ATTRIBUTEENUM_DataRef &&
+          eParentBindMatch == XFA_ATTRIBUTEENUM_DataRef) {
+        break;
+      }
+      if (eRelation == XFA_ATTRIBUTEENUM_Choice ||
+          eRelation == XFA_ATTRIBUTEENUM_Unordered) {
+        CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(
+            pDocument, pFormParentNode, pTemplateNode, FALSE, pSearchArray);
+        FXSYS_assert(pSubformSetNode);
+        if (!pFirstInstance) {
+          pFirstInstance = pSubformSetNode;
+        }
+        CFX_ArrayTemplate<XFA_DataMerge_RecurseRecord> rgItemMatchList;
+        CFX_ArrayTemplate<CXFA_Node*> rgItemUnmatchList;
+        for (CXFA_Node* pTemplateChild =
+                 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+             pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
+                                 XFA_NODEITEM_NextSibling)) {
+          if (XFA_NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
+            XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformSetNode,
+                                                pTemplateChild, TRUE);
+          } else if (pTemplateChild->GetObjectType() ==
+                     XFA_OBJECTTYPE_ContainerNode) {
+            CXFA_Node* pDataMatch;
+            bSelfMatch = FALSE;
+            eBindMatch = XFA_ATTRIBUTEENUM_None;
+            if (eRelation != XFA_ATTRIBUTEENUM_Ordered &&
+                (pDataMatch = XFA_DataMerge_FindMatchingDataNode(
+                     pDocument, pTemplateChild, pDataScope, bAccessedDataDOM,
+                     FALSE, NULL, bSelfMatch, eBindMatch))) {
+              XFA_DataMerge_RecurseRecord sNewRecord = {pTemplateChild,
+                                                        pDataMatch};
+              if (bSelfMatch) {
+                rgItemMatchList.InsertAt(0, sNewRecord);
+              } else {
+                rgItemMatchList.Add(sNewRecord);
+              }
+            } else {
+              rgItemUnmatchList.Add(pTemplateChild);
+            }
+          }
+        }
+        switch (eRelation) {
+          case XFA_ATTRIBUTEENUM_Choice: {
+            FXSYS_assert(rgItemMatchList.GetSize());
+            XFA_DataMerge_SortRecurseRecord(rgItemMatchList, pDataScope, TRUE);
+            pDocument->DataMerge_CopyContainer(
+                rgItemMatchList[0].pTemplateChild, pSubformSetNode, pDataScope);
+          } break;
+          case XFA_ATTRIBUTEENUM_Unordered: {
+            if (rgItemMatchList.GetSize()) {
+              XFA_DataMerge_SortRecurseRecord(rgItemMatchList, pDataScope);
+              for (int32_t i = 0, count = rgItemMatchList.GetSize(); i < count;
+                   i++) {
+                pDocument->DataMerge_CopyContainer(
+                    rgItemMatchList[i].pTemplateChild, pSubformSetNode,
+                    pDataScope);
+              }
+            }
+            for (int32_t i = 0, count = rgItemUnmatchList.GetSize(); i < count;
+                 i++) {
+              pDocument->DataMerge_CopyContainer(rgItemUnmatchList[i],
+                                                 pSubformSetNode, pDataScope);
+            }
+          } break;
+          default:
+            break;
+        }
+      } else {
+        CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(
+            pDocument, pFormParentNode, pTemplateNode, FALSE, pSearchArray);
+        FXSYS_assert(pSubformSetNode);
+        if (!pFirstInstance) {
+          pFirstInstance = pSubformSetNode;
+        }
+        for (CXFA_Node* pTemplateChild =
+                 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+             pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
+                                 XFA_NODEITEM_NextSibling)) {
+          if (XFA_NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
+            XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformSetNode,
+                                                pTemplateChild, TRUE);
+          } else if (pTemplateChild->GetObjectType() ==
+                     XFA_OBJECTTYPE_ContainerNode) {
+            pDocument->DataMerge_CopyContainer(pTemplateChild, pSubformSetNode,
+                                               pDataScope);
+          }
+        }
+      }
+    }
+    if (iCurRepeatIndex == 0 && bAccessedDataDOM == FALSE) {
+      int32_t iLimit = iMax;
+      if (pInstMgrNode && pTemplateNode->GetNameHash() == 0) {
+        iLimit = subformArray.GetSize();
+        if (iLimit < iMin) {
+          iLimit = iInit;
+        }
+      }
+      for (; (iLimit < 0 || iCurRepeatIndex < iLimit); iCurRepeatIndex++) {
+        if (pInstMgrNode) {
+          if (pSearchArray && pSearchArray->GetSize() < 1) {
+            if (pTemplateNode->GetNameHash() != 0) {
+              break;
+            }
+            pSearchArray = NULL;
+          }
+        } else if (!XFA_DataMerge_FindFormDOMInstance(
+                       pDocument, pTemplateNode->GetClassID(),
+                       pTemplateNode->GetNameHash(), pFormParentNode)) {
+          break;
+        }
+        CXFA_Node* pSubformNode = XFA_NodeMerge_CloneOrMergeContainer(
+            pDocument, pFormParentNode, pTemplateNode, FALSE, pSearchArray);
+        FXSYS_assert(pSubformNode);
+        if (!pFirstInstance) {
+          pFirstInstance = pSubformNode;
+        }
+        for (CXFA_Node* pTemplateChild =
+                 pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+             pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
+                                 XFA_NODEITEM_NextSibling)) {
+          if (XFA_NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
+            XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformNode,
+                                                pTemplateChild, TRUE);
+          } else if (pTemplateChild->GetObjectType() ==
+                     XFA_OBJECTTYPE_ContainerNode) {
+            pDocument->DataMerge_CopyContainer(pTemplateChild, pSubformNode,
+                                               pDataScope);
+          }
+        }
+      }
+    }
+  }
+  int32_t iMinimalLimit = iCurRepeatIndex == 0 ? iInit : iMin;
+  for (; iCurRepeatIndex < iMinimalLimit; iCurRepeatIndex++) {
+    CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(
+        pDocument, pFormParentNode, pTemplateNode, FALSE, pSearchArray);
+    FXSYS_assert(pSubformSetNode);
+    if (!pFirstInstance) {
+      pFirstInstance = pSubformSetNode;
+    }
+    FX_BOOL bFound = FALSE;
+    for (CXFA_Node* pTemplateChild =
+             pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+         pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
+                             XFA_NODEITEM_NextSibling)) {
+      if (XFA_NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
+        XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformSetNode,
+                                            pTemplateChild, TRUE);
+      } else if (pTemplateChild->GetObjectType() ==
+                 XFA_OBJECTTYPE_ContainerNode) {
+        if (bFound && eRelation == XFA_ATTRIBUTEENUM_Choice) {
+          continue;
+        }
+        pDocument->DataMerge_CopyContainer(pTemplateChild, pSubformSetNode,
+                                           pDataScope, FALSE, bDataMerge);
+        bFound = TRUE;
+      }
+    }
+  }
+  return pFirstInstance;
+}
+static CXFA_Node* XFA_DataMerge_CopyContainer_Field(CXFA_Document* pDocument,
+                                                    CXFA_Node* pTemplateNode,
+                                                    CXFA_Node* pFormNode,
+                                                    CXFA_Node* pDataScope,
+                                                    FX_BOOL bDataMerge,
+                                                    FX_BOOL bUpLevel = TRUE) {
+  CXFA_Node* pFieldNode = XFA_NodeMerge_CloneOrMergeContainer(
+      pDocument, pFormNode, pTemplateNode, FALSE);
+  FXSYS_assert(pFieldNode);
+  for (CXFA_Node* pTemplateChildNode =
+           pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+       pTemplateChildNode; pTemplateChildNode = pTemplateChildNode->GetNodeItem(
+                               XFA_NODEITEM_NextSibling)) {
+    if (XFA_NeedGenerateForm(pTemplateChildNode)) {
+      XFA_NodeMerge_CloneOrMergeContainer(pDocument, pFieldNode,
+                                          pTemplateChildNode, TRUE);
+    } else if (pTemplateNode->GetClassID() == XFA_ELEMENT_ExclGroup &&
+               pTemplateChildNode->IsContainerNode()) {
+      if (pTemplateChildNode->GetClassID() == XFA_ELEMENT_Field) {
+        XFA_DataMerge_CopyContainer_Field(pDocument, pTemplateChildNode,
+                                          pFieldNode, NULL, FALSE);
+      }
+    }
+  }
+  if (bDataMerge) {
+    FX_BOOL bAccessedDataDOM = FALSE;
+    FX_BOOL bSelfMatch = FALSE;
+    XFA_ATTRIBUTEENUM eBindMatch;
+    CXFA_Node* pDataNode = XFA_DataMerge_FindMatchingDataNode(
+        pDocument, pTemplateNode, pDataScope, bAccessedDataDOM, TRUE, NULL,
+        bSelfMatch, eBindMatch, bUpLevel);
+    if (pDataNode) {
+      XFA_DataMerge_CreateDataBinding(pFieldNode, pDataNode);
+    }
+  } else {
+    XFA_DataMerge_FormValueNode_MatchNoneCreateChild(pFieldNode);
+  }
+  return pFieldNode;
+}
+CXFA_Node* CXFA_Document::DataMerge_CopyContainer(CXFA_Node* pTemplateNode,
+                                                  CXFA_Node* pFormNode,
+                                                  CXFA_Node* pDataScope,
+                                                  FX_BOOL bOneInstance,
+                                                  FX_BOOL bDataMerge,
+                                                  FX_BOOL bUpLevel) {
+  switch (pTemplateNode->GetClassID()) {
+    case XFA_ELEMENT_SubformSet:
+    case XFA_ELEMENT_Subform:
+    case XFA_ELEMENT_Area:
+    case XFA_ELEMENT_PageArea:
+      return XFA_DataMerge_CopyContainer_SubformSet(
+          this, pTemplateNode, pFormNode, pDataScope, bOneInstance, bDataMerge);
+    case XFA_ELEMENT_ExclGroup:
+    case XFA_ELEMENT_Field:
+    case XFA_ELEMENT_Draw:
+    case XFA_ELEMENT_ContentArea:
+      return XFA_DataMerge_CopyContainer_Field(
+          this, pTemplateNode, pFormNode, pDataScope, bDataMerge, bUpLevel);
+    case XFA_ELEMENT_PageSet:
+      break;
+    case XFA_ELEMENT_Variables:
+      break;
+    default:
+      FXSYS_assert(FALSE);
+      break;
+  }
+  return NULL;
+}
+
+static void XFA_DataMerge_UpdateBindingRelations(CXFA_Document* pDocument,
+                                                 CXFA_Node* pFormNode,
+                                                 CXFA_Node* pDataScope,
+                                                 FX_BOOL bDataRef,
+                                                 FX_BOOL bParentDataRef) {
+  FX_BOOL bMatchRef = TRUE;
+  XFA_ELEMENT eClassID = pFormNode->GetClassID();
+  CXFA_Node* pDataNode = pFormNode->GetBindData();
+  if (eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup ||
+      eClassID == XFA_ELEMENT_Field) {
+    CXFA_Node* pTemplateNode = pFormNode->GetTemplateNode();
+    CXFA_Node* pTemplateNodeBind =
+        pTemplateNode ? pTemplateNode->GetFirstChildByClass(XFA_ELEMENT_Bind)
+                      : NULL;
+    XFA_ATTRIBUTEENUM eMatch =
+        pTemplateNodeBind ? pTemplateNodeBind->GetEnum(XFA_ATTRIBUTE_Match)
+                          : XFA_ATTRIBUTEENUM_Once;
+    switch (eMatch) {
+      case XFA_ATTRIBUTEENUM_None:
+        if (!bDataRef || bParentDataRef) {
+          XFA_DataMerge_FormValueNode_MatchNoneCreateChild(pFormNode);
+        }
+        break;
+      case XFA_ATTRIBUTEENUM_Once:
+        if (!bDataRef || bParentDataRef) {
+          if (!pDataNode) {
+            if (pFormNode->GetNameHash() != 0 &&
+                pFormNode->GetEnum(XFA_ATTRIBUTE_Scope) !=
+                    XFA_ATTRIBUTEENUM_None) {
+              XFA_ELEMENT eDataNodeType = (eClassID == XFA_ELEMENT_Subform ||
+                                           XFA_FieldIsMultiListBox(pFormNode))
+                                              ? XFA_ELEMENT_DataGroup
+                                              : XFA_ELEMENT_DataValue;
+              pDataNode = XFA_DataDescription_MaybeCreateDataNode(
+                  pDocument, pDataScope, eDataNodeType,
+                  pFormNode->GetCData(XFA_ATTRIBUTE_Name));
+              if (pDataNode) {
+                XFA_DataMerge_CreateDataBinding(pFormNode, pDataNode, FALSE);
+              }
+            }
+            if (!pDataNode) {
+              XFA_DataMerge_FormValueNode_MatchNoneCreateChild(pFormNode);
+            }
+          } else {
+            CXFA_Node* pDataParent =
+                pDataNode->GetNodeItem(XFA_NODEITEM_Parent);
+            if (pDataParent != pDataScope) {
+              FXSYS_assert(pDataParent);
+              pDataParent->RemoveChild(pDataNode);
+              pDataScope->InsertChild(pDataNode);
+            }
+          }
+        }
+        break;
+      case XFA_ATTRIBUTEENUM_Global:
+        if (!bDataRef || bParentDataRef) {
+          FX_DWORD dwNameHash = pFormNode->GetNameHash();
+          if (dwNameHash != 0 && !pDataNode) {
+            pDataNode = XFA_DataMerge_GetGlobalBinding(pDocument, dwNameHash);
+            if (!pDataNode) {
+              XFA_ELEMENT eDataNodeType = (eClassID == XFA_ELEMENT_Subform ||
+                                           XFA_FieldIsMultiListBox(pFormNode))
+                                              ? XFA_ELEMENT_DataGroup
+                                              : XFA_ELEMENT_DataValue;
+              CXFA_Node* pRecordNode =
+                  ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Record));
+              pDataNode = XFA_DataDescription_MaybeCreateDataNode(
+                  pDocument, pRecordNode, eDataNodeType,
+                  pFormNode->GetCData(XFA_ATTRIBUTE_Name));
+              if (pDataNode) {
+                XFA_DataMerge_CreateDataBinding(pFormNode, pDataNode, FALSE);
+                XFA_DataMerge_RegisterGlobalBinding(
+                    pDocument, pFormNode->GetNameHash(), pDataNode);
+              }
+            } else {
+              XFA_DataMerge_CreateDataBinding(pFormNode, pDataNode);
+            }
+          }
+          if (!pDataNode) {
+            XFA_DataMerge_FormValueNode_MatchNoneCreateChild(pFormNode);
+          }
+        }
+        break;
+      case XFA_ATTRIBUTEENUM_DataRef: {
+        bMatchRef = bDataRef;
+        bParentDataRef = TRUE;
+        if (!pDataNode && bDataRef) {
+          CFX_WideStringC wsRef =
+              pTemplateNodeBind->GetCData(XFA_ATTRIBUTE_Ref);
+          FX_DWORD dFlags =
+              XFA_RESOLVENODE_Children | XFA_RESOLVENODE_CreateNode;
+          XFA_RESOLVENODE_RS rs;
+          pDocument->GetScriptContext()->ResolveObjects(pDataScope, wsRef, rs,
+                                                        dFlags, pTemplateNode);
+          CXFA_Object* pObject = (rs.nodes.GetSize() > 0) ? rs.nodes[0] : NULL;
+          pDataNode = ToNode(pObject);
+          if (pDataNode) {
+            XFA_DataMerge_CreateDataBinding(
+                pFormNode, pDataNode,
+                rs.dwFlags == XFA_RESOVENODE_RSTYPE_ExistNodes);
+          } else {
+            XFA_DataMerge_FormValueNode_MatchNoneCreateChild(pFormNode);
+          }
+        }
+      } break;
+      default:
+        break;
+    }
+  }
+  if (bMatchRef &&
+      (eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_SubformSet ||
+       eClassID == XFA_ELEMENT_Area || eClassID == XFA_ELEMENT_PageArea ||
+       eClassID == XFA_ELEMENT_PageSet)) {
+    for (CXFA_Node* pFormChild =
+             pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+         pFormChild;
+         pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+      if (pFormChild->GetObjectType() != XFA_OBJECTTYPE_ContainerNode) {
+        continue;
+      }
+      if (pFormChild->HasFlag(XFA_NODEFLAG_UnusedNode)) {
+        continue;
+      }
+      XFA_DataMerge_UpdateBindingRelations(pDocument, pFormChild,
+                                           pDataNode ? pDataNode : pDataScope,
+                                           bDataRef, bParentDataRef);
+    }
+  }
+}
+CXFA_Node* XFA_DataMerge_FindDataScope(CXFA_Node* pParentFormNode) {
+  for (CXFA_Node* pRootBoundNode = pParentFormNode;
+       pRootBoundNode &&
+       pRootBoundNode->GetObjectType() == XFA_OBJECTTYPE_ContainerNode;
+       pRootBoundNode = pRootBoundNode->GetNodeItem(XFA_NODEITEM_Parent)) {
+    CXFA_Node* pDataScope = pRootBoundNode->GetBindData();
+    if (pDataScope) {
+      return pDataScope;
+    }
+  }
+  return ToNode(
+      pParentFormNode->GetDocument()->GetXFAObject(XFA_HASHCODE_Data));
+}
+void CXFA_Document::DataMerge_UpdateBindingRelations(
+    CXFA_Node* pFormUpdateRoot) {
+  CXFA_Node* pDataScope = XFA_DataMerge_FindDataScope(
+      pFormUpdateRoot->GetNodeItem(XFA_NODEITEM_Parent));
+  if (!pDataScope) {
+    return;
+  }
+  XFA_DataMerge_UpdateBindingRelations(this, pFormUpdateRoot, pDataScope, FALSE,
+                                       FALSE);
+  XFA_DataMerge_UpdateBindingRelations(this, pFormUpdateRoot, pDataScope, TRUE,
+                                       FALSE);
+}
+CXFA_Node* CXFA_Document::GetNotBindNode(CXFA_ObjArray& arrayNodes) {
+  for (int32_t i = 0; i < arrayNodes.GetSize(); i++) {
+    CXFA_Node* pNode = arrayNodes[i]->AsNode();
+    if (pNode && !pNode->HasBindItem())
+      return pNode;
+  }
+  return nullptr;
+}
+void CXFA_Document::DoDataMerge() {
+  CXFA_Node* pDatasetsRoot = ToNode(GetXFAObject(XFA_HASHCODE_Datasets));
+  if (!pDatasetsRoot) {
+    IFDE_XMLElement* pDatasetsXMLNode =
+        IFDE_XMLElement::Create(FX_WSTRC(L"xfa:datasets"));
+    FXSYS_assert(pDatasetsXMLNode);
+    pDatasetsXMLNode->SetString(
+        FX_WSTRC(L"xmlns:xfa"),
+        FX_WSTRC(L"http://www.xfa.org/schema/xfa-data/1.0/"));
+    pDatasetsRoot = CreateNode(XFA_XDPPACKET_Datasets, XFA_ELEMENT_DataModel);
+    pDatasetsRoot->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L"datasets"));
+    m_pRootNode->GetXMLMappingNode()->InsertChildNode(pDatasetsXMLNode);
+    m_pRootNode->InsertChild(pDatasetsRoot);
+    pDatasetsRoot->SetXMLMappingNode(pDatasetsXMLNode);
+  }
+  CXFA_Node *pDataRoot = NULL, *pDDRoot = NULL;
+  CFX_WideString wsDatasetsURI;
+  pDatasetsRoot->TryNamespace(wsDatasetsURI);
+  for (CXFA_Node* pChildNode =
+           pDatasetsRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
+       pChildNode;
+       pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pChildNode->GetClassID() != XFA_ELEMENT_DataGroup) {
+      continue;
+    }
+    CFX_WideString wsNamespaceURI;
+    if (!pDDRoot && pChildNode->GetNameHash() == XFA_HASHCODE_DataDescription) {
+      if (!pChildNode->TryNamespace(wsNamespaceURI)) {
+        continue;
+      }
+      if (wsNamespaceURI ==
+          FX_WSTRC(L"http://ns.adobe.com/data-description/")) {
+        pDDRoot = pChildNode;
+      }
+    } else if (!pDataRoot && pChildNode->GetNameHash() == XFA_HASHCODE_Data) {
+      if (!pChildNode->TryNamespace(wsNamespaceURI)) {
+        continue;
+      }
+      if (wsNamespaceURI == wsDatasetsURI) {
+        pDataRoot = pChildNode;
+      }
+    }
+    if (pDataRoot && pDDRoot) {
+      break;
+    }
+  }
+  if (!pDataRoot) {
+    IFDE_XMLElement* pDataRootXMLNode =
+        IFDE_XMLElement::Create(FX_WSTRC(L"xfa:data"));
+    FXSYS_assert(pDataRootXMLNode);
+    pDataRoot = CreateNode(XFA_XDPPACKET_Datasets, XFA_ELEMENT_DataGroup);
+    pDataRoot->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L"data"));
+    pDataRoot->SetXMLMappingNode(pDataRootXMLNode);
+    pDatasetsRoot->InsertChild(pDataRoot);
+  }
+  CXFA_Node* pDataTopLevel =
+      pDataRoot->GetFirstChildByClass(XFA_ELEMENT_DataGroup);
+  FX_DWORD dwNameHash = pDataTopLevel ? pDataTopLevel->GetNameHash() : 0;
+  CXFA_Node* pTemplateRoot =
+      m_pRootNode->GetFirstChildByClass(XFA_ELEMENT_Template);
+  if (!pTemplateRoot) {
+    return;
+  }
+  CXFA_Node* pTemplateChosen =
+      dwNameHash != 0 ? pTemplateRoot->GetFirstChildByName(dwNameHash) : NULL;
+  if (!pTemplateChosen ||
+      pTemplateChosen->GetClassID() != XFA_ELEMENT_Subform) {
+    pTemplateChosen = pTemplateRoot->GetFirstChildByClass(XFA_ELEMENT_Subform);
+  }
+  if (!pTemplateChosen) {
+    return;
+  }
+  CXFA_Node* pFormRoot = m_pRootNode->GetFirstChildByClass(XFA_ELEMENT_Form);
+  FX_BOOL bEmptyForm = FALSE;
+  if (!pFormRoot) {
+    bEmptyForm = TRUE;
+    pFormRoot = CreateNode(XFA_XDPPACKET_Form, XFA_ELEMENT_Form);
+    FXSYS_assert(pFormRoot);
+    pFormRoot->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L"form"));
+    m_pRootNode->InsertChild(pFormRoot, NULL);
+  } else {
+    CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode>
+        sIterator(pFormRoot);
+    for (CXFA_Node* pNode = sIterator.MoveToNext(); pNode;
+         pNode = sIterator.MoveToNext()) {
+      pNode->SetFlag(XFA_NODEFLAG_UnusedNode);
+    }
+  }
+  CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(
+      this, pFormRoot, pTemplateChosen, FALSE);
+  FXSYS_assert(pSubformSetNode);
+  if (!pDataTopLevel) {
+    CFX_WideStringC wsFormName = pSubformSetNode->GetCData(XFA_ATTRIBUTE_Name);
+    CFX_WideString wsDataTopLevelName =
+        wsFormName.IsEmpty() ? FX_WSTRC(L"form") : wsFormName;
+    IFDE_XMLElement* pDataTopLevelXMLNode =
+        IFDE_XMLElement::Create(wsDataTopLevelName);
+    FXSYS_assert(pDataTopLevelXMLNode);
+    pDataTopLevel = CreateNode(XFA_XDPPACKET_Datasets, XFA_ELEMENT_DataGroup);
+    pDataTopLevel->SetCData(XFA_ATTRIBUTE_Name, wsDataTopLevelName);
+    pDataTopLevel->SetXMLMappingNode(pDataTopLevelXMLNode);
+    CXFA_Node* pBeforeNode = pDataRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
+    pDataRoot->InsertChild(pDataTopLevel, pBeforeNode);
+  }
+  FXSYS_assert(pDataTopLevel);
+  XFA_DataMerge_CreateDataBinding(pSubformSetNode, pDataTopLevel);
+  for (CXFA_Node* pTemplateChild =
+           pTemplateChosen->GetNodeItem(XFA_NODEITEM_FirstChild);
+       pTemplateChild;
+       pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (XFA_NeedGenerateForm(pTemplateChild)) {
+      XFA_NodeMerge_CloneOrMergeContainer(this, pSubformSetNode, pTemplateChild,
+                                          TRUE);
+    } else if (pTemplateChild->GetObjectType() ==
+               XFA_OBJECTTYPE_ContainerNode) {
+      DataMerge_CopyContainer(pTemplateChild, pSubformSetNode, pDataTopLevel);
+    }
+  }
+  if (pDDRoot) {
+    XFA_DataDescription_UpdateDataRelation(pDataRoot, pDDRoot);
+  }
+  DataMerge_UpdateBindingRelations(pSubformSetNode);
+  CXFA_Node* pPageSetNode =
+      pSubformSetNode->GetFirstChildByClass(XFA_ELEMENT_PageSet);
+  while (pPageSetNode) {
+    m_pPendingPageSet.Add(pPageSetNode);
+    CXFA_Node* pNextPageSetNode =
+        pPageSetNode->GetNextSameClassSibling(XFA_ELEMENT_PageSet);
+    pSubformSetNode->RemoveChild(pPageSetNode);
+    pPageSetNode = pNextPageSetNode;
+  }
+  if (!bEmptyForm) {
+    CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode>
+        sIterator(pFormRoot);
+    CXFA_Node* pNode = sIterator.MoveToNext();
+    while (pNode) {
+      if (pNode->HasFlag(XFA_NODEFLAG_UnusedNode)) {
+        if (pNode->GetObjectType() == XFA_OBJECTTYPE_ContainerNode ||
+            pNode->GetClassID() == XFA_ELEMENT_InstanceManager) {
+          CXFA_Node* pNext = sIterator.SkipChildrenAndMoveToNext();
+          pNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pNode);
+          pNode = pNext;
+        } else {
+          pNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);
+          pNode->SetFlag(XFA_NODEFLAG_Initialized);
+          pNode = sIterator.MoveToNext();
+        }
+      } else {
+        pNode->SetFlag(XFA_NODEFLAG_Initialized);
+        pNode = sIterator.MoveToNext();
+      }
+    }
+  }
+}
+void CXFA_Document::DoDataRemerge(FX_BOOL bDoDataMerge) {
+  CXFA_Node* pFormRoot = ToNode(GetXFAObject(XFA_HASHCODE_Form));
+  if (pFormRoot) {
+    while (CXFA_Node* pNode = pFormRoot->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+      pFormRoot->RemoveChild(pNode);
+    }
+    pFormRoot->SetObject(XFA_ATTRIBUTE_BindingNode, NULL);
+  }
+  XFA_DataMerge_ClearGlobalBinding(this);
+  if (bDoDataMerge) {
+    DoDataMerge();
+  }
+  CXFA_LayoutProcessor* pLayoutProcessor = GetLayoutProcessor();
+  pLayoutProcessor->SetForceReLayout(TRUE);
+}
diff --git a/xfa/fxfa/parser/xfa_document_datamerger_imp.h b/xfa/fxfa/parser/xfa_document_datamerger_imp.h
new file mode 100644
index 0000000..a5583cb
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_document_datamerger_imp.h
@@ -0,0 +1,24 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_DOCUMENT_DATAMERGER_IMP_H_
+#define XFA_FXFA_PARSER_XFA_DOCUMENT_DATAMERGER_IMP_H_
+
+#include "xfa/fxfa/parser/xfa_object.h"
+
+CXFA_Node* XFA_NodeMerge_CloneOrMergeContainer(
+    CXFA_Document* pDocument,
+    CXFA_Node* pFormParent,
+    CXFA_Node* pTemplateNode,
+    FX_BOOL bRecursive,
+    CXFA_NodeArray* pSubformArray = NULL);
+CXFA_Node* XFA_DataMerge_FindDataScope(CXFA_Node* pParentFormNode);
+CXFA_Node* XFA_DataMerge_FindFormDOMInstance(CXFA_Document* pDocument,
+                                             XFA_ELEMENT eClassID,
+                                             FX_DWORD dwNameHash,
+                                             CXFA_Node* pFormParent);
+
+#endif  // XFA_FXFA_PARSER_XFA_DOCUMENT_DATAMERGER_IMP_H_
diff --git a/xfa/fxfa/parser/xfa_document_imp.cpp b/xfa/fxfa/parser/xfa_document_imp.cpp
new file mode 100644
index 0000000..ce07c47
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_document_imp.cpp
@@ -0,0 +1,441 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/include/fxcrt/fx_ext.h"
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_basic_imp.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_document_layout_imp.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_script_datawindow.h"
+#include "xfa/fxfa/parser/xfa_script_eventpseudomodel.h"
+#include "xfa/fxfa/parser/xfa_script_hostpseudomodel.h"
+#include "xfa/fxfa/parser/xfa_script_layoutpseudomodel.h"
+#include "xfa/fxfa/parser/xfa_script_logpseudomodel.h"
+#include "xfa/fxfa/parser/xfa_script_signaturepseudomodel.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+CXFA_Document::CXFA_Document(IXFA_DocParser* pParser)
+    : m_pParser(pParser),
+      m_pScriptContext(nullptr),
+      m_pLayoutProcessor(nullptr),
+      m_pRootNode(nullptr),
+      m_pLocalMgr(nullptr),
+      m_pScriptDataWindow(nullptr),
+      m_pScriptEvent(nullptr),
+      m_pScriptHost(nullptr),
+      m_pScriptLog(nullptr),
+      m_pScriptLayout(nullptr),
+      m_pScriptSignature(nullptr),
+      m_eCurVersionMode(XFA_VERSION_DEFAULT),
+      m_dwDocFlags(0) {
+  ASSERT(m_pParser);
+}
+CXFA_Document::~CXFA_Document() {
+  delete m_pRootNode;
+  PurgeNodes();
+}
+void CXFA_Document::ClearLayoutData() {
+  if (m_pLayoutProcessor) {
+    delete m_pLayoutProcessor;
+    m_pLayoutProcessor = NULL;
+  }
+  if (m_pScriptContext) {
+    m_pScriptContext->Release();
+    m_pScriptContext = NULL;
+  }
+  if (m_pLocalMgr) {
+    delete m_pLocalMgr;
+    m_pLocalMgr = NULL;
+  }
+  if (m_pScriptDataWindow) {
+    delete m_pScriptDataWindow;
+    m_pScriptDataWindow = NULL;
+  }
+  if (m_pScriptEvent) {
+    delete m_pScriptEvent;
+    m_pScriptEvent = NULL;
+  }
+  if (m_pScriptHost) {
+    delete m_pScriptHost;
+    m_pScriptHost = NULL;
+  }
+  if (m_pScriptLog) {
+    delete m_pScriptLog;
+    m_pScriptLog = NULL;
+  }
+  if (m_pScriptLayout) {
+    delete m_pScriptLayout;
+    m_pScriptLayout = NULL;
+  }
+  if (m_pScriptSignature) {
+    delete m_pScriptSignature;
+    m_pScriptSignature = NULL;
+  }
+}
+void CXFA_Document::SetRoot(CXFA_Node* pNewRoot) {
+  if (m_pRootNode) {
+    AddPurgeNode(m_pRootNode);
+  }
+  m_pRootNode = pNewRoot;
+  RemovePurgeNode(pNewRoot);
+}
+IXFA_Notify* CXFA_Document::GetNotify() const {
+  return m_pParser->GetNotify();
+}
+CXFA_Object* CXFA_Document::GetXFAObject(const CFX_WideStringC& wsNodeName) {
+  return GetXFAObject(
+      FX_HashCode_String_GetW(wsNodeName.GetPtr(), wsNodeName.GetLength()));
+}
+CXFA_Object* CXFA_Document::GetXFAObject(FX_DWORD dwNodeNameHash) {
+  switch (dwNodeNameHash) {
+    case XFA_HASHCODE_Data: {
+      CXFA_Node* pDatasetsNode = ToNode(GetXFAObject(XFA_HASHCODE_Datasets));
+      if (!pDatasetsNode) {
+        return NULL;
+      }
+      for (CXFA_Node* pDatasetsChild =
+               pDatasetsNode->GetFirstChildByClass(XFA_ELEMENT_DataGroup);
+           pDatasetsChild;
+           pDatasetsChild =
+               pDatasetsChild->GetNextSameClassSibling(XFA_ELEMENT_DataGroup)) {
+        if (pDatasetsChild->GetNameHash() != XFA_HASHCODE_Data) {
+          continue;
+        }
+        CFX_WideString wsNamespaceURI;
+        if (!pDatasetsChild->TryNamespace(wsNamespaceURI)) {
+          continue;
+        }
+        CFX_WideString wsDatasetsURI;
+        if (!pDatasetsNode->TryNamespace(wsDatasetsURI)) {
+          continue;
+        }
+        if (wsNamespaceURI == wsDatasetsURI) {
+          return pDatasetsChild;
+        }
+      }
+    }
+      return NULL;
+    case XFA_HASHCODE_Record: {
+      CXFA_Node* pData = ToNode(GetXFAObject(XFA_HASHCODE_Data));
+      return pData ? pData->GetFirstChildByClass(XFA_ELEMENT_DataGroup) : NULL;
+    }
+    case XFA_HASHCODE_DataWindow: {
+      if (m_pScriptDataWindow == NULL) {
+        m_pScriptDataWindow = new CScript_DataWindow(this);
+      }
+      return m_pScriptDataWindow;
+    }
+    case XFA_HASHCODE_Event: {
+      if (m_pScriptEvent == NULL) {
+        m_pScriptEvent = new CScript_EventPseudoModel(this);
+      }
+      return m_pScriptEvent;
+    }
+    case XFA_HASHCODE_Host: {
+      if (m_pScriptHost == NULL) {
+        m_pScriptHost = new CScript_HostPseudoModel(this);
+      }
+      return m_pScriptHost;
+    }
+    case XFA_HASHCODE_Log: {
+      if (m_pScriptLog == NULL) {
+        m_pScriptLog = new CScript_LogPseudoModel(this);
+      }
+      return m_pScriptLog;
+    }
+    case XFA_HASHCODE_Signature: {
+      if (m_pScriptSignature == NULL) {
+        m_pScriptSignature = new CScript_SignaturePseudoModel(this);
+      }
+      return m_pScriptSignature;
+    }
+    case XFA_HASHCODE_Layout: {
+      if (m_pScriptLayout == NULL) {
+        m_pScriptLayout = new CScript_LayoutPseudoModel(this);
+      }
+      return m_pScriptLayout;
+    }
+    default:
+      return m_pRootNode->GetFirstChildByName(dwNodeNameHash);
+  }
+}
+CXFA_Node* CXFA_Document::CreateNode(FX_DWORD dwPacket, XFA_ELEMENT eElement) {
+  return CreateNode(XFA_GetPacketByID(dwPacket), eElement);
+}
+CXFA_Node* CXFA_Document::CreateNode(const XFA_PACKETINFO* pPacket,
+                                     XFA_ELEMENT eElement) {
+  if (pPacket == NULL) {
+    return NULL;
+  }
+  const XFA_ELEMENTINFO* pElement = XFA_GetElementByID(eElement);
+  if (pElement && (pElement->dwPackets & pPacket->eName)) {
+    CXFA_Node* pNode = new CXFA_Node(this, pPacket->eName, pElement->eName);
+    if (pNode) {
+      AddPurgeNode(pNode);
+    }
+    return pNode;
+  }
+  return NULL;
+}
+void CXFA_Document::AddPurgeNode(CXFA_Node* pNode) {
+  m_rgPurgeNodes.Add(pNode);
+}
+FX_BOOL CXFA_Document::RemovePurgeNode(CXFA_Node* pNode) {
+  return m_rgPurgeNodes.RemoveKey(pNode);
+}
+void CXFA_Document::PurgeNodes() {
+  FX_POSITION psNode = m_rgPurgeNodes.GetStartPosition();
+  while (psNode) {
+    CXFA_Node* pNode;
+    m_rgPurgeNodes.GetNextAssoc(psNode, pNode);
+    delete pNode;
+  }
+  m_rgPurgeNodes.RemoveAll();
+}
+void CXFA_Document::SetFlag(FX_DWORD dwFlag, FX_BOOL bOn) {
+  if (bOn) {
+    m_dwDocFlags |= dwFlag;
+  } else {
+    m_dwDocFlags &= ~dwFlag;
+  }
+}
+FX_BOOL CXFA_Document::IsInteractive() {
+  if (m_dwDocFlags & XFA_DOCFLAG_HasInteractive) {
+    return m_dwDocFlags & XFA_DOCFLAG_Interactive;
+  }
+  CXFA_Node* pConfig = ToNode(GetXFAObject(XFA_HASHCODE_Config));
+  if (!pConfig) {
+    return FALSE;
+  }
+  CFX_WideString wsInteractive;
+  CXFA_Node* pPresent = pConfig->GetFirstChildByClass(XFA_ELEMENT_Present);
+  if (!pPresent) {
+    return FALSE;
+  }
+  CXFA_Node* pPDF = pPresent->GetFirstChildByClass(XFA_ELEMENT_Pdf);
+  if (!pPDF) {
+    return FALSE;
+  }
+  CXFA_Node* pInteractive = pPDF->GetChild(0, XFA_ELEMENT_Interactive);
+  if (pInteractive) {
+    m_dwDocFlags |= XFA_DOCFLAG_HasInteractive;
+    if (pInteractive->TryContent(wsInteractive) &&
+        wsInteractive == FX_WSTRC(L"1")) {
+      m_dwDocFlags |= XFA_DOCFLAG_Interactive;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+CXFA_LocaleMgr* CXFA_Document::GetLocalMgr() {
+  if (!m_pLocalMgr) {
+    CFX_WideString wsLanguage;
+    GetParser()->GetNotify()->GetAppProvider()->GetLanguage(wsLanguage);
+    m_pLocalMgr = new CXFA_LocaleMgr(
+        ToNode(GetXFAObject(XFA_HASHCODE_LocaleSet)), wsLanguage);
+  }
+  return m_pLocalMgr;
+}
+IXFA_ScriptContext* CXFA_Document::InitScriptContext(FXJSE_HRUNTIME hRuntime) {
+  if (!m_pScriptContext) {
+    m_pScriptContext = XFA_ScriptContext_Create(this);
+  }
+  m_pScriptContext->Initialize(hRuntime);
+  return m_pScriptContext;
+}
+IXFA_ScriptContext* CXFA_Document::GetScriptContext() {
+  if (!m_pScriptContext) {
+    m_pScriptContext = XFA_ScriptContext_Create(this);
+  }
+  return m_pScriptContext;
+}
+XFA_VERSION CXFA_Document::RecognizeXFAVersionNumber(
+    CFX_WideString& wsTemplateNS) {
+  CFX_WideStringC wsTemplateURIPrefix =
+      XFA_GetPacketByIndex(XFA_PACKET_Template)->pURI;
+  FX_STRSIZE nPrefixLength = wsTemplateURIPrefix.GetLength();
+  if (CFX_WideStringC(wsTemplateNS, wsTemplateNS.GetLength()) !=
+      wsTemplateURIPrefix) {
+    return XFA_VERSION_UNKNOWN;
+  }
+  FX_STRSIZE nDotPos = wsTemplateNS.Find('.', nPrefixLength);
+  if (nDotPos == (FX_STRSIZE)-1) {
+    return XFA_VERSION_UNKNOWN;
+  }
+  int8_t iMajor =
+      FXSYS_wtoi(wsTemplateNS.Mid(nPrefixLength, nDotPos - nPrefixLength));
+  int8_t iMinor = FXSYS_wtoi(
+      wsTemplateNS.Mid(nDotPos + 1, wsTemplateNS.GetLength() - nDotPos - 2));
+  XFA_VERSION eVersion = (XFA_VERSION)((int32_t)iMajor * 100 + iMinor);
+  if (eVersion < XFA_VERSION_MIN || eVersion > XFA_VERSION_MAX) {
+    return XFA_VERSION_UNKNOWN;
+  }
+  m_eCurVersionMode = eVersion;
+  return eVersion;
+}
+CXFA_Node* CXFA_Document::GetNodeByID(CXFA_Node* pRoot,
+                                      const CFX_WideStringC& wsID) {
+  if (!pRoot || wsID.IsEmpty()) {
+    return NULL;
+  }
+  CXFA_NodeIterator sIterator(pRoot);
+  for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
+       pNode = sIterator.MoveToNext()) {
+    CFX_WideStringC wsIDVal;
+    if (pNode->TryCData(XFA_ATTRIBUTE_Id, wsIDVal) && !wsIDVal.IsEmpty()) {
+      if (wsIDVal == wsID) {
+        return pNode;
+      }
+    }
+  }
+  return NULL;
+}
+static void XFA_ProtoMerge_MergeNodeRecurse(CXFA_Document* pDocument,
+                                            CXFA_Node* pDestNodeParent,
+                                            CXFA_Node* pProtoNode) {
+  CXFA_Node* pExistingNode = NULL;
+  for (CXFA_Node* pFormChild =
+           pDestNodeParent->GetNodeItem(XFA_NODEITEM_FirstChild);
+       pFormChild;
+       pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pFormChild->GetClassID() == pProtoNode->GetClassID() &&
+        pFormChild->GetNameHash() == pProtoNode->GetNameHash() &&
+        pFormChild->HasFlag(XFA_NODEFLAG_UnusedNode)) {
+      pFormChild->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);
+      pExistingNode = pFormChild;
+      break;
+    }
+  }
+  if (pExistingNode) {
+    pExistingNode->SetTemplateNode(pProtoNode);
+    for (CXFA_Node* pTemplateChild =
+             pProtoNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+         pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
+                             XFA_NODEITEM_NextSibling)) {
+      XFA_ProtoMerge_MergeNodeRecurse(pDocument, pExistingNode, pTemplateChild);
+    }
+    return;
+  }
+  CXFA_Node* pNewNode = pProtoNode->Clone(TRUE);
+  pNewNode->SetTemplateNode(pProtoNode);
+  pDestNodeParent->InsertChild(pNewNode, NULL);
+}
+static void XFA_ProtoMerge_MergeNode(CXFA_Document* pDocument,
+                                     CXFA_Node* pDestNode,
+                                     CXFA_Node* pProtoNode) {
+  {
+    CXFA_NodeIterator sIterator(pDestNode);
+    for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
+         pNode = sIterator.MoveToNext()) {
+      pNode->SetFlag(XFA_NODEFLAG_UnusedNode);
+    }
+  }
+  pDestNode->SetTemplateNode(pProtoNode);
+  for (CXFA_Node* pTemplateChild =
+           pProtoNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+       pTemplateChild;
+       pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    XFA_ProtoMerge_MergeNodeRecurse(pDocument, pDestNode, pTemplateChild);
+  }
+  {
+    CXFA_NodeIterator sIterator(pDestNode);
+    for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
+         pNode = sIterator.MoveToNext()) {
+      pNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);
+    }
+  }
+}
+void CXFA_Document::DoProtoMerge() {
+  CXFA_Node* pTemplateRoot = ToNode(GetXFAObject(XFA_HASHCODE_Template));
+  if (!pTemplateRoot) {
+    return;
+  }
+  CFX_MapPtrTemplate<FX_DWORD, CXFA_Node*> mIDMap;
+  CXFA_NodeSet sUseNodes;
+  CXFA_NodeIterator sIterator(pTemplateRoot);
+  for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
+       pNode = sIterator.MoveToNext()) {
+    CFX_WideStringC wsIDVal;
+    if (pNode->TryCData(XFA_ATTRIBUTE_Id, wsIDVal) && !wsIDVal.IsEmpty()) {
+      mIDMap[FX_HashCode_String_GetW(wsIDVal.GetPtr(), wsIDVal.GetLength())] =
+          pNode;
+    }
+    CFX_WideStringC wsUseVal;
+    if (pNode->TryCData(XFA_ATTRIBUTE_Use, wsUseVal) && !wsUseVal.IsEmpty()) {
+      sUseNodes.Add(pNode);
+    } else if (pNode->TryCData(XFA_ATTRIBUTE_Usehref, wsUseVal) &&
+               !wsUseVal.IsEmpty()) {
+      sUseNodes.Add(pNode);
+    }
+  }
+  FX_POSITION pos = sUseNodes.GetStartPosition();
+  while (pos) {
+    CXFA_Node* pUseHrefNode = NULL;
+    sUseNodes.GetNextAssoc(pos, pUseHrefNode);
+    CFX_WideString wsUseVal;
+    CFX_WideStringC wsURI, wsID, wsSOM;
+    if (pUseHrefNode->TryCData(XFA_ATTRIBUTE_Usehref, wsUseVal) &&
+        !wsUseVal.IsEmpty()) {
+      FX_STRSIZE uSharpPos = wsUseVal.Find('#');
+      if (uSharpPos < 0) {
+        wsURI = wsUseVal;
+      } else {
+        wsURI = CFX_WideStringC((const FX_WCHAR*)wsUseVal, uSharpPos);
+        FX_STRSIZE uLen = wsUseVal.GetLength();
+        if (uLen >= uSharpPos + 5 &&
+            CFX_WideStringC((const FX_WCHAR*)wsUseVal + uSharpPos, 5) ==
+                FX_WSTRC(L"#som(") &&
+            wsUseVal[uLen - 1] == ')') {
+          wsSOM = CFX_WideStringC((const FX_WCHAR*)wsUseVal + uSharpPos + 5,
+                                  uLen - 1 - uSharpPos - 5);
+        } else {
+          wsID = CFX_WideStringC((const FX_WCHAR*)wsUseVal + uSharpPos + 1,
+                                 uLen - uSharpPos - 1);
+        }
+      }
+    } else if (pUseHrefNode->TryCData(XFA_ATTRIBUTE_Use, wsUseVal) &&
+               !wsUseVal.IsEmpty()) {
+      if (wsUseVal[0] == '#') {
+        wsID = CFX_WideStringC((const FX_WCHAR*)wsUseVal + 1,
+                               wsUseVal.GetLength() - 1);
+      } else {
+        wsSOM =
+            CFX_WideStringC((const FX_WCHAR*)wsUseVal, wsUseVal.GetLength());
+      }
+    }
+    if (!wsURI.IsEmpty() && wsURI != FX_WSTRC(L".")) {
+      continue;
+    }
+    CXFA_Node* pProtoNode = NULL;
+    if (!wsSOM.IsEmpty()) {
+      FX_DWORD dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
+                        XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
+                        XFA_RESOLVENODE_Siblings;
+      XFA_RESOLVENODE_RS resoveNodeRS;
+      int32_t iRet = m_pScriptContext->ResolveObjects(pUseHrefNode, wsSOM,
+                                                      resoveNodeRS, dwFlag);
+      if (iRet > 0 && resoveNodeRS.nodes[0]->IsNode()) {
+        pProtoNode = resoveNodeRS.nodes[0]->AsNode();
+      }
+    } else if (!wsID.IsEmpty()) {
+      if (!mIDMap.Lookup(
+              FX_HashCode_String_GetW(wsID.GetPtr(), wsID.GetLength()),
+              pProtoNode)) {
+        continue;
+      }
+    }
+    if (!pProtoNode) {
+      continue;
+    }
+    XFA_ProtoMerge_MergeNode(this, pUseHrefNode, pProtoNode);
+  }
+}
diff --git a/xfa/fxfa/parser/xfa_document_layout_imp.cpp b/xfa/fxfa/parser/xfa_document_layout_imp.cpp
new file mode 100644
index 0000000..dbaa6e4
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_document_layout_imp.cpp
@@ -0,0 +1,208 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_document_layout_imp.h"
+
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_basic_imp.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_document_datamerger_imp.h"
+#include "xfa/fxfa/parser/xfa_layout_appadapter.h"
+#include "xfa/fxfa/parser/xfa_layout_itemlayout.h"
+#include "xfa/fxfa/parser/xfa_layout_pagemgr_new.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+CXFA_LayoutProcessor* CXFA_Document::GetLayoutProcessor() {
+  if (!m_pLayoutProcessor) {
+    m_pLayoutProcessor = new CXFA_LayoutProcessor(this);
+    ASSERT(m_pLayoutProcessor);
+  }
+  return m_pLayoutProcessor;
+}
+IXFA_DocLayout* CXFA_Document::GetDocLayout() {
+  return GetLayoutProcessor();
+}
+CXFA_LayoutProcessor::CXFA_LayoutProcessor(CXFA_Document* pDocument)
+    : m_pDocument(pDocument),
+      m_pRootItemLayoutProcessor(NULL),
+      m_pLayoutPageMgr(NULL),
+      m_nProgressCounter(0),
+      m_bNeeLayout(TRUE) {}
+CXFA_LayoutProcessor::~CXFA_LayoutProcessor() {
+  ClearLayoutData();
+}
+CXFA_Document* CXFA_LayoutProcessor::GetDocument() const {
+  return m_pDocument;
+}
+int32_t CXFA_LayoutProcessor::StartLayout(FX_BOOL bForceRestart) {
+  if (!bForceRestart && !IsNeedLayout()) {
+    return 100;
+  }
+  if (m_pRootItemLayoutProcessor) {
+    delete m_pRootItemLayoutProcessor;
+    m_pRootItemLayoutProcessor = NULL;
+  }
+  m_nProgressCounter = 0;
+  CXFA_Node* pFormPacketNode =
+      ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form));
+  if (!pFormPacketNode) {
+    return -1;
+  }
+  CXFA_Node* pFormRoot =
+      pFormPacketNode->GetFirstChildByClass(XFA_ELEMENT_Subform);
+  if (!pFormRoot) {
+    return -1;
+  }
+  if (!m_pLayoutPageMgr) {
+    m_pLayoutPageMgr = new CXFA_LayoutPageMgr(this);
+  }
+  if (!m_pLayoutPageMgr->InitLayoutPage(pFormRoot)) {
+    return -1;
+  }
+  if (!m_pLayoutPageMgr->PrepareFirstPage(pFormRoot)) {
+    return -1;
+  }
+  m_pRootItemLayoutProcessor =
+      new CXFA_ItemLayoutProcessor(pFormRoot, m_pLayoutPageMgr);
+  m_nProgressCounter = 1;
+  return 0;
+}
+int32_t CXFA_LayoutProcessor::DoLayout(IFX_Pause* pPause) {
+  if (m_nProgressCounter < 1) {
+    return -1;
+  }
+  XFA_ItemLayoutProcessorResult eStatus;
+  CXFA_Node* pFormNode = m_pRootItemLayoutProcessor->GetFormNode();
+  FX_FLOAT fPosX = pFormNode->GetMeasure(XFA_ATTRIBUTE_X).ToUnit(XFA_UNIT_Pt);
+  FX_FLOAT fPosY = pFormNode->GetMeasure(XFA_ATTRIBUTE_Y).ToUnit(XFA_UNIT_Pt);
+  do {
+    FX_FLOAT fAvailHeight = m_pLayoutPageMgr->GetAvailHeight();
+    eStatus =
+        m_pRootItemLayoutProcessor->DoLayout(TRUE, fAvailHeight, fAvailHeight);
+    if (eStatus != XFA_ItemLayoutProcessorResult_Done) {
+      m_nProgressCounter++;
+    }
+    CXFA_ContentLayoutItem* pLayoutItem =
+        m_pRootItemLayoutProcessor->ExtractLayoutItem();
+    if (pLayoutItem) {
+      pLayoutItem->m_sPos = CFX_PointF(fPosX, fPosY);
+    }
+    m_pLayoutPageMgr->SubmitContentItem(pLayoutItem, eStatus);
+  } while (eStatus != XFA_ItemLayoutProcessorResult_Done &&
+           (!pPause || !pPause->NeedToPauseNow()));
+  if (eStatus == XFA_ItemLayoutProcessorResult_Done) {
+    m_pLayoutPageMgr->FinishPaginatedPageSets();
+    m_pLayoutPageMgr->SyncLayoutData();
+    m_bNeeLayout = FALSE;
+    m_rgChangedContainers.RemoveAll();
+  }
+  return 100 * (eStatus == XFA_ItemLayoutProcessorResult_Done
+                    ? m_nProgressCounter
+                    : m_nProgressCounter - 1) /
+         m_nProgressCounter;
+}
+FX_BOOL CXFA_LayoutProcessor::IncrementLayout() {
+  if (m_bNeeLayout) {
+    StartLayout(TRUE);
+    return DoLayout(NULL) == 100;
+  }
+  for (int32_t i = 0, c = m_rgChangedContainers.GetSize(); i < c; i++) {
+    CXFA_Node* pNode = m_rgChangedContainers[i];
+    CXFA_Node* pParentNode =
+        pNode->GetNodeItem(XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode);
+    if (!pParentNode) {
+      return FALSE;
+    }
+    if (!CXFA_ItemLayoutProcessor::IncrementRelayoutNode(this, pNode,
+                                                         pParentNode)) {
+      return FALSE;
+    }
+  }
+  m_rgChangedContainers.RemoveAll();
+  return TRUE;
+}
+int32_t CXFA_LayoutProcessor::CountPages() const {
+  return m_pLayoutPageMgr ? m_pLayoutPageMgr->GetPageCount() : 0;
+}
+IXFA_LayoutPage* CXFA_LayoutProcessor::GetPage(int32_t index) const {
+  return m_pLayoutPageMgr ? m_pLayoutPageMgr->GetPage(index) : NULL;
+}
+CXFA_LayoutItem* CXFA_LayoutProcessor::GetLayoutItem(CXFA_Node* pFormItem) {
+  return static_cast<CXFA_LayoutItem*>(
+      pFormItem->GetUserData(XFA_LAYOUTITEMKEY));
+}
+void CXFA_LayoutProcessor::AddChangedContainer(CXFA_Node* pContainer) {
+  if (m_rgChangedContainers.Find(pContainer) < 0) {
+    m_rgChangedContainers.Add(pContainer);
+  }
+}
+CXFA_ContainerLayoutItem* CXFA_LayoutProcessor::GetRootLayoutItem() const {
+  return m_pLayoutPageMgr ? m_pLayoutPageMgr->GetRootLayoutItem() : NULL;
+}
+void CXFA_LayoutProcessor::ClearLayoutData() {
+  if (m_pLayoutPageMgr) {
+    delete m_pLayoutPageMgr;
+    m_pLayoutPageMgr = NULL;
+  }
+  if (m_pRootItemLayoutProcessor) {
+    delete m_pRootItemLayoutProcessor;
+    m_pRootItemLayoutProcessor = NULL;
+  }
+  m_nProgressCounter = 0;
+}
+FX_BOOL CXFA_LayoutProcessor::IsNeedLayout() {
+  return m_bNeeLayout || m_rgChangedContainers.GetSize() > 0;
+}
+CXFA_LayoutItem::CXFA_LayoutItem(CXFA_Node* pNode, FX_BOOL bIsContentLayoutItem)
+    : m_pFormNode(pNode),
+      m_pParent(NULL),
+      m_pNextSibling(NULL),
+      m_pFirstChild(NULL),
+      m_bIsContentLayoutItem(bIsContentLayoutItem) {}
+CXFA_LayoutItem::~CXFA_LayoutItem() {}
+CXFA_ContainerLayoutItem::CXFA_ContainerLayoutItem(CXFA_Node* pNode)
+    : CXFA_LayoutItem(pNode, FALSE), m_pOldSubform(NULL) {}
+IXFA_DocLayout* CXFA_ContainerLayoutItem::GetLayout() const {
+  return m_pFormNode->GetDocument()->GetLayoutProcessor();
+}
+int32_t CXFA_ContainerLayoutItem::GetPageIndex() const {
+  return m_pFormNode->GetDocument()
+      ->GetLayoutProcessor()
+      ->GetLayoutPageMgr()
+      ->GetPageIndex(this);
+}
+void CXFA_ContainerLayoutItem::GetPageSize(CFX_SizeF& size) {
+  size.clear();
+  CXFA_Node* pMedium = m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Medium);
+  if (!pMedium)
+    return;
+
+  size = CFX_SizeF(pMedium->GetMeasure(XFA_ATTRIBUTE_Short).ToUnit(XFA_UNIT_Pt),
+                   pMedium->GetMeasure(XFA_ATTRIBUTE_Long).ToUnit(XFA_UNIT_Pt));
+  if (pMedium->GetEnum(XFA_ATTRIBUTE_Orientation) ==
+      XFA_ATTRIBUTEENUM_Landscape) {
+    size = CFX_SizeF(size.y, size.x);
+  }
+}
+CXFA_Node* CXFA_ContainerLayoutItem::GetMasterPage() const {
+  return m_pFormNode;
+}
+CXFA_ContentLayoutItem::CXFA_ContentLayoutItem(CXFA_Node* pNode)
+    : CXFA_LayoutItem(pNode, TRUE),
+      m_pPrev(NULL),
+      m_pNext(NULL),
+      m_dwStatus(0) {}
+CXFA_ContentLayoutItem::~CXFA_ContentLayoutItem() {
+  if (m_pFormNode->GetUserData(XFA_LAYOUTITEMKEY) == this) {
+    m_pFormNode->SetUserData(XFA_LAYOUTITEMKEY, NULL);
+  }
+}
diff --git a/xfa/fxfa/parser/xfa_document_layout_imp.h b/xfa/fxfa/parser/xfa_document_layout_imp.h
new file mode 100644
index 0000000..7f6c14e
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_document_layout_imp.h
@@ -0,0 +1,49 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_DOCUMENT_LAYOUT_IMP_H_
+#define XFA_FXFA_PARSER_XFA_DOCUMENT_LAYOUT_IMP_H_
+
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+
+class CXFA_ItemLayoutProcessor;
+class CXFA_LayoutPageMgr;
+class CXFA_ContainerLayoutItem;
+
+class CXFA_LayoutProcessor : public IXFA_DocLayout {
+ public:
+  CXFA_LayoutProcessor(CXFA_Document* pDocument);
+  ~CXFA_LayoutProcessor();
+  virtual CXFA_Document* GetDocument() const;
+  virtual int32_t StartLayout(FX_BOOL bForceRestart = FALSE);
+  virtual int32_t DoLayout(IFX_Pause* pPause = NULL);
+  virtual FX_BOOL IncrementLayout();
+  virtual int32_t CountPages() const;
+  virtual IXFA_LayoutPage* GetPage(int32_t index) const;
+  virtual CXFA_LayoutItem* GetLayoutItem(CXFA_Node* pFormItem);
+
+  void AddChangedContainer(CXFA_Node* pContainer);
+  void SetForceReLayout(FX_BOOL bForceRestart) { m_bNeeLayout = bForceRestart; }
+  CXFA_ContainerLayoutItem* GetRootLayoutItem() const;
+  CXFA_ItemLayoutProcessor* GetRootRootItemLayoutProcessor() {
+    return m_pRootItemLayoutProcessor;
+  }
+  CXFA_LayoutPageMgr* GetLayoutPageMgr() { return m_pLayoutPageMgr; }
+
+ protected:
+  void ClearLayoutData();
+
+  FX_BOOL IsNeedLayout();
+
+  CXFA_Document* m_pDocument;
+  CXFA_ItemLayoutProcessor* m_pRootItemLayoutProcessor;
+  CXFA_LayoutPageMgr* m_pLayoutPageMgr;
+  CXFA_NodeArray m_rgChangedContainers;
+  uint32_t m_nProgressCounter;
+  FX_BOOL m_bNeeLayout;
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_DOCUMENT_LAYOUT_IMP_H_
diff --git a/xfa/fxfa/parser/xfa_document_serialize.cpp b/xfa/fxfa/parser/xfa_document_serialize.cpp
new file mode 100644
index 0000000..858efff
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_document_serialize.cpp
@@ -0,0 +1,590 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_document_serialize.h"
+
+#include "xfa/fgas/crt/fgas_codepage.h"
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+IXFA_PacketImport* IXFA_PacketImport::Create(CXFA_Document* pDocument) {
+  return new CXFA_DataImporter(pDocument);
+}
+CXFA_DataImporter::CXFA_DataImporter(CXFA_Document* pDocument)
+    : m_pDocument(pDocument) {
+  ASSERT(m_pDocument);
+}
+FX_BOOL CXFA_DataImporter::ImportData(IFX_FileRead* pDataDocument) {
+  IXFA_Parser* pDataDocumentParser = IXFA_Parser::Create(m_pDocument);
+  if (!pDataDocumentParser) {
+    return FALSE;
+  }
+  if (pDataDocumentParser->StartParse(pDataDocument, XFA_XDPPACKET_Datasets) !=
+      XFA_PARSESTATUS_Ready) {
+    pDataDocumentParser->Release();
+    return FALSE;
+  }
+  if (pDataDocumentParser->DoParse(NULL) < XFA_PARSESTATUS_Done) {
+    pDataDocumentParser->Release();
+    return FALSE;
+  }
+  CXFA_Node* pImportDataRoot = pDataDocumentParser->GetRootNode();
+  if (!pImportDataRoot) {
+    pDataDocumentParser->Release();
+    return FALSE;
+  }
+  CXFA_Node* pDataModel =
+      ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Datasets));
+  if (!pDataModel) {
+    pDataDocumentParser->Release();
+    return FALSE;
+  }
+  CXFA_Node* pDataNode = ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Data));
+  if (pDataNode) {
+    pDataModel->RemoveChild(pDataNode);
+  }
+  if (pImportDataRoot->GetClassID() == XFA_ELEMENT_DataModel) {
+    while (CXFA_Node* pChildNode =
+               pImportDataRoot->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+      pImportDataRoot->RemoveChild(pChildNode);
+      pDataModel->InsertChild(pChildNode);
+    }
+  } else {
+    IFDE_XMLNode* pXMLNode = pImportDataRoot->GetXMLMappingNode();
+    IFDE_XMLNode* pParentXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::Parent);
+    if (pParentXMLNode) {
+      pParentXMLNode->RemoveChildNode(pXMLNode);
+    }
+    pDataModel->InsertChild(pImportDataRoot);
+  }
+  m_pDocument->DoDataRemerge(FALSE);
+  pDataDocumentParser->Release();
+  return TRUE;
+}
+CFX_WideString XFA_ExportEncodeAttribute(const CFX_WideString& str) {
+  CFX_WideTextBuf textBuf;
+  int32_t iLen = str.GetLength();
+  for (int32_t i = 0; i < iLen; i++) {
+    switch (str[i]) {
+      case '&':
+        textBuf << FX_WSTRC(L"&amp;");
+        break;
+      case '<':
+        textBuf << FX_WSTRC(L"&lt;");
+        break;
+      case '>':
+        textBuf << FX_WSTRC(L"&gt;");
+        break;
+      case '\'':
+        textBuf << FX_WSTRC(L"&apos;");
+        break;
+      case '\"':
+        textBuf << FX_WSTRC(L"&quot;");
+        break;
+      default:
+        textBuf.AppendChar(str[i]);
+    }
+  }
+  return textBuf.GetWideString();
+}
+CFX_WideString XFA_ExportEncodeContent(const CFX_WideStringC& str) {
+  CFX_WideTextBuf textBuf;
+  int32_t iLen = str.GetLength();
+  for (int32_t i = 0; i < iLen; i++) {
+    FX_WCHAR ch = str.GetAt(i);
+    if (!FDE_IsXMLValidChar(ch)) {
+      continue;
+    }
+    if (ch == '&') {
+      textBuf << FX_WSTRC(L"&amp;");
+    } else if (ch == '<') {
+      textBuf << FX_WSTRC(L"&lt;");
+    } else if (ch == '>') {
+      textBuf << FX_WSTRC(L"&gt;");
+    } else if (ch == '\'') {
+      textBuf << FX_WSTRC(L"&apos;");
+    } else if (ch == '\"') {
+      textBuf << FX_WSTRC(L"&quot;");
+    } else if (ch == ' ') {
+      if (i && str.GetAt(i - 1) != ' ') {
+        textBuf.AppendChar(' ');
+      } else {
+        textBuf << FX_WSTRC(L"&#x20;");
+      }
+    } else {
+      textBuf.AppendChar(str.GetAt(i));
+    }
+  }
+  return textBuf.GetWideString();
+}
+static void XFA_SaveAttribute(CXFA_Node* pNode,
+                              XFA_ATTRIBUTE eName,
+                              const CFX_WideStringC& wsName,
+                              FX_BOOL bProto,
+                              CFX_WideString& wsOutput) {
+  CFX_WideString wsValue;
+  if ((!bProto && !pNode->HasAttribute((XFA_ATTRIBUTE)eName, bProto)) ||
+      !pNode->GetAttribute((XFA_ATTRIBUTE)eName, wsValue, FALSE)) {
+    return;
+  }
+  wsValue = XFA_ExportEncodeAttribute(wsValue);
+  wsOutput += FX_WSTRC(L" ");
+  wsOutput += wsName;
+  wsOutput += FX_WSTRC(L"=\"");
+  wsOutput += wsValue;
+  wsOutput += FX_WSTRC(L"\"");
+}
+static FX_BOOL XFA_DataExporter_AttributeSaveInDataModel(
+    CXFA_Node* pNode,
+    XFA_ATTRIBUTE eAttribute) {
+  FX_BOOL bSaveInDataModel = FALSE;
+  if (pNode->GetClassID() != XFA_ELEMENT_Image) {
+    return bSaveInDataModel;
+  }
+  CXFA_Node* pValueNode = pNode->GetNodeItem(XFA_NODEITEM_Parent);
+  if (!pValueNode || pValueNode->GetClassID() != XFA_ELEMENT_Value) {
+    return bSaveInDataModel;
+  }
+  CXFA_Node* pFieldNode = pValueNode->GetNodeItem(XFA_NODEITEM_Parent);
+  if (pFieldNode && pFieldNode->GetBindData() &&
+      eAttribute == XFA_ATTRIBUTE_Href) {
+    bSaveInDataModel = TRUE;
+  }
+  return bSaveInDataModel;
+}
+FX_BOOL XFA_DataExporter_ContentNodeNeedtoExport(CXFA_Node* pContentNode) {
+  CFX_WideString wsContent;
+  if (!pContentNode->TryContent(wsContent, FALSE, FALSE)) {
+    return FALSE;
+  }
+  FXSYS_assert(pContentNode->GetObjectType() == XFA_OBJECTTYPE_ContentNode);
+  CXFA_Node* pParentNode = pContentNode->GetNodeItem(XFA_NODEITEM_Parent);
+  if (!pParentNode || pParentNode->GetClassID() != XFA_ELEMENT_Value) {
+    return TRUE;
+  }
+  CXFA_Node* pGrandParentNode = pParentNode->GetNodeItem(XFA_NODEITEM_Parent);
+  if (!pGrandParentNode ||
+      pGrandParentNode->GetObjectType() != XFA_OBJECTTYPE_ContainerNode) {
+    return TRUE;
+  }
+  if (pGrandParentNode->GetBindData()) {
+    return FALSE;
+  }
+  CXFA_WidgetData* pWidgetData = pGrandParentNode->GetWidgetData();
+  XFA_ELEMENT eUIType = pWidgetData->GetUIType();
+  if (eUIType == XFA_ELEMENT_PasswordEdit) {
+    return FALSE;
+  }
+  return TRUE;
+}
+static void XFA_DataExporter_RecognizeXFAVersionNumber(
+    CXFA_Node* pTemplateRoot,
+    CFX_WideString& wsVersionNumber) {
+  wsVersionNumber.Empty();
+  if (!pTemplateRoot) {
+    return;
+  }
+  CFX_WideString wsTemplateNS;
+  if (!pTemplateRoot->TryNamespace(wsTemplateNS)) {
+    return;
+  }
+  XFA_VERSION eVersion =
+      pTemplateRoot->GetDocument()->RecognizeXFAVersionNumber(wsTemplateNS);
+  if (eVersion == XFA_VERSION_UNKNOWN) {
+    eVersion = XFA_VERSION_DEFAULT;
+  }
+  wsVersionNumber.Format(L"%i.%i", eVersion / 100, eVersion % 100);
+}
+static void XFA_DataExporter_RegenerateFormFile_Changed(
+    CXFA_Node* pNode,
+    CFX_WideTextBuf& buf,
+    FX_BOOL bSaveXML = FALSE) {
+  CFX_WideString wsAttrs;
+  int32_t iAttrs = 0;
+  const uint8_t* pAttrs = XFA_GetElementAttributes(pNode->GetClassID(), iAttrs);
+  while (iAttrs--) {
+    const XFA_ATTRIBUTEINFO* pAttr =
+        XFA_GetAttributeByID((XFA_ATTRIBUTE)pAttrs[iAttrs]);
+    if (pAttr->eName == XFA_ATTRIBUTE_Name ||
+        (XFA_DataExporter_AttributeSaveInDataModel(pNode, pAttr->eName) &&
+         !bSaveXML)) {
+      continue;
+    }
+    CFX_WideString wsAttr;
+    XFA_SaveAttribute(pNode, pAttr->eName, pAttr->pName, bSaveXML, wsAttr);
+    wsAttrs += wsAttr;
+  }
+  CFX_WideString wsChildren;
+  switch (pNode->GetObjectType()) {
+    case XFA_OBJECTTYPE_ContentNode: {
+      if (!bSaveXML && !XFA_DataExporter_ContentNodeNeedtoExport(pNode)) {
+        break;
+      }
+      CXFA_Node* pRawValueNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+      while (pRawValueNode &&
+             pRawValueNode->GetClassID() != XFA_ELEMENT_SharpxHTML &&
+             pRawValueNode->GetClassID() != XFA_ELEMENT_Sharptext &&
+             pRawValueNode->GetClassID() != XFA_ELEMENT_Sharpxml) {
+        pRawValueNode = pRawValueNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+      }
+      if (!pRawValueNode) {
+        break;
+      }
+      CFX_WideString wsContentType;
+      pNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);
+      if (pRawValueNode->GetClassID() == XFA_ELEMENT_SharpxHTML &&
+          wsContentType.Equal(FX_WSTRC(L"text/html"))) {
+        IFDE_XMLNode* pExDataXML = pNode->GetXMLMappingNode();
+        if (!pExDataXML) {
+          break;
+        }
+        IFDE_XMLNode* pRichTextXML =
+            pExDataXML->GetNodeItem(IFDE_XMLNode::FirstChild);
+        if (!pRichTextXML) {
+          break;
+        }
+        IFX_MemoryStream* pMemStream = FX_CreateMemoryStream(TRUE);
+        IFX_Stream* pTempStream = IFX_Stream::CreateStream(
+            (IFX_FileWrite*)pMemStream, FX_STREAMACCESS_Text |
+                                            FX_STREAMACCESS_Write |
+                                            FX_STREAMACCESS_Append);
+        pTempStream->SetCodePage(FX_CODEPAGE_UTF8);
+        pRichTextXML->SaveXMLNode(pTempStream);
+        wsChildren += CFX_WideString::FromUTF8(
+            (const FX_CHAR*)pMemStream->GetBuffer(), pMemStream->GetSize());
+        pTempStream->Release();
+        pMemStream->Release();
+      } else if (pRawValueNode->GetClassID() == XFA_ELEMENT_Sharpxml &&
+                 wsContentType.Equal(FX_WSTRC(L"text/xml"))) {
+        CFX_WideString wsRawValue;
+        pRawValueNode->GetAttribute(XFA_ATTRIBUTE_Value, wsRawValue, FALSE);
+        if (wsRawValue.IsEmpty()) {
+          break;
+        }
+        CFX_WideStringArray wsSelTextArray;
+        int32_t iStart = 0;
+        int32_t iEnd = wsRawValue.Find(L'\n', iStart);
+        iEnd = (iEnd == -1) ? wsRawValue.GetLength() : iEnd;
+        while (iEnd >= iStart) {
+          wsSelTextArray.Add(wsRawValue.Mid(iStart, iEnd - iStart));
+          iStart = iEnd + 1;
+          if (iStart >= wsRawValue.GetLength()) {
+            break;
+          }
+          iEnd = wsRawValue.Find(L'\n', iStart);
+        }
+        CXFA_Node* pParentNode = pNode->GetNodeItem(XFA_NODEITEM_Parent);
+        FXSYS_assert(pParentNode);
+        CXFA_Node* pGrandparentNode =
+            pParentNode->GetNodeItem(XFA_NODEITEM_Parent);
+        FXSYS_assert(pGrandparentNode);
+        CFX_WideString bodyTagName;
+        bodyTagName = pGrandparentNode->GetCData(XFA_ATTRIBUTE_Name);
+        if (bodyTagName.IsEmpty()) {
+          bodyTagName = FX_WSTRC(L"ListBox1");
+        }
+        buf << FX_WSTRC(L"<");
+        buf << bodyTagName;
+        buf << FX_WSTRC(L" xmlns=\"\"\n>");
+        for (int32_t i = 0; i < wsSelTextArray.GetSize(); i++) {
+          buf << FX_WSTRC(L"<value\n>");
+          buf << XFA_ExportEncodeContent(wsSelTextArray[i]);
+          buf << FX_WSTRC(L"</value\n>");
+        }
+        buf << FX_WSTRC(L"</");
+        buf << bodyTagName;
+        buf << FX_WSTRC(L"\n>");
+        wsChildren += buf.GetWideString();
+        buf.Clear();
+      } else {
+        CFX_WideStringC wsValue = pRawValueNode->GetCData(XFA_ATTRIBUTE_Value);
+        wsChildren += XFA_ExportEncodeContent(wsValue);
+      }
+    } break;
+    case XFA_OBJECTTYPE_TextNode:
+    case XFA_OBJECTTYPE_NodeC:
+    case XFA_OBJECTTYPE_NodeV: {
+      CFX_WideStringC wsValue = pNode->GetCData(XFA_ATTRIBUTE_Value);
+      wsChildren += XFA_ExportEncodeContent(wsValue);
+    } break;
+    default:
+      if (pNode->GetClassID() == XFA_ELEMENT_Items) {
+        CXFA_Node* pTemplateNode = pNode->GetTemplateNode();
+        if (!pTemplateNode ||
+            pTemplateNode->CountChildren(XFA_ELEMENT_UNKNOWN) !=
+                pNode->CountChildren(XFA_ELEMENT_UNKNOWN)) {
+          bSaveXML = TRUE;
+        }
+      }
+      CFX_WideTextBuf newBuf;
+      CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+      while (pChildNode) {
+        XFA_DataExporter_RegenerateFormFile_Changed(pChildNode, newBuf,
+                                                    bSaveXML);
+        wsChildren += newBuf.GetWideString();
+        newBuf.Clear();
+        pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+      }
+      if (!bSaveXML && !wsChildren.IsEmpty() &&
+          pNode->GetClassID() == XFA_ELEMENT_Items) {
+        wsChildren.Empty();
+        bSaveXML = TRUE;
+        CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+        while (pChildNode) {
+          XFA_DataExporter_RegenerateFormFile_Changed(pChildNode, newBuf,
+                                                      bSaveXML);
+          wsChildren += newBuf.GetWideString();
+          newBuf.Clear();
+          pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+        }
+      }
+      break;
+  }
+  if (!wsChildren.IsEmpty() || !wsAttrs.IsEmpty() ||
+      pNode->HasAttribute(XFA_ATTRIBUTE_Name)) {
+    CFX_WideStringC wsElement;
+    pNode->GetClassName(wsElement);
+    CFX_WideString wsName;
+    XFA_SaveAttribute(pNode, XFA_ATTRIBUTE_Name, FX_WSTRC(L"name"), TRUE,
+                      wsName);
+    buf << FX_WSTRC(L"<");
+    buf << wsElement;
+    buf << wsName;
+    buf << wsAttrs;
+    if (wsChildren.IsEmpty()) {
+      buf << FX_WSTRC(L"\n/>");
+    } else {
+      buf << FX_WSTRC(L"\n>");
+      buf << wsChildren;
+      buf << FX_WSTRC(L"</");
+      buf << wsElement;
+      buf << FX_WSTRC(L"\n>");
+    }
+  }
+}
+static void XFA_DataExporter_RegenerateFormFile_Container(
+    CXFA_Node* pNode,
+    IFX_Stream* pStream,
+    FX_BOOL bSaveXML = FALSE) {
+  XFA_ELEMENT eElement = pNode->GetClassID();
+  if (eElement == XFA_ELEMENT_Field || eElement == XFA_ELEMENT_Draw ||
+      !pNode->IsContainerNode()) {
+    CFX_WideTextBuf buf;
+    XFA_DataExporter_RegenerateFormFile_Changed(pNode, buf, bSaveXML);
+    FX_STRSIZE nLen = buf.GetLength();
+    if (nLen > 0) {
+      pStream->WriteString((const FX_WCHAR*)buf.GetBuffer(), nLen);
+    }
+    return;
+  }
+  CFX_WideStringC wsElement;
+  pNode->GetClassName(wsElement);
+  pStream->WriteString(L"<", 1);
+  pStream->WriteString(wsElement.GetPtr(), wsElement.GetLength());
+  CFX_WideString wsOutput;
+  XFA_SaveAttribute(pNode, XFA_ATTRIBUTE_Name, FX_WSTRC(L"name"), TRUE,
+                    wsOutput);
+  CFX_WideString wsAttrs;
+  int32_t iAttrs = 0;
+  const uint8_t* pAttrs = XFA_GetElementAttributes(pNode->GetClassID(), iAttrs);
+  while (iAttrs--) {
+    const XFA_ATTRIBUTEINFO* pAttr =
+        XFA_GetAttributeByID((XFA_ATTRIBUTE)pAttrs[iAttrs]);
+    if (pAttr->eName == XFA_ATTRIBUTE_Name) {
+      continue;
+    }
+    CFX_WideString wsAttr;
+    XFA_SaveAttribute(pNode, pAttr->eName, pAttr->pName, FALSE, wsAttr);
+    wsOutput += wsAttr;
+  }
+  if (!wsOutput.IsEmpty()) {
+    pStream->WriteString((const FX_WCHAR*)wsOutput, wsOutput.GetLength());
+  }
+  CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+  if (pChildNode) {
+    pStream->WriteString(L"\n>", 2);
+    while (pChildNode) {
+      XFA_DataExporter_RegenerateFormFile_Container(pChildNode, pStream,
+                                                    bSaveXML);
+      pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+    }
+    pStream->WriteString(L"</", 2);
+    pStream->WriteString(wsElement.GetPtr(), wsElement.GetLength());
+    pStream->WriteString(L"\n>", 2);
+  } else {
+    pStream->WriteString(L"\n/>", 3);
+  }
+}
+void XFA_DataExporter_RegenerateFormFile(CXFA_Node* pNode,
+                                         IFX_Stream* pStream,
+                                         const FX_CHAR* pChecksum,
+                                         FX_BOOL bSaveXML) {
+  if (pNode->GetObjectType() == XFA_OBJECTTYPE_ModelNode) {
+    static const FX_WCHAR* s_pwsTagName = L"<form";
+    static const FX_WCHAR* s_pwsClose = L"</form\n>";
+    pStream->WriteString(s_pwsTagName, FXSYS_wcslen(s_pwsTagName));
+    if (pChecksum) {
+      static const FX_WCHAR* s_pwChecksum = L" checksum=\"";
+      CFX_WideString wsChecksum =
+          CFX_WideString::FromUTF8(pChecksum, FXSYS_strlen(pChecksum));
+      pStream->WriteString(s_pwChecksum, FXSYS_wcslen(s_pwChecksum));
+      pStream->WriteString((const FX_WCHAR*)wsChecksum, wsChecksum.GetLength());
+      pStream->WriteString(L"\"", 1);
+    }
+    pStream->WriteString(L" xmlns=\"", FXSYS_wcslen(L" xmlns=\""));
+    const FX_WCHAR* pURI = XFA_GetPacketByIndex(XFA_PACKET_Form)->pURI;
+    pStream->WriteString(pURI, FXSYS_wcslen(pURI));
+    CFX_WideString wsVersionNumber;
+    XFA_DataExporter_RecognizeXFAVersionNumber(
+        ToNode(pNode->GetDocument()->GetXFAObject(XFA_XDPPACKET_Template)),
+        wsVersionNumber);
+    if (wsVersionNumber.IsEmpty()) {
+      wsVersionNumber = FX_WSTRC(L"2.8");
+    }
+    wsVersionNumber += FX_WSTRC(L"/\"\n>");
+    pStream->WriteString((const FX_WCHAR*)wsVersionNumber,
+                         wsVersionNumber.GetLength());
+    CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+    while (pChildNode) {
+      XFA_DataExporter_RegenerateFormFile_Container(pChildNode, pStream);
+      pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+    }
+    pStream->WriteString(s_pwsClose, FXSYS_wcslen(s_pwsClose));
+  } else {
+    XFA_DataExporter_RegenerateFormFile_Container(pNode, pStream, bSaveXML);
+  }
+}
+IXFA_PacketExport* IXFA_PacketExport::Create(CXFA_Document* pDocument,
+                                             XFA_DATAFORMAT eFormat) {
+  return new CXFA_DataExporter(pDocument);
+}
+CXFA_DataExporter::CXFA_DataExporter(CXFA_Document* pDocument)
+    : m_pDocument(pDocument) {
+  ASSERT(m_pDocument);
+}
+FX_BOOL CXFA_DataExporter::Export(IFX_FileWrite* pWrite) {
+  return Export(pWrite, m_pDocument->GetRoot());
+}
+FX_BOOL CXFA_DataExporter::Export(IFX_FileWrite* pWrite,
+                                  CXFA_Node* pNode,
+                                  FX_DWORD dwFlag,
+                                  const FX_CHAR* pChecksum) {
+  if (!pWrite) {
+    ASSERT(false);
+    return FALSE;
+  }
+  IFX_Stream* pStream = IFX_Stream::CreateStream(
+      pWrite,
+      FX_STREAMACCESS_Text | FX_STREAMACCESS_Write | FX_STREAMACCESS_Append);
+  if (pStream == NULL) {
+    return FALSE;
+  }
+  pStream->SetCodePage(FX_CODEPAGE_UTF8);
+  FX_BOOL bRet = Export(pStream, pNode, dwFlag, pChecksum);
+  pStream->Release();
+  return bRet;
+}
+FX_BOOL CXFA_DataExporter::Export(IFX_Stream* pStream,
+                                  CXFA_Node* pNode,
+                                  FX_DWORD dwFlag,
+                                  const FX_CHAR* pChecksum) {
+  IFDE_XMLDoc* pXMLDoc = m_pDocument->GetParser()->GetXMLDoc();
+  if (pNode->GetObjectType() == XFA_OBJECTTYPE_ModelNode) {
+    switch (pNode->GetPacketID()) {
+      case XFA_XDPPACKET_XDP: {
+        static const FX_WCHAR* s_pwsPreamble =
+            L"<xdp:xdp xmlns:xdp=\"http://ns.adobe.com/xdp/\">";
+        pStream->WriteString(s_pwsPreamble, FXSYS_wcslen(s_pwsPreamble));
+        for (CXFA_Node* pChild = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+             pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+          Export(pStream, pChild, dwFlag, pChecksum);
+        }
+        static const FX_WCHAR* s_pwsPostamble = L"</xdp:xdp\n>";
+        pStream->WriteString(s_pwsPostamble, FXSYS_wcslen(s_pwsPostamble));
+      } break;
+      case XFA_XDPPACKET_Datasets: {
+        IFDE_XMLElement* pElement =
+            (IFDE_XMLElement*)pNode->GetXMLMappingNode();
+        if (!pElement || pElement->GetType() != FDE_XMLNODE_Element) {
+          return FALSE;
+        }
+        CXFA_Node* pDataNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+        FXSYS_assert(pDataNode);
+        XFA_DataExporter_DealWithDataGroupNode(pDataNode);
+        pXMLDoc->SaveXMLNode(pStream, pElement);
+      } break;
+      case XFA_XDPPACKET_Form: {
+        XFA_DataExporter_RegenerateFormFile(pNode, pStream, pChecksum);
+      } break;
+      case XFA_XDPPACKET_Template:
+      default: {
+        IFDE_XMLElement* pElement =
+            (IFDE_XMLElement*)pNode->GetXMLMappingNode();
+        if (!pElement || pElement->GetType() != FDE_XMLNODE_Element) {
+          return FALSE;
+        }
+        pXMLDoc->SaveXMLNode(pStream, pElement);
+      } break;
+    }
+  } else {
+    CXFA_Node* pDataNode = pNode->GetNodeItem(XFA_NODEITEM_Parent);
+    CXFA_Node* pExportNode = pNode;
+    for (CXFA_Node* pChildNode =
+             pDataNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+         pChildNode;
+         pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+      if (pChildNode != pNode) {
+        pExportNode = pDataNode;
+        break;
+      }
+    }
+    IFDE_XMLElement* pElement =
+        (IFDE_XMLElement*)pExportNode->GetXMLMappingNode();
+    if (!pElement || pElement->GetType() != FDE_XMLNODE_Element) {
+      return FALSE;
+    }
+    XFA_DataExporter_DealWithDataGroupNode(pExportNode);
+    pElement->SetString(FX_WSTRC(L"xmlns:xfa"),
+                        FX_WSTRC(L"http://www.xfa.org/schema/xfa-data/1.0/"));
+    pXMLDoc->SaveXMLNode(pStream, pElement);
+    pElement->RemoveAttribute(L"xmlns:xfa");
+  }
+  return TRUE;
+}
+void XFA_DataExporter_DealWithDataGroupNode(CXFA_Node* pDataNode) {
+  if (!pDataNode || pDataNode->GetClassID() == XFA_ELEMENT_DataValue) {
+    return;
+  }
+  int32_t iChildNum = 0;
+  for (CXFA_Node* pChildNode = pDataNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+       pChildNode;
+       pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    iChildNum++;
+    XFA_DataExporter_DealWithDataGroupNode(pChildNode);
+  }
+  if (pDataNode->GetClassID() == XFA_ELEMENT_DataGroup) {
+    if (iChildNum > 0) {
+      IFDE_XMLNode* pXMLNode = pDataNode->GetXMLMappingNode();
+      FXSYS_assert(pXMLNode->GetType() == FDE_XMLNODE_Element);
+      IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLNode;
+      if (pXMLElement->HasAttribute(L"xfa:dataNode")) {
+        pXMLElement->RemoveAttribute(L"xfa:dataNode");
+      }
+    } else {
+      IFDE_XMLNode* pXMLNode = pDataNode->GetXMLMappingNode();
+      FXSYS_assert(pXMLNode->GetType() == FDE_XMLNODE_Element);
+      ((IFDE_XMLElement*)pXMLNode)
+          ->SetString(FX_WSTRC(L"xfa:dataNode"), FX_WSTRC(L"dataGroup"));
+    }
+  }
+}
diff --git a/xfa/fxfa/parser/xfa_document_serialize.h b/xfa/fxfa/parser/xfa_document_serialize.h
new file mode 100644
index 0000000..f9253fb
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_document_serialize.h
@@ -0,0 +1,40 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_DOCUMENT_SERIALIZE_H_
+#define XFA_FXFA_PARSER_XFA_DOCUMENT_SERIALIZE_H_
+
+#include "xfa/fxfa/parser/xfa_docdata.h"
+
+class CXFA_DataImporter : public IXFA_PacketImport {
+ public:
+  CXFA_DataImporter(CXFA_Document* pDocument);
+  virtual void Release() { delete this; }
+  virtual FX_BOOL ImportData(IFX_FileRead* pDataDocument);
+
+ protected:
+  CXFA_Document* m_pDocument;
+};
+
+class CXFA_DataExporter : public IXFA_PacketExport {
+ public:
+  CXFA_DataExporter(CXFA_Document* pDocument);
+  virtual void Release() { delete this; }
+  virtual FX_BOOL Export(IFX_FileWrite* pWrite);
+  virtual FX_BOOL Export(IFX_FileWrite* pWrite,
+                         CXFA_Node* pNode,
+                         FX_DWORD dwFlag = 0,
+                         const FX_CHAR* pChecksum = NULL);
+
+ protected:
+  FX_BOOL Export(IFX_Stream* pStream,
+                 CXFA_Node* pNode,
+                 FX_DWORD dwFlag,
+                 const FX_CHAR* pChecksum);
+  CXFA_Document* m_pDocument;
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_DOCUMENT_SERIALIZE_H_
diff --git a/xfa/fxfa/parser/xfa_layout_appadapter.cpp b/xfa/fxfa/parser/xfa_layout_appadapter.cpp
new file mode 100644
index 0000000..3515dee
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_layout_appadapter.cpp
@@ -0,0 +1,62 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_layout_appadapter.h"
+
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_document_layout_imp.h"
+#include "xfa/fxfa/parser/xfa_layout_itemlayout.h"
+#include "xfa/fxfa/parser/xfa_layout_pagemgr_new.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+FX_DWORD XFA_GetRelevant(CXFA_Node* pFormItem, FX_DWORD dwParentRelvant) {
+  FX_DWORD dwRelevant = XFA_LAYOUTSTATUS_Viewable | XFA_LAYOUTSTATUS_Printable;
+  CFX_WideStringC wsRelevant;
+  if (pFormItem->TryCData(XFA_ATTRIBUTE_Relevant, wsRelevant)) {
+    if (wsRelevant == FX_WSTRC(L"+print") || wsRelevant == FX_WSTRC(L"print")) {
+      dwRelevant &= ~XFA_LAYOUTSTATUS_Viewable;
+    } else if (wsRelevant == FX_WSTRC(L"-print")) {
+      dwRelevant &= ~XFA_LAYOUTSTATUS_Printable;
+    }
+  }
+  if (!(dwParentRelvant & XFA_LAYOUTSTATUS_Viewable) &&
+      (dwRelevant != XFA_LAYOUTSTATUS_Viewable)) {
+    dwRelevant &= ~XFA_LAYOUTSTATUS_Viewable;
+  }
+  if (!(dwParentRelvant & XFA_LAYOUTSTATUS_Printable) &&
+      (dwRelevant != XFA_LAYOUTSTATUS_Printable)) {
+    dwRelevant &= ~XFA_LAYOUTSTATUS_Printable;
+  }
+  return dwRelevant;
+}
+void XFA_ReleaseLayoutItem(CXFA_LayoutItem* pLayoutItem) {
+  CXFA_LayoutItem* pNode = pLayoutItem->m_pFirstChild;
+  IXFA_Notify* pNotify =
+      pLayoutItem->m_pFormNode->GetDocument()->GetParser()->GetNotify();
+  IXFA_DocLayout* pDocLayout =
+      pLayoutItem->m_pFormNode->GetDocument()->GetDocLayout();
+  while (pNode) {
+    CXFA_LayoutItem* pNext = pNode->m_pNextSibling;
+    pNode->m_pParent = nullptr;
+    pNotify->OnLayoutEvent(pDocLayout, static_cast<CXFA_LayoutItem*>(pNode),
+                           XFA_LAYOUTEVENT_ItemRemoving);
+    XFA_ReleaseLayoutItem(pNode);
+    pNode = pNext;
+  }
+  pNotify->OnLayoutEvent(pDocLayout, pLayoutItem, XFA_LAYOUTEVENT_ItemRemoving);
+  if (pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_PageArea) {
+    pNotify->OnPageEvent(static_cast<CXFA_ContainerLayoutItem*>(pLayoutItem),
+                         XFA_PAGEEVENT_PageRemoved);
+  }
+  delete pLayoutItem;
+}
diff --git a/xfa/fxfa/parser/xfa_layout_appadapter.h b/xfa/fxfa/parser/xfa_layout_appadapter.h
new file mode 100644
index 0000000..f20ee9b
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_layout_appadapter.h
@@ -0,0 +1,77 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_LAYOUT_APPADAPTER_H_
+#define XFA_FXFA_PARSER_XFA_LAYOUT_APPADAPTER_H_
+
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+
+class CXFA_TraverseStrategy_PageAreaContainerLayoutItem {
+ public:
+  static inline CXFA_ContainerLayoutItem* GetFirstChild(
+      CXFA_ContainerLayoutItem* pLayoutItem) {
+    if (pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_PageSet) {
+      return (CXFA_ContainerLayoutItem*)pLayoutItem->m_pFirstChild;
+    }
+    return NULL;
+  }
+  static inline CXFA_ContainerLayoutItem* GetNextSibling(
+      CXFA_ContainerLayoutItem* pLayoutItem) {
+    return (CXFA_ContainerLayoutItem*)pLayoutItem->m_pNextSibling;
+  }
+  static inline CXFA_ContainerLayoutItem* GetParent(
+      CXFA_ContainerLayoutItem* pLayoutItem) {
+    return (CXFA_ContainerLayoutItem*)pLayoutItem->m_pParent;
+  }
+};
+class CXFA_TraverseStrategy_ContentAreaContainerLayoutItem {
+ public:
+  static inline CXFA_ContainerLayoutItem* GetFirstChild(
+      CXFA_ContainerLayoutItem* pLayoutItem) {
+    for (CXFA_LayoutItem* pChildItem = pLayoutItem->m_pFirstChild; pChildItem;
+         pChildItem = pChildItem->m_pNextSibling) {
+      if (CXFA_ContainerLayoutItem* pContainer =
+              pChildItem->AsContainerLayoutItem()) {
+        return pContainer;
+      }
+    }
+    return nullptr;
+  }
+  static inline CXFA_ContainerLayoutItem* GetNextSibling(
+      CXFA_ContainerLayoutItem* pLayoutItem) {
+    for (CXFA_LayoutItem* pChildItem = pLayoutItem->m_pNextSibling; pChildItem;
+         pChildItem = pChildItem->m_pNextSibling) {
+      if (CXFA_ContainerLayoutItem* pContainer =
+              pChildItem->AsContainerLayoutItem()) {
+        return pContainer;
+      }
+    }
+    return nullptr;
+  }
+  static inline CXFA_ContainerLayoutItem* GetParent(
+      CXFA_ContainerLayoutItem* pLayoutItem) {
+    return (CXFA_ContainerLayoutItem*)pLayoutItem->m_pParent;
+  }
+};
+class CXFA_TraverseStrategy_ContentLayoutItem {
+ public:
+  static inline CXFA_ContentLayoutItem* GetFirstChild(
+      CXFA_ContentLayoutItem* pLayoutItem) {
+    return (CXFA_ContentLayoutItem*)pLayoutItem->m_pFirstChild;
+  }
+  static inline CXFA_ContentLayoutItem* GetNextSibling(
+      CXFA_ContentLayoutItem* pLayoutItem) {
+    return (CXFA_ContentLayoutItem*)pLayoutItem->m_pNextSibling;
+  }
+  static inline CXFA_ContentLayoutItem* GetParent(
+      CXFA_ContentLayoutItem* pLayoutItem) {
+    return (CXFA_ContentLayoutItem*)pLayoutItem->m_pParent;
+  }
+};
+FX_DWORD XFA_GetRelevant(CXFA_Node* pFormItem, FX_DWORD dwParentRelvant);
+void XFA_ReleaseLayoutItem(CXFA_LayoutItem* pLayoutItem);
+
+#endif  // XFA_FXFA_PARSER_XFA_LAYOUT_APPADAPTER_H_
diff --git a/xfa/fxfa/parser/xfa_layout_itemlayout.cpp b/xfa/fxfa/parser/xfa_layout_itemlayout.cpp
new file mode 100644
index 0000000..2924fad
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_layout_itemlayout.cpp
@@ -0,0 +1,2968 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_layout_itemlayout.h"
+
+#include <algorithm>
+#include <memory>
+
+#include "xfa/fgas/crt/fgas_algorithm.h"
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_document_layout_imp.h"
+#include "xfa/fxfa/parser/xfa_layout_appadapter.h"
+#include "xfa/fxfa/parser/xfa_layout_pagemgr_new.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+CXFA_ItemLayoutProcessor::CXFA_ItemLayoutProcessor(CXFA_Node* pNode,
+                                                   CXFA_LayoutPageMgr* pPageMgr)
+    : m_bKeepBreakFinish(FALSE),
+      m_bIsProcessKeep(FALSE),
+      m_pKeepHeadNode(nullptr),
+      m_pKeepTailNode(nullptr),
+      m_pFormNode(pNode),
+      m_pLayoutItem(nullptr),
+      m_pOldLayoutItem(nullptr),
+      m_pCurChildNode(XFA_LAYOUT_INVALIDNODE),
+      m_pCurChildPreprocessor(nullptr),
+      m_nCurChildNodeStage(XFA_ItemLayoutProcessorStages_None),
+      m_fUsedSize(0),
+      m_pPageMgr(pPageMgr),
+      m_bBreakPending(TRUE),
+      m_fLastRowWidth(0),
+      m_fLastRowY(0),
+      m_fWidthLimite(0),
+      m_bUseInheriated(FALSE),
+      m_ePreProcessRs(XFA_ItemLayoutProcessorResult_Done),
+      m_bHasAvailHeight(TRUE) {
+  FXSYS_assert(m_pFormNode && (m_pFormNode->IsContainerNode() ||
+                               m_pFormNode->GetClassID() == XFA_ELEMENT_Form));
+  m_pOldLayoutItem =
+      (CXFA_ContentLayoutItem*)m_pFormNode->GetUserData(XFA_LAYOUTITEMKEY);
+}
+CXFA_ContentLayoutItem* CXFA_ItemLayoutProcessor::CreateContentLayoutItem(
+    CXFA_Node* pFormNode) {
+  if (!pFormNode) {
+    return NULL;
+  }
+  CXFA_ContentLayoutItem* pLayoutItem = NULL;
+  if (m_pOldLayoutItem) {
+    pLayoutItem = m_pOldLayoutItem;
+    m_pOldLayoutItem = m_pOldLayoutItem->m_pNext;
+    return pLayoutItem;
+  }
+  pLayoutItem = (CXFA_ContentLayoutItem*)pFormNode->GetDocument()
+                    ->GetParser()
+                    ->GetNotify()
+                    ->OnCreateLayoutItem(pFormNode);
+  CXFA_ContentLayoutItem* pPrevLayoutItem =
+      (CXFA_ContentLayoutItem*)pFormNode->GetUserData(XFA_LAYOUTITEMKEY);
+  if (pPrevLayoutItem) {
+    while (pPrevLayoutItem->m_pNext) {
+      pPrevLayoutItem = pPrevLayoutItem->m_pNext;
+    }
+    pPrevLayoutItem->m_pNext = pLayoutItem;
+    pLayoutItem->m_pPrev = pPrevLayoutItem;
+  } else {
+    pFormNode->SetUserData(XFA_LAYOUTITEMKEY, pLayoutItem);
+  }
+  return pLayoutItem;
+}
+FX_BOOL CXFA_ItemLayoutProcessor::FindLayoutItemSplitPos(
+    CXFA_ContentLayoutItem* pLayoutItem,
+    FX_FLOAT fCurVerticalOffset,
+    FX_FLOAT& fProposedSplitPos,
+    FX_BOOL& bAppChange,
+    FX_BOOL bCalculateMargin) {
+  CXFA_Node* pFormNode = pLayoutItem->m_pFormNode;
+  if (fProposedSplitPos > fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION &&
+      fProposedSplitPos <= fCurVerticalOffset + pLayoutItem->m_sSize.y -
+                               XFA_LAYOUT_FLOAT_PERCISION) {
+    switch (pFormNode->GetIntact()) {
+      case XFA_ATTRIBUTEENUM_None: {
+        FX_BOOL bAnyChanged = FALSE;
+        CXFA_Document* pDocument = pFormNode->GetDocument();
+        IXFA_Notify* pNotify = pDocument->GetParser()->GetNotify();
+        FX_FLOAT fCurTopMargin = 0, fCurBottomMargin = 0;
+        CXFA_Node* pMarginNode =
+            pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
+        if (pMarginNode && bCalculateMargin) {
+          fCurTopMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset)
+                              .ToUnit(XFA_UNIT_Pt);
+          fCurBottomMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset)
+                                 .ToUnit(XFA_UNIT_Pt);
+        }
+        FX_BOOL bChanged = TRUE;
+        while (bChanged) {
+          bChanged = FALSE;
+          {
+            FX_FLOAT fRelSplitPos = fProposedSplitPos - fCurVerticalOffset;
+            if (pNotify->FindSplitPos(pFormNode, pLayoutItem->GetIndex(),
+                                      fRelSplitPos)) {
+              bAnyChanged = TRUE;
+              bChanged = TRUE;
+              fProposedSplitPos = fCurVerticalOffset + fRelSplitPos;
+              bAppChange = TRUE;
+              if (fProposedSplitPos <=
+                  fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION) {
+                return TRUE;
+              }
+            }
+          }
+          FX_FLOAT fRelSplitPos = fProposedSplitPos - fCurBottomMargin;
+          for (CXFA_ContentLayoutItem* pChildItem =
+                   (CXFA_ContentLayoutItem*)pLayoutItem->m_pFirstChild;
+               pChildItem;
+               pChildItem =
+                   (CXFA_ContentLayoutItem*)pChildItem->m_pNextSibling) {
+            FX_FLOAT fChildOffset =
+                fCurVerticalOffset + fCurTopMargin + pChildItem->m_sPos.y;
+            FX_BOOL bAppChange = FALSE;
+            if (FindLayoutItemSplitPos(pChildItem, fChildOffset, fRelSplitPos,
+                                       bAppChange, bCalculateMargin)) {
+              if (fRelSplitPos - fChildOffset < XFA_LAYOUT_FLOAT_PERCISION &&
+                  bAppChange) {
+                fProposedSplitPos = fRelSplitPos - fCurTopMargin;
+              } else {
+                fProposedSplitPos = fRelSplitPos + fCurBottomMargin;
+              }
+              bAnyChanged = TRUE;
+              bChanged = TRUE;
+              if (fProposedSplitPos <=
+                  fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION) {
+                return TRUE;
+              }
+              if (bAnyChanged) {
+                break;
+              }
+            }
+          }
+        }
+        return bAnyChanged;
+      } break;
+      case XFA_ATTRIBUTEENUM_ContentArea:
+      case XFA_ATTRIBUTEENUM_PageArea: {
+        fProposedSplitPos = fCurVerticalOffset;
+        return TRUE;
+      }
+      default:
+        return FALSE;
+    }
+  }
+  return FALSE;
+}
+static XFA_ATTRIBUTEENUM XFA_ItemLayoutProcessor_GetLayout(
+    CXFA_Node* pFormNode,
+    FX_BOOL& bRootForceTb) {
+  bRootForceTb = FALSE;
+  XFA_ATTRIBUTEENUM eLayoutMode;
+  if (pFormNode->TryEnum(XFA_ATTRIBUTE_Layout, eLayoutMode, FALSE)) {
+    return eLayoutMode;
+  }
+  CXFA_Node* pParentNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent);
+  if (pParentNode && pParentNode->GetClassID() == XFA_ELEMENT_Form) {
+    bRootForceTb = TRUE;
+    return XFA_ATTRIBUTEENUM_Tb;
+  }
+  return XFA_ATTRIBUTEENUM_Position;
+}
+static FX_BOOL XFA_ExistContainerKeep(CXFA_Node* pCurNode, FX_BOOL bPreFind) {
+  if (pCurNode == NULL || !XFA_ItemLayoutProcessor_IsTakingSpace(pCurNode)) {
+    return FALSE;
+  }
+  XFA_NODEITEM eItemType = XFA_NODEITEM_PrevSibling;
+  if (!bPreFind) {
+    eItemType = XFA_NODEITEM_NextSibling;
+  }
+  CXFA_Node* pPreContainer =
+      pCurNode->GetNodeItem(eItemType, XFA_OBJECTTYPE_ContainerNode);
+  if (pPreContainer == NULL) {
+    return FALSE;
+  }
+  CXFA_Node* pKeep = pCurNode->GetFirstChildByClass(XFA_ELEMENT_Keep);
+  if (pKeep) {
+    XFA_ATTRIBUTEENUM ePrevious;
+    XFA_ATTRIBUTE eKeepType = XFA_ATTRIBUTE_Previous;
+    if (!bPreFind) {
+      eKeepType = XFA_ATTRIBUTE_Next;
+    }
+    if (pKeep->TryEnum(eKeepType, ePrevious, FALSE)) {
+      if (ePrevious == XFA_ATTRIBUTEENUM_ContentArea ||
+          ePrevious == XFA_ATTRIBUTEENUM_PageArea) {
+        return TRUE;
+      }
+    }
+  }
+  pKeep = pPreContainer->GetFirstChildByClass(XFA_ELEMENT_Keep);
+  if (!pKeep) {
+    return FALSE;
+  }
+  XFA_ATTRIBUTEENUM eNext;
+  XFA_ATTRIBUTE eKeepType = XFA_ATTRIBUTE_Next;
+  if (!bPreFind) {
+    eKeepType = XFA_ATTRIBUTE_Previous;
+  }
+  if (!pKeep->TryEnum(eKeepType, eNext, FALSE)) {
+    return FALSE;
+  }
+  if (eNext == XFA_ATTRIBUTEENUM_ContentArea ||
+      eNext == XFA_ATTRIBUTEENUM_PageArea) {
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_FLOAT CXFA_ItemLayoutProcessor::FindSplitPos(FX_FLOAT fProposedSplitPos) {
+  ASSERT(m_pLayoutItem);
+  XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
+  FX_BOOL bCalculateMargin = TRUE;
+  if (eLayout == XFA_ATTRIBUTEENUM_Position) {
+    bCalculateMargin = FALSE;
+  }
+  while (fProposedSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {
+    FX_BOOL bAppChange = FALSE;
+    if (!FindLayoutItemSplitPos(m_pLayoutItem, 0, fProposedSplitPos, bAppChange,
+                                bCalculateMargin)) {
+      break;
+    }
+  }
+  return fProposedSplitPos;
+}
+void CXFA_ItemLayoutProcessor::SplitLayoutItem(
+    CXFA_ContentLayoutItem* pLayoutItem,
+    CXFA_ContentLayoutItem* pSecondParent,
+    FX_FLOAT fSplitPos) {
+  FX_FLOAT fCurTopMargin = 0, fCurBottomMargin = 0;
+  XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
+  FX_BOOL bCalculateMargin = TRUE;
+  if (eLayout == XFA_ATTRIBUTEENUM_Position) {
+    bCalculateMargin = FALSE;
+  }
+  CXFA_Node* pMarginNode =
+      pLayoutItem->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
+  if (pMarginNode && bCalculateMargin) {
+    fCurTopMargin =
+        pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
+    fCurBottomMargin =
+        pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
+  }
+  CXFA_ContentLayoutItem* pSecondLayoutItem = NULL;
+  if (m_pCurChildPreprocessor &&
+      m_pCurChildPreprocessor->m_pFormNode == pLayoutItem->m_pFormNode) {
+    pSecondLayoutItem = m_pCurChildPreprocessor->CreateContentLayoutItem(
+        pLayoutItem->m_pFormNode);
+  } else {
+    pSecondLayoutItem = CreateContentLayoutItem(pLayoutItem->m_pFormNode);
+  }
+  pSecondLayoutItem->m_sPos.x = pLayoutItem->m_sPos.x;
+  pSecondLayoutItem->m_sSize.x = pLayoutItem->m_sSize.x;
+  pSecondLayoutItem->m_sPos.y = 0;
+  pSecondLayoutItem->m_sSize.y = pLayoutItem->m_sSize.y - fSplitPos;
+  pLayoutItem->m_sSize.y -= pSecondLayoutItem->m_sSize.y;
+  if (pLayoutItem->m_pFirstChild) {
+    pSecondLayoutItem->m_sSize.y += fCurTopMargin;
+  }
+  if (pSecondParent) {
+    pSecondParent->AddChild(pSecondLayoutItem);
+    if (fCurTopMargin > 0 && pLayoutItem->m_pFirstChild) {
+      pSecondParent->m_sSize.y += fCurTopMargin;
+      CXFA_ContentLayoutItem* pParentItem =
+          (CXFA_ContentLayoutItem*)pSecondParent->m_pParent;
+      while (pParentItem) {
+        pParentItem->m_sSize.y += fCurTopMargin;
+        pParentItem = (CXFA_ContentLayoutItem*)pParentItem->m_pParent;
+      }
+    }
+  } else {
+    pSecondLayoutItem->m_pParent = pLayoutItem->m_pParent;
+    pSecondLayoutItem->m_pNextSibling = pLayoutItem->m_pNextSibling;
+    pLayoutItem->m_pNextSibling = pSecondLayoutItem;
+  }
+  CXFA_ContentLayoutItem* pChildren =
+      (CXFA_ContentLayoutItem*)pLayoutItem->m_pFirstChild;
+  pLayoutItem->m_pFirstChild = NULL;
+  FX_FLOAT lHeightForKeep = 0;
+  CFX_ArrayTemplate<CXFA_ContentLayoutItem*> keepLayoutItems;
+  FX_FLOAT fAddMarginHeight = 0;
+  for (CXFA_ContentLayoutItem *pChildItem = pChildren, *pChildNext = NULL;
+       pChildItem; pChildItem = pChildNext) {
+    pChildNext = (CXFA_ContentLayoutItem*)pChildItem->m_pNextSibling;
+    pChildItem->m_pNextSibling = NULL;
+    if (fSplitPos <= fCurTopMargin + pChildItem->m_sPos.y + fCurBottomMargin +
+                         XFA_LAYOUT_FLOAT_PERCISION) {
+      if (!XFA_ExistContainerKeep(pChildItem->m_pFormNode, TRUE)) {
+        pChildItem->m_sPos.y -= fSplitPos - fCurBottomMargin;
+        pChildItem->m_sPos.y += lHeightForKeep;
+        pChildItem->m_sPos.y += fAddMarginHeight;
+        pSecondLayoutItem->AddChild(pChildItem);
+      } else {
+        if (lHeightForKeep < XFA_LAYOUT_FLOAT_PERCISION) {
+          for (int32_t iIndex = 0; iIndex < keepLayoutItems.GetSize();
+               iIndex++) {
+            CXFA_ContentLayoutItem* pPreItem = keepLayoutItems[iIndex];
+            pLayoutItem->RemoveChild(pPreItem);
+            pPreItem->m_sPos.y -= fSplitPos;
+            if (pPreItem->m_sPos.y < 0) {
+              pPreItem->m_sPos.y = 0;
+            }
+            if (pPreItem->m_sPos.y + pPreItem->m_sSize.y > lHeightForKeep) {
+              pPreItem->m_sPos.y = lHeightForKeep;
+              lHeightForKeep += pPreItem->m_sSize.y;
+              pSecondLayoutItem->m_sSize.y += pPreItem->m_sSize.y;
+              if (pSecondParent) {
+                pSecondParent->m_sSize.y += pPreItem->m_sSize.y;
+              }
+            }
+            pSecondLayoutItem->AddChild(pPreItem);
+          }
+        }
+        pChildItem->m_sPos.y -= fSplitPos;
+        pChildItem->m_sPos.y += lHeightForKeep;
+        pChildItem->m_sPos.y += fAddMarginHeight;
+        pSecondLayoutItem->AddChild(pChildItem);
+      }
+    } else if (fSplitPos + XFA_LAYOUT_FLOAT_PERCISION >=
+               fCurTopMargin + fCurBottomMargin + pChildItem->m_sPos.y +
+                   pChildItem->m_sSize.y) {
+      pLayoutItem->AddChild(pChildItem);
+      if (XFA_ExistContainerKeep(pChildItem->m_pFormNode, FALSE)) {
+        keepLayoutItems.Add(pChildItem);
+      } else {
+        keepLayoutItems.RemoveAll();
+      }
+    } else {
+      FX_FLOAT fOldHeight = pSecondLayoutItem->m_sSize.y;
+      SplitLayoutItem(
+          pChildItem, pSecondLayoutItem,
+          fSplitPos - fCurTopMargin - fCurBottomMargin - pChildItem->m_sPos.y);
+      fAddMarginHeight = pSecondLayoutItem->m_sSize.y - fOldHeight;
+      pLayoutItem->AddChild(pChildItem);
+    }
+  }
+}
+void CXFA_ItemLayoutProcessor::SplitLayoutItem(FX_FLOAT fSplitPos) {
+  ASSERT(m_pLayoutItem);
+  SplitLayoutItem(m_pLayoutItem, NULL, fSplitPos);
+}
+
+IXFA_LayoutPage* CXFA_LayoutItem::GetPage() const {
+  for (CXFA_LayoutItem* pCurNode = const_cast<CXFA_LayoutItem*>(this); pCurNode;
+       pCurNode = pCurNode->m_pParent) {
+    if (pCurNode->m_pFormNode->GetClassID() == XFA_ELEMENT_PageArea)
+      return static_cast<CXFA_ContainerLayoutItem*>(pCurNode);
+  }
+  return nullptr;
+}
+
+CXFA_Node* CXFA_LayoutItem::GetFormNode() const {
+  return m_pFormNode;
+}
+
+void CXFA_LayoutItem::GetRect(CFX_RectF& rtLayout, FX_BOOL bRelative) const {
+  ASSERT(m_bIsContentLayoutItem);
+  const CXFA_ContentLayoutItem* pThis =
+      static_cast<const CXFA_ContentLayoutItem*>(this);
+  CFX_PointF sPos = pThis->m_sPos;
+  CFX_SizeF sSize = pThis->m_sSize;
+  if (!bRelative) {
+    for (CXFA_LayoutItem* pLayoutItem = pThis->m_pParent; pLayoutItem;
+         pLayoutItem = pLayoutItem->m_pParent) {
+      if (CXFA_ContentLayoutItem* pContent =
+              pLayoutItem->AsContentLayoutItem()) {
+        sPos += pContent->m_sPos;
+        if (CXFA_Node* pMarginNode =
+                pLayoutItem->m_pFormNode->GetFirstChildByClass(
+                    XFA_ELEMENT_Margin)) {
+          sPos += CFX_PointF(pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset)
+                                 .ToUnit(XFA_UNIT_Pt),
+                             pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset)
+                                 .ToUnit(XFA_UNIT_Pt));
+        }
+      } else {
+        if (pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_ContentArea) {
+          sPos +=
+              CFX_PointF(pLayoutItem->m_pFormNode->GetMeasure(XFA_ATTRIBUTE_X)
+                             .ToUnit(XFA_UNIT_Pt),
+                         pLayoutItem->m_pFormNode->GetMeasure(XFA_ATTRIBUTE_Y)
+                             .ToUnit(XFA_UNIT_Pt));
+          break;
+        } else if (pLayoutItem->m_pFormNode->GetClassID() ==
+                   XFA_ELEMENT_PageArea) {
+          break;
+        }
+      }
+    }
+  }
+  rtLayout.Set(sPos.x, sPos.y, sSize.x, sSize.y);
+}
+
+CXFA_LayoutItem* CXFA_LayoutItem::GetParent() const {
+  return m_pParent;
+}
+
+const CXFA_LayoutItem* CXFA_LayoutItem::GetFirst() const {
+  ASSERT(m_bIsContentLayoutItem);
+  const CXFA_ContentLayoutItem* pCurNode =
+      static_cast<const CXFA_ContentLayoutItem*>(this);
+  while (pCurNode->m_pPrev) {
+    pCurNode = pCurNode->m_pPrev;
+  }
+  return pCurNode;
+}
+
+CXFA_LayoutItem* CXFA_LayoutItem::GetFirst() {
+  ASSERT(m_bIsContentLayoutItem);
+  CXFA_ContentLayoutItem* pCurNode = static_cast<CXFA_ContentLayoutItem*>(this);
+  while (pCurNode->m_pPrev) {
+    pCurNode = pCurNode->m_pPrev;
+  }
+  return pCurNode;
+}
+
+CXFA_LayoutItem* CXFA_LayoutItem::GetLast() {
+  ASSERT(m_bIsContentLayoutItem);
+  CXFA_ContentLayoutItem* pCurNode = static_cast<CXFA_ContentLayoutItem*>(this);
+  while (pCurNode->m_pNext) {
+    pCurNode = pCurNode->m_pNext;
+  }
+  return pCurNode;
+}
+
+const CXFA_LayoutItem* CXFA_LayoutItem::GetLast() const {
+  ASSERT(m_bIsContentLayoutItem);
+  const CXFA_ContentLayoutItem* pCurNode =
+      static_cast<const CXFA_ContentLayoutItem*>(this);
+  while (pCurNode->m_pNext) {
+    pCurNode = pCurNode->m_pNext;
+  }
+  return pCurNode;
+}
+
+CXFA_LayoutItem* CXFA_LayoutItem::GetPrev() const {
+  ASSERT(m_bIsContentLayoutItem);
+  return static_cast<const CXFA_ContentLayoutItem*>(this)->m_pPrev;
+}
+
+CXFA_LayoutItem* CXFA_LayoutItem::GetNext() const {
+  ASSERT(m_bIsContentLayoutItem);
+  return static_cast<const CXFA_ContentLayoutItem*>(this)->m_pNext;
+}
+
+int32_t CXFA_LayoutItem::GetIndex() const {
+  ASSERT(m_bIsContentLayoutItem);
+  int32_t iIndex = 0;
+  const CXFA_ContentLayoutItem* pCurNode =
+      static_cast<const CXFA_ContentLayoutItem*>(this);
+  while (pCurNode->m_pPrev) {
+    pCurNode = pCurNode->m_pPrev;
+    ++iIndex;
+  }
+  return iIndex;
+}
+
+int32_t CXFA_LayoutItem::GetCount() const {
+  ASSERT(m_bIsContentLayoutItem);
+  int32_t iCount = GetIndex() + 1;
+  const CXFA_ContentLayoutItem* pCurNode =
+      static_cast<const CXFA_ContentLayoutItem*>(this);
+  while (pCurNode->m_pNext) {
+    pCurNode = pCurNode->m_pNext;
+    iCount++;
+  }
+  return iCount;
+}
+
+void CXFA_LayoutItem::AddChild(CXFA_LayoutItem* pChildItem) {
+  if (pChildItem->m_pParent) {
+    pChildItem->m_pParent->RemoveChild(pChildItem);
+  }
+  pChildItem->m_pParent = this;
+  if (m_pFirstChild == NULL) {
+    m_pFirstChild = pChildItem;
+  } else {
+    CXFA_LayoutItem* pExistingChildItem = m_pFirstChild;
+    while (pExistingChildItem->m_pNextSibling) {
+      pExistingChildItem = pExistingChildItem->m_pNextSibling;
+    }
+    pExistingChildItem->m_pNextSibling = pChildItem;
+  }
+}
+void CXFA_LayoutItem::AddHeadChild(CXFA_LayoutItem* pChildItem) {
+  if (pChildItem->m_pParent) {
+    pChildItem->m_pParent->RemoveChild(pChildItem);
+  }
+  pChildItem->m_pParent = this;
+  if (m_pFirstChild == NULL) {
+    m_pFirstChild = pChildItem;
+  } else {
+    CXFA_LayoutItem* pExistingChildItem = m_pFirstChild;
+    m_pFirstChild = pChildItem;
+    m_pFirstChild->m_pNextSibling = pExistingChildItem;
+  }
+}
+void CXFA_LayoutItem::InsertChild(CXFA_LayoutItem* pBeforeItem,
+                                  CXFA_LayoutItem* pChildItem) {
+  if (pBeforeItem->m_pParent != this) {
+    return;
+  }
+  if (pChildItem->m_pParent) {
+    pChildItem->m_pParent = NULL;
+  }
+  pChildItem->m_pParent = this;
+  CXFA_LayoutItem* pExistingChildItem = pBeforeItem->m_pNextSibling;
+  pBeforeItem->m_pNextSibling = pChildItem;
+  pChildItem->m_pNextSibling = pExistingChildItem;
+}
+void CXFA_LayoutItem::RemoveChild(CXFA_LayoutItem* pChildItem) {
+  if (pChildItem->m_pParent != this) {
+    return;
+  }
+  if (m_pFirstChild == pChildItem) {
+    m_pFirstChild = pChildItem->m_pNextSibling;
+  } else {
+    CXFA_LayoutItem* pExistingChildItem = m_pFirstChild;
+    while (pExistingChildItem &&
+           pExistingChildItem->m_pNextSibling != pChildItem) {
+      pExistingChildItem = pExistingChildItem->m_pNextSibling;
+    }
+    if (pExistingChildItem) {
+      pExistingChildItem->m_pNextSibling = pChildItem->m_pNextSibling;
+    }
+  }
+  pChildItem->m_pNextSibling = NULL;
+  pChildItem->m_pParent = NULL;
+}
+CXFA_ContentLayoutItem* CXFA_ItemLayoutProcessor::ExtractLayoutItem() {
+  CXFA_ContentLayoutItem* pLayoutItem = m_pLayoutItem;
+  if (pLayoutItem) {
+    m_pLayoutItem = (CXFA_ContentLayoutItem*)pLayoutItem->m_pNextSibling;
+    pLayoutItem->m_pNextSibling = NULL;
+  }
+  if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done &&
+      ToContentLayoutItem(m_pOldLayoutItem)) {
+    if (m_pOldLayoutItem->m_pPrev) {
+      m_pOldLayoutItem->m_pPrev->m_pNext = NULL;
+    }
+    IXFA_Notify* pNotify =
+        m_pOldLayoutItem->m_pFormNode->GetDocument()->GetParser()->GetNotify();
+    IXFA_DocLayout* pDocLayout =
+        m_pOldLayoutItem->m_pFormNode->GetDocument()->GetDocLayout();
+    CXFA_ContentLayoutItem* pOldLayoutItem = m_pOldLayoutItem;
+    while (pOldLayoutItem) {
+      CXFA_ContentLayoutItem* pNextOldLayoutItem = pOldLayoutItem->m_pNext;
+      pNotify->OnLayoutEvent(pDocLayout, pOldLayoutItem,
+                             XFA_LAYOUTEVENT_ItemRemoving);
+      delete pOldLayoutItem;
+      pOldLayoutItem = pNextOldLayoutItem;
+    }
+    m_pOldLayoutItem = NULL;
+  }
+  return pLayoutItem;
+}
+static FX_BOOL XFA_ItemLayoutProcessor_FindBreakNode(
+    CXFA_Node* pContainerNode,
+    CXFA_Node*& pCurActionNode,
+    XFA_ItemLayoutProcessorStages& nCurStage,
+    FX_BOOL bBreakBefore) {
+  FX_BOOL bFindRs = FALSE;
+  for (CXFA_Node* pBreakNode = pContainerNode; pBreakNode;
+       pBreakNode = pBreakNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    XFA_ATTRIBUTE eAttributeType = XFA_ATTRIBUTE_Before;
+    if (!bBreakBefore) {
+      eAttributeType = XFA_ATTRIBUTE_After;
+    }
+    switch (pBreakNode->GetClassID()) {
+      case XFA_ELEMENT_BreakBefore: {
+        if (bBreakBefore) {
+          pCurActionNode = pBreakNode;
+          nCurStage = XFA_ItemLayoutProcessorStages_BreakBefore;
+          bFindRs = TRUE;
+        }
+      } break;
+      case XFA_ELEMENT_BreakAfter: {
+        if (!bBreakBefore) {
+          pCurActionNode = pBreakNode;
+          nCurStage = XFA_ItemLayoutProcessorStages_BreakAfter;
+          bFindRs = TRUE;
+        }
+      } break;
+      case XFA_ELEMENT_Break:
+        if (pBreakNode->GetEnum(eAttributeType) != XFA_ATTRIBUTEENUM_Auto) {
+          pCurActionNode = pBreakNode;
+          nCurStage = XFA_ItemLayoutProcessorStages_BreakBefore;
+          if (!bBreakBefore) {
+            nCurStage = XFA_ItemLayoutProcessorStages_BreakAfter;
+          }
+          bFindRs = TRUE;
+          break;
+        }
+      default:
+        break;
+    }
+    if (bFindRs) {
+      break;
+    }
+  }
+  return bFindRs;
+}
+static void XFA_DeleteLayoutGeneratedNode(CXFA_Node* pGenerateNode) {
+  IXFA_Notify* pNotify = pGenerateNode->GetDocument()->GetParser()->GetNotify();
+  IXFA_DocLayout* pDocLayout = pGenerateNode->GetDocument()->GetDocLayout();
+  CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(
+      pGenerateNode);
+  for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
+       pNode = sIterator.MoveToNext()) {
+    CXFA_ContentLayoutItem* pCurLayoutItem =
+        (CXFA_ContentLayoutItem*)pNode->GetUserData(XFA_LAYOUTITEMKEY);
+    CXFA_ContentLayoutItem* pNextLayoutItem = NULL;
+    while (pCurLayoutItem) {
+      pNextLayoutItem = pCurLayoutItem->m_pNext;
+      pNotify->OnLayoutEvent(pDocLayout, pCurLayoutItem,
+                             XFA_LAYOUTEVENT_ItemRemoving);
+      delete pCurLayoutItem;
+      pCurLayoutItem = pNextLayoutItem;
+    }
+  }
+  pGenerateNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pGenerateNode);
+}
+void CXFA_ItemLayoutProcessor::XFA_ItemLayoutProcessor_GotoNextContainerNode(
+    CXFA_Node*& pCurActionNode,
+    XFA_ItemLayoutProcessorStages& nCurStage,
+    CXFA_Node* pParentContainer,
+    FX_BOOL bUsePageBreak) {
+  CXFA_Node* pEntireContainer = pParentContainer;
+  CXFA_Node* pChildContainer = XFA_LAYOUT_INVALIDNODE;
+  switch (nCurStage) {
+    case XFA_ItemLayoutProcessorStages_BreakBefore:
+    case XFA_ItemLayoutProcessorStages_BreakAfter: {
+      pChildContainer = pCurActionNode->GetNodeItem(XFA_NODEITEM_Parent);
+    } break;
+    case XFA_ItemLayoutProcessorStages_Keep:
+    case XFA_ItemLayoutProcessorStages_Container:
+      pChildContainer = pCurActionNode;
+      break;
+    default:
+      pChildContainer = XFA_LAYOUT_INVALIDNODE;
+      break;
+  }
+  switch (nCurStage) {
+    case XFA_ItemLayoutProcessorStages_Keep: {
+      CXFA_Node* pBreakAfterNode =
+          pChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild);
+      if (!m_bKeepBreakFinish &&
+          XFA_ItemLayoutProcessor_FindBreakNode(pBreakAfterNode, pCurActionNode,
+                                                nCurStage, FALSE)) {
+        return;
+      }
+      goto CheckNextChildContainer;
+    }
+    case XFA_ItemLayoutProcessorStages_None: {
+      pCurActionNode = XFA_LAYOUT_INVALIDNODE;
+      case XFA_ItemLayoutProcessorStages_BookendLeader:
+        for (CXFA_Node* pBookendNode =
+                 pCurActionNode == XFA_LAYOUT_INVALIDNODE
+                     ? pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild)
+                     : pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+             pBookendNode; pBookendNode = pBookendNode->GetNodeItem(
+                               XFA_NODEITEM_NextSibling)) {
+          switch (pBookendNode->GetClassID()) {
+            case XFA_ELEMENT_Bookend:
+            case XFA_ELEMENT_Break:
+              pCurActionNode = pBookendNode;
+              nCurStage = XFA_ItemLayoutProcessorStages_BookendLeader;
+              return;
+            default:
+              break;
+          }
+        }
+    }
+      {
+        pCurActionNode = XFA_LAYOUT_INVALIDNODE;
+        case XFA_ItemLayoutProcessorStages_BreakBefore:
+          if (pCurActionNode != XFA_LAYOUT_INVALIDNODE) {
+            CXFA_Node* pBreakBeforeNode =
+                pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+            if (!m_bKeepBreakFinish &&
+                XFA_ItemLayoutProcessor_FindBreakNode(
+                    pBreakBeforeNode, pCurActionNode, nCurStage, TRUE)) {
+              return;
+            }
+            if (m_bIsProcessKeep) {
+              if (ProcessKeepNodesForBreakBefore(pCurActionNode, nCurStage,
+                                                 pChildContainer)) {
+                return;
+              }
+              goto CheckNextChildContainer;
+            }
+            pCurActionNode = pChildContainer;
+            nCurStage = XFA_ItemLayoutProcessorStages_Container;
+            return;
+          }
+          goto CheckNextChildContainer;
+      }
+    case XFA_ItemLayoutProcessorStages_Container: {
+      pCurActionNode = XFA_LAYOUT_INVALIDNODE;
+      case XFA_ItemLayoutProcessorStages_BreakAfter: {
+        if (pCurActionNode == XFA_LAYOUT_INVALIDNODE) {
+          CXFA_Node* pBreakAfterNode =
+              pChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild);
+          if (!m_bKeepBreakFinish &&
+              XFA_ItemLayoutProcessor_FindBreakNode(
+                  pBreakAfterNode, pCurActionNode, nCurStage, FALSE)) {
+            return;
+          }
+        } else {
+          CXFA_Node* pBreakAfterNode =
+              pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+          if (XFA_ItemLayoutProcessor_FindBreakNode(
+                  pBreakAfterNode, pCurActionNode, nCurStage, FALSE)) {
+            return;
+          }
+        }
+        goto CheckNextChildContainer;
+      }
+    }
+    CheckNextChildContainer : {
+      CXFA_Node* pNextChildContainer =
+          pChildContainer == XFA_LAYOUT_INVALIDNODE
+              ? pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild,
+                                              XFA_OBJECTTYPE_ContainerNode)
+              : pChildContainer->GetNodeItem(XFA_NODEITEM_NextSibling,
+                                             XFA_OBJECTTYPE_ContainerNode);
+      while (pNextChildContainer &&
+             pNextChildContainer->HasFlag(XFA_NODEFLAG_LayoutGeneratedNode)) {
+        CXFA_Node* pSaveNode = pNextChildContainer;
+        pNextChildContainer = pNextChildContainer->GetNodeItem(
+            XFA_NODEITEM_NextSibling, XFA_OBJECTTYPE_ContainerNode);
+        if (pSaveNode->HasFlag(XFA_NODEFLAG_UnusedNode)) {
+          XFA_DeleteLayoutGeneratedNode(pSaveNode);
+        }
+      }
+      if (!pNextChildContainer) {
+        goto NoMoreChildContainer;
+      }
+      FX_BOOL bLastKeep = FALSE;
+      if (ProcessKeepNodesForCheckNext(pCurActionNode, nCurStage,
+                                       pNextChildContainer, bLastKeep)) {
+        return;
+      }
+      if (!m_bKeepBreakFinish && !bLastKeep &&
+          XFA_ItemLayoutProcessor_FindBreakNode(
+              pNextChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild),
+              pCurActionNode, nCurStage, TRUE)) {
+        return;
+      }
+      pCurActionNode = pNextChildContainer;
+      if (m_bIsProcessKeep) {
+        nCurStage = XFA_ItemLayoutProcessorStages_Keep;
+      } else {
+        nCurStage = XFA_ItemLayoutProcessorStages_Container;
+      }
+      return;
+    }
+    NoMoreChildContainer : {
+      pCurActionNode = XFA_LAYOUT_INVALIDNODE;
+      case XFA_ItemLayoutProcessorStages_BookendTrailer:
+        for (CXFA_Node* pBookendNode =
+                 pCurActionNode == XFA_LAYOUT_INVALIDNODE
+                     ? pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild)
+                     : pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+             pBookendNode; pBookendNode = pBookendNode->GetNodeItem(
+                               XFA_NODEITEM_NextSibling)) {
+          switch (pBookendNode->GetClassID()) {
+            case XFA_ELEMENT_Bookend:
+            case XFA_ELEMENT_Break:
+              pCurActionNode = pBookendNode;
+              nCurStage = XFA_ItemLayoutProcessorStages_BookendTrailer;
+              return;
+            default:
+              break;
+          }
+        }
+    }
+    default:
+      pCurActionNode = NULL;
+      nCurStage = XFA_ItemLayoutProcessorStages_Done;
+  }
+}
+FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepNodesForCheckNext(
+    CXFA_Node*& pCurActionNode,
+    XFA_ItemLayoutProcessorStages& nCurStage,
+    CXFA_Node*& pNextContainer,
+    FX_BOOL& bLastKeepNode) {
+  const bool bCanSplit = pNextContainer->GetIntact() == XFA_ATTRIBUTEENUM_None;
+  FX_BOOL bNextKeep = FALSE;
+  if (XFA_ExistContainerKeep(pNextContainer, FALSE)) {
+    bNextKeep = TRUE;
+  }
+  if (bNextKeep && !bCanSplit) {
+    if (!m_bIsProcessKeep && !m_bKeepBreakFinish) {
+      m_pKeepHeadNode = pNextContainer;
+      m_bIsProcessKeep = TRUE;
+    }
+  } else {
+    if (m_bIsProcessKeep && m_pKeepHeadNode) {
+      m_pKeepTailNode = pNextContainer;
+      if (!m_bKeepBreakFinish &&
+          XFA_ItemLayoutProcessor_FindBreakNode(
+              pNextContainer->GetNodeItem(XFA_NODEITEM_FirstChild),
+              pCurActionNode, nCurStage, TRUE)) {
+        return TRUE;
+      } else {
+        pNextContainer = m_pKeepHeadNode;
+        m_bKeepBreakFinish = TRUE;
+        m_pKeepHeadNode = NULL;
+        m_pKeepTailNode = NULL;
+        m_bIsProcessKeep = FALSE;
+      }
+    } else {
+      if (m_bKeepBreakFinish) {
+        bLastKeepNode = TRUE;
+      }
+      m_bKeepBreakFinish = FALSE;
+    }
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepNodesForBreakBefore(
+    CXFA_Node*& pCurActionNode,
+    XFA_ItemLayoutProcessorStages& nCurStage,
+    CXFA_Node* pContainerNode) {
+  if (m_pKeepTailNode == pContainerNode) {
+    pCurActionNode = m_pKeepHeadNode;
+    m_bKeepBreakFinish = TRUE;
+    m_pKeepHeadNode = NULL;
+    m_pKeepTailNode = NULL;
+    m_bIsProcessKeep = FALSE;
+    nCurStage = XFA_ItemLayoutProcessorStages_Container;
+    return TRUE;
+  }
+  CXFA_Node* pBreakAfterNode =
+      pContainerNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+  if (XFA_ItemLayoutProcessor_FindBreakNode(pBreakAfterNode, pCurActionNode,
+                                            nCurStage, FALSE)) {
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL XFA_ItemLayoutProcessor_IsTakingSpace(CXFA_Node* pNode) {
+  XFA_ATTRIBUTEENUM ePresence = pNode->GetEnum(XFA_ATTRIBUTE_Presence);
+  return ePresence == XFA_ATTRIBUTEENUM_Visible ||
+         ePresence == XFA_ATTRIBUTEENUM_Invisible;
+}
+static inline void XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(
+    CXFA_Node* pFormNode,
+    FX_FLOAT& fContainerWidth,
+    FX_FLOAT& fContainerHeight,
+    FX_BOOL& bContainerWidthAutoSize,
+    FX_BOOL& bContainerHeightAutoSize) {
+  fContainerWidth = 0;
+  fContainerHeight = 0;
+  bContainerWidthAutoSize = TRUE;
+  bContainerHeightAutoSize = TRUE;
+  XFA_ELEMENT eClassID = pFormNode->GetClassID();
+  CXFA_Measurement mTmpValue;
+  if (bContainerWidthAutoSize &&
+      (eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup) &&
+      pFormNode->TryMeasure(XFA_ATTRIBUTE_W, mTmpValue, FALSE) &&
+      mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
+    fContainerWidth = mTmpValue.ToUnit(XFA_UNIT_Pt);
+    bContainerWidthAutoSize = FALSE;
+  }
+  if (bContainerHeightAutoSize &&
+      (eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup) &&
+      pFormNode->TryMeasure(XFA_ATTRIBUTE_H, mTmpValue, FALSE) &&
+      mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
+    fContainerHeight = mTmpValue.ToUnit(XFA_UNIT_Pt);
+    bContainerHeightAutoSize = FALSE;
+  }
+  if (bContainerWidthAutoSize && eClassID == XFA_ELEMENT_Subform &&
+      pFormNode->TryMeasure(XFA_ATTRIBUTE_MaxW, mTmpValue, FALSE) &&
+      mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
+    fContainerWidth = mTmpValue.ToUnit(XFA_UNIT_Pt);
+    bContainerWidthAutoSize = FALSE;
+  }
+  if (bContainerHeightAutoSize && eClassID == XFA_ELEMENT_Subform &&
+      pFormNode->TryMeasure(XFA_ATTRIBUTE_MaxH, mTmpValue, FALSE) &&
+      mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
+    fContainerHeight = mTmpValue.ToUnit(XFA_UNIT_Pt);
+    bContainerHeightAutoSize = FALSE;
+  }
+}
+static inline void
+XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(
+    CXFA_Node* pFormNode,
+    FX_BOOL bContainerWidthAutoSize,
+    FX_FLOAT fContentCalculatedWidth,
+    FX_FLOAT& fContainerWidth,
+    FX_BOOL bContainerHeightAutoSize,
+    FX_FLOAT fContentCalculatedHeight,
+    FX_FLOAT& fContainerHeight) {
+  CXFA_Node* pMarginNode = pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
+  CXFA_Measurement mTmpValue;
+  if (bContainerWidthAutoSize) {
+    fContainerWidth = fContentCalculatedWidth;
+    if (pMarginNode) {
+      if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_LeftInset, mTmpValue, FALSE)) {
+        fContainerWidth += mTmpValue.ToUnit(XFA_UNIT_Pt);
+      }
+      if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_RightInset, mTmpValue, FALSE)) {
+        fContainerWidth += mTmpValue.ToUnit(XFA_UNIT_Pt);
+      }
+    }
+  }
+  if (bContainerHeightAutoSize) {
+    fContainerHeight = fContentCalculatedHeight;
+    if (pMarginNode) {
+      if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_TopInset, mTmpValue, FALSE)) {
+        fContainerHeight += mTmpValue.ToUnit(XFA_UNIT_Pt);
+      }
+      if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_BottomInset, mTmpValue,
+                                  FALSE)) {
+        fContainerHeight += mTmpValue.ToUnit(XFA_UNIT_Pt);
+      }
+    }
+  }
+}
+void CXFA_ItemLayoutProcessor::CalculatePositionedContainerPos(
+    CXFA_Node* pNode,
+    FX_FLOAT fWidth,
+    FX_FLOAT fHeight,
+    FX_FLOAT& fAbsoluteX,
+    FX_FLOAT& fAbsoluteY) {
+  XFA_ATTRIBUTEENUM eAnchorType = pNode->GetEnum(XFA_ATTRIBUTE_AnchorType);
+  int32_t nAnchorType = 0;
+  switch (eAnchorType) {
+    case XFA_ATTRIBUTEENUM_TopLeft:
+      nAnchorType = 0;
+      break;
+    case XFA_ATTRIBUTEENUM_TopCenter:
+      nAnchorType = 1;
+      break;
+    case XFA_ATTRIBUTEENUM_TopRight:
+      nAnchorType = 2;
+      break;
+    case XFA_ATTRIBUTEENUM_MiddleLeft:
+      nAnchorType = 3;
+      break;
+    case XFA_ATTRIBUTEENUM_MiddleCenter:
+      nAnchorType = 4;
+      break;
+    case XFA_ATTRIBUTEENUM_MiddleRight:
+      nAnchorType = 5;
+      break;
+    case XFA_ATTRIBUTEENUM_BottomLeft:
+      nAnchorType = 6;
+      break;
+    case XFA_ATTRIBUTEENUM_BottomCenter:
+      nAnchorType = 7;
+      break;
+    case XFA_ATTRIBUTEENUM_BottomRight:
+      nAnchorType = 8;
+      break;
+    default:
+      break;
+  }
+  static const uint8_t nNextPos[4][9] = {{0, 1, 2, 3, 4, 5, 6, 7, 8},
+                                         {6, 3, 0, 7, 4, 1, 8, 5, 2},
+                                         {8, 7, 6, 5, 4, 3, 2, 1, 0},
+                                         {2, 5, 8, 1, 4, 7, 0, 3, 6}};
+
+  FX_FLOAT fAnchorX = pNode->GetMeasure(XFA_ATTRIBUTE_X).ToUnit(XFA_UNIT_Pt);
+  FX_FLOAT fAnchorY = pNode->GetMeasure(XFA_ATTRIBUTE_Y).ToUnit(XFA_UNIT_Pt);
+  int32_t nRotate =
+      FXSYS_round(pNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue());
+  nRotate = XFA_MapRotation(nRotate) / 90;
+  int32_t nAbsoluteAnchorType = nNextPos[nRotate][nAnchorType];
+  fAbsoluteX = fAnchorX;
+  fAbsoluteY = fAnchorY;
+  switch (nAbsoluteAnchorType / 3) {
+    case 1:
+      fAbsoluteY -= fHeight / 2;
+      break;
+    case 2:
+      fAbsoluteY -= fHeight;
+      break;
+    default:
+      break;
+  }
+  switch (nAbsoluteAnchorType % 3) {
+    case 1:
+      fAbsoluteX -= fWidth / 2;
+      break;
+    case 2:
+      fAbsoluteX -= fWidth;
+      break;
+    default:
+      break;
+  }
+}
+FX_BOOL CXFA_ItemLayoutProcessor::IncrementRelayoutNode(
+    CXFA_LayoutProcessor* pLayoutProcessor,
+    CXFA_Node* pNode,
+    CXFA_Node* pParentNode) {
+  return FALSE;
+}
+void CXFA_ItemLayoutProcessor::DoLayoutPageArea(
+    CXFA_ContainerLayoutItem* pPageAreaLayoutItem) {
+  CXFA_Node* pFormNode = pPageAreaLayoutItem->m_pFormNode;
+  CXFA_Node* pCurChildNode = XFA_LAYOUT_INVALIDNODE;
+  XFA_ItemLayoutProcessorStages nCurChildNodeStage =
+      XFA_ItemLayoutProcessorStages_None;
+  CXFA_LayoutItem* pBeforeItem = NULL;
+  for (XFA_ItemLayoutProcessor_GotoNextContainerNode(
+           pCurChildNode, nCurChildNodeStage, pFormNode, FALSE);
+       pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode(
+           pCurChildNode, nCurChildNodeStage, pFormNode, FALSE)) {
+    if (nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) {
+      continue;
+    }
+    if (pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) {
+      continue;
+    }
+    CXFA_ItemLayoutProcessor* pProcessor =
+        new CXFA_ItemLayoutProcessor(pCurChildNode, NULL);
+    pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX);
+    if (!pProcessor->HasLayoutItem()) {
+      delete pProcessor;
+      continue;
+    }
+    FX_FLOAT fWidth, fHeight;
+    pProcessor->GetCurrentComponentSize(fWidth, fHeight);
+    FX_FLOAT fAbsoluteX = 0, fAbsoluteY = 0;
+    CalculatePositionedContainerPos(pCurChildNode, fWidth, fHeight, fAbsoluteX,
+                                    fAbsoluteY);
+    pProcessor->SetCurrentComponentPos(fAbsoluteX, fAbsoluteY);
+    CXFA_LayoutItem* pProcessItem = pProcessor->ExtractLayoutItem();
+    if (pBeforeItem == NULL) {
+      pPageAreaLayoutItem->AddHeadChild(pProcessItem);
+    } else {
+      pPageAreaLayoutItem->InsertChild(pBeforeItem, pProcessItem);
+    }
+    pBeforeItem = pProcessItem;
+    delete pProcessor;
+  }
+  pBeforeItem = NULL;
+  CXFA_LayoutItem* pLayoutItem = pPageAreaLayoutItem->m_pFirstChild;
+  while (pLayoutItem) {
+    if (!pLayoutItem->IsContentLayoutItem() ||
+        pLayoutItem->m_pFormNode->GetClassID() != XFA_ELEMENT_Draw) {
+      pLayoutItem = pLayoutItem->m_pNextSibling;
+      continue;
+    }
+    if (pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_Draw) {
+      CXFA_LayoutItem* pNextLayoutItem = pLayoutItem->m_pNextSibling;
+      pPageAreaLayoutItem->RemoveChild(pLayoutItem);
+      if (pBeforeItem == NULL) {
+        pPageAreaLayoutItem->AddHeadChild(pLayoutItem);
+      } else {
+        pPageAreaLayoutItem->InsertChild(pBeforeItem, pLayoutItem);
+      }
+      pBeforeItem = pLayoutItem;
+      pLayoutItem = pNextLayoutItem;
+    }
+  }
+}
+void CXFA_ItemLayoutProcessor::DoLayoutPositionedContainer(
+    CXFA_LayoutContext* pContext) {
+  if (m_pLayoutItem)
+    return;
+
+  m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
+  FX_BOOL bIgnoreXY = (m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout) !=
+                       XFA_ATTRIBUTEENUM_Position);
+  FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;
+  FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;
+  XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(
+      m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize,
+      bContainerHeightAutoSize);
+  FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;
+  FX_FLOAT fHiddenContentCalculatedWidth = 0,
+           fHiddenContentCalculatedHeight = 0;
+  if (m_pCurChildNode == XFA_LAYOUT_INVALIDNODE) {
+    XFA_ItemLayoutProcessor_GotoNextContainerNode(
+        m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE);
+  }
+  int32_t iColIndex = 0;
+  for (; m_pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode(
+           m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE)) {
+    if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) {
+      continue;
+    }
+    if (m_pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) {
+      continue;
+    }
+    CXFA_ItemLayoutProcessor* pProcessor =
+        new CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr);
+    if (pContext && pContext->m_prgSpecifiedColumnWidths) {
+      int32_t iColSpan = m_pCurChildNode->GetInteger(XFA_ATTRIBUTE_ColSpan);
+      if (iColSpan <=
+          pContext->m_prgSpecifiedColumnWidths->GetSize() - iColIndex) {
+        pContext->m_fCurColumnWidth = 0;
+        pContext->m_bCurColumnWidthAvaiable = TRUE;
+        if (iColSpan == -1)
+          iColSpan = pContext->m_prgSpecifiedColumnWidths->GetSize();
+        for (int32_t i = 0; iColIndex + i < iColSpan; ++i) {
+          pContext->m_fCurColumnWidth +=
+              pContext->m_prgSpecifiedColumnWidths->GetAt(iColIndex + i);
+        }
+        if (pContext->m_fCurColumnWidth == 0)
+          pContext->m_bCurColumnWidthAvaiable = FALSE;
+        iColIndex += iColSpan >= 0 ? iColSpan : 0;
+      }
+    }
+    pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX,
+                         pContext);
+    if (!pProcessor->HasLayoutItem()) {
+      delete pProcessor;
+      continue;
+    }
+    FX_FLOAT fWidth, fHeight;
+    pProcessor->GetCurrentComponentSize(fWidth, fHeight);
+    FX_BOOL bChangeParentSize = FALSE;
+    if (XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode)) {
+      bChangeParentSize = TRUE;
+    }
+    FX_FLOAT fAbsoluteX = 0, fAbsoluteY = 0;
+    if (!bIgnoreXY) {
+      CalculatePositionedContainerPos(m_pCurChildNode, fWidth, fHeight,
+                                      fAbsoluteX, fAbsoluteY);
+    }
+    pProcessor->SetCurrentComponentPos(fAbsoluteX, fAbsoluteY);
+    if (bContainerWidthAutoSize) {
+      FX_FLOAT fChildSuppliedWidth = fAbsoluteX + fWidth;
+      if (bChangeParentSize) {
+        if (fContentCalculatedWidth < fChildSuppliedWidth) {
+          fContentCalculatedWidth = fChildSuppliedWidth;
+        }
+      } else {
+        if (fHiddenContentCalculatedWidth < fChildSuppliedWidth &&
+            m_pCurChildNode->GetClassID() != XFA_ELEMENT_Subform) {
+          fHiddenContentCalculatedWidth = fChildSuppliedWidth;
+        }
+      }
+    }
+    if (bContainerHeightAutoSize) {
+      FX_FLOAT fChildSuppliedHeight = fAbsoluteY + fHeight;
+      if (bChangeParentSize) {
+        if (fContentCalculatedHeight < fChildSuppliedHeight) {
+          fContentCalculatedHeight = fChildSuppliedHeight;
+        }
+      } else {
+        if (fHiddenContentCalculatedHeight < fChildSuppliedHeight &&
+            m_pCurChildNode->GetClassID() != XFA_ELEMENT_Subform) {
+          fHiddenContentCalculatedHeight = fChildSuppliedHeight;
+        }
+      }
+    }
+    m_pLayoutItem->AddChild(pProcessor->ExtractLayoutItem());
+    delete pProcessor;
+  }
+  XFA_VERSION eVersion = m_pFormNode->GetDocument()->GetCurVersionMode();
+  if (fContentCalculatedWidth == 0 && eVersion < XFA_VERSION_207) {
+    fContentCalculatedWidth = fHiddenContentCalculatedWidth;
+  }
+  if (fContentCalculatedHeight == 0 && eVersion < XFA_VERSION_207) {
+    fContentCalculatedHeight = fHiddenContentCalculatedHeight;
+  }
+  XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(
+      m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth,
+      fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight,
+      fContainerHeight);
+  SetCurrentComponentSize(fContainerWidth, fContainerHeight);
+}
+static inline void XFA_ItemLayoutProcessor_UpdateWidgetSize(
+    CXFA_ContentLayoutItem* pLayoutItem,
+    FX_FLOAT& fWidth,
+    FX_FLOAT& fHeight) {
+  CXFA_Node* pNode = pLayoutItem->m_pFormNode;
+  ASSERT(pNode);
+  XFA_ELEMENT eClassID = pNode->GetClassID();
+  switch (eClassID) {
+    case XFA_ELEMENT_Subform:
+    case XFA_ELEMENT_Area:
+    case XFA_ELEMENT_ExclGroup:
+    case XFA_ELEMENT_SubformSet: {
+      if (fWidth < -XFA_LAYOUT_FLOAT_PERCISION) {
+        fWidth = pLayoutItem->m_sSize.x;
+      }
+      if (fHeight < -XFA_LAYOUT_FLOAT_PERCISION) {
+        fHeight = pLayoutItem->m_sSize.y;
+      }
+      break;
+    }
+    case XFA_ELEMENT_Draw:
+    case XFA_ELEMENT_Field: {
+      pNode->GetDocument()->GetParser()->GetNotify()->StartFieldDrawLayout(
+          pNode, fWidth, fHeight);
+      break;
+    }
+    default:
+      ASSERT(FALSE);
+  }
+}
+static inline void XFA_ItemLayoutProcessor_RelocateTableRowCells(
+    CXFA_ContentLayoutItem* pLayoutRow,
+    const CFX_ArrayTemplate<FX_FLOAT>& rgSpecifiedColumnWidths,
+    XFA_ATTRIBUTEENUM eLayout) {
+  FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;
+  FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;
+  XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(
+      pLayoutRow->m_pFormNode, fContainerWidth, fContainerHeight,
+      bContainerWidthAutoSize, bContainerHeightAutoSize);
+  CXFA_Node* pMarginNode =
+      pLayoutRow->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
+  FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;
+  if (pMarginNode) {
+    fLeftInset =
+        pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
+    fTopInset =
+        pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
+    fRightInset =
+        pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
+    fBottomInset =
+        pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
+  }
+  FX_FLOAT fContentWidthLimit =
+      bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX
+                              : fContainerWidth - fLeftInset - fRightInset;
+  FX_FLOAT fContentCurrentHeight =
+      pLayoutRow->m_sSize.y - fTopInset - fBottomInset;
+  FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;
+  FX_FLOAT fCurrentColX = 0;
+  int32_t nCurrentColIdx = 0;
+  FX_BOOL bMetWholeRowCell = FALSE;
+  for (CXFA_ContentLayoutItem* pLayoutChild =
+           (CXFA_ContentLayoutItem*)pLayoutRow->m_pFirstChild;
+       pLayoutChild;
+       pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) {
+    int32_t nOriginalColSpan =
+        pLayoutChild->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan);
+    int32_t nColSpan = nOriginalColSpan;
+    FX_FLOAT fColSpanWidth = 0;
+    if (nColSpan == -1 ||
+        nCurrentColIdx + nColSpan > rgSpecifiedColumnWidths.GetSize()) {
+      nColSpan = rgSpecifiedColumnWidths.GetSize() - nCurrentColIdx;
+    }
+    for (int32_t i = 0; i < nColSpan; i++) {
+      fColSpanWidth += rgSpecifiedColumnWidths[nCurrentColIdx + i];
+    }
+    if (nColSpan != nOriginalColSpan) {
+      fColSpanWidth = bMetWholeRowCell ? 0 : std::max(fColSpanWidth,
+                                                      pLayoutChild->m_sSize.y);
+    }
+    if (nOriginalColSpan == -1) {
+      bMetWholeRowCell = TRUE;
+    }
+    pLayoutChild->m_sPos = CFX_PointF(fCurrentColX, 0);
+    pLayoutChild->m_sSize.x = fColSpanWidth;
+    if (XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) {
+      fCurrentColX += fColSpanWidth;
+      nCurrentColIdx += nColSpan;
+      FX_FLOAT fNewHeight =
+          bContainerHeightAutoSize ? -1 : fContentCurrentHeight;
+      XFA_ItemLayoutProcessor_UpdateWidgetSize(pLayoutChild, fColSpanWidth,
+                                               fNewHeight);
+      pLayoutChild->m_sSize.y = fNewHeight;
+      if (bContainerHeightAutoSize) {
+        FX_FLOAT fChildSuppliedHeight = pLayoutChild->m_sSize.y;
+        if (fContentCalculatedHeight < fChildSuppliedHeight) {
+          fContentCalculatedHeight = fChildSuppliedHeight;
+        }
+      }
+    }
+  }
+  if (bContainerHeightAutoSize) {
+    for (CXFA_ContentLayoutItem* pLayoutChild =
+             (CXFA_ContentLayoutItem*)pLayoutRow->m_pFirstChild;
+         pLayoutChild;
+         pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) {
+      XFA_ItemLayoutProcessor_UpdateWidgetSize(
+          pLayoutChild, pLayoutChild->m_sSize.x, fContentCalculatedHeight);
+      FX_FLOAT fOldChildHeight = pLayoutChild->m_sSize.y;
+      pLayoutChild->m_sSize.y = fContentCalculatedHeight;
+      CXFA_Node* pParaNode =
+          pLayoutChild->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Para);
+      if (pParaNode && pLayoutChild->m_pFirstChild) {
+        FX_FLOAT fOffHeight = fContentCalculatedHeight - fOldChildHeight;
+        XFA_ATTRIBUTEENUM eVType = pParaNode->GetEnum(XFA_ATTRIBUTE_VAlign);
+        switch (eVType) {
+          case XFA_ATTRIBUTEENUM_Middle:
+            fOffHeight = fOffHeight / 2;
+            break;
+          case XFA_ATTRIBUTEENUM_Bottom:
+            break;
+          case XFA_ATTRIBUTEENUM_Top:
+          default:
+            fOffHeight = 0;
+            break;
+        }
+        if (fOffHeight > 0) {
+          for (CXFA_ContentLayoutItem* pInnerLayoutChild =
+                   (CXFA_ContentLayoutItem*)pLayoutChild->m_pFirstChild;
+               pInnerLayoutChild;
+               pInnerLayoutChild =
+                   (CXFA_ContentLayoutItem*)pInnerLayoutChild->m_pNextSibling) {
+            pInnerLayoutChild->m_sPos.y += fOffHeight;
+          }
+        }
+      }
+    }
+  }
+  if (bContainerWidthAutoSize) {
+    FX_FLOAT fChildSuppliedWidth = fCurrentColX;
+    if (fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX &&
+        fContentWidthLimit > fChildSuppliedWidth) {
+      fChildSuppliedWidth = fContentWidthLimit;
+    }
+    if (fContentCalculatedWidth < fChildSuppliedWidth) {
+      fContentCalculatedWidth = fChildSuppliedWidth;
+    }
+  } else {
+    fContentCalculatedWidth = fContainerWidth - fLeftInset - fRightInset;
+  }
+  if (pLayoutRow->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout) ==
+      XFA_ATTRIBUTEENUM_Rl_row) {
+    for (CXFA_ContentLayoutItem* pLayoutChild =
+             (CXFA_ContentLayoutItem*)pLayoutRow->m_pFirstChild;
+         pLayoutChild;
+         pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) {
+      pLayoutChild->m_sPos.x = fContentCalculatedWidth -
+                               pLayoutChild->m_sPos.x - pLayoutChild->m_sSize.x;
+    }
+  }
+  XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(
+      pLayoutRow->m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth,
+      fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight,
+      fContainerHeight);
+  pLayoutRow->m_sSize = CFX_SizeF(fContainerWidth, fContainerHeight);
+}
+void CXFA_ItemLayoutProcessor::DoLayoutTableContainer(CXFA_Node* pLayoutNode) {
+  if (m_pLayoutItem)
+    return;
+
+  if (pLayoutNode == NULL) {
+    pLayoutNode = m_pFormNode;
+  }
+  ASSERT(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE);
+  m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
+  FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;
+  FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;
+  XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(
+      m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize,
+      bContainerHeightAutoSize);
+  FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;
+  CXFA_Node* pMarginNode =
+      m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
+  FX_FLOAT fLeftInset = 0;
+  FX_FLOAT fRightInset = 0;
+  if (pMarginNode) {
+    fLeftInset =
+        pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
+    fRightInset =
+        pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
+  }
+  FX_FLOAT fContentWidthLimit =
+      bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX
+                              : fContainerWidth - fLeftInset - fRightInset;
+  CFX_WideStringC wsColumnWidths;
+  if (pLayoutNode->TryCData(XFA_ATTRIBUTE_ColumnWidths, wsColumnWidths)) {
+    CFX_WideStringArray widths;
+    if (FX_SeparateStringW(wsColumnWidths.GetPtr(), wsColumnWidths.GetLength(),
+                           L' ', widths) > 0) {
+      int32_t iCols = widths.GetSize();
+      CFX_WideString wsWidth;
+      for (int32_t i = 0; i < iCols; i++) {
+        wsWidth = widths[i];
+        wsWidth.TrimLeft(L' ');
+        if (!wsWidth.IsEmpty()) {
+          CXFA_Measurement measure(wsWidth);
+          m_rgSpecifiedColumnWidths.Add(measure.ToUnit(XFA_UNIT_Pt));
+        }
+      }
+    }
+  }
+  int32_t iSpecifiedColumnCount = m_rgSpecifiedColumnWidths.GetSize();
+  CXFA_LayoutContext layoutContext;
+  layoutContext.m_prgSpecifiedColumnWidths = &m_rgSpecifiedColumnWidths;
+  CXFA_LayoutContext* pLayoutContext =
+      iSpecifiedColumnCount > 0 ? &layoutContext : NULL;
+  if (m_pCurChildNode == XFA_LAYOUT_INVALIDNODE) {
+    XFA_ItemLayoutProcessor_GotoNextContainerNode(
+        m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE);
+  }
+  for (; m_pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode(
+           m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE)) {
+    layoutContext.m_bCurColumnWidthAvaiable = FALSE;
+    layoutContext.m_fCurColumnWidth = 0;
+    if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) {
+      continue;
+    }
+    CXFA_ItemLayoutProcessor* pProcessor =
+        new CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr);
+    pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX,
+                         pLayoutContext);
+    if (!pProcessor->HasLayoutItem()) {
+      delete pProcessor;
+      continue;
+    }
+    m_pLayoutItem->AddChild(pProcessor->ExtractLayoutItem());
+    delete pProcessor;
+  }
+  int32_t iRowCount = 0, iColCount = 0;
+  {
+    CFX_ArrayTemplate<CXFA_ContentLayoutItem*> rgRowItems;
+    CFX_ArrayTemplate<int32_t> rgRowItemsSpan;
+    CFX_ArrayTemplate<FX_FLOAT> rgRowItemsWidth;
+    for (CXFA_ContentLayoutItem* pLayoutChild =
+             (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild;
+         pLayoutChild;
+         pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) {
+      if (pLayoutChild->m_pFormNode->GetClassID() != XFA_ELEMENT_Subform) {
+        continue;
+      }
+      if (!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) {
+        continue;
+      }
+      XFA_ATTRIBUTEENUM eLayout =
+          pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
+      if (eLayout != XFA_ATTRIBUTEENUM_Row &&
+          eLayout != XFA_ATTRIBUTEENUM_Rl_row) {
+        continue;
+      }
+      if (CXFA_ContentLayoutItem* pRowLayoutCell =
+              (CXFA_ContentLayoutItem*)pLayoutChild->m_pFirstChild) {
+        rgRowItems.Add(pRowLayoutCell);
+        int32_t iColSpan =
+            pRowLayoutCell->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan);
+        rgRowItemsSpan.Add(iColSpan);
+        rgRowItemsWidth.Add(pRowLayoutCell->m_sSize.x);
+      }
+    }
+    iRowCount = rgRowItems.GetSize();
+    iColCount = 0;
+    FX_BOOL bMoreColumns = TRUE;
+    while (bMoreColumns) {
+      bMoreColumns = FALSE;
+      FX_BOOL bAutoCol = FALSE;
+      for (int32_t i = 0; i < iRowCount; i++) {
+        while (rgRowItems[i] && (rgRowItemsSpan[i] <= 0 ||
+                                 !XFA_ItemLayoutProcessor_IsTakingSpace(
+                                     rgRowItems[i]->m_pFormNode))) {
+          CXFA_ContentLayoutItem* pNewCell =
+              (CXFA_ContentLayoutItem*)rgRowItems[i]->m_pNextSibling;
+          if (rgRowItemsSpan[i] < 0 && XFA_ItemLayoutProcessor_IsTakingSpace(
+                                           rgRowItems[i]->m_pFormNode)) {
+            pNewCell = NULL;
+          }
+          rgRowItems[i] = pNewCell;
+          rgRowItemsSpan[i] =
+              pNewCell
+                  ? pNewCell->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan)
+                  : 0;
+          rgRowItemsWidth[i] = pNewCell ? pNewCell->m_sSize.x : 0;
+        }
+        CXFA_ContentLayoutItem* pCell = rgRowItems[i];
+        if (!pCell) {
+          continue;
+        }
+        bMoreColumns = TRUE;
+        if (rgRowItemsSpan[i] == 1) {
+          if (iColCount >= iSpecifiedColumnCount) {
+            for (int32_t j = 0, c = iColCount + 1 -
+                                    m_rgSpecifiedColumnWidths.GetSize();
+                 j < c; j++) {
+              m_rgSpecifiedColumnWidths.Add(0);
+            }
+          }
+          if (m_rgSpecifiedColumnWidths[iColCount] <
+              XFA_LAYOUT_FLOAT_PERCISION) {
+            bAutoCol = TRUE;
+          }
+          if (bAutoCol &&
+              m_rgSpecifiedColumnWidths[iColCount] < rgRowItemsWidth[i]) {
+            m_rgSpecifiedColumnWidths[iColCount] = rgRowItemsWidth[i];
+          }
+        }
+      }
+      if (bMoreColumns) {
+        FX_FLOAT fFinalColumnWidth = 0.0f;
+        if (iColCount < m_rgSpecifiedColumnWidths.GetSize())
+          fFinalColumnWidth = m_rgSpecifiedColumnWidths[iColCount];
+        for (int32_t i = 0; i < iRowCount; ++i) {
+          if (!rgRowItems[i])
+            continue;
+          --rgRowItemsSpan[i];
+          rgRowItemsWidth[i] -= fFinalColumnWidth;
+        }
+        ++iColCount;
+      }
+    }
+  }
+  FX_FLOAT fCurrentRowY = 0;
+  for (CXFA_ContentLayoutItem* pLayoutChild =
+           (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild;
+       pLayoutChild;
+       pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) {
+    if (!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) {
+      continue;
+    }
+    if (pLayoutChild->m_pFormNode->GetClassID() == XFA_ELEMENT_Subform) {
+      XFA_ATTRIBUTEENUM eSubformLayout =
+          pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
+      if (eSubformLayout == XFA_ATTRIBUTEENUM_Row ||
+          eSubformLayout == XFA_ATTRIBUTEENUM_Rl_row) {
+        XFA_ItemLayoutProcessor_RelocateTableRowCells(
+            pLayoutChild, m_rgSpecifiedColumnWidths, eSubformLayout);
+      }
+    }
+    pLayoutChild->m_sPos.y = fCurrentRowY;
+    if (bContainerWidthAutoSize) {
+      pLayoutChild->m_sPos.x = 0;
+    } else {
+      switch (pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) {
+        case XFA_ATTRIBUTEENUM_Left:
+        default:
+          pLayoutChild->m_sPos.x = 0;
+          break;
+        case XFA_ATTRIBUTEENUM_Center:
+          pLayoutChild->m_sPos.x =
+              (fContentWidthLimit - pLayoutChild->m_sSize.x) / 2;
+          break;
+        case XFA_ATTRIBUTEENUM_Right:
+          pLayoutChild->m_sPos.x = fContentWidthLimit - pLayoutChild->m_sSize.x;
+          break;
+      }
+    }
+    if (bContainerWidthAutoSize) {
+      FX_FLOAT fChildSuppliedWidth =
+          pLayoutChild->m_sPos.x + pLayoutChild->m_sSize.x;
+      if (fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX &&
+          fContentWidthLimit > fChildSuppliedWidth) {
+        fChildSuppliedWidth = fContentWidthLimit;
+      }
+      if (fContentCalculatedWidth < fChildSuppliedWidth) {
+        fContentCalculatedWidth = fChildSuppliedWidth;
+      }
+    }
+    fCurrentRowY += pLayoutChild->m_sSize.y;
+  }
+  if (bContainerHeightAutoSize) {
+    FX_FLOAT fChildSuppliedHeight = fCurrentRowY;
+    if (fContentCalculatedHeight < fChildSuppliedHeight) {
+      fContentCalculatedHeight = fChildSuppliedHeight;
+    }
+  }
+  XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(
+      m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth,
+      fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight,
+      fContainerHeight);
+  SetCurrentComponentSize(fContainerWidth, fContainerHeight);
+}
+static uint8_t XFA_ItemLayoutProcessor_HAlignEnumToInt(
+    XFA_ATTRIBUTEENUM eHAlign) {
+  switch (eHAlign) {
+    case XFA_ATTRIBUTEENUM_Center:
+      return 1;
+    case XFA_ATTRIBUTEENUM_Right:
+      return 2;
+    case XFA_ATTRIBUTEENUM_Left:
+    default:
+      return 0;
+  }
+}
+static void XFA_ItemLayoutProcessor_UpdatePendedItemLayout(
+    CXFA_ItemLayoutProcessor* pProcessor,
+    CXFA_ContentLayoutItem* pLayoutItem) {
+  XFA_ATTRIBUTEENUM eLayout =
+      pLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
+  switch (eLayout) {
+    case XFA_ATTRIBUTEENUM_Row:
+    case XFA_ATTRIBUTEENUM_Rl_row:
+      XFA_ItemLayoutProcessor_RelocateTableRowCells(
+          pLayoutItem, pProcessor->m_rgSpecifiedColumnWidths, eLayout);
+      break;
+    default:
+      break;
+  }
+}
+FX_BOOL CXFA_ItemLayoutProcessor::IsAddNewRowForTrailer(
+    CXFA_ContentLayoutItem* pTrailerItem) {
+  if (!pTrailerItem) {
+    return FALSE;
+  }
+  FX_FLOAT fWidth = pTrailerItem->m_sSize.x;
+  XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
+  if (eLayout != XFA_ATTRIBUTEENUM_Tb && m_fWidthLimite > fWidth) {
+    return FALSE;
+  }
+  return TRUE;
+}
+static void XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(
+    CXFA_ItemLayoutProcessor* pProcessor,
+    FX_FLOAT fSplitPos,
+    CXFA_ContentLayoutItem* pTrailerLayoutItem,
+    FX_BOOL bUseInherited = FALSE) {
+  if (!pTrailerLayoutItem) {
+    return;
+  }
+  FX_FLOAT fHeight = pTrailerLayoutItem->m_sSize.y;
+  if (bUseInherited) {
+    FX_FLOAT fNewSplitPos = 0;
+    if (fSplitPos - fHeight > XFA_LAYOUT_FLOAT_PERCISION) {
+      fNewSplitPos = pProcessor->FindSplitPos(fSplitPos - fHeight);
+    }
+    if (fNewSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {
+      pProcessor->SplitLayoutItem(fNewSplitPos);
+    }
+    return;
+  }
+  XFA_ItemLayoutProcessor_UpdatePendedItemLayout(pProcessor,
+                                                 pTrailerLayoutItem);
+  CXFA_Node* pMarginNode =
+      pProcessor->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
+  FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;
+  if (pMarginNode) {
+    fLeftInset =
+        pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
+    fTopInset =
+        pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
+    fRightInset =
+        pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
+    fBottomInset =
+        pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
+  }
+  if (!pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem)) {
+    pTrailerLayoutItem->m_sPos.y = pProcessor->m_fLastRowY;
+    pTrailerLayoutItem->m_sPos.x = pProcessor->m_fLastRowWidth;
+    pProcessor->m_pLayoutItem->m_sSize.x += pTrailerLayoutItem->m_sSize.x;
+    pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem);
+    return;
+  }
+  FX_FLOAT fNewSplitPos = 0;
+  if (fSplitPos - fHeight > XFA_LAYOUT_FLOAT_PERCISION) {
+    fNewSplitPos = pProcessor->FindSplitPos(fSplitPos - fHeight);
+  }
+  if (fNewSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {
+    pProcessor->SplitLayoutItem(fNewSplitPos);
+    pTrailerLayoutItem->m_sPos.y = fNewSplitPos - fTopInset - fBottomInset;
+  } else {
+    pTrailerLayoutItem->m_sPos.y = fSplitPos - fTopInset - fBottomInset;
+  }
+  switch (pTrailerLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) {
+    case XFA_ATTRIBUTEENUM_Left:
+    default:
+      pTrailerLayoutItem->m_sPos.x = fLeftInset;
+      break;
+    case XFA_ATTRIBUTEENUM_Right:
+      pTrailerLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.x -
+                                     fRightInset -
+                                     pTrailerLayoutItem->m_sSize.x;
+      break;
+    case XFA_ATTRIBUTEENUM_Center:
+      pTrailerLayoutItem->m_sPos.x =
+          (pProcessor->m_pLayoutItem->m_sSize.x - fLeftInset - fRightInset -
+           pTrailerLayoutItem->m_sSize.x) /
+          2;
+      break;
+  }
+  pProcessor->m_pLayoutItem->m_sSize.y += fHeight;
+  pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem);
+}
+static void XFA_ItemLayoutProcessor_AddLeaderAfterSplit(
+    CXFA_ItemLayoutProcessor* pProcessor,
+    CXFA_ContentLayoutItem* pLeaderLayoutItem) {
+  XFA_ItemLayoutProcessor_UpdatePendedItemLayout(pProcessor, pLeaderLayoutItem);
+  CXFA_Node* pMarginNode =
+      pProcessor->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
+  FX_FLOAT fLeftInset = 0;
+  FX_FLOAT fRightInset = 0;
+  if (pMarginNode) {
+    fLeftInset =
+        pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
+    fRightInset =
+        pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
+  }
+  FX_FLOAT fHeight = pLeaderLayoutItem->m_sSize.y;
+  for (CXFA_ContentLayoutItem* pChildItem =
+           (CXFA_ContentLayoutItem*)pProcessor->m_pLayoutItem->m_pFirstChild;
+       pChildItem;
+       pChildItem = (CXFA_ContentLayoutItem*)pChildItem->m_pNextSibling) {
+    pChildItem->m_sPos.y += fHeight;
+  }
+  pLeaderLayoutItem->m_sPos.y = 0;
+  switch (pLeaderLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) {
+    case XFA_ATTRIBUTEENUM_Left:
+    default:
+      pLeaderLayoutItem->m_sPos.x = fLeftInset;
+      break;
+    case XFA_ATTRIBUTEENUM_Right:
+      pLeaderLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.x -
+                                    fRightInset - pLeaderLayoutItem->m_sSize.x;
+      break;
+    case XFA_ATTRIBUTEENUM_Center:
+      pLeaderLayoutItem->m_sPos.x =
+          (pProcessor->m_pLayoutItem->m_sSize.x - fLeftInset - fRightInset -
+           pLeaderLayoutItem->m_sSize.x) /
+          2;
+      break;
+  }
+  pProcessor->m_pLayoutItem->m_sSize.y += fHeight;
+  pProcessor->m_pLayoutItem->AddChild(pLeaderLayoutItem);
+}
+static void XFA_ItemLayoutProcessor_AddPendingNode(
+    CXFA_ItemLayoutProcessor* pProcessor,
+    CXFA_Node* pPendingNode,
+    FX_BOOL bBreakPending) {
+  pProcessor->m_PendingNodes.push_back(pPendingNode);
+  pProcessor->m_bBreakPending = bBreakPending;
+}
+static FX_FLOAT XFA_ItemLayoutProcessor_InsertPendingItems(
+    CXFA_ItemLayoutProcessor* pProcessor,
+    CXFA_Node* pCurChildNode) {
+  FX_FLOAT fTotalHeight = 0;
+  if (pProcessor->m_PendingNodes.empty()) {
+    return fTotalHeight;
+  }
+  if (!pProcessor->m_pLayoutItem) {
+    pProcessor->m_pLayoutItem =
+        pProcessor->CreateContentLayoutItem(pCurChildNode);
+    pProcessor->m_pLayoutItem->m_sSize.clear();
+  }
+  while (!pProcessor->m_PendingNodes.empty()) {
+    std::unique_ptr<CXFA_ItemLayoutProcessor> pPendingProcessor(
+        new CXFA_ItemLayoutProcessor(pProcessor->m_PendingNodes.front(),
+                                     nullptr));
+    pProcessor->m_PendingNodes.pop_front();
+    pPendingProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX);
+    CXFA_ContentLayoutItem* pPendingLayoutItem =
+        pPendingProcessor->HasLayoutItem()
+            ? pPendingProcessor->ExtractLayoutItem()
+            : nullptr;
+    if (pPendingLayoutItem) {
+      XFA_ItemLayoutProcessor_AddLeaderAfterSplit(pProcessor,
+                                                  pPendingLayoutItem);
+      if (pProcessor->m_bBreakPending) {
+        fTotalHeight += pPendingLayoutItem->m_sSize.y;
+      }
+    }
+  }
+  return fTotalHeight;
+}
+FX_FLOAT CXFA_ItemLayoutProcessor::InsertKeepLayoutItems() {
+  FX_FLOAT fTotalHeight = 0;
+  if (m_arrayKeepItems.GetSize()) {
+    if (!m_pLayoutItem) {
+      m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
+      m_pLayoutItem->m_sSize.clear();
+    }
+    for (int32_t iIndex = m_arrayKeepItems.GetSize() - 1; iIndex >= 0;
+         iIndex--) {
+      XFA_ItemLayoutProcessor_AddLeaderAfterSplit(this,
+                                                  m_arrayKeepItems[iIndex]);
+      fTotalHeight += m_arrayKeepItems[iIndex]->m_sSize.y;
+    }
+    m_arrayKeepItems.RemoveAll();
+  }
+  return fTotalHeight;
+}
+FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepForSplite(
+    CXFA_ItemLayoutProcessor* pParentProcessor,
+    CXFA_ItemLayoutProcessor* pChildProcessor,
+    XFA_ItemLayoutProcessorResult eRetValue,
+    CFX_ArrayTemplate<CXFA_ContentLayoutItem*>& rgCurLineLayoutItem,
+    FX_FLOAT& fContentCurRowAvailWidth,
+    FX_FLOAT& fContentCurRowHeight,
+    FX_FLOAT& fContentCurRowY,
+    FX_BOOL& bAddedItemInRow,
+    FX_BOOL& bForceEndPage,
+    XFA_ItemLayoutProcessorResult& result) {
+  if (pParentProcessor == NULL || pChildProcessor == NULL) {
+    return FALSE;
+  }
+  if (pParentProcessor->m_pCurChildNode->GetIntact() !=
+          XFA_ATTRIBUTEENUM_None ||
+      !pChildProcessor->m_bHasAvailHeight) {
+    if (XFA_ExistContainerKeep(pParentProcessor->m_pCurChildNode, TRUE)) {
+      FX_FLOAT fChildWidth, fChildHeight;
+      pChildProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);
+      CFX_ArrayTemplate<CXFA_ContentLayoutItem*> keepLayoutItems;
+      if (pParentProcessor->JudgePutNextPage(pParentProcessor->m_pLayoutItem,
+                                             fChildHeight, keepLayoutItems)) {
+        m_arrayKeepItems.RemoveAll();
+        for (int32_t iIndex = 0; iIndex < keepLayoutItems.GetSize(); iIndex++) {
+          CXFA_ContentLayoutItem* pItem = keepLayoutItems.GetAt(iIndex);
+          pParentProcessor->m_pLayoutItem->RemoveChild(pItem);
+          fContentCurRowY -= pItem->m_sSize.y;
+          m_arrayKeepItems.Add(pItem);
+        }
+        bAddedItemInRow = TRUE;
+        bForceEndPage = TRUE;
+        result = XFA_ItemLayoutProcessorResult_PageFullBreak;
+        return TRUE;
+      }
+      rgCurLineLayoutItem.Add(pChildProcessor->ExtractLayoutItem());
+      bAddedItemInRow = TRUE;
+      fContentCurRowAvailWidth -= fChildWidth;
+      if (fContentCurRowHeight < fChildHeight) {
+        fContentCurRowHeight = fChildHeight;
+      }
+      result = eRetValue;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_ItemLayoutProcessor::JudgePutNextPage(
+    CXFA_ContentLayoutItem* pParentLayoutItem,
+    FX_FLOAT fChildHeight,
+    CFX_ArrayTemplate<CXFA_ContentLayoutItem*>& pKeepItems) {
+  if (pParentLayoutItem == NULL) {
+    return FALSE;
+  }
+  FX_FLOAT fItemsHeight = 0;
+  for (CXFA_ContentLayoutItem* pChildLayoutItem =
+           (CXFA_ContentLayoutItem*)pParentLayoutItem->m_pFirstChild;
+       pChildLayoutItem;
+       pChildLayoutItem =
+           (CXFA_ContentLayoutItem*)pChildLayoutItem->m_pNextSibling) {
+    if (XFA_ExistContainerKeep(pChildLayoutItem->m_pFormNode, FALSE)) {
+      pKeepItems.Add(pChildLayoutItem);
+      fItemsHeight += pChildLayoutItem->m_sSize.y;
+    } else {
+      pKeepItems.RemoveAll();
+      fItemsHeight = 0;
+    }
+  }
+  fItemsHeight += fChildHeight;
+  if (m_pPageMgr->GetNextAvailContentHeight(fItemsHeight)) {
+    return TRUE;
+  }
+  return FALSE;
+}
+void CXFA_ItemLayoutProcessor::ProcessUnUseBinds(CXFA_Node* pFormNode) {
+  if (!pFormNode) {
+    return;
+  }
+  CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(
+      pFormNode);
+  for (CXFA_Node* pNode = sIterator.MoveToNext(); pNode;
+       pNode = sIterator.MoveToNext()) {
+    if (pNode->IsContainerNode()) {
+      CXFA_Node* pBindNode = pNode->GetBindData();
+      if (pBindNode) {
+        pBindNode->RemoveBindItem(pNode);
+        pNode->SetObject(XFA_ATTRIBUTE_BindingNode, NULL);
+      }
+    }
+    pNode->SetFlag(XFA_NODEFLAG_UnusedNode);
+  }
+}
+void CXFA_ItemLayoutProcessor::ProcessUnUseOverFlow(
+    CXFA_Node* pLeaderNode,
+    CXFA_Node* pTrailerNode,
+    CXFA_ContentLayoutItem* pTrailerItem,
+    CXFA_Node* pFormNode) {
+  ProcessUnUseBinds(pLeaderNode);
+  ProcessUnUseBinds(pTrailerNode);
+  if (pFormNode == NULL) {
+    return;
+  }
+  if (pFormNode->GetClassID() == XFA_ELEMENT_Overflow ||
+      pFormNode->GetClassID() == XFA_ELEMENT_Break) {
+    pFormNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent);
+  }
+  if (pLeaderNode && pFormNode) {
+    pFormNode->RemoveChild(pLeaderNode);
+  }
+  if (pTrailerNode && pFormNode) {
+    pFormNode->RemoveChild(pTrailerNode);
+  }
+  if (pTrailerItem) {
+    XFA_ReleaseLayoutItem(pTrailerItem);
+  }
+}
+static XFA_ItemLayoutProcessorResult XFA_ItemLayoutProcessor_InsertFlowedItem(
+    CXFA_ItemLayoutProcessor* pThis,
+    CXFA_ItemLayoutProcessor*& pProcessor,
+    FX_BOOL bContainerWidthAutoSize,
+    FX_BOOL bContainerHeightAutoSize,
+    FX_FLOAT fContainerHeight,
+    XFA_ATTRIBUTEENUM eFlowStrategy,
+    uint8_t& uCurHAlignState,
+    CFX_ArrayTemplate<CXFA_ContentLayoutItem*>(&rgCurLineLayoutItems)[3],
+    FX_BOOL bUseBreakControl,
+    FX_FLOAT fAvailHeight,
+    FX_FLOAT fRealHeight,
+    FX_FLOAT& fContentCurRowY,
+    FX_FLOAT& fContentWidthLimit,
+    FX_FLOAT& fContentCurRowAvailWidth,
+    FX_FLOAT& fContentCurRowHeight,
+    FX_BOOL& bAddedItemInRow,
+    FX_BOOL& bForceEndPage,
+    CXFA_LayoutContext* pLayoutContext = NULL,
+    FX_BOOL bNewRow = FALSE) {
+  FX_BOOL bTakeSpace =
+      XFA_ItemLayoutProcessor_IsTakingSpace(pProcessor->m_pFormNode);
+  uint8_t uHAlign = XFA_ItemLayoutProcessor_HAlignEnumToInt(
+      pThis->m_pCurChildNode->GetEnum(XFA_ATTRIBUTE_HAlign));
+  if (bContainerWidthAutoSize) {
+    uHAlign = 0;
+  }
+  if ((eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb && uHAlign < uCurHAlignState) ||
+      (eFlowStrategy == XFA_ATTRIBUTEENUM_Rl_tb && uHAlign > uCurHAlignState)) {
+    return XFA_ItemLayoutProcessorResult_RowFullBreak;
+  }
+  uCurHAlignState = uHAlign;
+  FX_BOOL bIsOwnSplite =
+      pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None;
+  FX_BOOL bUseRealHeight =
+      bTakeSpace && bContainerHeightAutoSize && bIsOwnSplite &&
+      pProcessor->m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent)->GetIntact() ==
+          XFA_ATTRIBUTEENUM_None;
+  FX_BOOL bIsTransHeight = bTakeSpace;
+  if (bIsTransHeight && !bIsOwnSplite) {
+    FX_BOOL bRootForceTb = FALSE;
+    XFA_ATTRIBUTEENUM eLayoutStrategy = XFA_ItemLayoutProcessor_GetLayout(
+        pProcessor->m_pFormNode, bRootForceTb);
+    if (eLayoutStrategy == XFA_ATTRIBUTEENUM_Lr_tb ||
+        eLayoutStrategy == XFA_ATTRIBUTEENUM_Rl_tb) {
+      bIsTransHeight = FALSE;
+    }
+  }
+  FX_BOOL bUseInherited = FALSE;
+  CXFA_LayoutContext layoutContext;
+  if (pThis->m_pPageMgr) {
+    CXFA_Node* pOverflowNode =
+        pThis->m_pPageMgr->QueryOverflow(pThis->m_pFormNode);
+    if (pOverflowNode) {
+      layoutContext.m_pOverflowNode = pOverflowNode;
+      layoutContext.m_pOverflowProcessor = pThis;
+      pLayoutContext = &layoutContext;
+    }
+  }
+  XFA_ItemLayoutProcessorResult eRetValue = XFA_ItemLayoutProcessorResult_Done;
+  if (!bNewRow ||
+      pProcessor->m_ePreProcessRs == XFA_ItemLayoutProcessorResult_Done) {
+    eRetValue = pProcessor->DoLayout(
+        bTakeSpace ? bUseBreakControl : FALSE,
+        bUseRealHeight ? fRealHeight - fContentCurRowY : XFA_LAYOUT_FLOAT_MAX,
+        bIsTransHeight ? fRealHeight - fContentCurRowY : XFA_LAYOUT_FLOAT_MAX,
+        pLayoutContext);
+    pProcessor->m_ePreProcessRs = eRetValue;
+  } else {
+    eRetValue = pProcessor->m_ePreProcessRs;
+    pProcessor->m_ePreProcessRs = XFA_ItemLayoutProcessorResult_Done;
+  }
+  if (pProcessor->HasLayoutItem() == FALSE) {
+    return eRetValue;
+  }
+  FX_FLOAT fChildWidth, fChildHeight;
+  pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);
+  if (bUseRealHeight && fRealHeight < XFA_LAYOUT_FLOAT_PERCISION) {
+    fRealHeight = XFA_LAYOUT_FLOAT_MAX;
+    fAvailHeight = XFA_LAYOUT_FLOAT_MAX;
+  }
+  if (!bTakeSpace ||
+      (fChildWidth <= fContentCurRowAvailWidth + XFA_LAYOUT_FLOAT_PERCISION) ||
+      (fContentWidthLimit - fContentCurRowAvailWidth <=
+       XFA_LAYOUT_FLOAT_PERCISION)) {
+    CXFA_Node *pOverflowLeaderNode = NULL, *pOverflowTrailerNode = NULL,
+              *pFormNode = NULL;
+    CXFA_ContentLayoutItem* pTrailerLayoutItem = NULL;
+    FX_BOOL bIsAddTrailerHeight = FALSE;
+    if (pThis->m_pPageMgr &&
+        pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None) {
+      pFormNode = pThis->m_pPageMgr->QueryOverflow(pProcessor->m_pFormNode);
+      if (pFormNode == NULL && pLayoutContext &&
+          pLayoutContext->m_pOverflowProcessor) {
+        pFormNode = pLayoutContext->m_pOverflowNode;
+        bUseInherited = TRUE;
+      }
+      if (pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode,
+                                             pOverflowTrailerNode, FALSE,
+                                             FALSE)) {
+        if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowTrailerNode)) {
+          if (pOverflowTrailerNode) {
+            CXFA_ItemLayoutProcessor* pOverflowLeaderProcessor =
+                new CXFA_ItemLayoutProcessor(pOverflowTrailerNode, NULL);
+            pOverflowLeaderProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX);
+            pTrailerLayoutItem =
+                pOverflowLeaderProcessor->HasLayoutItem()
+                    ? pOverflowLeaderProcessor->ExtractLayoutItem()
+                    : NULL;
+            delete pOverflowLeaderProcessor;
+          }
+          if (bUseInherited) {
+            bIsAddTrailerHeight =
+                pThis->IsAddNewRowForTrailer(pTrailerLayoutItem);
+          } else {
+            bIsAddTrailerHeight =
+                pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem);
+          }
+          if (bIsAddTrailerHeight) {
+            FX_FLOAT fTrailerHeight = pTrailerLayoutItem->m_sSize.y;
+            fChildHeight += fTrailerHeight;
+            bIsAddTrailerHeight = TRUE;
+          }
+        }
+      }
+    }
+    if (!bTakeSpace ||
+        fContentCurRowY + fChildHeight <=
+            fAvailHeight + XFA_LAYOUT_FLOAT_PERCISION ||
+        (!bContainerHeightAutoSize &&
+         pThis->m_fUsedSize + fAvailHeight + XFA_LAYOUT_FLOAT_PERCISION >=
+             fContainerHeight)) {
+      if (!bTakeSpace || eRetValue == XFA_ItemLayoutProcessorResult_Done) {
+        if (pProcessor->m_bUseInheriated) {
+          if (pTrailerLayoutItem) {
+            XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(
+                pProcessor, fChildHeight, pTrailerLayoutItem);
+          }
+          if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {
+            XFA_ItemLayoutProcessor_AddPendingNode(pProcessor,
+                                                   pOverflowLeaderNode, FALSE);
+          }
+          pProcessor->m_bUseInheriated = FALSE;
+        } else {
+          if (bIsAddTrailerHeight) {
+            fChildHeight -= pTrailerLayoutItem->m_sSize.y;
+          }
+          pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
+                                           pOverflowTrailerNode,
+                                           pTrailerLayoutItem, pFormNode);
+        }
+        CXFA_ContentLayoutItem* pChildLayoutItem =
+            pProcessor->ExtractLayoutItem();
+        if (XFA_ExistContainerKeep(pProcessor->m_pFormNode, FALSE) &&
+            pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None) {
+          pThis->m_arrayKeepItems.Add(pChildLayoutItem);
+        } else {
+          pThis->m_arrayKeepItems.RemoveAll();
+        }
+        rgCurLineLayoutItems[uHAlign].Add(pChildLayoutItem);
+        bAddedItemInRow = TRUE;
+        if (bTakeSpace) {
+          fContentCurRowAvailWidth -= fChildWidth;
+          if (fContentCurRowHeight < fChildHeight) {
+            fContentCurRowHeight = fChildHeight;
+          }
+        }
+        return XFA_ItemLayoutProcessorResult_Done;
+      } else {
+        if (eRetValue == XFA_ItemLayoutProcessorResult_PageFullBreak) {
+          if (pProcessor->m_bUseInheriated) {
+            if (pTrailerLayoutItem) {
+              XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(
+                  pProcessor, fChildHeight, pTrailerLayoutItem);
+            }
+            if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {
+              XFA_ItemLayoutProcessor_AddPendingNode(
+                  pProcessor, pOverflowLeaderNode, FALSE);
+            }
+            pProcessor->m_bUseInheriated = FALSE;
+          } else {
+            if (bIsAddTrailerHeight) {
+              fChildHeight -= pTrailerLayoutItem->m_sSize.y;
+            }
+            pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
+                                             pOverflowTrailerNode,
+                                             pTrailerLayoutItem, pFormNode);
+          }
+        }
+        rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());
+        bAddedItemInRow = TRUE;
+        fContentCurRowAvailWidth -= fChildWidth;
+        if (fContentCurRowHeight < fChildHeight) {
+          fContentCurRowHeight = fChildHeight;
+        }
+        return eRetValue;
+      }
+    } else {
+      XFA_ItemLayoutProcessorResult eResult;
+      if (pThis->ProcessKeepForSplite(
+              pThis, pProcessor, eRetValue, rgCurLineLayoutItems[uHAlign],
+              fContentCurRowAvailWidth, fContentCurRowHeight, fContentCurRowY,
+              bAddedItemInRow, bForceEndPage, eResult)) {
+        return eResult;
+      }
+      bForceEndPage = TRUE;
+      FX_FLOAT fSplitPos =
+          pProcessor->FindSplitPos(fAvailHeight - fContentCurRowY);
+      if (fSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {
+        XFA_ATTRIBUTEENUM eLayout =
+            pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
+        if (eLayout == XFA_ATTRIBUTEENUM_Tb &&
+            eRetValue == XFA_ItemLayoutProcessorResult_Done) {
+          pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
+                                           pOverflowTrailerNode,
+                                           pTrailerLayoutItem, pFormNode);
+          rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());
+          bAddedItemInRow = TRUE;
+          if (bTakeSpace) {
+            fContentCurRowAvailWidth -= fChildWidth;
+            if (fContentCurRowHeight < fChildHeight) {
+              fContentCurRowHeight = fChildHeight;
+            }
+          }
+          return XFA_ItemLayoutProcessorResult_PageFullBreak;
+        }
+        CXFA_Node *pTempLeaderNode = NULL, *pTempTrailerNode = NULL;
+        if (pThis->m_pPageMgr && !pProcessor->m_bUseInheriated &&
+            eRetValue != XFA_ItemLayoutProcessorResult_PageFullBreak) {
+          pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode,
+                                             pTempTrailerNode, FALSE, TRUE);
+        }
+        if (pTrailerLayoutItem && bIsAddTrailerHeight) {
+          XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(
+              pProcessor, fSplitPos, pTrailerLayoutItem, bUseInherited);
+        } else {
+          pProcessor->SplitLayoutItem(fSplitPos);
+        }
+        if (bUseInherited) {
+          pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
+                                           pOverflowTrailerNode,
+                                           pTrailerLayoutItem, pFormNode);
+          pThis->m_bUseInheriated = TRUE;
+        } else {
+          if (pProcessor->m_pLayoutItem->m_pFirstChild &&
+              pProcessor->m_pLayoutItem->m_pFirstChild->m_pNextSibling ==
+                  NULL &&
+              pProcessor->m_pLayoutItem->m_pFirstChild->m_pFormNode->HasFlag(
+                  XFA_NODEFLAG_LayoutGeneratedNode)) {
+            pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
+                                             pOverflowTrailerNode,
+                                             pTrailerLayoutItem, pFormNode);
+          } else {
+            if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {
+              XFA_ItemLayoutProcessor_AddPendingNode(
+                  pProcessor, pOverflowLeaderNode, FALSE);
+            }
+          }
+        }
+        if (pProcessor->m_pLayoutItem->m_pNextSibling) {
+          pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);
+          rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());
+          bAddedItemInRow = TRUE;
+          if (bTakeSpace) {
+            fContentCurRowAvailWidth -= fChildWidth;
+            if (fContentCurRowHeight < fChildHeight) {
+              fContentCurRowHeight = fChildHeight;
+            }
+          }
+        }
+        return XFA_ItemLayoutProcessorResult_PageFullBreak;
+      } else if (fContentCurRowY <= XFA_LAYOUT_FLOAT_PERCISION) {
+        pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);
+        if (pProcessor->m_pPageMgr->GetNextAvailContentHeight(fChildHeight)) {
+          CXFA_Node *pTempLeaderNode = NULL, *pTempTrailerNode = NULL;
+          if (pThis->m_pPageMgr) {
+            if (pFormNode == NULL && pLayoutContext) {
+              pFormNode = pLayoutContext->m_pOverflowProcessor->m_pFormNode;
+            }
+            pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode,
+                                               pTempTrailerNode, FALSE, TRUE);
+          }
+          if (bUseInherited) {
+            pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
+                                             pOverflowTrailerNode,
+                                             pTrailerLayoutItem, pFormNode);
+            pThis->m_bUseInheriated = TRUE;
+          }
+          return XFA_ItemLayoutProcessorResult_PageFullBreak;
+        }
+        rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());
+        bAddedItemInRow = TRUE;
+        if (bTakeSpace) {
+          fContentCurRowAvailWidth -= fChildWidth;
+          if (fContentCurRowHeight < fChildHeight) {
+            fContentCurRowHeight = fChildHeight;
+          }
+        }
+        if (eRetValue == XFA_ItemLayoutProcessorResult_Done) {
+          bForceEndPage = FALSE;
+        }
+        return eRetValue;
+      } else {
+        XFA_ATTRIBUTEENUM eLayout =
+            pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
+        if (pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None &&
+            eLayout == XFA_ATTRIBUTEENUM_Tb) {
+          if (pThis->m_pPageMgr) {
+            pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode,
+                                               pOverflowTrailerNode, FALSE,
+                                               TRUE);
+          }
+          if (pTrailerLayoutItem) {
+            XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(pProcessor, fSplitPos,
+                                                          pTrailerLayoutItem);
+          }
+          if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {
+            XFA_ItemLayoutProcessor_AddPendingNode(pProcessor,
+                                                   pOverflowLeaderNode, FALSE);
+          }
+        } else {
+          if (eRetValue == XFA_ItemLayoutProcessorResult_Done) {
+            if (pFormNode == NULL && pLayoutContext) {
+              pFormNode = pLayoutContext->m_pOverflowProcessor->m_pFormNode;
+            }
+            if (pThis->m_pPageMgr) {
+              pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode,
+                                                 pOverflowTrailerNode, FALSE,
+                                                 TRUE);
+            }
+            if (bUseInherited) {
+              pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode,
+                                               pOverflowTrailerNode,
+                                               pTrailerLayoutItem, pFormNode);
+              pThis->m_bUseInheriated = TRUE;
+            }
+          }
+        }
+        return XFA_ItemLayoutProcessorResult_PageFullBreak;
+      }
+    }
+  } else {
+    return XFA_ItemLayoutProcessorResult_RowFullBreak;
+  }
+  return XFA_ItemLayoutProcessorResult_Done;
+}
+XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayoutFlowedContainer(
+    FX_BOOL bUseBreakControl,
+    XFA_ATTRIBUTEENUM eFlowStrategy,
+    FX_FLOAT fHeightLimit,
+    FX_FLOAT fRealHeight,
+    CXFA_LayoutContext* pContext,
+    FX_BOOL bRootForceTb) {
+  m_bHasAvailHeight = TRUE;
+  FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;
+  FX_BOOL bBreakDone = FALSE;
+  FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;
+  FX_BOOL bForceEndPage = FALSE;
+  FX_BOOL bIsManualBreak = FALSE;
+  if (m_pCurChildPreprocessor) {
+    m_pCurChildPreprocessor->m_ePreProcessRs =
+        XFA_ItemLayoutProcessorResult_Done;
+  }
+  XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(
+      m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize,
+      bContainerHeightAutoSize);
+  if (pContext && pContext->m_bCurColumnWidthAvaiable) {
+    bContainerWidthAutoSize = FALSE;
+    fContainerWidth = pContext->m_fCurColumnWidth;
+  }
+  if (!bContainerHeightAutoSize) {
+    fContainerHeight -= m_fUsedSize;
+  }
+  if (!bContainerHeightAutoSize) {
+    CXFA_Node* pParentNode = m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent);
+    FX_BOOL bFocrTb = FALSE;
+    if (pParentNode &&
+        XFA_ItemLayoutProcessor_GetLayout(pParentNode, bFocrTb) ==
+            XFA_ATTRIBUTEENUM_Row) {
+      CXFA_Node* pChildContainer = m_pFormNode->GetNodeItem(
+          XFA_NODEITEM_FirstChild, XFA_OBJECTTYPE_ContainerNode);
+      if (pChildContainer &&
+          pChildContainer->GetNodeItem(XFA_NODEITEM_NextSibling,
+                                       XFA_OBJECTTYPE_ContainerNode)) {
+        fContainerHeight = 0;
+        bContainerHeightAutoSize = TRUE;
+      }
+    }
+  }
+  CXFA_Node* pMarginNode =
+      m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
+  FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;
+  if (pMarginNode) {
+    fLeftInset =
+        pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
+    fTopInset =
+        pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
+    fRightInset =
+        pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
+    fBottomInset =
+        pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
+  }
+  FX_FLOAT fContentWidthLimit =
+      bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX
+                              : fContainerWidth - fLeftInset - fRightInset;
+  FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;
+  FX_FLOAT fAvailHeight = fHeightLimit - fTopInset - fBottomInset;
+  if (fAvailHeight < 0) {
+    m_bHasAvailHeight = FALSE;
+  }
+  fRealHeight = fRealHeight - fTopInset - fBottomInset;
+  FX_FLOAT fContentCurRowY = 0;
+  CXFA_ContentLayoutItem* pLayoutChild = NULL;
+  if (m_pLayoutItem) {
+    if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Done &&
+        eFlowStrategy != XFA_ATTRIBUTEENUM_Tb) {
+      pLayoutChild = (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild;
+      for (CXFA_ContentLayoutItem* pLayoutNext = pLayoutChild; pLayoutNext;
+           pLayoutNext = (CXFA_ContentLayoutItem*)pLayoutNext->m_pNextSibling) {
+        if (pLayoutNext->m_sPos.y != pLayoutChild->m_sPos.y) {
+          pLayoutChild = pLayoutNext;
+        }
+      }
+    }
+    for (CXFA_ContentLayoutItem* pLayoutTempChild =
+             (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild;
+         pLayoutTempChild != pLayoutChild;
+         pLayoutTempChild =
+             (CXFA_ContentLayoutItem*)pLayoutTempChild->m_pNextSibling) {
+      if (XFA_ItemLayoutProcessor_IsTakingSpace(
+              pLayoutTempChild->m_pFormNode)) {
+        FX_FLOAT fChildContentWidth =
+            pLayoutTempChild->m_sPos.x + pLayoutTempChild->m_sSize.x;
+        FX_FLOAT fChildContentHeight =
+            pLayoutTempChild->m_sPos.y + pLayoutTempChild->m_sSize.y;
+        if (fContentCalculatedWidth < fChildContentWidth) {
+          fContentCalculatedWidth = fChildContentWidth;
+        }
+        if (fContentCalculatedHeight < fChildContentHeight) {
+          fContentCalculatedHeight = fChildContentHeight;
+        }
+      }
+    }
+    if (pLayoutChild) {
+      fContentCurRowY = pLayoutChild->m_sPos.y;
+    } else {
+      fContentCurRowY = fContentCalculatedHeight;
+    }
+  }
+  fContentCurRowY += InsertKeepLayoutItems();
+  if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_None) {
+    XFA_ItemLayoutProcessor_GotoNextContainerNode(
+        m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);
+  }
+  fContentCurRowY +=
+      XFA_ItemLayoutProcessor_InsertPendingItems(this, m_pFormNode);
+  if (m_pCurChildPreprocessor &&
+      m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Container) {
+    if (XFA_ExistContainerKeep(m_pCurChildPreprocessor->GetFormNode(), FALSE)) {
+      m_pKeepHeadNode = m_pCurChildNode;
+      m_bIsProcessKeep = TRUE;
+      m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Keep;
+    }
+  }
+  while (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Done) {
+    FX_FLOAT fContentCurRowHeight = 0;
+    FX_FLOAT fContentCurRowAvailWidth = fContentWidthLimit;
+    m_fWidthLimite = fContentCurRowAvailWidth;
+    CFX_ArrayTemplate<CXFA_ContentLayoutItem*> rgCurLineLayoutItems[3];
+    uint8_t uCurHAlignState =
+        (eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb ? 0 : 2);
+    if (pLayoutChild) {
+      for (CXFA_ContentLayoutItem* pLayoutNext = pLayoutChild; pLayoutNext;
+           pLayoutNext = (CXFA_ContentLayoutItem*)pLayoutNext->m_pNextSibling) {
+        if (pLayoutNext->m_pNextSibling == NULL && m_pCurChildPreprocessor &&
+            m_pCurChildPreprocessor->m_pFormNode == pLayoutNext->m_pFormNode) {
+          pLayoutNext->m_pNext = m_pCurChildPreprocessor->m_pLayoutItem;
+          m_pCurChildPreprocessor->m_pLayoutItem = pLayoutNext;
+          break;
+        }
+        uint8_t uHAlign = XFA_ItemLayoutProcessor_HAlignEnumToInt(
+            pLayoutNext->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign));
+        rgCurLineLayoutItems[uHAlign].Add(pLayoutNext);
+        if (eFlowStrategy == XFA_ATTRIBUTEENUM_Lr_tb) {
+          if (uHAlign > uCurHAlignState) {
+            uCurHAlignState = uHAlign;
+          }
+        } else if (uHAlign < uCurHAlignState) {
+          uCurHAlignState = uHAlign;
+        }
+        if (XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutNext->m_pFormNode)) {
+          if (pLayoutNext->m_sSize.y > fContentCurRowHeight) {
+            fContentCurRowHeight = pLayoutNext->m_sSize.y;
+          }
+          fContentCurRowAvailWidth -= pLayoutNext->m_sSize.x;
+        }
+      }
+      if ((CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild ==
+          pLayoutChild) {
+        m_pLayoutItem->m_pFirstChild = NULL;
+      } else {
+        CXFA_ContentLayoutItem* pLayoutNext =
+            (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild;
+        for (; pLayoutNext;
+             pLayoutNext =
+                 (CXFA_ContentLayoutItem*)pLayoutNext->m_pNextSibling) {
+          if ((CXFA_ContentLayoutItem*)pLayoutNext->m_pNextSibling ==
+              pLayoutChild) {
+            pLayoutNext->m_pNextSibling = NULL;
+            break;
+          }
+        }
+      }
+      CXFA_ContentLayoutItem* pLayoutNextTemp =
+          (CXFA_ContentLayoutItem*)pLayoutChild;
+      while (pLayoutNextTemp) {
+        pLayoutNextTemp->m_pParent = NULL;
+        CXFA_ContentLayoutItem* pSaveLayoutNext =
+            (CXFA_ContentLayoutItem*)pLayoutNextTemp->m_pNextSibling;
+        pLayoutNextTemp->m_pNextSibling = NULL;
+        pLayoutNextTemp = pSaveLayoutNext;
+      }
+      pLayoutChild = NULL;
+    }
+    while (m_pCurChildNode) {
+      CXFA_ItemLayoutProcessor* pProcessor = NULL;
+      FX_BOOL bAddedItemInRow = FALSE;
+      fContentCurRowY +=
+          XFA_ItemLayoutProcessor_InsertPendingItems(this, m_pFormNode);
+      switch (m_nCurChildNodeStage) {
+        case XFA_ItemLayoutProcessorStages_Keep:
+        case XFA_ItemLayoutProcessorStages_None:
+          break;
+        case XFA_ItemLayoutProcessorStages_BreakBefore: {
+          for (int32_t iIndex = 0; iIndex < m_arrayKeepItems.GetSize();
+               iIndex++) {
+            CXFA_ContentLayoutItem* pItem = m_arrayKeepItems.GetAt(iIndex);
+            m_pLayoutItem->RemoveChild(pItem);
+            fContentCalculatedHeight -= pItem->m_sSize.y;
+          }
+          CXFA_Node *pLeaderNode = NULL, *pTrailerNode = NULL;
+          FX_BOOL bCreatePage = FALSE;
+          if (bUseBreakControl && m_pPageMgr &&
+              m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, TRUE,
+                                                    pLeaderNode, pTrailerNode,
+                                                    bCreatePage) &&
+              m_pFormNode->GetClassID() != XFA_ELEMENT_Form && bCreatePage) {
+            if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) {
+              XFA_ItemLayoutProcessor_AddPendingNode(this, pLeaderNode, TRUE);
+            }
+            if (JudgeLeaderOrTrailerForOccur(pTrailerNode)) {
+              if (m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent)->GetClassID() ==
+                      XFA_ELEMENT_Form &&
+                  m_pLayoutItem == NULL) {
+                XFA_ItemLayoutProcessor_AddPendingNode(this, pTrailerNode,
+                                                       TRUE);
+              } else {
+                CXFA_ItemLayoutProcessor* pProcessor =
+                    new CXFA_ItemLayoutProcessor(pTrailerNode, NULL);
+                XFA_ItemLayoutProcessor_InsertFlowedItem(
+                    this, pProcessor, bContainerWidthAutoSize,
+                    bContainerHeightAutoSize, fContainerHeight, eFlowStrategy,
+                    uCurHAlignState, rgCurLineLayoutItems, FALSE,
+                    XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY,
+                    fContentWidthLimit, fContentCurRowAvailWidth,
+                    fContentCurRowHeight, bAddedItemInRow, bForceEndPage,
+                    pContext);
+                delete pProcessor;
+                pProcessor = NULL;
+              }
+            }
+            XFA_ItemLayoutProcessor_GotoNextContainerNode(
+                m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);
+            bForceEndPage = TRUE;
+            bIsManualBreak = TRUE;
+            goto SuspendAndCreateNewRow;
+          }
+        } break;
+        case XFA_ItemLayoutProcessorStages_BreakAfter: {
+          CXFA_Node *pLeaderNode = NULL, *pTrailerNode = NULL;
+          FX_BOOL bCreatePage = FALSE;
+          if (bUseBreakControl && m_pPageMgr &&
+              m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, FALSE,
+                                                    pLeaderNode, pTrailerNode,
+                                                    bCreatePage) &&
+              m_pFormNode->GetClassID() != XFA_ELEMENT_Form) {
+            if (JudgeLeaderOrTrailerForOccur(pTrailerNode)) {
+              CXFA_ItemLayoutProcessor* pProcessor =
+                  new CXFA_ItemLayoutProcessor(pTrailerNode, NULL);
+              XFA_ItemLayoutProcessor_InsertFlowedItem(
+                  this, pProcessor, bContainerWidthAutoSize,
+                  bContainerHeightAutoSize, fContainerHeight, eFlowStrategy,
+                  uCurHAlignState, rgCurLineLayoutItems, FALSE,
+                  XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY,
+                  fContentWidthLimit, fContentCurRowAvailWidth,
+                  fContentCurRowHeight, bAddedItemInRow, bForceEndPage,
+                  pContext);
+              delete pProcessor;
+              pProcessor = NULL;
+            }
+            if (!bCreatePage) {
+              if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) {
+                CalculateRowChildPosition(
+                    rgCurLineLayoutItems, eFlowStrategy,
+                    bContainerHeightAutoSize, bContainerWidthAutoSize,
+                    fContentCalculatedWidth, fContentCalculatedHeight,
+                    fContentCurRowY, fContentCurRowHeight, fContentWidthLimit);
+                rgCurLineLayoutItems->RemoveAll();
+                CXFA_ItemLayoutProcessor* pProcessor =
+                    new CXFA_ItemLayoutProcessor(pLeaderNode, NULL);
+                XFA_ItemLayoutProcessor_InsertFlowedItem(
+                    this, pProcessor, bContainerWidthAutoSize,
+                    bContainerHeightAutoSize, fContainerHeight, eFlowStrategy,
+                    uCurHAlignState, rgCurLineLayoutItems, FALSE,
+                    XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY,
+                    fContentWidthLimit, fContentCurRowAvailWidth,
+                    fContentCurRowHeight, bAddedItemInRow, bForceEndPage,
+                    pContext);
+                delete pProcessor;
+                pProcessor = NULL;
+              }
+            } else {
+              if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) {
+                XFA_ItemLayoutProcessor_AddPendingNode(this, pLeaderNode, TRUE);
+              }
+            }
+            XFA_ItemLayoutProcessor_GotoNextContainerNode(
+                m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);
+            if (bCreatePage) {
+              bForceEndPage = TRUE;
+              bIsManualBreak = TRUE;
+              if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done) {
+                bBreakDone = TRUE;
+              }
+            }
+            goto SuspendAndCreateNewRow;
+          }
+        } break;
+        case XFA_ItemLayoutProcessorStages_BookendLeader: {
+          CXFA_Node* pLeaderNode = NULL;
+          if (m_pCurChildPreprocessor) {
+            pProcessor = m_pCurChildPreprocessor;
+            m_pCurChildPreprocessor = NULL;
+          } else if (m_pPageMgr &&
+                     m_pPageMgr->ProcessBookendLeaderOrTrailer(
+                         m_pCurChildNode, TRUE, pLeaderNode)) {
+            pProcessor = new CXFA_ItemLayoutProcessor(pLeaderNode, m_pPageMgr);
+          }
+          if (pProcessor) {
+            if (XFA_ItemLayoutProcessor_InsertFlowedItem(
+                    this, pProcessor, bContainerWidthAutoSize,
+                    bContainerHeightAutoSize, fContainerHeight, eFlowStrategy,
+                    uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl,
+                    fAvailHeight, fRealHeight, fContentCurRowY,
+                    fContentWidthLimit, fContentCurRowAvailWidth,
+                    fContentCurRowHeight, bAddedItemInRow, bForceEndPage,
+                    pContext) != XFA_ItemLayoutProcessorResult_Done) {
+              goto SuspendAndCreateNewRow;
+            } else {
+              delete pProcessor;
+              pProcessor = NULL;
+            }
+          }
+        } break;
+        case XFA_ItemLayoutProcessorStages_BookendTrailer: {
+          CXFA_Node* pTrailerNode = NULL;
+          if (m_pCurChildPreprocessor) {
+            pProcessor = m_pCurChildPreprocessor;
+            m_pCurChildPreprocessor = NULL;
+          } else if (m_pPageMgr &&
+                     m_pPageMgr->ProcessBookendLeaderOrTrailer(
+                         m_pCurChildNode, FALSE, pTrailerNode)) {
+            pProcessor = new CXFA_ItemLayoutProcessor(pTrailerNode, m_pPageMgr);
+          }
+          if (pProcessor) {
+            if (XFA_ItemLayoutProcessor_InsertFlowedItem(
+                    this, pProcessor, bContainerWidthAutoSize,
+                    bContainerHeightAutoSize, fContainerHeight, eFlowStrategy,
+                    uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl,
+                    fAvailHeight, fRealHeight, fContentCurRowY,
+                    fContentWidthLimit, fContentCurRowAvailWidth,
+                    fContentCurRowHeight, bAddedItemInRow, bForceEndPage,
+                    pContext) != XFA_ItemLayoutProcessorResult_Done) {
+              goto SuspendAndCreateNewRow;
+            } else {
+              delete pProcessor;
+              pProcessor = NULL;
+            }
+          }
+        } break;
+        case XFA_ItemLayoutProcessorStages_Container:
+          ASSERT(m_pCurChildNode->IsContainerNode());
+          if (m_pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) {
+            break;
+          }
+          if (fContentCurRowY >= fHeightLimit + XFA_LAYOUT_FLOAT_PERCISION &&
+              XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode)) {
+            bForceEndPage = TRUE;
+            goto SuspendAndCreateNewRow;
+          }
+          if (m_pCurChildNode->IsContainerNode()) {
+            FX_BOOL bNewRow = FALSE;
+            if (m_pCurChildPreprocessor) {
+              pProcessor = m_pCurChildPreprocessor;
+              m_pCurChildPreprocessor = NULL;
+              bNewRow = TRUE;
+            } else {
+              pProcessor =
+                  new CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr);
+            }
+            XFA_ItemLayoutProcessor_InsertPendingItems(pProcessor,
+                                                       m_pCurChildNode);
+            XFA_ItemLayoutProcessorResult rs =
+                XFA_ItemLayoutProcessor_InsertFlowedItem(
+                    this, pProcessor, bContainerWidthAutoSize,
+                    bContainerHeightAutoSize, fContainerHeight, eFlowStrategy,
+                    uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl,
+                    fAvailHeight, fRealHeight, fContentCurRowY,
+                    fContentWidthLimit, fContentCurRowAvailWidth,
+                    fContentCurRowHeight, bAddedItemInRow, bForceEndPage,
+                    pContext, bNewRow);
+            switch (rs) {
+              case XFA_ItemLayoutProcessorResult_ManualBreak:
+                bIsManualBreak = TRUE;
+              case XFA_ItemLayoutProcessorResult_PageFullBreak:
+                bForceEndPage = TRUE;
+              case XFA_ItemLayoutProcessorResult_RowFullBreak:
+                goto SuspendAndCreateNewRow;
+              case XFA_ItemLayoutProcessorResult_Done:
+              default:
+                fContentCurRowY += XFA_ItemLayoutProcessor_InsertPendingItems(
+                    pProcessor, m_pCurChildNode);
+                delete pProcessor;
+                pProcessor = NULL;
+            }
+          }
+          break;
+        case XFA_ItemLayoutProcessorStages_Done:
+          break;
+        default:
+          break;
+      }
+      XFA_ItemLayoutProcessor_GotoNextContainerNode(
+          m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);
+      if (bAddedItemInRow && eFlowStrategy == XFA_ATTRIBUTEENUM_Tb) {
+        break;
+      } else {
+        continue;
+      }
+    SuspendAndCreateNewRow:
+      if (pProcessor) {
+        m_pCurChildPreprocessor = pProcessor;
+      }
+      break;
+    }
+    CalculateRowChildPosition(rgCurLineLayoutItems, eFlowStrategy,
+                              bContainerHeightAutoSize, bContainerWidthAutoSize,
+                              fContentCalculatedWidth, fContentCalculatedHeight,
+                              fContentCurRowY, fContentCurRowHeight,
+                              fContentWidthLimit, bRootForceTb);
+    m_fWidthLimite = fContentCurRowAvailWidth;
+    if (bForceEndPage) {
+      break;
+    }
+  }
+  FX_BOOL bRetValue =
+      m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done &&
+      m_PendingNodes.empty();
+  if (bBreakDone) {
+    bRetValue = FALSE;
+  }
+  XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(
+      m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth,
+      fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight,
+      fContainerHeight);
+  if (fContainerHeight >= XFA_LAYOUT_FLOAT_PERCISION || m_pLayoutItem ||
+      bRetValue) {
+    if (m_pLayoutItem == NULL) {
+      m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
+    }
+    if (fContainerHeight < 0) {
+      fContainerHeight = 0;
+    }
+    SetCurrentComponentSize(fContainerWidth, fContainerHeight);
+    if (bForceEndPage) {
+      m_fUsedSize = 0;
+    } else {
+      m_fUsedSize += m_pLayoutItem->m_sSize.y;
+    }
+  }
+  return bRetValue
+             ? XFA_ItemLayoutProcessorResult_Done
+             : (bIsManualBreak ? XFA_ItemLayoutProcessorResult_ManualBreak
+                               : XFA_ItemLayoutProcessorResult_PageFullBreak);
+}
+FX_BOOL CXFA_ItemLayoutProcessor::CalculateRowChildPosition(
+    CFX_ArrayTemplate<CXFA_ContentLayoutItem*>(&rgCurLineLayoutItems)[3],
+    XFA_ATTRIBUTEENUM eFlowStrategy,
+    FX_BOOL bContainerHeightAutoSize,
+    FX_BOOL bContainerWidthAutoSize,
+    FX_FLOAT& fContentCalculatedWidth,
+    FX_FLOAT& fContentCalculatedHeight,
+    FX_FLOAT& fContentCurRowY,
+    FX_FLOAT fContentCurRowHeight,
+    FX_FLOAT fContentWidthLimit,
+    FX_BOOL bRootForceTb) {
+  int32_t nGroupLengths[3] = {0, 0, 0};
+  FX_FLOAT fGroupWidths[3] = {0, 0, 0};
+  int32_t nTotalLength = 0;
+  for (int32_t i = 0; i < 3; i++) {
+    nGroupLengths[i] = rgCurLineLayoutItems[i].GetSize();
+    for (int32_t c = nGroupLengths[i], j = 0; j < c; j++) {
+      nTotalLength++;
+      if (XFA_ItemLayoutProcessor_IsTakingSpace(
+              rgCurLineLayoutItems[i][j]->m_pFormNode)) {
+        fGroupWidths[i] += rgCurLineLayoutItems[i][j]->m_sSize.x;
+      }
+    }
+  }
+  if (!nTotalLength) {
+    if (bContainerHeightAutoSize) {
+      FX_FLOAT fNewHeight = fContentCurRowY;
+      if (fContentCalculatedHeight > fNewHeight) {
+        fContentCalculatedHeight = fNewHeight;
+      }
+    }
+    return FALSE;
+  }
+  if (m_pLayoutItem == NULL) {
+    m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
+  }
+  if (eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb) {
+    FX_FLOAT fCurPos;
+    fCurPos = 0;
+    for (int32_t c = nGroupLengths[0], j = 0; j < c; j++) {
+      if (bRootForceTb) {
+        FX_FLOAT fAbsoluteX, fAbsoluteY;
+        CalculatePositionedContainerPos(rgCurLineLayoutItems[0][j]->m_pFormNode,
+                                        rgCurLineLayoutItems[0][j]->m_sSize.x,
+                                        rgCurLineLayoutItems[0][j]->m_sSize.y,
+                                        fAbsoluteX, fAbsoluteY);
+        rgCurLineLayoutItems[0][j]->m_sPos = CFX_PointF(fAbsoluteX, fAbsoluteY);
+      } else {
+        rgCurLineLayoutItems[0][j]->m_sPos =
+            CFX_PointF(fCurPos, fContentCurRowY);
+        if (XFA_ItemLayoutProcessor_IsTakingSpace(
+                rgCurLineLayoutItems[0][j]->m_pFormNode)) {
+          fCurPos += rgCurLineLayoutItems[0][j]->m_sSize.x;
+        }
+      }
+      m_pLayoutItem->AddChild(rgCurLineLayoutItems[0][j]);
+      m_fLastRowWidth = fCurPos;
+    }
+    fCurPos = (fContentWidthLimit + fGroupWidths[0] - fGroupWidths[1] -
+               fGroupWidths[2]) /
+              2;
+    for (int32_t c = nGroupLengths[1], j = 0; j < c; j++) {
+      if (bRootForceTb) {
+        FX_FLOAT fAbsoluteX, fAbsoluteY;
+        CalculatePositionedContainerPos(rgCurLineLayoutItems[1][j]->m_pFormNode,
+                                        rgCurLineLayoutItems[1][j]->m_sSize.x,
+                                        rgCurLineLayoutItems[1][j]->m_sSize.y,
+                                        fAbsoluteX, fAbsoluteY);
+        rgCurLineLayoutItems[1][j]->m_sPos = CFX_PointF(fAbsoluteX, fAbsoluteY);
+      } else {
+        rgCurLineLayoutItems[1][j]->m_sPos =
+            CFX_PointF(fCurPos, fContentCurRowY);
+        if (XFA_ItemLayoutProcessor_IsTakingSpace(
+                rgCurLineLayoutItems[1][j]->m_pFormNode)) {
+          fCurPos += rgCurLineLayoutItems[1][j]->m_sSize.x;
+        }
+      }
+      m_pLayoutItem->AddChild(rgCurLineLayoutItems[1][j]);
+      m_fLastRowWidth = fCurPos;
+    }
+    fCurPos = fContentWidthLimit - fGroupWidths[2];
+    for (int32_t c = nGroupLengths[2], j = 0; j < c; j++) {
+      if (bRootForceTb) {
+        FX_FLOAT fAbsoluteX, fAbsoluteY;
+        CalculatePositionedContainerPos(rgCurLineLayoutItems[2][j]->m_pFormNode,
+                                        rgCurLineLayoutItems[2][j]->m_sSize.x,
+                                        rgCurLineLayoutItems[2][j]->m_sSize.y,
+                                        fAbsoluteX, fAbsoluteY);
+        rgCurLineLayoutItems[2][j]->m_sPos = CFX_PointF(fAbsoluteX, fAbsoluteY);
+      } else {
+        rgCurLineLayoutItems[2][j]->m_sPos =
+            CFX_PointF(fCurPos, fContentCurRowY);
+        if (XFA_ItemLayoutProcessor_IsTakingSpace(
+                rgCurLineLayoutItems[2][j]->m_pFormNode)) {
+          fCurPos += rgCurLineLayoutItems[2][j]->m_sSize.x;
+        }
+      }
+      m_pLayoutItem->AddChild(rgCurLineLayoutItems[2][j]);
+      m_fLastRowWidth = fCurPos;
+    }
+  } else {
+    FX_FLOAT fCurPos;
+    fCurPos = fGroupWidths[0];
+    for (int32_t c = nGroupLengths[0], j = 0; j < c; j++) {
+      if (XFA_ItemLayoutProcessor_IsTakingSpace(
+              rgCurLineLayoutItems[0][j]->m_pFormNode)) {
+        fCurPos -= rgCurLineLayoutItems[0][j]->m_sSize.x;
+      }
+      rgCurLineLayoutItems[0][j]->m_sPos = CFX_PointF(fCurPos, fContentCurRowY);
+      m_pLayoutItem->AddChild(rgCurLineLayoutItems[0][j]);
+      m_fLastRowWidth = fCurPos;
+    }
+    fCurPos = (fContentWidthLimit + fGroupWidths[0] + fGroupWidths[1] -
+               fGroupWidths[2]) /
+              2;
+    for (int32_t c = nGroupLengths[1], j = 0; j < c; j++) {
+      if (XFA_ItemLayoutProcessor_IsTakingSpace(
+              rgCurLineLayoutItems[1][j]->m_pFormNode)) {
+        fCurPos -= rgCurLineLayoutItems[1][j]->m_sSize.x;
+      }
+      rgCurLineLayoutItems[1][j]->m_sPos = CFX_PointF(fCurPos, fContentCurRowY);
+      m_pLayoutItem->AddChild(rgCurLineLayoutItems[1][j]);
+      m_fLastRowWidth = fCurPos;
+    }
+    fCurPos = fContentWidthLimit;
+    for (int32_t c = nGroupLengths[2], j = 0; j < c; j++) {
+      if (XFA_ItemLayoutProcessor_IsTakingSpace(
+              rgCurLineLayoutItems[2][j]->m_pFormNode)) {
+        fCurPos -= rgCurLineLayoutItems[2][j]->m_sSize.x;
+      }
+      rgCurLineLayoutItems[2][j]->m_sPos = CFX_PointF(fCurPos, fContentCurRowY);
+      m_pLayoutItem->AddChild(rgCurLineLayoutItems[2][j]);
+      m_fLastRowWidth = fCurPos;
+    }
+  }
+  m_fLastRowY = fContentCurRowY;
+  fContentCurRowY += fContentCurRowHeight;
+  if (bContainerWidthAutoSize) {
+    FX_FLOAT fChildSuppliedWidth = fGroupWidths[0];
+    if (fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX &&
+        fContentWidthLimit > fChildSuppliedWidth) {
+      fChildSuppliedWidth = fContentWidthLimit;
+    }
+    if (fContentCalculatedWidth < fChildSuppliedWidth) {
+      fContentCalculatedWidth = fChildSuppliedWidth;
+    }
+  }
+  if (bContainerHeightAutoSize) {
+    FX_FLOAT fChildSuppliedHeight = fContentCurRowY;
+    if (fContentCalculatedHeight < fChildSuppliedHeight) {
+      fContentCalculatedHeight = fChildSuppliedHeight;
+    }
+  }
+  return TRUE;
+}
+CXFA_Node* CXFA_ItemLayoutProcessor::GetSubformSetParent(
+    CXFA_Node* pSubformSet) {
+  if (pSubformSet && pSubformSet->GetClassID() == XFA_ELEMENT_SubformSet) {
+    CXFA_Node* pParent = pSubformSet->GetNodeItem(XFA_NODEITEM_Parent);
+    while (pParent) {
+      if (pParent->GetClassID() != XFA_ELEMENT_SubformSet) {
+        return pParent;
+      }
+      pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent);
+    }
+  }
+  return pSubformSet;
+}
+void CXFA_ItemLayoutProcessor::DoLayoutField() {
+  if (m_pLayoutItem)
+    return;
+
+  ASSERT(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE);
+  m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
+  if (!m_pLayoutItem) {
+    return;
+  }
+  CXFA_Document* pDocument = m_pFormNode->GetDocument();
+  IXFA_Notify* pNotify = pDocument->GetParser()->GetNotify();
+  FX_FLOAT fHeight = -1;
+  FX_FLOAT fWidth = -1;
+  pNotify->StartFieldDrawLayout(m_pFormNode, fWidth, fHeight);
+  int32_t nRotate =
+      FXSYS_round(m_pFormNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue());
+  nRotate = XFA_MapRotation(nRotate);
+  if (nRotate == 90 || nRotate == 270) {
+    FX_FLOAT fTmp = fWidth;
+    fWidth = fHeight;
+    fHeight = fTmp;
+  }
+  SetCurrentComponentSize(fWidth, fHeight);
+}
+XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayout(
+    FX_BOOL bUseBreakControl,
+    FX_FLOAT fHeightLimit,
+    FX_FLOAT fRealHeight,
+    CXFA_LayoutContext* pContext) {
+  XFA_ELEMENT eClassID = m_pFormNode->GetClassID();
+  switch (eClassID) {
+    case XFA_ELEMENT_Subform:
+    case XFA_ELEMENT_Area:
+    case XFA_ELEMENT_ExclGroup:
+    case XFA_ELEMENT_SubformSet: {
+      FX_BOOL bRootForceTb = FALSE;
+      CXFA_Node* pLayoutNode = GetSubformSetParent(m_pFormNode);
+      XFA_ATTRIBUTEENUM eLayoutStrategy =
+          XFA_ItemLayoutProcessor_GetLayout(pLayoutNode, bRootForceTb);
+      switch (eLayoutStrategy) {
+        case XFA_ATTRIBUTEENUM_Tb:
+        case XFA_ATTRIBUTEENUM_Lr_tb:
+        case XFA_ATTRIBUTEENUM_Rl_tb:
+          return DoLayoutFlowedContainer(bUseBreakControl, eLayoutStrategy,
+                                         fHeightLimit, fRealHeight, pContext,
+                                         bRootForceTb);
+        case XFA_ATTRIBUTEENUM_Position:
+        case XFA_ATTRIBUTEENUM_Row:
+        case XFA_ATTRIBUTEENUM_Rl_row:
+        default:
+          DoLayoutPositionedContainer(pContext);
+          m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done;
+          return XFA_ItemLayoutProcessorResult_Done;
+        case XFA_ATTRIBUTEENUM_Table:
+          DoLayoutTableContainer(pLayoutNode);
+          m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done;
+          return XFA_ItemLayoutProcessorResult_Done;
+      }
+    }
+    case XFA_ELEMENT_Draw:
+    case XFA_ELEMENT_Field:
+      DoLayoutField();
+      m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done;
+      return XFA_ItemLayoutProcessorResult_Done;
+    case XFA_ELEMENT_ContentArea:
+      return XFA_ItemLayoutProcessorResult_Done;
+    default:
+      return XFA_ItemLayoutProcessorResult_Done;
+  }
+}
+void CXFA_ItemLayoutProcessor::GetCurrentComponentPos(FX_FLOAT& fAbsoluteX,
+                                                      FX_FLOAT& fAbsoluteY) {
+  ASSERT(m_pLayoutItem);
+  fAbsoluteX = m_pLayoutItem->m_sPos.x;
+  fAbsoluteY = m_pLayoutItem->m_sPos.y;
+}
+void CXFA_ItemLayoutProcessor::GetCurrentComponentSize(FX_FLOAT& fWidth,
+                                                       FX_FLOAT& fHeight) {
+  ASSERT(m_pLayoutItem);
+  fWidth = m_pLayoutItem->m_sSize.x;
+  fHeight = m_pLayoutItem->m_sSize.y;
+}
+void CXFA_ItemLayoutProcessor::SetCurrentComponentPos(FX_FLOAT fAbsoluteX,
+                                                      FX_FLOAT fAbsoluteY) {
+  m_pLayoutItem->m_sPos = CFX_PointF(fAbsoluteX, fAbsoluteY);
+}
+void CXFA_ItemLayoutProcessor::SetCurrentComponentSize(FX_FLOAT fWidth,
+                                                       FX_FLOAT fHeight) {
+  m_pLayoutItem->m_sSize = CFX_SizeF(fWidth, fHeight);
+}
+FX_BOOL CXFA_ItemLayoutProcessor::JudgeLeaderOrTrailerForOccur(
+    CXFA_Node* pFormNode) {
+  if (pFormNode == NULL) {
+    return FALSE;
+  }
+  CXFA_Node* pTemplate = pFormNode->GetTemplateNode();
+  if (!pTemplate) {
+    pTemplate = pFormNode;
+  }
+  CXFA_Occur NodeOccur(pTemplate->GetFirstChildByClass(XFA_ELEMENT_Occur));
+  int32_t iMax = NodeOccur.GetMax();
+  if (iMax > -1) {
+    int32_t iCount =
+        (int32_t)(uintptr_t)m_PendingNodesCount.GetValueAt(pTemplate);
+    if (iCount >= iMax) {
+      return FALSE;
+    }
+    iCount++;
+    m_PendingNodesCount.SetAt(pTemplate, (void*)(uintptr_t)(iCount));
+    return TRUE;
+  }
+  return TRUE;
+}
diff --git a/xfa/fxfa/parser/xfa_layout_itemlayout.h b/xfa/fxfa/parser/xfa_layout_itemlayout.h
new file mode 100644
index 0000000..362e1c1
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_layout_itemlayout.h
@@ -0,0 +1,195 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_LAYOUT_ITEMLAYOUT_H_
+#define XFA_FXFA_PARSER_XFA_LAYOUT_ITEMLAYOUT_H_
+
+#include <float.h>
+
+#include <list>
+
+#include "core/include/fxcrt/fx_basic.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document_layout_imp.h"
+
+#define XFA_LAYOUT_INVALIDNODE ((CXFA_Node*)(intptr_t)-1)
+#define XFA_LAYOUT_FLOAT_PERCISION (0.0005f)
+#define XFA_LAYOUT_FLOAT_MAX FLT_MAX
+
+class CXFA_ContainerLayoutItem;
+class CXFA_ContentLayoutItem;
+class CXFA_ItemLayoutProcessor;
+class CXFA_LayoutPageMgr;
+class CXFA_Node;
+
+enum XFA_ItemLayoutProcessorResult {
+  XFA_ItemLayoutProcessorResult_Done,
+  XFA_ItemLayoutProcessorResult_PageFullBreak,
+  XFA_ItemLayoutProcessorResult_RowFullBreak,
+  XFA_ItemLayoutProcessorResult_ManualBreak,
+};
+
+enum XFA_ItemLayoutProcessorStages {
+  XFA_ItemLayoutProcessorStages_None,
+  XFA_ItemLayoutProcessorStages_BookendLeader,
+  XFA_ItemLayoutProcessorStages_BreakBefore,
+  XFA_ItemLayoutProcessorStages_Keep,
+  XFA_ItemLayoutProcessorStages_Container,
+  XFA_ItemLayoutProcessorStages_BreakAfter,
+  XFA_ItemLayoutProcessorStages_BookendTrailer,
+  XFA_ItemLayoutProcessorStages_Done,
+};
+
+class CXFA_LayoutContext {
+ public:
+  CXFA_LayoutContext()
+      : m_prgSpecifiedColumnWidths(NULL),
+        m_fCurColumnWidth(0),
+        m_bCurColumnWidthAvaiable(FALSE),
+        m_pOverflowProcessor(NULL),
+        m_pOverflowNode(NULL) {}
+  ~CXFA_LayoutContext() { m_pOverflowProcessor = NULL; }
+  CFX_ArrayTemplate<FX_FLOAT>* m_prgSpecifiedColumnWidths;
+  FX_FLOAT m_fCurColumnWidth;
+  FX_BOOL m_bCurColumnWidthAvaiable;
+  CXFA_ItemLayoutProcessor* m_pOverflowProcessor;
+  CXFA_Node* m_pOverflowNode;
+};
+
+class CXFA_ItemLayoutProcessor {
+ public:
+  CXFA_ItemLayoutProcessor(CXFA_Node* pNode, CXFA_LayoutPageMgr* pPageMgr);
+
+  XFA_ItemLayoutProcessorResult DoLayout(
+      FX_BOOL bUseBreakControl,
+      FX_FLOAT fHeightLimit,
+      FX_FLOAT fRealHeight = XFA_LAYOUT_FLOAT_MAX,
+      CXFA_LayoutContext* pContext = NULL);
+
+  void GetCurrentComponentPos(FX_FLOAT& fAbsoluteX, FX_FLOAT& fAbsoluteY);
+
+  void GetCurrentComponentSize(FX_FLOAT& fWidth, FX_FLOAT& fHeight);
+
+  void SetCurrentComponentPos(FX_FLOAT fAbsoluteX, FX_FLOAT fAbsoluteY);
+
+  void SetCurrentComponentSize(FX_FLOAT fWidth, FX_FLOAT fHeight);
+  inline CXFA_Node* GetFormNode() { return m_pFormNode; }
+  inline FX_BOOL HasLayoutItem() { return m_pLayoutItem != NULL; }
+  CXFA_ContentLayoutItem* ExtractLayoutItem();
+
+  static FX_BOOL IncrementRelayoutNode(CXFA_LayoutProcessor* pLayoutProcessor,
+                                       CXFA_Node* pNode,
+                                       CXFA_Node* pParentNode);
+  static void CalculatePositionedContainerPos(CXFA_Node* pNode,
+                                              FX_FLOAT fWidth,
+                                              FX_FLOAT fHeight,
+                                              FX_FLOAT& fAbsoluteX,
+                                              FX_FLOAT& fAbsoluteY);
+  static FX_BOOL FindLayoutItemSplitPos(CXFA_ContentLayoutItem* pLayoutItem,
+                                        FX_FLOAT fCurVerticalOffset,
+                                        FX_FLOAT& fProposedSplitPos,
+                                        FX_BOOL& bAppChange,
+                                        FX_BOOL bCalculateMargin = TRUE);
+  FX_FLOAT FindSplitPos(FX_FLOAT fProposedSplitPos);
+  void SplitLayoutItem(CXFA_ContentLayoutItem* pLayoutItem,
+                       CXFA_ContentLayoutItem* pSecondParent,
+                       FX_FLOAT fSplitPos);
+  void SplitLayoutItem(FX_FLOAT fSplitPos);
+  FX_BOOL JudgePutNextPage(
+      CXFA_ContentLayoutItem* pParentLayoutItem,
+      FX_FLOAT fChildHeight,
+      CFX_ArrayTemplate<CXFA_ContentLayoutItem*>& pKeepItems);
+  FX_BOOL ProcessKeepForSplite(
+      CXFA_ItemLayoutProcessor* pParentProcessor,
+      CXFA_ItemLayoutProcessor* pChildProcessor,
+      XFA_ItemLayoutProcessorResult eRetValue,
+      CFX_ArrayTemplate<CXFA_ContentLayoutItem*>& rgCurLineLayoutItem,
+      FX_FLOAT& fContentCurRowAvailWidth,
+      FX_FLOAT& fContentCurRowHeight,
+      FX_FLOAT& fContentCurRowY,
+      FX_BOOL& bAddedItemInRow,
+      FX_BOOL& bForceEndPage,
+      XFA_ItemLayoutProcessorResult& result);
+  FX_FLOAT InsertKeepLayoutItems();
+  void DoLayoutPageArea(CXFA_ContainerLayoutItem* pPageAreaLayoutItem);
+  FX_BOOL CalculateRowChildPosition(
+      CFX_ArrayTemplate<CXFA_ContentLayoutItem*>(&rgCurLineLayoutItems)[3],
+      XFA_ATTRIBUTEENUM eFlowStrategy,
+      FX_BOOL bContainerHeightAutoSize,
+      FX_BOOL bContainerWidthAutoSize,
+      FX_FLOAT& fContentCalculatedWidth,
+      FX_FLOAT& fContentCalculatedHeight,
+      FX_FLOAT& fContentCurRowY,
+      FX_FLOAT fContentCurRowHeight,
+      FX_FLOAT fContentWidthLimit,
+      FX_BOOL bRootForceTb = FALSE);
+
+  void ProcessUnUseOverFlow(CXFA_Node* pLeaderNode,
+                            CXFA_Node* pTrailerNode,
+                            CXFA_ContentLayoutItem* pTrailerItem,
+                            CXFA_Node* pFormNode);
+  void ProcessUnUseBinds(CXFA_Node* pFormNode);
+  FX_BOOL IsAddNewRowForTrailer(CXFA_ContentLayoutItem* pTrailerItem);
+  FX_BOOL JudgeLeaderOrTrailerForOccur(CXFA_Node* pFormNode);
+  CXFA_ContentLayoutItem* CreateContentLayoutItem(CXFA_Node* pFormNode);
+
+ protected:
+  void DoLayoutPositionedContainer(CXFA_LayoutContext* pContext = NULL);
+  void DoLayoutTableContainer(CXFA_Node* pLayoutNode);
+  XFA_ItemLayoutProcessorResult DoLayoutFlowedContainer(
+      FX_BOOL bUseBreakControl,
+      XFA_ATTRIBUTEENUM eFlowStrategy,
+      FX_FLOAT fHeightLimit,
+      FX_FLOAT fRealHeight,
+      CXFA_LayoutContext* pContext = NULL,
+      FX_BOOL bRootForceTb = FALSE);
+  void DoLayoutField();
+  void XFA_ItemLayoutProcessor_GotoNextContainerNode(
+      CXFA_Node*& pCurActionNode,
+      XFA_ItemLayoutProcessorStages& nCurStage,
+      CXFA_Node* pParentContainer,
+      FX_BOOL bUsePageBreak);
+
+  FX_BOOL ProcessKeepNodesForCheckNext(CXFA_Node*& pCurActionNode,
+                                       XFA_ItemLayoutProcessorStages& nCurStage,
+                                       CXFA_Node*& pNextContainer,
+                                       FX_BOOL& bLastKeepNode);
+
+  FX_BOOL ProcessKeepNodesForBreakBefore(
+      CXFA_Node*& pCurActionNode,
+      XFA_ItemLayoutProcessorStages& nCurStage,
+      CXFA_Node* pContainerNode);
+
+  CXFA_Node* GetSubformSetParent(CXFA_Node* pSubformSet);
+
+ public:
+  FX_BOOL m_bKeepBreakFinish;
+  FX_BOOL m_bIsProcessKeep;
+  CXFA_Node* m_pKeepHeadNode;
+  CXFA_Node* m_pKeepTailNode;
+  CXFA_Node* m_pFormNode;
+  CXFA_ContentLayoutItem* m_pLayoutItem;
+  CXFA_ContentLayoutItem* m_pOldLayoutItem;
+  CXFA_Node* m_pCurChildNode;
+  CXFA_ItemLayoutProcessor* m_pCurChildPreprocessor;
+  XFA_ItemLayoutProcessorStages m_nCurChildNodeStage;
+  FX_FLOAT m_fUsedSize;
+  CXFA_LayoutPageMgr* m_pPageMgr;
+  std::list<CXFA_Node*> m_PendingNodes;
+  FX_BOOL m_bBreakPending;
+  CFX_ArrayTemplate<FX_FLOAT> m_rgSpecifiedColumnWidths;
+  CFX_ArrayTemplate<CXFA_ContentLayoutItem*> m_arrayKeepItems;
+  CFX_MapPtrToPtr m_PendingNodesCount;
+  FX_FLOAT m_fLastRowWidth;
+  FX_FLOAT m_fLastRowY;
+  FX_FLOAT m_fWidthLimite;
+  FX_BOOL m_bUseInheriated;
+  XFA_ItemLayoutProcessorResult m_ePreProcessRs;
+  FX_BOOL m_bHasAvailHeight;
+};
+FX_BOOL XFA_ItemLayoutProcessor_IsTakingSpace(CXFA_Node* pNode);
+
+#endif  // XFA_FXFA_PARSER_XFA_LAYOUT_ITEMLAYOUT_H_
diff --git a/xfa/fxfa/parser/xfa_layout_pagemgr_new.cpp b/xfa/fxfa/parser/xfa_layout_pagemgr_new.cpp
new file mode 100644
index 0000000..b46d882
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_layout_pagemgr_new.cpp
@@ -0,0 +1,1931 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_layout_pagemgr_new.h"
+
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_document_datamerger_imp.h"
+#include "xfa/fxfa/parser/xfa_document_layout_imp.h"
+#include "xfa/fxfa/parser/xfa_layout_appadapter.h"
+#include "xfa/fxfa/parser/xfa_layout_itemlayout.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+CXFA_LayoutPageMgr::CXFA_LayoutPageMgr(CXFA_LayoutProcessor* pLayoutProcessor)
+    : m_pLayoutProcessor(pLayoutProcessor),
+      m_pTemplatePageSetRoot(nullptr),
+      m_pPageSetLayoutItemRoot(nullptr),
+      m_pPageSetCurRoot(nullptr),
+      m_pCurrentContainerRecord(nullptr),
+      m_pCurPageArea(nullptr),
+      m_nAvailPages(0),
+      m_nCurPageCount(0),
+      m_ePageSetMode(XFA_ATTRIBUTEENUM_OrderedOccurrence),
+      m_bCreateOverFlowPage(FALSE) {}
+CXFA_LayoutPageMgr::~CXFA_LayoutPageMgr() {
+  ClearData();
+  CXFA_LayoutItem* pLayoutItem = GetRootLayoutItem();
+  CXFA_LayoutItem* pNextLayout = NULL;
+  for (; pLayoutItem; pLayoutItem = pNextLayout) {
+    pNextLayout = pLayoutItem->m_pNextSibling;
+    XFA_ReleaseLayoutItem(pLayoutItem);
+  }
+}
+FX_BOOL CXFA_LayoutPageMgr::InitLayoutPage(CXFA_Node* pFormNode) {
+  PrepareLayout();
+  CXFA_Node* pTemplateNode = pFormNode->GetTemplateNode();
+  if (!pTemplateNode) {
+    return FALSE;
+  }
+  m_pTemplatePageSetRoot = pTemplateNode->GetProperty(0, XFA_ELEMENT_PageSet);
+  ASSERT(m_pTemplatePageSetRoot);
+  if (m_pPageSetLayoutItemRoot) {
+    m_pPageSetLayoutItemRoot->m_pParent = NULL;
+    m_pPageSetLayoutItemRoot->m_pFirstChild = NULL;
+    m_pPageSetLayoutItemRoot->m_pNextSibling = NULL;
+    m_pPageSetLayoutItemRoot->m_pFormNode = m_pTemplatePageSetRoot;
+  } else {
+    m_pPageSetLayoutItemRoot =
+        new CXFA_ContainerLayoutItem(m_pTemplatePageSetRoot);
+  }
+  m_pPageSetCurRoot = m_pPageSetLayoutItemRoot;
+  m_pTemplatePageSetRoot->SetUserData(XFA_LAYOUTITEMKEY,
+                                      (void*)m_pPageSetLayoutItemRoot);
+  XFA_ATTRIBUTEENUM eRelation =
+      m_pTemplatePageSetRoot->GetEnum(XFA_ATTRIBUTE_Relation);
+  if (eRelation != XFA_ATTRIBUTEENUM_Unknown) {
+    m_ePageSetMode = eRelation;
+  }
+  InitPageSetMap();
+  CXFA_Node* pPageArea = NULL;
+  int32_t iCount = 0;
+  for (pPageArea = m_pTemplatePageSetRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
+       pPageArea;
+       pPageArea = pPageArea->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pPageArea->GetClassID() == XFA_ELEMENT_PageArea) {
+      iCount++;
+      if (pPageArea->GetFirstChildByClass(XFA_ELEMENT_ContentArea)) {
+        return TRUE;
+      }
+    }
+  }
+  if (iCount > 0) {
+    return FALSE;
+  }
+  CXFA_Document* pDocument = pTemplateNode->GetDocument();
+  IXFA_ObjFactory* pObjFactory = pDocument->GetParser()->GetFactory();
+  pPageArea = m_pTemplatePageSetRoot->GetChild(0, XFA_ELEMENT_PageArea);
+  if (!pPageArea) {
+    pPageArea = pObjFactory->CreateNode(m_pTemplatePageSetRoot->GetPacketID(),
+                                        XFA_ELEMENT_PageArea);
+    if (!pPageArea) {
+      return FALSE;
+    }
+    m_pTemplatePageSetRoot->InsertChild(pPageArea, NULL);
+    pPageArea->SetFlag(XFA_NODEFLAG_Initialized);
+  }
+  CXFA_Node* pContentArea = pPageArea->GetChild(0, XFA_ELEMENT_ContentArea);
+  if (!pContentArea) {
+    pContentArea = pObjFactory->CreateNode(pPageArea->GetPacketID(),
+                                           XFA_ELEMENT_ContentArea);
+    if (!pContentArea) {
+      return FALSE;
+    }
+    pPageArea->InsertChild(pContentArea, NULL);
+    pContentArea->SetFlag(XFA_NODEFLAG_Initialized);
+    pContentArea->SetMeasure(XFA_ATTRIBUTE_X,
+                             CXFA_Measurement(0.25f, XFA_UNIT_In));
+    pContentArea->SetMeasure(XFA_ATTRIBUTE_Y,
+                             CXFA_Measurement(0.25f, XFA_UNIT_In));
+    pContentArea->SetMeasure(XFA_ATTRIBUTE_W,
+                             CXFA_Measurement(8.0f, XFA_UNIT_In));
+    pContentArea->SetMeasure(XFA_ATTRIBUTE_H,
+                             CXFA_Measurement(10.5f, XFA_UNIT_In));
+  }
+  CXFA_Node* pMedium = pPageArea->GetChild(0, XFA_ELEMENT_Medium);
+  if (!pMedium) {
+    pMedium =
+        pObjFactory->CreateNode(pPageArea->GetPacketID(), XFA_ELEMENT_Medium);
+    if (!pContentArea) {
+      return FALSE;
+    }
+    pPageArea->InsertChild(pMedium, NULL);
+    pMedium->SetFlag(XFA_NODEFLAG_Initialized);
+    pMedium->SetMeasure(XFA_ATTRIBUTE_Short,
+                        CXFA_Measurement(8.5f, XFA_UNIT_In));
+    pMedium->SetMeasure(XFA_ATTRIBUTE_Long,
+                        CXFA_Measurement(11.0f, XFA_UNIT_In));
+  }
+  return TRUE;
+}
+FX_BOOL CXFA_LayoutPageMgr::PrepareFirstPage(CXFA_Node* pRootSubform) {
+  FX_BOOL bProBreakBefore = FALSE;
+  CXFA_Node* pBreakBeforeNode = NULL;
+  while (pRootSubform) {
+    for (CXFA_Node* pBreakNode =
+             pRootSubform->GetNodeItem(XFA_NODEITEM_FirstChild);
+         pBreakNode;
+         pBreakNode = pBreakNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+      XFA_ELEMENT eType = pBreakNode->GetClassID();
+      if (eType == XFA_ELEMENT_BreakBefore ||
+          (eType == XFA_ELEMENT_Break &&
+           pBreakNode->GetEnum(XFA_ATTRIBUTE_Before) !=
+               XFA_ATTRIBUTEENUM_Auto)) {
+        bProBreakBefore = TRUE;
+        pBreakBeforeNode = pBreakNode;
+        break;
+      }
+    }
+    if (bProBreakBefore) {
+      break;
+    }
+    bProBreakBefore = TRUE;
+    pRootSubform = pRootSubform->GetFirstChildByClass(XFA_ELEMENT_Subform);
+    while (pRootSubform &&
+           !XFA_ItemLayoutProcessor_IsTakingSpace(pRootSubform)) {
+      pRootSubform = pRootSubform->GetNextSameClassSibling(XFA_ELEMENT_Subform);
+    }
+  }
+  CXFA_Node *pLeader, *pTrailer;
+  if (pBreakBeforeNode &&
+      ExecuteBreakBeforeOrAfter(pBreakBeforeNode, TRUE, pLeader, pTrailer)) {
+    m_pCurrentContainerRecord = m_rgProposedContainerRecord.GetHeadPosition();
+    return TRUE;
+  }
+  return AppendNewPage(TRUE);
+}
+FX_BOOL CXFA_LayoutPageMgr::AppendNewPage(FX_BOOL bFirstTemPage) {
+  if (m_pCurrentContainerRecord !=
+      m_rgProposedContainerRecord.GetTailPosition()) {
+    return TRUE;
+  }
+  CXFA_Node* pPageNode = GetNextAvailPageArea(NULL);
+  if (!pPageNode) {
+    return FALSE;
+  }
+  if (bFirstTemPage && m_pCurrentContainerRecord == NULL) {
+    m_pCurrentContainerRecord = m_rgProposedContainerRecord.GetHeadPosition();
+  }
+  return !bFirstTemPage || m_pCurrentContainerRecord;
+}
+static void XFA_LayoutItemMgr_ReorderLayoutItemToTail(
+    CXFA_ContainerLayoutItem* pLayoutItem) {
+  CXFA_ContainerLayoutItem* pParentLayoutItem =
+      (CXFA_ContainerLayoutItem*)pLayoutItem->m_pParent;
+  if (!pParentLayoutItem) {
+    return;
+  }
+  pParentLayoutItem->RemoveChild(pLayoutItem);
+  pParentLayoutItem->AddChild(pLayoutItem);
+}
+static void XFA_LayoutItemMgr_RemoveLayoutItem(
+    CXFA_ContainerLayoutItem* pLayoutItem) {
+  CXFA_ContainerLayoutItem* pParentLayoutItem =
+      (CXFA_ContainerLayoutItem*)pLayoutItem->m_pParent;
+  if (!pParentLayoutItem) {
+    return;
+  }
+  pParentLayoutItem->RemoveChild(pLayoutItem);
+}
+void CXFA_LayoutPageMgr::RemoveLayoutRecord(CXFA_ContainerRecord* pNewRecord,
+                                            CXFA_ContainerRecord* pPrevRecord) {
+  if (!pNewRecord || !pPrevRecord) {
+    return;
+  }
+  if (pNewRecord->pCurPageSet != pPrevRecord->pCurPageSet) {
+    XFA_LayoutItemMgr_RemoveLayoutItem(pNewRecord->pCurPageSet);
+    return;
+  }
+  if (pNewRecord->pCurPageArea != pPrevRecord->pCurPageArea) {
+    XFA_LayoutItemMgr_RemoveLayoutItem(pNewRecord->pCurPageArea);
+    return;
+  }
+  if (pNewRecord->pCurContentArea != pPrevRecord->pCurContentArea) {
+    XFA_LayoutItemMgr_RemoveLayoutItem(pNewRecord->pCurContentArea);
+    return;
+  }
+}
+void CXFA_LayoutPageMgr::ReorderPendingLayoutRecordToTail(
+    CXFA_ContainerRecord* pNewRecord,
+    CXFA_ContainerRecord* pPrevRecord) {
+  if (!pNewRecord || !pPrevRecord) {
+    return;
+  }
+  if (pNewRecord->pCurPageSet != pPrevRecord->pCurPageSet) {
+    XFA_LayoutItemMgr_ReorderLayoutItemToTail(pNewRecord->pCurPageSet);
+    return;
+  }
+  if (pNewRecord->pCurPageArea != pPrevRecord->pCurPageArea) {
+    XFA_LayoutItemMgr_ReorderLayoutItemToTail(pNewRecord->pCurPageArea);
+    return;
+  }
+  if (pNewRecord->pCurContentArea != pPrevRecord->pCurContentArea) {
+    XFA_LayoutItemMgr_ReorderLayoutItemToTail(pNewRecord->pCurContentArea);
+    return;
+  }
+}
+void CXFA_LayoutPageMgr::SubmitContentItem(
+    CXFA_ContentLayoutItem* pContentLayoutItem,
+    XFA_ItemLayoutProcessorResult eStatus) {
+  if (pContentLayoutItem) {
+    GetCurrentContainerRecord()->pCurContentArea->AddChild(pContentLayoutItem);
+    m_bCreateOverFlowPage = FALSE;
+  }
+  if (eStatus != XFA_ItemLayoutProcessorResult_Done) {
+    if (eStatus == XFA_ItemLayoutProcessorResult_PageFullBreak &&
+        m_pCurrentContainerRecord ==
+            m_rgProposedContainerRecord.GetTailPosition()) {
+      AppendNewPage();
+    }
+    m_pCurrentContainerRecord = m_rgProposedContainerRecord.GetTailPosition();
+    m_pCurPageArea = GetCurrentContainerRecord()->pCurPageArea->m_pFormNode;
+  }
+}
+FX_FLOAT CXFA_LayoutPageMgr::GetAvailHeight() {
+  CXFA_ContainerLayoutItem* pLayoutItem =
+      GetCurrentContainerRecord()->pCurContentArea;
+  if (!pLayoutItem || !pLayoutItem->m_pFormNode)
+    return 0.0f;
+  FX_FLOAT fAvailHeight =
+      pLayoutItem->m_pFormNode->GetMeasure(XFA_ATTRIBUTE_H).ToUnit(XFA_UNIT_Pt);
+  if (fAvailHeight >= XFA_LAYOUT_FLOAT_PERCISION)
+    return fAvailHeight;
+  if (m_pCurrentContainerRecord ==
+      m_rgProposedContainerRecord.GetHeadPosition()) {
+    return 0.0f;
+  }
+  return XFA_LAYOUT_FLOAT_MAX;
+}
+static CXFA_Node* XFA_ResolveBreakTarget(CXFA_Node* pPageSetRoot,
+                                         FX_BOOL bNewExprStyle,
+                                         CFX_WideStringC& wsTargetExpr) {
+  CXFA_Document* pDocument = pPageSetRoot->GetDocument();
+  if (wsTargetExpr.IsEmpty()) {
+    return NULL;
+  }
+  CFX_WideString wsTargetAll = wsTargetExpr;
+  wsTargetAll.TrimLeft();
+  wsTargetAll.TrimRight();
+  int32_t iSpliteIndex = 0;
+  FX_BOOL bTargetAllFind = TRUE;
+  while (iSpliteIndex != -1) {
+    CFX_WideString wsTargetExpr;
+    int32_t iSpliteNextIndex = 0;
+    if (!bTargetAllFind) {
+      iSpliteNextIndex = wsTargetAll.Find(' ', iSpliteIndex);
+      wsTargetExpr =
+          wsTargetAll.Mid(iSpliteIndex, iSpliteNextIndex - iSpliteIndex);
+    } else {
+      wsTargetExpr = wsTargetAll;
+    }
+    if (wsTargetExpr.IsEmpty()) {
+      return NULL;
+    }
+    bTargetAllFind = FALSE;
+    if (wsTargetExpr.GetAt(0) == '#') {
+      CXFA_Node* pNode = pDocument->GetNodeByID(
+          ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Template)),
+          wsTargetExpr.Mid(1));
+      if (pNode) {
+        return pNode;
+      }
+    } else if (bNewExprStyle) {
+      CFX_WideString wsProcessedTarget = wsTargetExpr;
+      if (wsTargetExpr.Left(4) == FX_WSTRC(L"som(") &&
+          wsTargetExpr.Right(1) == FX_WSTRC(L")")) {
+        wsProcessedTarget = wsTargetExpr.Mid(4, wsTargetExpr.GetLength() - 5);
+      }
+      XFA_RESOLVENODE_RS rs;
+      int32_t iCount = pDocument->GetScriptContext()->ResolveObjects(
+          pPageSetRoot, wsProcessedTarget, rs,
+          XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
+              XFA_RESOLVENODE_Attributes | XFA_RESOLVENODE_Siblings |
+              XFA_RESOLVENODE_Parent);
+      if (iCount > 0 && rs.nodes[0]->IsNode()) {
+        return rs.nodes[0]->AsNode();
+      }
+    }
+    iSpliteIndex = iSpliteNextIndex;
+  }
+  return NULL;
+}
+
+FX_BOOL XFA_LayoutPageMgr_RunBreakTestScript(CXFA_Node* pTestScript) {
+  CFX_WideString wsExpression;
+  pTestScript->TryContent(wsExpression);
+  if (wsExpression.IsEmpty()) {
+    return TRUE;
+  }
+  return pTestScript->GetDocument()->GetParser()->GetNotify()->RunScript(
+      pTestScript, pTestScript->GetNodeItem(XFA_NODEITEM_Parent,
+                                            XFA_OBJECTTYPE_ContainerNode));
+}
+CXFA_ContainerRecord* CXFA_LayoutPageMgr::CreateContainerRecord(
+    CXFA_Node* pPageNode,
+    FX_BOOL bCreateNew) {
+  CXFA_ContainerRecord* pNewRecord = new CXFA_ContainerRecord();
+  if (m_pCurrentContainerRecord) {
+    if (!IsPageSetRootOrderedOccurrence() || pPageNode == NULL) {
+      *pNewRecord = *GetCurrentContainerRecord();
+      m_rgProposedContainerRecord.AddTail(pNewRecord);
+      return pNewRecord;
+    }
+    CXFA_Node* pPageSet = pPageNode->GetNodeItem(XFA_NODEITEM_Parent);
+    if (!bCreateNew) {
+      if (pPageSet == m_pTemplatePageSetRoot) {
+        pNewRecord->pCurPageSet = m_pPageSetCurRoot;
+      } else {
+        CXFA_ContainerLayoutItem* pParentLayoutItem =
+            (CXFA_ContainerLayoutItem*)pPageSet->GetUserData(XFA_LAYOUTITEMKEY);
+        if (pParentLayoutItem == NULL) {
+          pParentLayoutItem = m_pPageSetCurRoot;
+        }
+        pNewRecord->pCurPageSet = pParentLayoutItem;
+      }
+    } else {
+      CXFA_ContainerLayoutItem* pParentPageSetLayout = NULL;
+      if (pPageSet == GetCurrentContainerRecord()->pCurPageSet->m_pFormNode) {
+        pParentPageSetLayout =
+            (CXFA_ContainerLayoutItem*)GetCurrentContainerRecord()
+                ->pCurPageSet->m_pParent;
+      } else {
+        pParentPageSetLayout =
+            (CXFA_ContainerLayoutItem*)pPageSet->GetNodeItem(
+                                                   XFA_NODEITEM_Parent)
+                ->GetUserData(XFA_LAYOUTITEMKEY);
+      }
+      CXFA_ContainerLayoutItem* pPageSetLayoutItem =
+          new CXFA_ContainerLayoutItem(pPageSet);
+      pPageSet->SetUserData(XFA_LAYOUTITEMKEY, (void*)pPageSetLayoutItem);
+      if (pParentPageSetLayout == NULL) {
+        CXFA_ContainerLayoutItem* pPrePageSet = m_pPageSetLayoutItemRoot;
+        while (pPrePageSet->m_pNextSibling) {
+          pPrePageSet = (CXFA_ContainerLayoutItem*)pPrePageSet->m_pNextSibling;
+        }
+        pPrePageSet->m_pNextSibling = pPageSetLayoutItem;
+        m_pPageSetCurRoot = pPageSetLayoutItem;
+      } else {
+        pParentPageSetLayout->AddChild(pPageSetLayoutItem);
+      }
+      pNewRecord->pCurPageSet = pPageSetLayoutItem;
+    }
+  } else {
+    if (pPageNode) {
+      CXFA_Node* pPageSet = pPageNode->GetNodeItem(XFA_NODEITEM_Parent);
+      if (pPageSet == m_pTemplatePageSetRoot) {
+        pNewRecord->pCurPageSet = m_pPageSetLayoutItemRoot;
+      } else {
+        CXFA_ContainerLayoutItem* pPageSetLayoutItem =
+            new CXFA_ContainerLayoutItem(pPageSet);
+        pPageSet->SetUserData(XFA_LAYOUTITEMKEY, (void*)pPageSetLayoutItem);
+        m_pPageSetLayoutItemRoot->AddChild(pPageSetLayoutItem);
+        pNewRecord->pCurPageSet = pPageSetLayoutItem;
+      }
+    } else {
+      pNewRecord->pCurPageSet = m_pPageSetLayoutItemRoot;
+    }
+  }
+  m_rgProposedContainerRecord.AddTail(pNewRecord);
+  return pNewRecord;
+}
+void CXFA_LayoutPageMgr::AddPageAreaLayoutItem(CXFA_ContainerRecord* pNewRecord,
+                                               CXFA_Node* pNewPageArea) {
+  CXFA_ContainerLayoutItem* pNewPageAreaLayoutItem = NULL;
+  if (m_PageArray.GetSize() > m_nAvailPages) {
+    CXFA_ContainerLayoutItem* pContainerItem = m_PageArray[m_nAvailPages];
+    pContainerItem->m_pFormNode = pNewPageArea;
+    m_nAvailPages++;
+    pNewPageAreaLayoutItem = pContainerItem;
+  } else {
+    IXFA_Notify* pNotify =
+        pNewPageArea->GetDocument()->GetParser()->GetNotify();
+    CXFA_ContainerLayoutItem* pContainerItem =
+        (CXFA_ContainerLayoutItem*)pNotify->OnCreateLayoutItem(pNewPageArea);
+    m_PageArray.Add(pContainerItem);
+    m_nAvailPages++;
+    pNotify->OnPageEvent(pContainerItem, XFA_PAGEEVENT_PageAdded,
+                         (void*)(uintptr_t)m_nAvailPages);
+    pNewPageAreaLayoutItem = pContainerItem;
+  }
+  pNewRecord->pCurPageSet->AddChild(pNewPageAreaLayoutItem);
+  pNewRecord->pCurPageArea = pNewPageAreaLayoutItem;
+  pNewRecord->pCurContentArea = NULL;
+}
+void CXFA_LayoutPageMgr::AddContentAreaLayoutItem(
+    CXFA_ContainerRecord* pNewRecord,
+    CXFA_Node* pContentArea) {
+  if (pContentArea == NULL) {
+    pNewRecord->pCurContentArea = NULL;
+    return;
+  }
+  CXFA_ContainerLayoutItem* pNewContentAreaLayoutItem =
+      new CXFA_ContainerLayoutItem(pContentArea);
+  ASSERT(pNewRecord->pCurPageArea);
+  pNewRecord->pCurPageArea->AddChild(pNewContentAreaLayoutItem);
+  pNewRecord->pCurContentArea = pNewContentAreaLayoutItem;
+}
+class CXFA_TraverseStrategy_PageSetContainerLayoutItem {
+ public:
+  static inline CXFA_ContainerLayoutItem* GetFirstChild(
+      CXFA_ContainerLayoutItem* pLayoutItem) {
+    if (pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_PageSet) {
+      CXFA_ContainerLayoutItem* pChildItem =
+          (CXFA_ContainerLayoutItem*)pLayoutItem->m_pFirstChild;
+      while (pChildItem &&
+             pChildItem->m_pFormNode->GetClassID() != XFA_ELEMENT_PageSet) {
+        pChildItem = (CXFA_ContainerLayoutItem*)pChildItem->m_pNextSibling;
+      }
+      return pChildItem;
+    }
+    return NULL;
+  }
+  static inline CXFA_ContainerLayoutItem* GetNextSibling(
+      CXFA_ContainerLayoutItem* pLayoutItem) {
+    CXFA_ContainerLayoutItem* pChildItem =
+        (CXFA_ContainerLayoutItem*)pLayoutItem->m_pNextSibling;
+    while (pChildItem &&
+           pChildItem->m_pFormNode->GetClassID() != XFA_ELEMENT_PageSet) {
+      pChildItem = (CXFA_ContainerLayoutItem*)pChildItem->m_pNextSibling;
+    }
+    return pChildItem;
+  }
+  static inline CXFA_ContainerLayoutItem* GetParent(
+      CXFA_ContainerLayoutItem* pLayoutItem) {
+    return (CXFA_ContainerLayoutItem*)pLayoutItem->m_pParent;
+  }
+};
+void CXFA_LayoutPageMgr::FinishPaginatedPageSets() {
+  CXFA_ContainerLayoutItem* pRootPageSetLayoutItem = m_pPageSetLayoutItemRoot;
+  for (; pRootPageSetLayoutItem;
+       pRootPageSetLayoutItem =
+           (CXFA_ContainerLayoutItem*)pRootPageSetLayoutItem->m_pNextSibling) {
+    CXFA_NodeIteratorTemplate<CXFA_ContainerLayoutItem,
+                              CXFA_TraverseStrategy_PageSetContainerLayoutItem>
+        sIterator(pRootPageSetLayoutItem);
+    for (CXFA_ContainerLayoutItem* pPageSetLayoutItem = sIterator.GetCurrent();
+         pPageSetLayoutItem; pPageSetLayoutItem = sIterator.MoveToNext()) {
+      XFA_ATTRIBUTEENUM ePageRelation =
+          pPageSetLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Relation);
+      switch (ePageRelation) {
+        case XFA_ATTRIBUTEENUM_OrderedOccurrence:
+        default: { ProcessLastPageSet(); } break;
+        case XFA_ATTRIBUTEENUM_SimplexPaginated:
+        case XFA_ATTRIBUTEENUM_DuplexPaginated: {
+          CXFA_LayoutItem* pLastPageAreaLayoutItem = NULL;
+          int32_t nPageAreaCount = 0;
+          for (CXFA_LayoutItem* pPageAreaLayoutItem =
+                   pPageSetLayoutItem->m_pFirstChild;
+               pPageAreaLayoutItem;
+               pPageAreaLayoutItem = pPageAreaLayoutItem->m_pNextSibling) {
+            if (pPageAreaLayoutItem->m_pFormNode->GetClassID() !=
+                XFA_ELEMENT_PageArea) {
+              continue;
+            }
+            nPageAreaCount++;
+            pLastPageAreaLayoutItem = pPageAreaLayoutItem;
+          }
+          if (!pLastPageAreaLayoutItem) {
+            break;
+          }
+          if (!FindPageAreaFromPageSet_SimplexDuplex(
+                  pPageSetLayoutItem->m_pFormNode, NULL, NULL, NULL, TRUE, TRUE,
+                  nPageAreaCount == 1 ? XFA_ATTRIBUTEENUM_Only
+                                      : XFA_ATTRIBUTEENUM_Last) &&
+              (nPageAreaCount == 1 &&
+               !FindPageAreaFromPageSet_SimplexDuplex(
+                   pPageSetLayoutItem->m_pFormNode, NULL, NULL, NULL, TRUE,
+                   TRUE, XFA_ATTRIBUTEENUM_Last))) {
+            break;
+          }
+          CXFA_Node* pNode = m_pCurPageArea;
+          XFA_ATTRIBUTEENUM eCurChoice =
+              pNode->GetEnum(XFA_ATTRIBUTE_PagePosition);
+          if (eCurChoice == XFA_ATTRIBUTEENUM_Last) {
+            XFA_ATTRIBUTEENUM eOddOrEven = XFA_ATTRIBUTEENUM_Any;
+            pNode->TryEnum(XFA_ATTRIBUTE_OddOrEven, eOddOrEven);
+            XFA_ATTRIBUTEENUM eLastChoice =
+                pLastPageAreaLayoutItem->m_pFormNode->GetEnum(
+                    XFA_ATTRIBUTE_PagePosition);
+            if (eLastChoice == XFA_ATTRIBUTEENUM_First &&
+                (ePageRelation == XFA_ATTRIBUTEENUM_SimplexPaginated ||
+                 eOddOrEven != XFA_ATTRIBUTEENUM_Odd)) {
+              CXFA_ContainerRecord* pRecord = CreateContainerRecord();
+              AddPageAreaLayoutItem(pRecord, pNode);
+              break;
+            }
+          }
+          FX_BOOL bUsable = TRUE;
+          CFX_ArrayTemplate<FX_FLOAT> rgUsedHeights;
+          for (CXFA_LayoutItem* pChildLayoutItem =
+                   pLastPageAreaLayoutItem->m_pFirstChild;
+               pChildLayoutItem;
+               pChildLayoutItem = pChildLayoutItem->m_pNextSibling) {
+            if (pChildLayoutItem->m_pFormNode->GetClassID() !=
+                XFA_ELEMENT_ContentArea) {
+              continue;
+            }
+            FX_FLOAT fUsedHeight = 0;
+            for (CXFA_LayoutItem* pContentChildLayoutItem =
+                     pChildLayoutItem->m_pFirstChild;
+                 pContentChildLayoutItem;
+                 pContentChildLayoutItem =
+                     pContentChildLayoutItem->m_pNextSibling) {
+              if (CXFA_ContentLayoutItem* pContent =
+                      pContentChildLayoutItem->AsContentLayoutItem()) {
+                fUsedHeight += pContent->m_sSize.y;
+              }
+            }
+            rgUsedHeights.Add(fUsedHeight);
+          }
+          int32_t iCurContentAreaIndex = -1;
+          for (CXFA_Node* pContentAreaNode =
+                   pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+               pContentAreaNode;
+               pContentAreaNode =
+                   pContentAreaNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+            if (pContentAreaNode->GetClassID() != XFA_ELEMENT_ContentArea) {
+              continue;
+            }
+            iCurContentAreaIndex++;
+            if (rgUsedHeights[iCurContentAreaIndex] >
+                pContentAreaNode->GetMeasure(XFA_ATTRIBUTE_H)
+                        .ToUnit(XFA_UNIT_Pt) +
+                    XFA_LAYOUT_FLOAT_PERCISION) {
+              bUsable = FALSE;
+              break;
+            }
+          }
+          if (bUsable) {
+            CXFA_LayoutItem* pChildLayoutItem =
+                pLastPageAreaLayoutItem->m_pFirstChild;
+            CXFA_Node* pContentAreaNode =
+                pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+            pLastPageAreaLayoutItem->m_pFormNode = pNode;
+            while (pChildLayoutItem && pContentAreaNode) {
+              if (pChildLayoutItem->m_pFormNode->GetClassID() !=
+                  XFA_ELEMENT_ContentArea) {
+                pChildLayoutItem = pChildLayoutItem->m_pNextSibling;
+                continue;
+              }
+              if (pContentAreaNode->GetClassID() != XFA_ELEMENT_ContentArea) {
+                pContentAreaNode =
+                    pContentAreaNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+                continue;
+              }
+              pChildLayoutItem->m_pFormNode = pContentAreaNode;
+              pChildLayoutItem = pChildLayoutItem->m_pNextSibling;
+              pContentAreaNode =
+                  pContentAreaNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+            }
+          } else if (pNode->GetEnum(XFA_ATTRIBUTE_PagePosition) ==
+                     XFA_ATTRIBUTEENUM_Last) {
+            CXFA_ContainerRecord* pRecord = CreateContainerRecord();
+            AddPageAreaLayoutItem(pRecord, pNode);
+          }
+        } break;
+      }
+    }
+  }
+}
+int32_t CXFA_LayoutPageMgr::GetPageCount() const {
+  return m_PageArray.GetSize();
+}
+IXFA_LayoutPage* CXFA_LayoutPageMgr::GetPage(int32_t index) const {
+  if (index < 0 || index >= m_PageArray.GetSize())
+    return nullptr;
+  return m_PageArray[index];
+}
+int32_t CXFA_LayoutPageMgr::GetPageIndex(const IXFA_LayoutPage* pPage) const {
+  // FIXME: Find() method should take const.
+  return m_PageArray.Find(static_cast<CXFA_ContainerLayoutItem*>(
+      const_cast<IXFA_LayoutPage*>(pPage)));
+}
+FX_BOOL CXFA_LayoutPageMgr::RunBreak(XFA_ELEMENT eBreakType,
+                                     XFA_ATTRIBUTEENUM eTargetType,
+                                     CXFA_Node* pTarget,
+                                     FX_BOOL bStartNew) {
+  FX_BOOL bRet = FALSE;
+  switch (eTargetType) {
+    case XFA_ATTRIBUTEENUM_ContentArea:
+      if (pTarget && pTarget->GetClassID() != XFA_ELEMENT_ContentArea) {
+        pTarget = NULL;
+      }
+      if (!pTarget || !m_pCurrentContainerRecord ||
+          pTarget !=
+              GetCurrentContainerRecord()->pCurContentArea->m_pFormNode ||
+          bStartNew) {
+        CXFA_Node* pPageArea = NULL;
+        if (pTarget) {
+          pPageArea = pTarget->GetNodeItem(XFA_NODEITEM_Parent);
+        }
+        pPageArea = GetNextAvailPageArea(pPageArea, pTarget);
+        bRet = pPageArea != NULL;
+      }
+      break;
+    case XFA_ATTRIBUTEENUM_PageArea:
+      if (pTarget && pTarget->GetClassID() != XFA_ELEMENT_PageArea) {
+        pTarget = NULL;
+      }
+      if (!pTarget || !m_pCurrentContainerRecord ||
+          pTarget != GetCurrentContainerRecord()->pCurPageArea->m_pFormNode ||
+          bStartNew) {
+        CXFA_Node* pPageArea = GetNextAvailPageArea(pTarget, NULL, TRUE);
+        bRet = pPageArea != NULL;
+      }
+      break;
+    case XFA_ATTRIBUTEENUM_PageOdd:
+      if (pTarget && pTarget->GetClassID() != XFA_ELEMENT_PageArea) {
+        pTarget = NULL;
+      }
+      if (m_nAvailPages % 2 != 1 || !m_pCurrentContainerRecord ||
+          (pTarget &&
+           pTarget != GetCurrentContainerRecord()->pCurPageArea->m_pFormNode) ||
+          bStartNew) {
+        if (m_nAvailPages % 2 == 1) {
+        }
+      }
+      break;
+    case XFA_ATTRIBUTEENUM_PageEven:
+      if (pTarget && pTarget->GetClassID() != XFA_ELEMENT_PageArea) {
+        pTarget = NULL;
+      }
+      if (m_nAvailPages % 2 != 0 || !m_pCurrentContainerRecord ||
+          (pTarget &&
+           pTarget != GetCurrentContainerRecord()->pCurPageArea->m_pFormNode) ||
+          bStartNew) {
+        if (m_nAvailPages % 2 == 0) {
+        }
+      }
+      break;
+    case XFA_ATTRIBUTEENUM_Auto:
+    default:
+      break;
+  }
+  return bRet;
+}
+FX_BOOL CXFA_LayoutPageMgr::ExecuteBreakBeforeOrAfter(
+    CXFA_Node* pCurNode,
+    FX_BOOL bBefore,
+    CXFA_Node*& pBreakLeaderTemplate,
+    CXFA_Node*& pBreakTrailerTemplate) {
+  XFA_ELEMENT eType = pCurNode->GetClassID();
+  switch (eType) {
+    case XFA_ELEMENT_BreakBefore:
+    case XFA_ELEMENT_BreakAfter: {
+      CFX_WideStringC wsBreakLeader, wsBreakTrailer;
+      CXFA_Node* pFormNode = pCurNode->GetNodeItem(
+          XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode);
+      CXFA_Node* pContainer = pFormNode->GetTemplateNode();
+      FX_BOOL bStartNew = pCurNode->GetInteger(XFA_ATTRIBUTE_StartNew) != 0;
+      CXFA_Node* pScript = pCurNode->GetFirstChildByClass(XFA_ELEMENT_Script);
+      if (pScript && !XFA_LayoutPageMgr_RunBreakTestScript(pScript)) {
+        return FALSE;
+      }
+      CFX_WideStringC wsTarget = pCurNode->GetCData(XFA_ATTRIBUTE_Target);
+      CXFA_Node* pTarget =
+          XFA_ResolveBreakTarget(m_pTemplatePageSetRoot, TRUE, wsTarget);
+      wsBreakTrailer = pCurNode->GetCData(XFA_ATTRIBUTE_Trailer);
+      wsBreakLeader = pCurNode->GetCData(XFA_ATTRIBUTE_Leader);
+      pBreakLeaderTemplate =
+          XFA_ResolveBreakTarget(pContainer, TRUE, wsBreakLeader);
+      pBreakTrailerTemplate =
+          XFA_ResolveBreakTarget(pContainer, TRUE, wsBreakTrailer);
+      if (RunBreak(eType, pCurNode->GetEnum(XFA_ATTRIBUTE_TargetType), pTarget,
+                   bStartNew)) {
+        return TRUE;
+      } else {
+        if (m_rgProposedContainerRecord.GetCount() > 0 &&
+            m_pCurrentContainerRecord ==
+                m_rgProposedContainerRecord.GetHeadPosition() &&
+            eType == XFA_ELEMENT_BreakBefore) {
+          CXFA_Node* pParentNode = pFormNode->GetNodeItem(
+              XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode);
+          if (!pParentNode ||
+              pFormNode !=
+                  pParentNode->GetNodeItem(XFA_NODEITEM_FirstChild,
+                                           XFA_OBJECTTYPE_ContainerNode)) {
+            break;
+          }
+          pParentNode = pParentNode->GetNodeItem(XFA_NODEITEM_Parent);
+          if (!pParentNode || pParentNode->GetClassID() != XFA_ELEMENT_Form) {
+            break;
+          }
+          return TRUE;
+        }
+      }
+    } break;
+    case XFA_ELEMENT_Break: {
+      FX_BOOL bStartNew = pCurNode->GetInteger(XFA_ATTRIBUTE_StartNew) != 0;
+      CFX_WideStringC wsTarget = pCurNode->GetCData(
+          bBefore ? XFA_ATTRIBUTE_BeforeTarget : XFA_ATTRIBUTE_AfterTarget);
+      CXFA_Node* pTarget =
+          XFA_ResolveBreakTarget(m_pTemplatePageSetRoot, TRUE, wsTarget);
+      if (RunBreak(bBefore ? XFA_ELEMENT_BreakBefore : XFA_ELEMENT_BreakAfter,
+                   pCurNode->GetEnum(bBefore ? XFA_ATTRIBUTE_Before
+                                             : XFA_ATTRIBUTE_After),
+                   pTarget, bStartNew)) {
+        return TRUE;
+      }
+    } break;
+    default:
+      break;
+  }
+  return FALSE;
+}
+static void XFA_SetLayoutGeneratedNodeFlag(CXFA_Node* pNode) {
+  pNode->SetFlag(XFA_NODEFLAG_LayoutGeneratedNode, TRUE, FALSE);
+  pNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE, FALSE);
+}
+FX_BOOL CXFA_LayoutPageMgr::ProcessBreakBeforeOrAfter(
+    CXFA_Node* pBreakNode,
+    FX_BOOL bBefore,
+    CXFA_Node*& pBreakLeaderNode,
+    CXFA_Node*& pBreakTrailerNode,
+    FX_BOOL& bCreatePage) {
+  CXFA_Node *pLeaderTemplate = NULL, *pTrailerTemplate = NULL;
+  CXFA_Node* pFormNode = pBreakNode->GetNodeItem(XFA_NODEITEM_Parent,
+                                                 XFA_OBJECTTYPE_ContainerNode);
+  if (XFA_ItemLayoutProcessor_IsTakingSpace(pFormNode)) {
+    bCreatePage = ExecuteBreakBeforeOrAfter(pBreakNode, bBefore,
+                                            pLeaderTemplate, pTrailerTemplate);
+    CXFA_Document* pDocument = pBreakNode->GetDocument();
+    CXFA_Node* pDataScope = NULL;
+    pFormNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent,
+                                       XFA_OBJECTTYPE_ContainerNode);
+    if (pLeaderTemplate) {
+      if (!pDataScope) {
+        pDataScope = XFA_DataMerge_FindDataScope(pFormNode);
+      }
+      pBreakLeaderNode = pDocument->DataMerge_CopyContainer(
+          pLeaderTemplate, pFormNode, pDataScope, TRUE);
+      pDocument->DataMerge_UpdateBindingRelations(pBreakLeaderNode);
+      XFA_SetLayoutGeneratedNodeFlag(pBreakLeaderNode);
+    }
+    if (pTrailerTemplate) {
+      if (!pDataScope) {
+        pDataScope = XFA_DataMerge_FindDataScope(pFormNode);
+      }
+      pBreakTrailerNode = pDocument->DataMerge_CopyContainer(
+          pTrailerTemplate, pFormNode, pDataScope, TRUE);
+      pDocument->DataMerge_UpdateBindingRelations(pBreakTrailerNode);
+      XFA_SetLayoutGeneratedNodeFlag(pBreakTrailerNode);
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_LayoutPageMgr::ProcessBookendLeaderOrTrailer(
+    CXFA_Node* pBookendNode,
+    FX_BOOL bLeader,
+    CXFA_Node*& pBookendAppendNode) {
+  CXFA_Node* pLeaderTemplate = NULL;
+  CXFA_Node* pFormNode = pBookendNode->GetNodeItem(
+      XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode);
+  if (ResolveBookendLeaderOrTrailer(pBookendNode, bLeader, pLeaderTemplate)) {
+    CXFA_Document* pDocument = pBookendNode->GetDocument();
+    CXFA_Node* pDataScope = NULL;
+    if (pLeaderTemplate) {
+      if (!pDataScope) {
+        pDataScope = XFA_DataMerge_FindDataScope(pFormNode);
+      }
+      pBookendAppendNode = pDocument->DataMerge_CopyContainer(
+          pLeaderTemplate, pFormNode, pDataScope, TRUE);
+      pDocument->DataMerge_UpdateBindingRelations(pBookendAppendNode);
+      XFA_SetLayoutGeneratedNodeFlag(pBookendAppendNode);
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+CXFA_Node* CXFA_LayoutPageMgr::BreakOverflow(CXFA_Node* pOverflowNode,
+                                             CXFA_Node*& pLeaderTemplate,
+                                             CXFA_Node*& pTrailerTemplate,
+                                             FX_BOOL bCreatePage) {
+  CFX_WideStringC wsOverflowLeader, wsOverflowTrailer;
+  CXFA_Node* pContainer =
+      pOverflowNode->GetNodeItem(XFA_NODEITEM_Parent,
+                                 XFA_OBJECTTYPE_ContainerNode)
+          ->GetTemplateNode();
+  if (pOverflowNode->GetClassID() == XFA_ELEMENT_Break) {
+    CFX_WideStringC wsOverflowLeader;
+    CFX_WideStringC wsOverflowTarget;
+    CFX_WideStringC wsOverflowTrailer;
+    pOverflowNode->TryCData(XFA_ATTRIBUTE_OverflowLeader, wsOverflowLeader);
+    pOverflowNode->TryCData(XFA_ATTRIBUTE_OverflowTrailer, wsOverflowTrailer);
+    pOverflowNode->TryCData(XFA_ATTRIBUTE_OverflowTarget, wsOverflowTarget);
+    if (!wsOverflowLeader.IsEmpty() || !wsOverflowTrailer.IsEmpty() ||
+        !wsOverflowTarget.IsEmpty()) {
+      if (!wsOverflowTarget.IsEmpty() && bCreatePage &&
+          !m_bCreateOverFlowPage) {
+        CXFA_Node* pTarget = XFA_ResolveBreakTarget(m_pTemplatePageSetRoot,
+                                                    TRUE, wsOverflowTarget);
+        if (pTarget) {
+          m_bCreateOverFlowPage = TRUE;
+          switch (pTarget->GetClassID()) {
+            case XFA_ELEMENT_PageArea:
+              RunBreak(XFA_ELEMENT_Overflow, XFA_ATTRIBUTEENUM_PageArea,
+                       pTarget, TRUE);
+              break;
+            case XFA_ELEMENT_ContentArea:
+              RunBreak(XFA_ELEMENT_Overflow, XFA_ATTRIBUTEENUM_ContentArea,
+                       pTarget, TRUE);
+              break;
+            default:
+              break;
+          }
+        }
+      }
+      if (!bCreatePage) {
+        pLeaderTemplate =
+            XFA_ResolveBreakTarget(pContainer, TRUE, wsOverflowLeader);
+        pTrailerTemplate =
+            XFA_ResolveBreakTarget(pContainer, TRUE, wsOverflowTrailer);
+      }
+      return pOverflowNode;
+    }
+    return NULL;
+  } else if (pOverflowNode->GetClassID() == XFA_ELEMENT_Overflow) {
+    CFX_WideStringC wsOverflowTarget;
+    pOverflowNode->TryCData(XFA_ATTRIBUTE_Leader, wsOverflowLeader);
+    pOverflowNode->TryCData(XFA_ATTRIBUTE_Trailer, wsOverflowTrailer);
+    pOverflowNode->TryCData(XFA_ATTRIBUTE_Target, wsOverflowTarget);
+    if (!wsOverflowTarget.IsEmpty() && bCreatePage && !m_bCreateOverFlowPage) {
+      CXFA_Node* pTarget = XFA_ResolveBreakTarget(m_pTemplatePageSetRoot, TRUE,
+                                                  wsOverflowTarget);
+      if (pTarget) {
+        m_bCreateOverFlowPage = TRUE;
+        switch (pTarget->GetClassID()) {
+          case XFA_ELEMENT_PageArea:
+            RunBreak(XFA_ELEMENT_Overflow, XFA_ATTRIBUTEENUM_PageArea, pTarget,
+                     TRUE);
+            break;
+          case XFA_ELEMENT_ContentArea:
+            RunBreak(XFA_ELEMENT_Overflow, XFA_ATTRIBUTEENUM_ContentArea,
+                     pTarget, TRUE);
+            break;
+          default:
+            break;
+        }
+      }
+    }
+    if (!bCreatePage) {
+      pLeaderTemplate =
+          XFA_ResolveBreakTarget(pContainer, TRUE, wsOverflowLeader);
+      pTrailerTemplate =
+          XFA_ResolveBreakTarget(pContainer, TRUE, wsOverflowTrailer);
+    }
+    return pOverflowNode;
+  }
+  return NULL;
+}
+FX_BOOL CXFA_LayoutPageMgr::ProcessOverflow(CXFA_Node* pFormNode,
+                                            CXFA_Node*& pLeaderNode,
+                                            CXFA_Node*& pTrailerNode,
+                                            FX_BOOL bDataMerge,
+                                            FX_BOOL bCreatePage) {
+  if (pFormNode == NULL) {
+    return FALSE;
+  }
+  CXFA_Node *pLeaderTemplate = NULL, *pTrailerTemplate = NULL;
+  FX_BOOL bIsOverflowNode = FALSE;
+  if (pFormNode->GetClassID() == XFA_ELEMENT_Overflow ||
+      pFormNode->GetClassID() == XFA_ELEMENT_Break) {
+    bIsOverflowNode = TRUE;
+  }
+  for (CXFA_Node* pCurNode =
+           bIsOverflowNode ? pFormNode
+                           : pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+       pCurNode; pCurNode = pCurNode->GetNodeItem((XFA_NODEITEM_NextSibling))) {
+    if (BreakOverflow(pCurNode, pLeaderTemplate, pTrailerTemplate,
+                      bCreatePage)) {
+      if (bIsOverflowNode) {
+        pFormNode = pCurNode->GetNodeItem(XFA_NODEITEM_Parent);
+      }
+      CXFA_Document* pDocument = pCurNode->GetDocument();
+      CXFA_Node* pDataScope = NULL;
+      if (pLeaderTemplate) {
+        if (!pDataScope) {
+          pDataScope = XFA_DataMerge_FindDataScope(pFormNode);
+        }
+        pLeaderNode = pDocument->DataMerge_CopyContainer(
+            pLeaderTemplate, pFormNode, pDataScope, TRUE);
+        pDocument->DataMerge_UpdateBindingRelations(pLeaderNode);
+        XFA_SetLayoutGeneratedNodeFlag(pLeaderNode);
+      }
+      if (pTrailerTemplate) {
+        if (!pDataScope) {
+          pDataScope = XFA_DataMerge_FindDataScope(pFormNode);
+        }
+        pTrailerNode = pDocument->DataMerge_CopyContainer(
+            pTrailerTemplate, pFormNode, pDataScope, TRUE);
+        pDocument->DataMerge_UpdateBindingRelations(pTrailerNode);
+        XFA_SetLayoutGeneratedNodeFlag(pTrailerNode);
+      }
+      return TRUE;
+    }
+    if (bIsOverflowNode) {
+      break;
+    }
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_LayoutPageMgr::ResolveBookendLeaderOrTrailer(
+    CXFA_Node* pBookendNode,
+    FX_BOOL bLeader,
+    CXFA_Node*& pBookendAppendTemplate) {
+  CFX_WideStringC wsBookendLeader;
+  CXFA_Node* pContainer =
+      pBookendNode->GetNodeItem(XFA_NODEITEM_Parent,
+                                XFA_OBJECTTYPE_ContainerNode)
+          ->GetTemplateNode();
+  if (pBookendNode->GetClassID() == XFA_ELEMENT_Break) {
+    pBookendNode->TryCData(
+        bLeader ? XFA_ATTRIBUTE_BookendLeader : XFA_ATTRIBUTE_BookendTrailer,
+        wsBookendLeader);
+    if (!wsBookendLeader.IsEmpty()) {
+      pBookendAppendTemplate =
+          XFA_ResolveBreakTarget(pContainer, FALSE, wsBookendLeader);
+      return TRUE;
+    }
+    return FALSE;
+  } else if (pBookendNode->GetClassID() == XFA_ELEMENT_Bookend) {
+    pBookendNode->TryCData(
+        bLeader ? XFA_ATTRIBUTE_Leader : XFA_ATTRIBUTE_Trailer,
+        wsBookendLeader);
+    pBookendAppendTemplate =
+        XFA_ResolveBreakTarget(pContainer, TRUE, wsBookendLeader);
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_LayoutPageMgr::FindPageAreaFromPageSet(
+    CXFA_Node* pPageSet,
+    CXFA_Node* pStartChild,
+    CXFA_Node* pTargetPageArea,
+    CXFA_Node* pTargetContentArea,
+    FX_BOOL bNewPage,
+    FX_BOOL bQuery) {
+  if (pPageSet == NULL && pStartChild == NULL) {
+    return FALSE;
+  }
+  if (IsPageSetRootOrderedOccurrence()) {
+    return FindPageAreaFromPageSet_Ordered(pPageSet, pStartChild,
+                                           pTargetPageArea, pTargetContentArea,
+                                           bNewPage, bQuery);
+  }
+  XFA_ATTRIBUTEENUM ePreferredPosition = m_pCurrentContainerRecord
+                                             ? XFA_ATTRIBUTEENUM_Rest
+                                             : XFA_ATTRIBUTEENUM_First;
+  return FindPageAreaFromPageSet_SimplexDuplex(
+      pPageSet, pStartChild, pTargetPageArea, pTargetContentArea, bNewPage,
+      bQuery, ePreferredPosition);
+}
+FX_BOOL CXFA_LayoutPageMgr::FindPageAreaFromPageSet_Ordered(
+    CXFA_Node* pPageSet,
+    CXFA_Node* pStartChild,
+    CXFA_Node* pTargetPageArea,
+    CXFA_Node* pTargetContentArea,
+    FX_BOOL bNewPage,
+    FX_BOOL bQuery) {
+  int32_t iPageSetCount = 0;
+  if (!pStartChild && !bQuery) {
+    m_pPageSetMap.Lookup(pPageSet, iPageSetCount);
+    int32_t iMax = -1;
+    CXFA_Node* pOccurNode = pPageSet->GetFirstChildByClass(XFA_ELEMENT_Occur);
+    if (pOccurNode) {
+      pOccurNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, FALSE);
+    }
+    if (iMax >= 0 && iMax <= iPageSetCount) {
+      return FALSE;
+    }
+  }
+  FX_BOOL bRes = FALSE;
+  CXFA_Node* pCurrentNode =
+      pStartChild ? pStartChild->GetNodeItem(XFA_NODEITEM_NextSibling)
+                  : pPageSet->GetNodeItem(XFA_NODEITEM_FirstChild);
+  for (; pCurrentNode;
+       pCurrentNode = pCurrentNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pCurrentNode->GetClassID() == XFA_ELEMENT_PageArea) {
+      if ((pTargetPageArea == pCurrentNode || pTargetPageArea == NULL)) {
+        if (pCurrentNode->GetFirstChildByClass(XFA_ELEMENT_ContentArea) ==
+            NULL) {
+          if (pTargetPageArea == pCurrentNode) {
+            CreateMinPageRecord(pCurrentNode, TRUE);
+            pTargetPageArea = NULL;
+          }
+          continue;
+        }
+        if (!bQuery) {
+          CXFA_ContainerRecord* pNewRecord =
+              CreateContainerRecord(pCurrentNode, pStartChild == NULL);
+          AddPageAreaLayoutItem(pNewRecord, pCurrentNode);
+          if (pTargetContentArea == NULL) {
+            pTargetContentArea =
+                pCurrentNode->GetFirstChildByClass(XFA_ELEMENT_ContentArea);
+          }
+          AddContentAreaLayoutItem(pNewRecord, pTargetContentArea);
+        }
+        m_pCurPageArea = pCurrentNode;
+        m_nCurPageCount = 1;
+        bRes = TRUE;
+        break;
+      }
+      if (!bQuery) {
+        CreateMinPageRecord(pCurrentNode, FALSE);
+      }
+    } else if (pCurrentNode->GetClassID() == XFA_ELEMENT_PageSet) {
+      if (FindPageAreaFromPageSet_Ordered(pCurrentNode, NULL, pTargetPageArea,
+                                          pTargetContentArea, bNewPage,
+                                          bQuery)) {
+        bRes = TRUE;
+        break;
+      }
+      if (!bQuery) {
+        CreateMinPageSetRecord(pCurrentNode, TRUE);
+      }
+    }
+  }
+  if (!pStartChild && bRes && !bQuery) {
+    m_pPageSetMap.SetAt(pPageSet, ++iPageSetCount);
+  }
+  return bRes;
+}
+FX_BOOL CXFA_LayoutPageMgr::FindPageAreaFromPageSet_SimplexDuplex(
+    CXFA_Node* pPageSet,
+    CXFA_Node* pStartChild,
+    CXFA_Node* pTargetPageArea,
+    CXFA_Node* pTargetContentArea,
+    FX_BOOL bNewPage,
+    FX_BOOL bQuery,
+    XFA_ATTRIBUTEENUM ePreferredPosition) {
+  const XFA_ATTRIBUTEENUM eFallbackPosition = XFA_ATTRIBUTEENUM_Any;
+  CXFA_Node *pPreferredPageArea = NULL, *pFallbackPageArea = NULL;
+  CXFA_Node* pCurrentNode = NULL;
+  if (!pStartChild || pStartChild->GetClassID() == XFA_ELEMENT_PageArea) {
+    pCurrentNode = pPageSet->GetNodeItem(XFA_NODEITEM_FirstChild);
+  } else {
+    pCurrentNode = pStartChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+  }
+  for (; pCurrentNode;
+       pCurrentNode = pCurrentNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pCurrentNode->GetClassID() == XFA_ELEMENT_PageArea) {
+      if (!MatchPageAreaOddOrEven(pCurrentNode, FALSE)) {
+        continue;
+      }
+      XFA_ATTRIBUTEENUM eCurPagePosition =
+          pCurrentNode->GetEnum(XFA_ATTRIBUTE_PagePosition);
+      if (ePreferredPosition == XFA_ATTRIBUTEENUM_Last) {
+        if (eCurPagePosition != ePreferredPosition) {
+          continue;
+        }
+        if (m_ePageSetMode == XFA_ATTRIBUTEENUM_SimplexPaginated ||
+            pCurrentNode->GetEnum(XFA_ATTRIBUTE_OddOrEven) ==
+                XFA_ATTRIBUTEENUM_Any) {
+          pPreferredPageArea = pCurrentNode;
+          break;
+        }
+        CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
+        AddPageAreaLayoutItem(pNewRecord, pCurrentNode);
+        AddContentAreaLayoutItem(pNewRecord, pCurrentNode->GetFirstChildByClass(
+                                                 XFA_ELEMENT_ContentArea));
+        pPreferredPageArea = pCurrentNode;
+        return FALSE;
+      } else if (ePreferredPosition == XFA_ATTRIBUTEENUM_Only) {
+        if (eCurPagePosition != ePreferredPosition) {
+          continue;
+        }
+        if (m_ePageSetMode != XFA_ATTRIBUTEENUM_DuplexPaginated ||
+            pCurrentNode->GetEnum(XFA_ATTRIBUTE_OddOrEven) ==
+                XFA_ATTRIBUTEENUM_Any) {
+          pPreferredPageArea = pCurrentNode;
+          break;
+        }
+        return FALSE;
+      }
+      if ((pTargetPageArea == pCurrentNode || pTargetPageArea == NULL)) {
+        if (pCurrentNode->GetFirstChildByClass(XFA_ELEMENT_ContentArea) ==
+            NULL) {
+          if (pTargetPageArea == pCurrentNode) {
+            CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
+            AddPageAreaLayoutItem(pNewRecord, pCurrentNode);
+            pTargetPageArea = NULL;
+          }
+          continue;
+        }
+        if ((ePreferredPosition == XFA_ATTRIBUTEENUM_Rest &&
+             eCurPagePosition == XFA_ATTRIBUTEENUM_Any) ||
+            eCurPagePosition == ePreferredPosition) {
+          pPreferredPageArea = pCurrentNode;
+          break;
+        } else if (eCurPagePosition == eFallbackPosition &&
+                   !pFallbackPageArea) {
+          pFallbackPageArea = pCurrentNode;
+        }
+      } else if (pTargetPageArea &&
+                 !MatchPageAreaOddOrEven(pTargetPageArea, FALSE)) {
+        CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
+        AddPageAreaLayoutItem(pNewRecord, pCurrentNode);
+        AddContentAreaLayoutItem(pNewRecord, pCurrentNode->GetFirstChildByClass(
+                                                 XFA_ELEMENT_ContentArea));
+      }
+    } else if (pCurrentNode->GetClassID() == XFA_ELEMENT_PageSet) {
+      if (FindPageAreaFromPageSet_SimplexDuplex(
+              pCurrentNode, NULL, pTargetPageArea, pTargetContentArea, bNewPage,
+              bQuery, ePreferredPosition)) {
+        break;
+      }
+    }
+  }
+  CXFA_Node* pCurPageArea = NULL;
+  if (pPreferredPageArea) {
+    pCurPageArea = pPreferredPageArea;
+  } else if (pFallbackPageArea) {
+    pCurPageArea = pFallbackPageArea;
+  }
+  if (!pCurPageArea) {
+    return FALSE;
+  }
+  if (!bQuery) {
+    CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
+    AddPageAreaLayoutItem(pNewRecord, pCurPageArea);
+    if (pTargetContentArea == NULL) {
+      pTargetContentArea =
+          pCurPageArea->GetFirstChildByClass(XFA_ELEMENT_ContentArea);
+    }
+    AddContentAreaLayoutItem(pNewRecord, pTargetContentArea);
+  }
+  m_pCurPageArea = pCurPageArea;
+  return TRUE;
+}
+FX_BOOL CXFA_LayoutPageMgr::MatchPageAreaOddOrEven(CXFA_Node* pPageArea,
+                                                   FX_BOOL bLastMatch) {
+  if (m_ePageSetMode != XFA_ATTRIBUTEENUM_DuplexPaginated) {
+    return TRUE;
+  }
+  XFA_ATTRIBUTEENUM eOddOrEven = XFA_ATTRIBUTEENUM_Any;
+  pPageArea->TryEnum(XFA_ATTRIBUTE_OddOrEven, eOddOrEven);
+  if (eOddOrEven != XFA_ATTRIBUTEENUM_Any) {
+    int32_t iPageCount = GetPageCount();
+    if (bLastMatch) {
+      return eOddOrEven == XFA_ATTRIBUTEENUM_Odd ? iPageCount % 2 == 1
+                                                 : iPageCount % 2 == 0;
+    }
+    return eOddOrEven == XFA_ATTRIBUTEENUM_Odd ? iPageCount % 2 == 0
+                                               : iPageCount % 2 == 1;
+  }
+  return TRUE;
+}
+CXFA_Node* CXFA_LayoutPageMgr::GetNextAvailPageArea(
+    CXFA_Node* pTargetPageArea,
+    CXFA_Node* pTargetContentArea,
+    FX_BOOL bNewPage,
+    FX_BOOL bQuery) {
+  if (m_pCurPageArea == NULL) {
+    FindPageAreaFromPageSet(m_pTemplatePageSetRoot, NULL, pTargetPageArea,
+                            pTargetContentArea, bNewPage, bQuery);
+    ASSERT(m_pCurPageArea);
+    return m_pCurPageArea;
+  }
+  if (pTargetPageArea == NULL || pTargetPageArea == m_pCurPageArea) {
+    if (!bNewPage && GetNextContentArea(pTargetContentArea)) {
+      return m_pCurPageArea;
+    }
+    if (IsPageSetRootOrderedOccurrence()) {
+      int32_t iMax = -1;
+      CXFA_Node* pOccurNode =
+          m_pCurPageArea->GetFirstChildByClass(XFA_ELEMENT_Occur);
+      if (pOccurNode) {
+        pOccurNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, FALSE);
+      }
+      if ((iMax < 0 || m_nCurPageCount < iMax)) {
+        if (!bQuery) {
+          CXFA_ContainerRecord* pNewRecord =
+              CreateContainerRecord(m_pCurPageArea);
+          AddPageAreaLayoutItem(pNewRecord, m_pCurPageArea);
+          if (pTargetContentArea == NULL) {
+            pTargetContentArea =
+                m_pCurPageArea->GetFirstChildByClass(XFA_ELEMENT_ContentArea);
+          }
+          AddContentAreaLayoutItem(pNewRecord, pTargetContentArea);
+        }
+        m_nCurPageCount++;
+        return m_pCurPageArea;
+      }
+    }
+  }
+  if (!bQuery && IsPageSetRootOrderedOccurrence()) {
+    CreateMinPageRecord(m_pCurPageArea, FALSE, TRUE);
+  }
+  if (FindPageAreaFromPageSet(m_pCurPageArea->GetNodeItem(XFA_NODEITEM_Parent),
+                              m_pCurPageArea, pTargetPageArea,
+                              pTargetContentArea, bNewPage, bQuery)) {
+    return m_pCurPageArea;
+  }
+  CXFA_Node* pPageSet = m_pCurPageArea->GetNodeItem(XFA_NODEITEM_Parent);
+  while (TRUE) {
+    if (FindPageAreaFromPageSet(pPageSet, NULL, pTargetPageArea,
+                                pTargetContentArea, bNewPage, bQuery)) {
+      return m_pCurPageArea;
+    }
+    if (!bQuery && IsPageSetRootOrderedOccurrence()) {
+      CreateMinPageSetRecord(pPageSet);
+    }
+    if (FindPageAreaFromPageSet(NULL, pPageSet, pTargetPageArea,
+                                pTargetContentArea, bNewPage, bQuery)) {
+      return m_pCurPageArea;
+    }
+    if (pPageSet == m_pTemplatePageSetRoot) {
+      break;
+    }
+    pPageSet = pPageSet->GetNodeItem(XFA_NODEITEM_Parent);
+  }
+  return NULL;
+}
+static FX_BOOL XFA_LayoutPageMgr_CheckContentAreaNotUsed(
+    CXFA_ContainerLayoutItem* pPageAreaLayoutItem,
+    CXFA_Node* pContentArea,
+    CXFA_ContainerLayoutItem*& pContentAreaLayoutItem) {
+  for (CXFA_ContainerLayoutItem* pLayoutItem =
+           (CXFA_ContainerLayoutItem*)pPageAreaLayoutItem->m_pFirstChild;
+       pLayoutItem;
+       pLayoutItem = (CXFA_ContainerLayoutItem*)pLayoutItem->m_pNextSibling) {
+    if (pLayoutItem->m_pFormNode == pContentArea) {
+      if (pLayoutItem->m_pFirstChild == NULL) {
+        pContentAreaLayoutItem = pLayoutItem;
+        return TRUE;
+      }
+      return FALSE;
+    }
+  }
+  return TRUE;
+}
+FX_BOOL CXFA_LayoutPageMgr::GetNextContentArea(CXFA_Node* pContentArea) {
+  CXFA_Node* pCurContentNode =
+      GetCurrentContainerRecord()->pCurContentArea->m_pFormNode;
+  if (pContentArea == NULL) {
+    pContentArea =
+        pCurContentNode->GetNextSameClassSibling(XFA_ELEMENT_ContentArea);
+    if (pContentArea == NULL) {
+      return FALSE;
+    }
+  } else {
+    if (pContentArea->GetNodeItem(XFA_NODEITEM_Parent) != m_pCurPageArea) {
+      return FALSE;
+    }
+    CXFA_ContainerLayoutItem* pContentAreaLayout = NULL;
+    if (!XFA_LayoutPageMgr_CheckContentAreaNotUsed(
+            GetCurrentContainerRecord()->pCurPageArea, pContentArea,
+            pContentAreaLayout)) {
+      return FALSE;
+    }
+    if (pContentAreaLayout) {
+      if (pContentAreaLayout->m_pFormNode != pCurContentNode) {
+        CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
+        pNewRecord->pCurContentArea = pContentAreaLayout;
+        return TRUE;
+      } else {
+        return FALSE;
+      }
+    }
+  }
+  CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
+  AddContentAreaLayoutItem(pNewRecord, pContentArea);
+  return TRUE;
+}
+void CXFA_LayoutPageMgr::InitPageSetMap() {
+  if (!IsPageSetRootOrderedOccurrence()) {
+    return;
+  }
+  CXFA_NodeIterator sIterator(m_pTemplatePageSetRoot);
+  for (CXFA_Node* pPageSetNode = sIterator.GetCurrent(); pPageSetNode;
+       pPageSetNode = sIterator.MoveToNext()) {
+    if (pPageSetNode->GetClassID() == XFA_ELEMENT_PageSet) {
+      XFA_ATTRIBUTEENUM eRelation =
+          pPageSetNode->GetEnum(XFA_ATTRIBUTE_Relation);
+      if (eRelation == XFA_ATTRIBUTEENUM_OrderedOccurrence) {
+        m_pPageSetMap.SetAt(pPageSetNode, 0);
+      }
+    }
+  }
+}
+int32_t CXFA_LayoutPageMgr::CreateMinPageRecord(CXFA_Node* pPageArea,
+                                                FX_BOOL bTargetPageArea,
+                                                FX_BOOL bCreateLast) {
+  if (pPageArea == NULL) {
+    return 0;
+  }
+  CXFA_Node* pOccurNode = pPageArea->GetFirstChildByClass(XFA_ELEMENT_Occur);
+  int32_t iMin = 0;
+  if ((pOccurNode && pOccurNode->TryInteger(XFA_ATTRIBUTE_Min, iMin, FALSE)) ||
+      bTargetPageArea) {
+    CXFA_Node* pContentArea =
+        pPageArea->GetFirstChildByClass(XFA_ELEMENT_ContentArea);
+    if (iMin < 1 && bTargetPageArea && !pContentArea) {
+      iMin = 1;
+    }
+    int32_t i = 0;
+    if (bCreateLast) {
+      i = m_nCurPageCount;
+    }
+    for (; i < iMin; i++) {
+      CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
+      AddPageAreaLayoutItem(pNewRecord, pPageArea);
+      AddContentAreaLayoutItem(pNewRecord, pContentArea);
+    }
+  }
+  return iMin;
+}
+void CXFA_LayoutPageMgr::CreateMinPageSetRecord(CXFA_Node* pPageSet,
+                                                FX_BOOL bCreateAll) {
+  if (pPageSet == NULL) {
+    return;
+  }
+  int32_t iCurSetCount = 0;
+  if (!m_pPageSetMap.Lookup(pPageSet, iCurSetCount)) {
+    return;
+  }
+  if (bCreateAll) {
+    iCurSetCount = 0;
+  }
+  CXFA_Node* pOccurNode = pPageSet->GetFirstChildByClass(XFA_ELEMENT_Occur);
+  int32_t iMin = 0;
+  if (pOccurNode && pOccurNode->TryInteger(XFA_ATTRIBUTE_Min, iMin, FALSE)) {
+    if (iCurSetCount < iMin) {
+      for (int32_t i = 0; i < iMin - iCurSetCount; i++) {
+        for (CXFA_Node* pCurrentPageNode =
+                 pPageSet->GetNodeItem(XFA_NODEITEM_FirstChild);
+             pCurrentPageNode; pCurrentPageNode = pCurrentPageNode->GetNodeItem(
+                                   XFA_NODEITEM_NextSibling)) {
+          if (pCurrentPageNode->GetClassID() == XFA_ELEMENT_PageArea) {
+            CreateMinPageRecord(pCurrentPageNode, FALSE);
+          } else if (pCurrentPageNode->GetClassID() == XFA_ELEMENT_PageSet) {
+            CreateMinPageSetRecord(pCurrentPageNode, TRUE);
+          }
+        }
+      }
+      m_pPageSetMap.SetAt(pPageSet, iMin);
+    }
+  }
+}
+void CXFA_LayoutPageMgr::CreateNextMinRecord(CXFA_Node* pRecordNode) {
+  if (pRecordNode == NULL) {
+    return;
+  }
+  for (CXFA_Node* pCurrentNode =
+           pRecordNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+       pCurrentNode;
+       pCurrentNode = pCurrentNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pCurrentNode->GetClassID() == XFA_ELEMENT_PageArea) {
+      CreateMinPageRecord(pCurrentNode, FALSE);
+    } else if (pCurrentNode->GetClassID() == XFA_ELEMENT_PageSet) {
+      CreateMinPageSetRecord(pCurrentNode, TRUE);
+    }
+  }
+}
+void CXFA_LayoutPageMgr::ProcessLastPageSet() {
+  CreateMinPageRecord(m_pCurPageArea, FALSE, TRUE);
+  CreateNextMinRecord(m_pCurPageArea);
+  CXFA_Node* pPageSet = m_pCurPageArea->GetNodeItem(XFA_NODEITEM_Parent);
+  while (TRUE) {
+    CreateMinPageSetRecord(pPageSet);
+    if (pPageSet == m_pTemplatePageSetRoot) {
+      break;
+    }
+    CreateNextMinRecord(pPageSet);
+    pPageSet = pPageSet->GetNodeItem(XFA_NODEITEM_Parent);
+  }
+}
+FX_BOOL CXFA_LayoutPageMgr::GetNextAvailContentHeight(FX_FLOAT fChildHeight) {
+  CXFA_Node* pCurContentNode =
+      GetCurrentContainerRecord()->pCurContentArea->m_pFormNode;
+  if (pCurContentNode == NULL) {
+    return FALSE;
+  }
+  pCurContentNode =
+      pCurContentNode->GetNextSameClassSibling(XFA_ELEMENT_ContentArea);
+  if (pCurContentNode) {
+    FX_FLOAT fNextContentHeight =
+        pCurContentNode->GetMeasure(XFA_ATTRIBUTE_H).ToUnit(XFA_UNIT_Pt);
+    return fNextContentHeight > fChildHeight;
+  }
+  CXFA_Node* pPageNode = GetCurrentContainerRecord()->pCurPageArea->m_pFormNode;
+  CXFA_Node* pOccurNode = pPageNode->GetFirstChildByClass(XFA_ELEMENT_Occur);
+  int32_t iMax = 0;
+  if (pOccurNode && pOccurNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, FALSE)) {
+    if (m_nCurPageCount == iMax) {
+      CXFA_Node* pSrcPage = m_pCurPageArea;
+      int32_t nSrcPageCount = m_nCurPageCount;
+      FX_POSITION psSrcRecord = m_rgProposedContainerRecord.GetTailPosition();
+      CXFA_Node* pNextPage = GetNextAvailPageArea(NULL, NULL, FALSE, TRUE);
+      m_pCurPageArea = pSrcPage;
+      m_nCurPageCount = nSrcPageCount;
+      CXFA_ContainerRecord* pPrevRecord =
+          (CXFA_ContainerRecord*)m_rgProposedContainerRecord.GetNext(
+              psSrcRecord);
+      while (psSrcRecord) {
+        FX_POSITION psSaveRecord = psSrcRecord;
+        CXFA_ContainerRecord* pInsertRecord =
+            (CXFA_ContainerRecord*)m_rgProposedContainerRecord.GetNext(
+                psSrcRecord);
+        RemoveLayoutRecord(pInsertRecord, pPrevRecord);
+        delete pInsertRecord;
+        m_rgProposedContainerRecord.RemoveAt(psSaveRecord);
+      }
+      if (pNextPage) {
+        CXFA_Node* pContentArea =
+            pNextPage->GetFirstChildByClass(XFA_ELEMENT_ContentArea);
+        if (pContentArea) {
+          FX_FLOAT fNextContentHeight =
+              pContentArea->GetMeasure(XFA_ATTRIBUTE_H).ToUnit(XFA_UNIT_Pt);
+          if (fNextContentHeight > fChildHeight) {
+            return TRUE;
+          }
+        }
+      }
+      return FALSE;
+    }
+  }
+  CXFA_Node* pContentArea =
+      pPageNode->GetFirstChildByClass(XFA_ELEMENT_ContentArea);
+  FX_FLOAT fNextContentHeight =
+      pContentArea->GetMeasure(XFA_ATTRIBUTE_H).ToUnit(XFA_UNIT_Pt);
+  if (fNextContentHeight < XFA_LAYOUT_FLOAT_PERCISION) {
+    return TRUE;
+  }
+  if (fNextContentHeight > fChildHeight) {
+    return TRUE;
+  }
+  return FALSE;
+}
+void CXFA_LayoutPageMgr::ClearData() {
+  ClearRecordList();
+}
+void CXFA_LayoutPageMgr::ClearRecordList() {
+  if (!m_pTemplatePageSetRoot) {
+    return;
+  }
+  if (m_rgProposedContainerRecord.GetCount() > 0) {
+    FX_POSITION sPos;
+    sPos = m_rgProposedContainerRecord.GetHeadPosition();
+    while (sPos) {
+      CXFA_ContainerRecord* pRecord =
+          (CXFA_ContainerRecord*)m_rgProposedContainerRecord.GetNext(sPos);
+      delete pRecord;
+    }
+    m_rgProposedContainerRecord.RemoveAll();
+  }
+  m_pCurrentContainerRecord = NULL;
+  m_pCurPageArea = NULL;
+  m_nCurPageCount = 0;
+  m_bCreateOverFlowPage = FALSE;
+  m_pPageSetMap.RemoveAll();
+}
+CXFA_LayoutItem* CXFA_LayoutPageMgr::FindOrCreateLayoutItem(
+    CXFA_Node* pFormNode) {
+  return pFormNode->GetDocument()->GetParser()->GetNotify()->OnCreateLayoutItem(
+      pFormNode);
+}
+static void XFA_SyncRemoveLayoutItem(CXFA_LayoutItem* pParentLayoutItem,
+                                     IXFA_Notify* pNotify,
+                                     IXFA_DocLayout* pDocLayout) {
+  CXFA_LayoutItem* pNextLayoutItem;
+  CXFA_LayoutItem* pCurLayoutItem = pParentLayoutItem->m_pFirstChild;
+  while (pCurLayoutItem) {
+    pNextLayoutItem = pCurLayoutItem->m_pNextSibling;
+    if (pCurLayoutItem->m_pFirstChild) {
+      XFA_SyncRemoveLayoutItem(pCurLayoutItem, pNotify, pDocLayout);
+    }
+    pNotify->OnLayoutEvent(pDocLayout, pCurLayoutItem,
+                           XFA_LAYOUTEVENT_ItemRemoving);
+    delete pCurLayoutItem;
+    pCurLayoutItem = pNextLayoutItem;
+  }
+}
+void CXFA_LayoutPageMgr::SaveLayoutItem(CXFA_LayoutItem* pParentLayoutItem) {
+  CXFA_LayoutItem* pNextLayoutItem;
+  CXFA_LayoutItem* pCurLayoutItem = pParentLayoutItem->m_pFirstChild;
+  while (pCurLayoutItem) {
+    pNextLayoutItem = pCurLayoutItem->m_pNextSibling;
+    if (pCurLayoutItem->IsContentLayoutItem()) {
+      FX_DWORD dwFlag = pCurLayoutItem->m_pFormNode->GetFlag();
+      if (dwFlag & (XFA_NODEFLAG_HasRemoved)) {
+        IXFA_Notify* pNotify =
+            m_pTemplatePageSetRoot->GetDocument()->GetParser()->GetNotify();
+        IXFA_DocLayout* pDocLayout =
+            m_pTemplatePageSetRoot->GetDocument()->GetDocLayout();
+        if (pCurLayoutItem->m_pFirstChild) {
+          XFA_SyncRemoveLayoutItem(pCurLayoutItem, pNotify, pDocLayout);
+        }
+        pNotify->OnLayoutEvent(pDocLayout, pCurLayoutItem,
+                               XFA_LAYOUTEVENT_ItemRemoving);
+        delete pCurLayoutItem;
+        pCurLayoutItem = pNextLayoutItem;
+        continue;
+      }
+      if (dwFlag & XFA_NODEFLAG_LayoutGeneratedNode) {
+        CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode>
+            sIterator(pCurLayoutItem->m_pFormNode);
+        for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
+             pNode = sIterator.MoveToNext()) {
+          pNode->SetFlag(XFA_NODEFLAG_UnusedNode, TRUE, FALSE);
+        }
+      }
+    }
+    if (pCurLayoutItem->m_pFirstChild) {
+      SaveLayoutItem(pCurLayoutItem);
+    }
+    pCurLayoutItem->m_pParent = NULL;
+    pCurLayoutItem->m_pNextSibling = NULL;
+    pCurLayoutItem->m_pFirstChild = NULL;
+    if (!pCurLayoutItem->IsContentLayoutItem() &&
+        pCurLayoutItem->m_pFormNode->GetClassID() != XFA_ELEMENT_PageArea) {
+      delete pCurLayoutItem;
+    }
+    pCurLayoutItem = pNextLayoutItem;
+  }
+}
+CXFA_Node* CXFA_LayoutPageMgr::QueryOverflow(
+    CXFA_Node* pFormNode,
+    CXFA_LayoutContext* pLayoutContext) {
+  for (CXFA_Node* pCurNode = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+       pCurNode; pCurNode = pCurNode->GetNodeItem((XFA_NODEITEM_NextSibling))) {
+    if (pCurNode->GetClassID() == XFA_ELEMENT_Break) {
+      CFX_WideStringC wsOverflowLeader;
+      CFX_WideStringC wsOverflowTarget;
+      CFX_WideStringC wsOverflowTrailer;
+      pCurNode->TryCData(XFA_ATTRIBUTE_OverflowLeader, wsOverflowLeader);
+      pCurNode->TryCData(XFA_ATTRIBUTE_OverflowTrailer, wsOverflowTrailer);
+      pCurNode->TryCData(XFA_ATTRIBUTE_OverflowTarget, wsOverflowTarget);
+      if (!wsOverflowLeader.IsEmpty() || !wsOverflowTrailer.IsEmpty() ||
+          !wsOverflowTarget.IsEmpty()) {
+        return pCurNode;
+      }
+      return NULL;
+    } else if (pCurNode->GetClassID() == XFA_ELEMENT_Overflow) {
+      return pCurNode;
+    }
+  }
+  return NULL;
+}
+void CXFA_LayoutPageMgr::MergePageSetContents() {
+  CXFA_Document* pDocument = m_pTemplatePageSetRoot->GetDocument();
+  IXFA_Notify* pNotify = pDocument->GetParser()->GetNotify();
+  IXFA_DocLayout* pDocLayout = pDocument->GetDocLayout();
+  CXFA_ContainerLayoutItem* pRootLayout = GetRootLayoutItem();
+  {
+    for (int32_t iIndex = 0; iIndex < pDocument->m_pPendingPageSet.GetSize();
+         iIndex++) {
+      CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode>
+          sIterator(pDocument->m_pPendingPageSet.GetAt(iIndex));
+      for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
+           pNode = sIterator.MoveToNext()) {
+        if (pNode->IsContainerNode()) {
+          CXFA_Node* pBindNode = pNode->GetBindData();
+          if (pBindNode) {
+            pBindNode->RemoveBindItem(pNode);
+            pNode->SetObject(XFA_ATTRIBUTE_BindingNode, NULL);
+          }
+        }
+        pNode->SetFlag(XFA_NODEFLAG_UnusedNode);
+      }
+    }
+  }
+  int32_t iIndex = 0;
+  CXFA_Node* pPendingPageSet = NULL;
+  for (; pRootLayout;
+       pRootLayout = (CXFA_ContainerLayoutItem*)pRootLayout->m_pNextSibling) {
+    pPendingPageSet = NULL;
+    CXFA_NodeIteratorTemplate<
+        CXFA_ContainerLayoutItem,
+        CXFA_TraverseStrategy_ContentAreaContainerLayoutItem>
+        iterator(pRootLayout);
+    CXFA_ContainerLayoutItem* pRootPageSetContainerItem = iterator.GetCurrent();
+    ASSERT(pRootPageSetContainerItem->m_pFormNode->GetClassID() ==
+           XFA_ELEMENT_PageSet);
+    if (iIndex < pDocument->m_pPendingPageSet.GetSize()) {
+      pPendingPageSet = pDocument->m_pPendingPageSet.GetAt(iIndex);
+      iIndex++;
+    }
+    if (!pPendingPageSet) {
+      if (pRootPageSetContainerItem->m_pFormNode->GetPacketID() ==
+          XFA_XDPPACKET_Template) {
+        pPendingPageSet =
+            pRootPageSetContainerItem->m_pFormNode->CloneTemplateToForm(FALSE);
+      } else {
+        pPendingPageSet = pRootPageSetContainerItem->m_pFormNode;
+      }
+    }
+    if (pRootPageSetContainerItem->m_pFormNode->GetUserData(
+            XFA_LAYOUTITEMKEY) == pRootPageSetContainerItem) {
+      pRootPageSetContainerItem->m_pFormNode->SetUserData(XFA_LAYOUTITEMKEY,
+                                                          NULL);
+    }
+    pRootPageSetContainerItem->m_pFormNode = pPendingPageSet;
+    pPendingPageSet->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);
+    for (CXFA_ContainerLayoutItem* pContainerItem = iterator.MoveToNext();
+         pContainerItem; pContainerItem = iterator.MoveToNext()) {
+      CXFA_Node* pNode = pContainerItem->m_pFormNode;
+      if (pNode->GetPacketID() != XFA_XDPPACKET_Template) {
+        continue;
+      }
+      switch (pNode->GetClassID()) {
+        case XFA_ELEMENT_PageSet: {
+          CXFA_Node* pParentNode = pContainerItem->m_pParent->m_pFormNode;
+          pContainerItem->m_pFormNode = XFA_NodeMerge_CloneOrMergeContainer(
+              pDocument, pParentNode, pContainerItem->m_pFormNode, TRUE);
+        } break;
+        case XFA_ELEMENT_PageArea: {
+          CXFA_ContainerLayoutItem* pFormLayout = pContainerItem;
+          CXFA_Node* pParentNode = pContainerItem->m_pParent->m_pFormNode;
+          FX_BOOL bIsExistForm = TRUE;
+          for (int32_t iLevel = 0; iLevel < 3; iLevel++) {
+            pFormLayout = (CXFA_ContainerLayoutItem*)pFormLayout->m_pFirstChild;
+            if (iLevel == 2) {
+              while (pFormLayout &&
+                     !XFA_ItemLayoutProcessor_IsTakingSpace(
+                         pFormLayout->m_pFormNode)) {
+                pFormLayout =
+                    (CXFA_ContainerLayoutItem*)pFormLayout->m_pNextSibling;
+              }
+            }
+            if (pFormLayout == NULL) {
+              bIsExistForm = FALSE;
+              break;
+            }
+          }
+          if (bIsExistForm) {
+            CXFA_Node* pNewSubform = pFormLayout->m_pFormNode;
+            if (pContainerItem->m_pOldSubform &&
+                pContainerItem->m_pOldSubform != pNewSubform) {
+              CXFA_Node* pExistingNode = XFA_DataMerge_FindFormDOMInstance(
+                  pDocument, pContainerItem->m_pFormNode->GetClassID(),
+                  pContainerItem->m_pFormNode->GetNameHash(), pParentNode);
+              CXFA_ContainerIterator sIterator(pExistingNode);
+              for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
+                   pNode = sIterator.MoveToNext()) {
+                if (pNode->GetClassID() != XFA_ELEMENT_ContentArea) {
+                  CXFA_LayoutItem* pLayoutItem = static_cast<CXFA_LayoutItem*>(
+                      pNode->GetUserData(XFA_LAYOUTITEMKEY));
+                  if (pLayoutItem) {
+                    pNotify->OnLayoutEvent(pDocLayout, pLayoutItem,
+                                           XFA_LAYOUTEVENT_ItemRemoving);
+                    delete pLayoutItem;
+                  }
+                }
+              }
+              if (pExistingNode) {
+                pParentNode->RemoveChild(pExistingNode);
+              }
+            }
+            pContainerItem->m_pOldSubform = pNewSubform;
+          }
+          pContainerItem->m_pFormNode = pDocument->DataMerge_CopyContainer(
+              pContainerItem->m_pFormNode, pParentNode,
+              ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Record)), TRUE);
+        } break;
+        case XFA_ELEMENT_ContentArea: {
+          CXFA_Node* pParentNode = pContainerItem->m_pParent->m_pFormNode;
+          for (CXFA_Node* pChildNode =
+                   pParentNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+               pChildNode;
+               pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+            if (pChildNode->GetTemplateNode() != pContainerItem->m_pFormNode) {
+              continue;
+            }
+            pContainerItem->m_pFormNode = pChildNode;
+            break;
+          }
+        } break;
+        default:
+          break;
+      }
+    }
+    if (!pPendingPageSet->GetNodeItem(XFA_NODEITEM_Parent)) {
+      CXFA_Node* pFormToplevelSubform =
+          pDocument->GetXFAObject(XFA_HASHCODE_Form)
+              ->AsNode()
+              ->GetFirstChildByClass(XFA_ELEMENT_Subform);
+      pFormToplevelSubform->InsertChild(pPendingPageSet);
+    }
+    pDocument->DataMerge_UpdateBindingRelations(pPendingPageSet);
+    pPendingPageSet->SetFlag(XFA_NODEFLAG_Initialized);
+  }
+  pPendingPageSet = GetRootLayoutItem()->m_pFormNode;
+  while (pPendingPageSet) {
+    CXFA_Node* pNextPendingPageSet =
+        pPendingPageSet->GetNextSameClassSibling(XFA_ELEMENT_PageSet);
+    CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode>
+        sIterator(pPendingPageSet);
+    CXFA_Node* pNode = sIterator.GetCurrent();
+    while (pNode) {
+      if (pNode->HasFlag(XFA_NODEFLAG_UnusedNode)) {
+        if (pNode->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {
+          XFA_ELEMENT eCurId = pNode->GetClassID();
+          if (eCurId == XFA_ELEMENT_PageArea || eCurId == XFA_ELEMENT_PageSet) {
+            CXFA_ContainerIterator iteChild(pNode);
+            CXFA_Node* pChildNode = iteChild.MoveToNext();
+            for (; pChildNode; pChildNode = iteChild.MoveToNext()) {
+              CXFA_LayoutItem* pLayoutItem = static_cast<CXFA_LayoutItem*>(
+                  pChildNode->GetUserData(XFA_LAYOUTITEMKEY));
+              if (pLayoutItem) {
+                pNotify->OnLayoutEvent(pDocLayout, pLayoutItem,
+                                       XFA_LAYOUTEVENT_ItemRemoving);
+                delete pLayoutItem;
+              }
+            }
+          } else if (eCurId != XFA_ELEMENT_ContentArea) {
+            CXFA_LayoutItem* pLayoutItem = static_cast<CXFA_LayoutItem*>(
+                pNode->GetUserData(XFA_LAYOUTITEMKEY));
+            if (pLayoutItem) {
+              pNotify->OnLayoutEvent(pDocLayout, pLayoutItem,
+                                     XFA_LAYOUTEVENT_ItemRemoving);
+              delete pLayoutItem;
+            }
+          }
+          CXFA_Node* pNext = sIterator.SkipChildrenAndMoveToNext();
+          pNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pNode);
+          pNode = pNext;
+        } else {
+          pNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);
+          pNode->SetFlag(XFA_NODEFLAG_Initialized);
+          pNode = sIterator.MoveToNext();
+        }
+      } else {
+        pNode->SetFlag(XFA_NODEFLAG_Initialized);
+        pNode = sIterator.MoveToNext();
+      }
+    }
+    pPendingPageSet = pNextPendingPageSet;
+  }
+}
+void CXFA_LayoutPageMgr::LayoutPageSetContents() {
+  CXFA_ContainerLayoutItem* pRootLayoutItem = GetRootLayoutItem();
+  for (; pRootLayoutItem;
+       pRootLayoutItem =
+           (CXFA_ContainerLayoutItem*)pRootLayoutItem->m_pNextSibling) {
+    CXFA_NodeIteratorTemplate<
+        CXFA_ContainerLayoutItem,
+        CXFA_TraverseStrategy_ContentAreaContainerLayoutItem>
+        iterator(pRootLayoutItem);
+    for (CXFA_ContainerLayoutItem* pContainerItem = iterator.GetCurrent();
+         pContainerItem; pContainerItem = iterator.MoveToNext()) {
+      CXFA_Node* pNode = pContainerItem->m_pFormNode;
+      switch (pNode->GetClassID()) {
+        case XFA_ELEMENT_PageArea:
+          m_pLayoutProcessor->GetRootRootItemLayoutProcessor()
+              ->DoLayoutPageArea(pContainerItem);
+          break;
+        default:
+          break;
+      }
+    }
+  }
+}
+void XFA_SyncContainer(IXFA_Notify* pNotify,
+                       IXFA_DocLayout* pDocLayout,
+                       CXFA_LayoutItem* pContainerItem,
+                       FX_DWORD dwRelevant,
+                       FX_BOOL bVisible,
+                       int32_t nPageIndex) {
+  FX_BOOL bVisibleItem = FALSE;
+  FX_DWORD dwStatus = 0;
+  FX_DWORD dwRelevantContainer = 0;
+  if (bVisible) {
+    XFA_ATTRIBUTEENUM eAttributeValue =
+        pContainerItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Presence);
+    if (eAttributeValue == XFA_ATTRIBUTEENUM_Visible ||
+        eAttributeValue == XFA_ATTRIBUTEENUM_Unknown) {
+      bVisibleItem = TRUE;
+    }
+    dwRelevantContainer =
+        XFA_GetRelevant(pContainerItem->m_pFormNode, dwRelevant);
+    dwStatus =
+        (bVisibleItem ? XFA_LAYOUTSTATUS_Visible : 0) | dwRelevantContainer;
+  }
+  pNotify->OnLayoutEvent(pDocLayout, pContainerItem, XFA_LAYOUTEVENT_ItemAdded,
+                         (void*)(uintptr_t)nPageIndex,
+                         (void*)(uintptr_t)dwStatus);
+  for (CXFA_LayoutItem* pChild = pContainerItem->m_pFirstChild; pChild;
+       pChild = pChild->m_pNextSibling) {
+    if (pChild->IsContentLayoutItem()) {
+      XFA_SyncContainer(pNotify, pDocLayout, pChild, dwRelevantContainer,
+                        bVisibleItem, nPageIndex);
+    }
+  }
+}
+void CXFA_LayoutPageMgr::SyncLayoutData() {
+  MergePageSetContents();
+  LayoutPageSetContents();
+  IXFA_Notify* pNotify =
+      m_pTemplatePageSetRoot->GetDocument()->GetParser()->GetNotify();
+  int32_t nPageIdx = -1;
+  CXFA_ContainerLayoutItem* pRootLayoutItem = GetRootLayoutItem();
+  for (; pRootLayoutItem;
+       pRootLayoutItem =
+           (CXFA_ContainerLayoutItem*)pRootLayoutItem->m_pNextSibling) {
+    CXFA_NodeIteratorTemplate<
+        CXFA_ContainerLayoutItem,
+        CXFA_TraverseStrategy_ContentAreaContainerLayoutItem>
+        iteratorParent(pRootLayoutItem);
+    for (CXFA_ContainerLayoutItem* pContainerItem = iteratorParent.GetCurrent();
+         pContainerItem; pContainerItem = iteratorParent.MoveToNext()) {
+      switch (pContainerItem->m_pFormNode->GetClassID()) {
+        case XFA_ELEMENT_PageArea: {
+          nPageIdx++;
+          FX_DWORD dwRelevant =
+              XFA_LAYOUTSTATUS_Viewable | XFA_LAYOUTSTATUS_Printable;
+          CXFA_NodeIteratorTemplate<CXFA_LayoutItem,
+                                    CXFA_TraverseStrategy_LayoutItem>
+              iterator(pContainerItem);
+          CXFA_LayoutItem* pChildLayoutItem = iterator.GetCurrent();
+          while (pChildLayoutItem) {
+            CXFA_ContentLayoutItem* pContentItem =
+                pChildLayoutItem->AsContentLayoutItem();
+            if (!pContentItem) {
+              pChildLayoutItem = iterator.MoveToNext();
+              continue;
+            }
+            FX_BOOL bVisible =
+                (pContentItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Presence) ==
+                 XFA_ATTRIBUTEENUM_Visible);
+            FX_DWORD dwRelevantChild =
+                XFA_GetRelevant(pContentItem->m_pFormNode, dwRelevant);
+            XFA_SyncContainer(pNotify, m_pLayoutProcessor, pContentItem,
+                              dwRelevantChild, bVisible, nPageIdx);
+            pChildLayoutItem = iterator.SkipChildrenAndMoveToNext();
+          }
+        } break;
+        default:
+          break;
+      }
+    }
+  }
+  int32_t nPage = m_PageArray.GetSize();
+  for (int32_t i = nPage - 1; i >= m_nAvailPages; i--) {
+    CXFA_ContainerLayoutItem* pPage = m_PageArray[i];
+    m_PageArray.RemoveAt(i);
+    pNotify->OnPageEvent(pPage, XFA_PAGEEVENT_PageRemoved);
+    delete pPage;
+  }
+  ClearRecordList();
+}
+void XFA_ReleaseLayoutItem_NoPageArea(CXFA_LayoutItem* pLayoutItem) {
+  CXFA_LayoutItem *pNext, *pNode = pLayoutItem->m_pFirstChild;
+  while (pNode) {
+    pNext = pNode->m_pNextSibling;
+    pNode->m_pParent = NULL;
+    XFA_ReleaseLayoutItem_NoPageArea(pNode);
+    pNode = pNext;
+  }
+  if (pLayoutItem->m_pFormNode->GetClassID() != XFA_ELEMENT_PageArea) {
+    delete pLayoutItem;
+  }
+}
+void CXFA_LayoutPageMgr::PrepareLayout() {
+  m_pPageSetCurRoot = NULL;
+  m_ePageSetMode = XFA_ATTRIBUTEENUM_OrderedOccurrence;
+  m_nAvailPages = 0;
+  ClearRecordList();
+  if (!m_pPageSetLayoutItemRoot) {
+    return;
+  }
+  CXFA_ContainerLayoutItem* pRootLayoutItem = m_pPageSetLayoutItemRoot;
+  if (pRootLayoutItem &&
+      pRootLayoutItem->m_pFormNode->GetPacketID() == XFA_XDPPACKET_Form) {
+    CXFA_Node* pPageSetFormNode = pRootLayoutItem->m_pFormNode;
+    pRootLayoutItem->m_pFormNode->GetDocument()->m_pPendingPageSet.RemoveAll();
+    if (pPageSetFormNode->HasFlag(XFA_NODEFLAG_HasRemoved)) {
+      XFA_ReleaseLayoutItem(pRootLayoutItem);
+      m_pPageSetLayoutItemRoot = NULL;
+      pRootLayoutItem = NULL;
+      pPageSetFormNode = NULL;
+      m_PageArray.RemoveAll();
+    }
+    while (pPageSetFormNode) {
+      CXFA_Node* pNextPageSet =
+          pPageSetFormNode->GetNextSameClassSibling(XFA_ELEMENT_PageSet);
+      pPageSetFormNode->GetNodeItem(XFA_NODEITEM_Parent)
+          ->RemoveChild(pPageSetFormNode, FALSE);
+      pRootLayoutItem->m_pFormNode->GetDocument()->m_pPendingPageSet.Add(
+          pPageSetFormNode);
+      pPageSetFormNode = pNextPageSet;
+    }
+  }
+  pRootLayoutItem = m_pPageSetLayoutItemRoot;
+  CXFA_ContainerLayoutItem* pNextLayout = NULL;
+  for (; pRootLayoutItem; pRootLayoutItem = pNextLayout) {
+    pNextLayout = (CXFA_ContainerLayoutItem*)pRootLayoutItem->m_pNextSibling;
+    SaveLayoutItem(pRootLayoutItem);
+    delete pRootLayoutItem;
+  }
+  m_pPageSetLayoutItemRoot = NULL;
+}
diff --git a/xfa/fxfa/parser/xfa_layout_pagemgr_new.h b/xfa/fxfa/parser/xfa_layout_pagemgr_new.h
new file mode 100644
index 0000000..354daa5
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_layout_pagemgr_new.h
@@ -0,0 +1,152 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_LAYOUT_PAGEMGR_NEW_H_
+#define XFA_FXFA_PARSER_XFA_LAYOUT_PAGEMGR_NEW_H_
+
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_layout_itemlayout.h"
+
+class CXFA_ContainerRecord {
+ public:
+  CXFA_ContainerRecord(CXFA_ContainerLayoutItem* pPageSet = NULL,
+                       CXFA_ContainerLayoutItem* pPageArea = NULL,
+                       CXFA_ContainerLayoutItem* pContentArea = NULL)
+      : pCurPageSet(pPageSet),
+        pCurPageArea(pPageArea),
+        pCurContentArea(pContentArea) {}
+  CXFA_ContainerLayoutItem* pCurPageSet;
+  CXFA_ContainerLayoutItem* pCurPageArea;
+  CXFA_ContainerLayoutItem* pCurContentArea;
+};
+class CXFA_LayoutPageMgr {
+ public:
+  CXFA_LayoutPageMgr(CXFA_LayoutProcessor* pLayoutProcessor);
+  ~CXFA_LayoutPageMgr();
+  FX_BOOL InitLayoutPage(CXFA_Node* pFormNode);
+  FX_BOOL PrepareFirstPage(CXFA_Node* pRootSubform);
+  FX_FLOAT GetAvailHeight();
+  FX_BOOL GetNextAvailContentHeight(FX_FLOAT fChildHeight);
+  void SubmitContentItem(CXFA_ContentLayoutItem* pContentLayoutItem,
+                         XFA_ItemLayoutProcessorResult eStatus);
+  void FinishPaginatedPageSets();
+  void SyncLayoutData();
+  int32_t GetPageCount() const;
+  IXFA_LayoutPage* GetPage(int32_t index) const;
+  int32_t GetPageIndex(const IXFA_LayoutPage* pPage) const;
+  inline CXFA_ContainerLayoutItem* GetRootLayoutItem() const {
+    return m_pPageSetLayoutItemRoot;
+  }
+  FX_BOOL ProcessBreakBeforeOrAfter(CXFA_Node* pBreakNode,
+                                    FX_BOOL bBefore,
+                                    CXFA_Node*& pBreakLeaderNode,
+                                    CXFA_Node*& pBreakTrailerNode,
+                                    FX_BOOL& bCreatePage);
+  FX_BOOL ProcessOverflow(CXFA_Node* pFormNode,
+                          CXFA_Node*& pLeaderNode,
+                          CXFA_Node*& pTrailerNode,
+                          FX_BOOL bDataMerge = FALSE,
+                          FX_BOOL bCreatePage = TRUE);
+  CXFA_Node* QueryOverflow(CXFA_Node* pFormNode,
+                           CXFA_LayoutContext* pLayoutContext = NULL);
+  FX_BOOL ProcessBookendLeaderOrTrailer(CXFA_Node* pBookendNode,
+                                        FX_BOOL bLeader,
+                                        CXFA_Node*& pBookendAppendNode);
+  CXFA_LayoutItem* FindOrCreateLayoutItem(CXFA_Node* pFormNode);
+
+ protected:
+  FX_BOOL AppendNewPage(FX_BOOL bFirstTemPage = FALSE);
+  void ReorderPendingLayoutRecordToTail(CXFA_ContainerRecord* pNewRecord,
+                                        CXFA_ContainerRecord* pPrevRecord);
+  void RemoveLayoutRecord(CXFA_ContainerRecord* pNewRecord,
+                          CXFA_ContainerRecord* pPrevRecord);
+  inline CXFA_ContainerRecord* GetCurrentContainerRecord() {
+    CXFA_ContainerRecord* result =
+        ((CXFA_ContainerRecord*)m_rgProposedContainerRecord.GetAt(
+            m_pCurrentContainerRecord));
+    ASSERT(result);
+    return result;
+  }
+  CXFA_ContainerRecord* CreateContainerRecord(CXFA_Node* pPageNode = NULL,
+                                              FX_BOOL bCreateNew = FALSE);
+  void AddPageAreaLayoutItem(CXFA_ContainerRecord* pNewRecord,
+                             CXFA_Node* pNewPageArea);
+  void AddContentAreaLayoutItem(CXFA_ContainerRecord* pNewRecord,
+                                CXFA_Node* pContentArea);
+  FX_BOOL RunBreak(XFA_ELEMENT eBreakType,
+                   XFA_ATTRIBUTEENUM eTargetType,
+                   CXFA_Node* pTarget,
+                   FX_BOOL bStartNew);
+  CXFA_Node* BreakOverflow(CXFA_Node* pOverflowNode,
+                           CXFA_Node*& pLeaderTemplate,
+                           CXFA_Node*& pTrailerTemplate,
+                           FX_BOOL bCreatePage = TRUE);
+  FX_BOOL ResolveBookendLeaderOrTrailer(CXFA_Node* pBookendNode,
+                                        FX_BOOL bLeader,
+                                        CXFA_Node*& pBookendAppendTemplate);
+  FX_BOOL ExecuteBreakBeforeOrAfter(CXFA_Node* pCurNode,
+                                    FX_BOOL bBefore,
+                                    CXFA_Node*& pBreakLeaderTemplate,
+                                    CXFA_Node*& pBreakTrailerTemplate);
+
+  int32_t CreateMinPageRecord(CXFA_Node* pPageArea,
+                              FX_BOOL bTargetPageArea,
+                              FX_BOOL bCreateLast = FALSE);
+  void CreateMinPageSetRecord(CXFA_Node* pPageSet, FX_BOOL bCreateAll = FALSE);
+  void CreateNextMinRecord(CXFA_Node* pRecordNode);
+  FX_BOOL FindPageAreaFromPageSet(CXFA_Node* pPageSet,
+                                  CXFA_Node* pStartChild,
+                                  CXFA_Node* pTargetPageArea = NULL,
+                                  CXFA_Node* pTargetContentArea = NULL,
+                                  FX_BOOL bNewPage = FALSE,
+                                  FX_BOOL bQuery = FALSE);
+  FX_BOOL FindPageAreaFromPageSet_Ordered(CXFA_Node* pPageSet,
+                                          CXFA_Node* pStartChild,
+                                          CXFA_Node* pTargetPageArea = NULL,
+                                          CXFA_Node* pTargetContentArea = NULL,
+                                          FX_BOOL bNewPage = FALSE,
+                                          FX_BOOL bQuery = FALSE);
+  FX_BOOL FindPageAreaFromPageSet_SimplexDuplex(
+      CXFA_Node* pPageSet,
+      CXFA_Node* pStartChild,
+      CXFA_Node* pTargetPageArea = NULL,
+      CXFA_Node* pTargetContentArea = NULL,
+      FX_BOOL bNewPage = FALSE,
+      FX_BOOL bQuery = FALSE,
+      XFA_ATTRIBUTEENUM ePreferredPosition = XFA_ATTRIBUTEENUM_First);
+  FX_BOOL MatchPageAreaOddOrEven(CXFA_Node* pPageArea, FX_BOOL bLastMatch);
+  CXFA_Node* GetNextAvailPageArea(CXFA_Node* pTargetPageArea,
+                                  CXFA_Node* pTargetContentArea = NULL,
+                                  FX_BOOL bNewPage = FALSE,
+                                  FX_BOOL bQuery = FALSE);
+  FX_BOOL GetNextContentArea(CXFA_Node* pTargetContentArea);
+  void InitPageSetMap();
+  void ProcessLastPageSet();
+  inline FX_BOOL IsPageSetRootOrderedOccurrence() {
+    return m_ePageSetMode == XFA_ATTRIBUTEENUM_OrderedOccurrence;
+  }
+  void ClearData();
+  void ClearRecordList();
+  void MergePageSetContents();
+  void LayoutPageSetContents();
+  void PrepareLayout();
+  void SaveLayoutItem(CXFA_LayoutItem* pParentLayoutItem);
+  CXFA_LayoutProcessor* m_pLayoutProcessor;
+  CXFA_Node* m_pTemplatePageSetRoot;
+  CXFA_ContainerLayoutItem* m_pPageSetLayoutItemRoot;
+  CXFA_ContainerLayoutItem* m_pPageSetCurRoot;
+  FX_POSITION m_pCurrentContainerRecord;
+  CFX_PtrList m_rgProposedContainerRecord;
+  CXFA_Node* m_pCurPageArea;
+  int32_t m_nAvailPages;
+  int32_t m_nCurPageCount;
+  XFA_ATTRIBUTEENUM m_ePageSetMode;
+  FX_BOOL m_bCreateOverFlowPage;
+  CFX_MapPtrTemplate<CXFA_Node*, int32_t> m_pPageSetMap;
+  CFX_ArrayTemplate<CXFA_ContainerLayoutItem*> m_PageArray;
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_LAYOUT_PAGEMGR_NEW_H_
diff --git a/xfa/fxfa/parser/xfa_locale.cpp b/xfa/fxfa/parser/xfa_locale.cpp
new file mode 100644
index 0000000..eb8c244
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_locale.cpp
@@ -0,0 +1,377 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_locale.h"
+
+#include "core/include/fxcrt/fx_xml.h"
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+static const FX_WCHAR g_FX_Percent[] = L"z,zzz,zzz,zzz,zzz,zzz%";
+static const FX_WCHAR g_FX_Currency[] = L"$z,zzz,zzz,zzz,zzz,zz9.99";
+static const FX_WCHAR g_FX_Decimal[] = L"z,zzz,zzz,zzz,zzz,zz9.zzz";
+static const FX_WCHAR g_FX_Integer[] = L"z,zzz,zzz,zzz,zzz,zzz";
+
+CXFA_XMLLocale::CXFA_XMLLocale(CXML_Element* pLocaleData) {
+  m_pLocaleData = pLocaleData;
+}
+CXFA_XMLLocale::~CXFA_XMLLocale() {
+  if (m_pLocaleData) {
+    delete m_pLocaleData;
+  }
+}
+void CXFA_XMLLocale::Release() {
+  delete this;
+}
+CFX_WideString CXFA_XMLLocale::GetName() {
+  return m_pLocaleData ? m_pLocaleData->GetAttrValue("name") : CFX_WideString();
+}
+void CXFA_XMLLocale::GetNumbericSymbol(FX_LOCALENUMSYMBOL eType,
+                                       CFX_WideString& wsNumSymbol) const {
+  CFX_ByteString bsSymbols;
+  CFX_WideString wsName;
+  switch (eType) {
+    case FX_LOCALENUMSYMBOL_Decimal:
+      bsSymbols = "numberSymbols";
+      wsName = FX_WSTRC(L"decimal");
+      break;
+    case FX_LOCALENUMSYMBOL_Grouping:
+      bsSymbols = "numberSymbols";
+      wsName = FX_WSTRC(L"grouping");
+      break;
+    case FX_LOCALENUMSYMBOL_Percent:
+      bsSymbols = "numberSymbols";
+      wsName = FX_WSTRC(L"percent");
+      break;
+    case FX_LOCALENUMSYMBOL_Minus:
+      bsSymbols = "numberSymbols";
+      wsName = FX_WSTRC(L"minus");
+      break;
+    case FX_LOCALENUMSYMBOL_Zero:
+      bsSymbols = "numberSymbols";
+      wsName = FX_WSTRC(L"zero");
+      break;
+    case FX_LOCALENUMSYMBOL_CurrencySymbol:
+      bsSymbols = "currencySymbols";
+      wsName = FX_WSTRC(L"symbol");
+      break;
+    case FX_LOCALENUMSYMBOL_CurrencyName:
+      bsSymbols = "currencySymbols";
+      wsName = FX_WSTRC(L"isoname");
+      break;
+    default:
+      return;
+  }
+  CXML_Element* pElement = m_pLocaleData->GetElement("", bsSymbols);
+  if (!pElement) {
+    return;
+  }
+  GetPattern(pElement, CFX_ByteStringC((const FX_CHAR*)bsSymbols,
+                                       bsSymbols.GetLength() - 1),
+             wsName, wsNumSymbol);
+}
+void CXFA_XMLLocale::GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const {
+  if (!m_pLocaleData) {
+    return;
+  }
+  CFX_ByteString bsSpace;
+  CXML_Element* pNumberSymbols =
+      m_pLocaleData->GetElement(bsSpace, "dateTimeSymbols");
+  if (!pNumberSymbols) {
+    return;
+  }
+  wsDtSymbol = pNumberSymbols->GetContent(0);
+}
+void CXFA_XMLLocale::GetMonthName(int32_t nMonth,
+                                  CFX_WideString& wsMonthName,
+                                  FX_BOOL bAbbr) const {
+  wsMonthName = GetCalendarSymbol("month", nMonth, bAbbr);
+}
+void CXFA_XMLLocale::GetDayName(int32_t nWeek,
+                                CFX_WideString& wsDayName,
+                                FX_BOOL bAbbr) const {
+  wsDayName = GetCalendarSymbol("day", nWeek, bAbbr);
+}
+void CXFA_XMLLocale::GetMeridiemName(CFX_WideString& wsMeridiemName,
+                                     FX_BOOL bAM) const {
+  wsMeridiemName = GetCalendarSymbol("meridiem", bAM ? 0 : 1, FALSE);
+}
+void CXFA_XMLLocale::GetTimeZone(FX_TIMEZONE& tz) const {
+  IXFA_TimeZoneProvider* pProvider = IXFA_TimeZoneProvider::Get();
+  pProvider->GetTimeZone(tz);
+}
+void CXFA_XMLLocale::GetEraName(CFX_WideString& wsEraName, FX_BOOL bAD) const {
+  wsEraName = GetCalendarSymbol("era", bAD ? 1 : 0, FALSE);
+}
+CFX_WideString CXFA_XMLLocale::GetCalendarSymbol(const CFX_ByteStringC& symbol,
+                                                 int index,
+                                                 FX_BOOL bAbbr) const {
+  CFX_ByteString pstrSymbolNames = symbol + "Names";
+  CFX_WideString wsSymbolName = L"";
+  if (m_pLocaleData) {
+    CXML_Element* pChild = m_pLocaleData->GetElement("", "calendarSymbols");
+    if (pChild) {
+      CXML_Element* pSymbolNames = pChild->GetElement("", pstrSymbolNames);
+      if (pSymbolNames) {
+        if (pSymbolNames->GetAttrInteger("abbr") != bAbbr) {
+          pSymbolNames = pChild->GetElement("", pstrSymbolNames, 1);
+        }
+        if (pSymbolNames && pSymbolNames->GetAttrInteger("abbr") == bAbbr) {
+          CXML_Element* pSymbolName =
+              pSymbolNames->GetElement("", symbol, index);
+          if (pSymbolName) {
+            wsSymbolName = pSymbolName->GetContent(0);
+          }
+        }
+      }
+    }
+  }
+  return wsSymbolName;
+}
+void CXFA_XMLLocale::GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType,
+                                    CFX_WideString& wsPattern) const {
+  CXML_Element* pElement = m_pLocaleData->GetElement("", "datePatterns");
+  if (pElement == NULL) {
+    return;
+  }
+  CFX_WideString wsName;
+  switch (eType) {
+    case FX_LOCALEDATETIMESUBCATEGORY_Short:
+      wsName = L"short";
+      break;
+    case FX_LOCALEDATETIMESUBCATEGORY_Default:
+    case FX_LOCALEDATETIMESUBCATEGORY_Medium:
+      wsName = L"med";
+      break;
+    case FX_LOCALEDATETIMESUBCATEGORY_Full:
+      wsName = L"full";
+      break;
+    case FX_LOCALEDATETIMESUBCATEGORY_Long:
+      wsName = L"long";
+      break;
+  }
+  GetPattern(pElement, "datePattern", wsName, wsPattern);
+}
+void CXFA_XMLLocale::GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType,
+                                    CFX_WideString& wsPattern) const {
+  CXML_Element* pElement = m_pLocaleData->GetElement("", "timePatterns");
+  if (pElement == NULL) {
+    return;
+  }
+  CFX_WideString wsName;
+  switch (eType) {
+    case FX_LOCALEDATETIMESUBCATEGORY_Short:
+      wsName = L"short";
+      break;
+    case FX_LOCALEDATETIMESUBCATEGORY_Default:
+    case FX_LOCALEDATETIMESUBCATEGORY_Medium:
+      wsName = L"med";
+      break;
+    case FX_LOCALEDATETIMESUBCATEGORY_Full:
+      wsName = L"full";
+      break;
+    case FX_LOCALEDATETIMESUBCATEGORY_Long:
+      wsName = L"long";
+      break;
+  }
+  GetPattern(pElement, "timePattern", wsName, wsPattern);
+}
+void CXFA_XMLLocale::GetNumPattern(FX_LOCALENUMSUBCATEGORY eType,
+                                   CFX_WideString& wsPattern) const {
+  CXML_Element* pElement = m_pLocaleData->GetElement("", "numberPatterns");
+  if (pElement == NULL) {
+    return;
+  }
+  switch (eType) {
+    case FX_LOCALENUMPATTERN_Percent:
+      wsPattern = g_FX_Percent;
+      break;
+    case FX_LOCALENUMPATTERN_Currency:
+      wsPattern = g_FX_Currency;
+      break;
+    case FX_LOCALENUMPATTERN_Decimal:
+      wsPattern = g_FX_Decimal;
+      break;
+    case FX_LOCALENUMPATTERN_Integer:
+      wsPattern = g_FX_Integer;
+      break;
+  }
+}
+void CXFA_XMLLocale::GetPattern(CXML_Element* pElement,
+                                const CFX_ByteStringC& bsTag,
+                                const CFX_WideStringC& wsName,
+                                CFX_WideString& wsPattern) const {
+  int32_t iCount = pElement->CountElements("", bsTag);
+  for (int32_t i = 0; i < iCount; i++) {
+    CXML_Element* pChild = pElement->GetElement("", bsTag, i);
+    if (pChild->GetAttrValue("name") == wsName) {
+      wsPattern = pChild->GetContent(0);
+      return;
+    }
+  }
+}
+CXFA_NodeLocale::CXFA_NodeLocale(CXFA_Node* pLocale) {
+  m_pLocale = pLocale;
+}
+CXFA_NodeLocale::~CXFA_NodeLocale() {}
+void CXFA_NodeLocale::Release() {
+  delete this;
+}
+CFX_WideString CXFA_NodeLocale::GetName() {
+  return m_pLocale ? m_pLocale->GetCData(XFA_ATTRIBUTE_Name) : NULL;
+}
+void CXFA_NodeLocale::GetNumbericSymbol(FX_LOCALENUMSYMBOL eType,
+                                        CFX_WideString& wsNumSymbol) const {
+  switch (eType) {
+    case FX_LOCALENUMSYMBOL_Decimal:
+      wsNumSymbol = GetSymbol(XFA_ELEMENT_NumberSymbols, FX_WSTRC(L"decimal"));
+      break;
+    case FX_LOCALENUMSYMBOL_Grouping:
+      wsNumSymbol = GetSymbol(XFA_ELEMENT_NumberSymbols, FX_WSTRC(L"grouping"));
+      break;
+    case FX_LOCALENUMSYMBOL_Percent:
+      wsNumSymbol = GetSymbol(XFA_ELEMENT_NumberSymbols, FX_WSTRC(L"percent"));
+      break;
+    case FX_LOCALENUMSYMBOL_Minus:
+      wsNumSymbol = GetSymbol(XFA_ELEMENT_NumberSymbols, FX_WSTRC(L"minus"));
+      break;
+    case FX_LOCALENUMSYMBOL_Zero:
+      wsNumSymbol = GetSymbol(XFA_ELEMENT_NumberSymbols, FX_WSTRC(L"zero"));
+      break;
+    case FX_LOCALENUMSYMBOL_CurrencySymbol:
+      wsNumSymbol = GetSymbol(XFA_ELEMENT_CurrencySymbols, FX_WSTRC(L"symbol"));
+      break;
+    case FX_LOCALENUMSYMBOL_CurrencyName:
+      wsNumSymbol =
+          GetSymbol(XFA_ELEMENT_CurrencySymbols, FX_WSTRC(L"isoname"));
+      break;
+  }
+}
+void CXFA_NodeLocale::GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const {
+  CXFA_Node* pSymbols =
+      m_pLocale ? m_pLocale->GetChild(0, XFA_ELEMENT_DateTimeSymbols) : NULL;
+  wsDtSymbol = pSymbols ? pSymbols->GetContent() : CFX_WideString();
+}
+void CXFA_NodeLocale::GetMonthName(int32_t nMonth,
+                                   CFX_WideString& wsMonthName,
+                                   FX_BOOL bAbbr) const {
+  wsMonthName = GetCalendarSymbol(XFA_ELEMENT_MonthNames, nMonth, bAbbr);
+}
+void CXFA_NodeLocale::GetDayName(int32_t nWeek,
+                                 CFX_WideString& wsDayName,
+                                 FX_BOOL bAbbr) const {
+  wsDayName = GetCalendarSymbol(XFA_ELEMENT_DayNames, nWeek, bAbbr);
+}
+void CXFA_NodeLocale::GetMeridiemName(CFX_WideString& wsMeridiemName,
+                                      FX_BOOL bAM) const {
+  wsMeridiemName =
+      GetCalendarSymbol(XFA_ELEMENT_MeridiemNames, bAM ? 0 : 1, FALSE);
+}
+void CXFA_NodeLocale::GetTimeZone(FX_TIMEZONE& tz) const {
+  IXFA_TimeZoneProvider* pProvider = IXFA_TimeZoneProvider::Get();
+  pProvider->GetTimeZone(tz);
+}
+void CXFA_NodeLocale::GetEraName(CFX_WideString& wsEraName, FX_BOOL bAD) const {
+  wsEraName = GetCalendarSymbol(XFA_ELEMENT_EraNames, bAD ? 1 : 0, FALSE);
+}
+void CXFA_NodeLocale::GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType,
+                                     CFX_WideString& wsPattern) const {
+  switch (eType) {
+    case FX_LOCALEDATETIMESUBCATEGORY_Short:
+      wsPattern = GetSymbol(XFA_ELEMENT_DatePatterns, FX_WSTRC(L"short"));
+      break;
+    case FX_LOCALEDATETIMESUBCATEGORY_Medium:
+    case FX_LOCALEDATETIMESUBCATEGORY_Default:
+      wsPattern = GetSymbol(XFA_ELEMENT_DatePatterns, FX_WSTRC(L"med"));
+      break;
+    case FX_LOCALEDATETIMESUBCATEGORY_Full:
+      wsPattern = GetSymbol(XFA_ELEMENT_DatePatterns, FX_WSTRC(L"full"));
+      break;
+    case FX_LOCALEDATETIMESUBCATEGORY_Long:
+      wsPattern = GetSymbol(XFA_ELEMENT_DatePatterns, FX_WSTRC(L"long"));
+      break;
+  }
+}
+void CXFA_NodeLocale::GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType,
+                                     CFX_WideString& wsPattern) const {
+  switch (eType) {
+    case FX_LOCALEDATETIMESUBCATEGORY_Short:
+      wsPattern = GetSymbol(XFA_ELEMENT_TimePatterns, FX_WSTRC(L"short"));
+      break;
+    case FX_LOCALEDATETIMESUBCATEGORY_Medium:
+    case FX_LOCALEDATETIMESUBCATEGORY_Default:
+      wsPattern = GetSymbol(XFA_ELEMENT_TimePatterns, FX_WSTRC(L"med"));
+      break;
+    case FX_LOCALEDATETIMESUBCATEGORY_Full:
+      wsPattern = GetSymbol(XFA_ELEMENT_TimePatterns, FX_WSTRC(L"full"));
+      break;
+    case FX_LOCALEDATETIMESUBCATEGORY_Long:
+      wsPattern = GetSymbol(XFA_ELEMENT_TimePatterns, FX_WSTRC(L"long"));
+      break;
+  }
+}
+void CXFA_NodeLocale::GetNumPattern(FX_LOCALENUMSUBCATEGORY eType,
+                                    CFX_WideString& wsPattern) const {
+  switch (eType) {
+    case FX_LOCALENUMPATTERN_Percent:
+      wsPattern = g_FX_Percent;
+      break;
+    case FX_LOCALENUMPATTERN_Currency:
+      wsPattern = g_FX_Currency;
+      break;
+    case FX_LOCALENUMPATTERN_Decimal:
+      wsPattern = g_FX_Decimal;
+      break;
+    case FX_LOCALENUMPATTERN_Integer:
+      wsPattern = g_FX_Integer;
+      break;
+  }
+}
+CXFA_Node* CXFA_NodeLocale::GetNodeByName(CXFA_Node* pParent,
+                                          const CFX_WideStringC& wsName) const {
+  CXFA_Node* pChild =
+      pParent ? pParent->GetNodeItem(XFA_NODEITEM_FirstChild) : NULL;
+  while (pChild) {
+    CFX_WideString wsChild;
+    if (pChild->GetAttribute(XFA_ATTRIBUTE_Name, wsChild)) {
+      if (wsChild == wsName) {
+        return pChild;
+      }
+    }
+    pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+  }
+  return NULL;
+}
+CFX_WideString CXFA_NodeLocale::GetSymbol(
+    XFA_ELEMENT eElement,
+    const CFX_WideStringC& symbol_type) const {
+  CXFA_Node* pSymbols = m_pLocale ? m_pLocale->GetChild(0, eElement) : NULL;
+  CXFA_Node* pSymbol = GetNodeByName(pSymbols, symbol_type);
+  return pSymbol ? pSymbol->GetContent() : CFX_WideString();
+}
+CFX_WideString CXFA_NodeLocale::GetCalendarSymbol(XFA_ELEMENT eElement,
+                                                  int index,
+                                                  FX_BOOL bAbbr) const {
+  CXFA_Node* pCalendar =
+      m_pLocale ? m_pLocale->GetChild(0, XFA_ELEMENT_CalendarSymbols) : NULL;
+  if (pCalendar) {
+    CXFA_Node* pNode = pCalendar->GetFirstChildByClass(eElement);
+    for (; pNode; pNode = pNode->GetNextSameClassSibling(eElement)) {
+      if (pNode->GetBoolean(XFA_ATTRIBUTE_Abbr) == bAbbr) {
+        CXFA_Node* pSymbol = pNode->GetChild(index, XFA_ELEMENT_UNKNOWN);
+        return pSymbol ? pSymbol->GetContent() : CFX_WideString();
+      }
+    }
+  }
+  return CFX_WideString();
+}
diff --git a/xfa/fxfa/parser/xfa_locale.h b/xfa/fxfa/parser/xfa_locale.h
new file mode 100644
index 0000000..522df19
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_locale.h
@@ -0,0 +1,93 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_LOCALE_H_
+#define XFA_FXFA_PARSER_XFA_LOCALE_H_
+
+#include "xfa/fgas/localization/fgas_locale.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+
+class CXFA_XMLLocale : public IFX_Locale {
+ public:
+  CXFA_XMLLocale(CXML_Element* pLocaleData);
+  virtual void Release();
+  virtual CFX_WideString GetName();
+  virtual void GetNumbericSymbol(FX_LOCALENUMSYMBOL eType,
+                                 CFX_WideString& wsNumSymbol) const;
+
+  virtual void GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const;
+  virtual void GetMonthName(int32_t nMonth,
+                            CFX_WideString& wsMonthName,
+                            FX_BOOL bAbbr = TRUE) const;
+  virtual void GetDayName(int32_t nWeek,
+                          CFX_WideString& wsDayName,
+                          FX_BOOL bAbbr = TRUE) const;
+  virtual void GetMeridiemName(CFX_WideString& wsMeridiemName,
+                               FX_BOOL bAM = TRUE) const;
+  virtual void GetTimeZone(FX_TIMEZONE& tz) const;
+  virtual void GetEraName(CFX_WideString& wsEraName, FX_BOOL bAD = TRUE) const;
+
+  virtual void GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType,
+                              CFX_WideString& wsPattern) const;
+  virtual void GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType,
+                              CFX_WideString& wsPattern) const;
+  virtual void GetNumPattern(FX_LOCALENUMSUBCATEGORY eType,
+                             CFX_WideString& wsPattern) const;
+
+ protected:
+  ~CXFA_XMLLocale();
+  void GetPattern(CXML_Element* pElement,
+                  const CFX_ByteStringC& bsTag,
+                  const CFX_WideStringC& wsName,
+                  CFX_WideString& wsPattern) const;
+  CFX_WideString GetCalendarSymbol(const CFX_ByteStringC& symbol,
+                                   int index,
+                                   FX_BOOL bAbbr) const;
+
+ private:
+  CXML_Element* m_pLocaleData;
+};
+class CXFA_NodeLocale : public IFX_Locale {
+ public:
+  CXFA_NodeLocale(CXFA_Node* pLocale);
+  virtual void Release();
+  virtual CFX_WideString GetName();
+  virtual void GetNumbericSymbol(FX_LOCALENUMSYMBOL eType,
+                                 CFX_WideString& wsNumSymbol) const;
+
+  virtual void GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const;
+  virtual void GetMonthName(int32_t nMonth,
+                            CFX_WideString& wsMonthName,
+                            FX_BOOL bAbbr = TRUE) const;
+  virtual void GetDayName(int32_t nWeek,
+                          CFX_WideString& wsDayName,
+                          FX_BOOL bAbbr = TRUE) const;
+  virtual void GetMeridiemName(CFX_WideString& wsMeridiemName,
+                               FX_BOOL bAM = TRUE) const;
+  virtual void GetTimeZone(FX_TIMEZONE& tz) const;
+  virtual void GetEraName(CFX_WideString& wsEraName, FX_BOOL bAD = TRUE) const;
+
+  virtual void GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType,
+                              CFX_WideString& wsPattern) const;
+  virtual void GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType,
+                              CFX_WideString& wsPattern) const;
+  virtual void GetNumPattern(FX_LOCALENUMSUBCATEGORY eType,
+                             CFX_WideString& wsPattern) const;
+
+ protected:
+  ~CXFA_NodeLocale();
+  CXFA_Node* GetNodeByName(CXFA_Node* pParent,
+                           const CFX_WideStringC& wsName) const;
+  CFX_WideString GetSymbol(XFA_ELEMENT eElement,
+                           const CFX_WideStringC& symbol_type) const;
+  CFX_WideString GetCalendarSymbol(XFA_ELEMENT eElement,
+                                   int index,
+                                   FX_BOOL bAbbr) const;
+
+  CXFA_Node* m_pLocale;
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_LOCALE_H_
diff --git a/xfa/fxfa/parser/xfa_localemgr.cpp b/xfa/fxfa/parser/xfa_localemgr.cpp
new file mode 100644
index 0000000..c3ec203
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_localemgr.cpp
@@ -0,0 +1,1305 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+
+#include "core/include/fxcodec/fx_codec.h"
+#include "core/include/fxcrt/fx_xml.h"
+#include "core/include/fxge/fx_ge.h"
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_locale.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+const uint8_t g_enUS_Locale[] = {
+    0x78, 0x9C, 0x95, 0x56, 0xD1, 0x6E, 0x9B, 0x30, 0x14, 0x7D, 0x9F, 0xB4,
+    0x7F, 0x40, 0xD6, 0x2A, 0xB5, 0x52, 0x56, 0x6F, 0x8F, 0xA9, 0x88, 0xA5,
+    0x6C, 0x24, 0x9B, 0x3A, 0xD1, 0x55, 0x22, 0x55, 0xB5, 0xBE, 0x4C, 0x0E,
+    0xDC, 0x05, 0x34, 0xB0, 0x23, 0x83, 0x37, 0x05, 0xED, 0xE3, 0x67, 0x07,
+    0xC3, 0xC0, 0xF6, 0x24, 0xC2, 0x4B, 0x7C, 0xCF, 0x3D, 0xE7, 0xE6, 0xDE,
+    0x63, 0x30, 0x84, 0x25, 0x4F, 0x69, 0x09, 0x01, 0xA3, 0x15, 0xAC, 0x10,
+    0xB0, 0xEF, 0x4F, 0x09, 0x0A, 0x32, 0xA8, 0xD3, 0x15, 0xDA, 0xB0, 0x43,
+    0x59, 0xD4, 0xF9, 0xF5, 0xBA, 0x02, 0x51, 0xA4, 0xF4, 0x06, 0x91, 0x50,
+    0x53, 0x59, 0x46, 0x45, 0x72, 0xAA, 0xF6, 0xBC, 0xAC, 0x8D, 0xEA, 0x20,
+    0xE0, 0xC0, 0x45, 0x41, 0x99, 0x62, 0x54, 0x9C, 0x35, 0xF9, 0x83, 0x82,
+    0x6B, 0xB3, 0x26, 0xF7, 0x94, 0x49, 0x2A, 0x4E, 0x21, 0xEE, 0xC2, 0xD7,
+    0xAF, 0x0C, 0xBE, 0x85, 0xBD, 0xF0, 0x26, 0x62, 0x2A, 0xD2, 0xDC, 0x41,
+    0xD7, 0x47, 0x51, 0x94, 0x1E, 0xAE, 0xAB, 0xBF, 0x97, 0x0C, 0x3C, 0x60,
+    0xE9, 0x32, 0xD7, 0xF2, 0x20, 0xEB, 0xC6, 0x81, 0x13, 0x38, 0x36, 0x50,
+    0xED, 0x41, 0x38, 0x99, 0xAF, 0x69, 0xC3, 0x7D, 0xF8, 0x03, 0xFF, 0xE5,
+    0x17, 0x44, 0x90, 0xDA, 0x09, 0x3C, 0xB2, 0xA8, 0xE7, 0x9D, 0xA3, 0x80,
+    0xEE, 0xF7, 0x62, 0x85, 0xDE, 0xA3, 0x91, 0x73, 0x3E, 0xD7, 0x7C, 0x86,
+    0xF9, 0xEC, 0x9A, 0x6B, 0x96, 0xCF, 0x2B, 0x9F, 0x55, 0x3E, 0x9F, 0x7C,
+    0x0E, 0xF9, 0xDC, 0xF1, 0x19, 0xF3, 0x7F, 0x4F, 0x32, 0x7A, 0x32, 0xB7,
+    0x90, 0x5A, 0x91, 0x44, 0xAA, 0x5B, 0x4E, 0x75, 0xAE, 0xD7, 0x5D, 0x92,
+    0xC4, 0xDC, 0x81, 0x76, 0x12, 0x6A, 0x1B, 0x7B, 0x86, 0x8C, 0xB9, 0xE8,
+    0x2E, 0x97, 0xC2, 0x01, 0xB7, 0xA2, 0xB0, 0xA1, 0x84, 0x36, 0x52, 0x8C,
+    0x41, 0x3C, 0xF4, 0x35, 0xEA, 0x71, 0xB4, 0x6B, 0xA6, 0x59, 0xBB, 0x53,
+    0xBB, 0x4D, 0xBB, 0x45, 0xBB, 0x39, 0xBB, 0x2F, 0xBB, 0x29, 0x7F, 0x3F,
+    0xFA, 0x21, 0xCD, 0x0A, 0xA8, 0xFA, 0x67, 0xCF, 0x84, 0x64, 0x1D, 0x2B,
+    0x77, 0xFB, 0x60, 0xC4, 0x23, 0x8F, 0x56, 0x02, 0x4F, 0x2B, 0x28, 0x04,
+    0x04, 0x35, 0xD5, 0xD4, 0x8A, 0x7C, 0xF8, 0x18, 0x62, 0xFD, 0xDB, 0x25,
+    0xC8, 0x3A, 0x1A, 0x42, 0x3C, 0x10, 0x75, 0x60, 0x9D, 0x11, 0x5D, 0xE3,
+    0x0D, 0x3C, 0xD2, 0xA6, 0x01, 0xC1, 0xCE, 0x7B, 0x3A, 0x44, 0xE6, 0x00,
+    0xF9, 0x21, 0xCB, 0x12, 0x91, 0x8D, 0xBA, 0x16, 0x41, 0xAC, 0xAE, 0x20,
+    0x5A, 0x04, 0xDF, 0xD4, 0xA5, 0x27, 0x1C, 0xB8, 0x56, 0x21, 0x23, 0x2D,
+    0x39, 0x3B, 0x20, 0x72, 0xA1, 0xA8, 0x82, 0xEC, 0xAC, 0xB9, 0x40, 0x52,
+    0xE7, 0x5C, 0x34, 0x4A, 0x84, 0x23, 0xEC, 0xE1, 0xE3, 0xC9, 0x84, 0x0A,
+    0x68, 0x8A, 0x6A, 0x34, 0xF1, 0x28, 0x9A, 0x4C, 0x9C, 0xDF, 0xC5, 0xF1,
+    0x5D, 0x92, 0x04, 0xEB, 0xE0, 0x25, 0xC4, 0x23, 0x92, 0x55, 0x61, 0x32,
+    0xEA, 0x65, 0x9A, 0xF3, 0xA4, 0x83, 0x64, 0x86, 0xC0, 0xCC, 0xA9, 0x25,
+    0x1E, 0x3E, 0x9E, 0xCC, 0x65, 0x8C, 0xDA, 0x29, 0xAC, 0xDF, 0xEC, 0x4F,
+    0xA7, 0x38, 0xFB, 0xF9, 0xB9, 0xAA, 0x93, 0x4D, 0xB4, 0xFD, 0xFD, 0x4C,
+    0xF3, 0x2F, 0xED, 0x4B, 0x67, 0xCE, 0x98, 0xA4, 0x74, 0x4C, 0xEA, 0x53,
+    0xF1, 0x9F, 0x43, 0x93, 0xD8, 0xB4, 0xA2, 0x30, 0xFD, 0xE2, 0x41, 0xA4,
+    0x5D, 0xB4, 0xED, 0xF2, 0xB6, 0x6D, 0xDB, 0x10, 0x4F, 0x78, 0x4E, 0x21,
+    0x23, 0x4C, 0xA5, 0x10, 0xC0, 0xD2, 0x13, 0x22, 0x6F, 0x3A, 0xE9, 0x72,
+    0xF9, 0xE7, 0x7A, 0x58, 0xDE, 0xCC, 0xAC, 0x72, 0x04, 0x91, 0x02, 0x6B,
+    0xCC, 0xDF, 0x5F, 0x79, 0x54, 0xD8, 0x9A, 0x62, 0x28, 0xD4, 0x0F, 0x3A,
+    0x09, 0x4D, 0xD9, 0x0C, 0xD2, 0xA2, 0xA2, 0x6A, 0xF3, 0x6F, 0x7B, 0x7D,
+    0x97, 0xB6, 0xD5, 0xC3, 0xBB, 0x95, 0xCB, 0x63, 0xA1, 0x37, 0x7E, 0x31,
+    0x8B, 0x3F, 0x74, 0x7D, 0x35, 0x8B, 0x5E, 0x15, 0x4C, 0xD6, 0x88, 0xBC,
+    0x9D, 0x45, 0x6E, 0x41, 0x70, 0x44, 0xDE, 0xB9, 0x5C, 0x3C, 0x1D, 0x5B,
+    0x21, 0xFD, 0x16, 0x0C, 0x4E, 0x4C, 0x81, 0xFE, 0x66, 0x3B, 0x07, 0x6A,
+    0x9B, 0xD4, 0xA9, 0x31, 0xC9, 0xBB, 0x25, 0x8C, 0xA2, 0xA8, 0xB9, 0x5E,
+    0x20, 0xF2, 0x94, 0x44, 0xB3, 0x45, 0x63, 0xCB, 0x5D, 0x09, 0xB6, 0x7B,
+    0xD5, 0x58, 0xF7, 0x55, 0xA4, 0x96, 0x7F, 0x01, 0x75, 0x37, 0x1B, 0x8B,
+};
+const uint8_t g_enGB_Locale[] = {
+    0x78, 0x9C, 0x95, 0x56, 0xD1, 0x6E, 0xD3, 0x30, 0x14, 0x7D, 0x47, 0xE2,
+    0x1F, 0xA2, 0x88, 0x49, 0x20, 0x6D, 0x33, 0x3C, 0x6E, 0xEA, 0x2C, 0x75,
+    0xEB, 0xD6, 0x32, 0xC8, 0xA8, 0x48, 0xC5, 0xC4, 0x5E, 0x90, 0x9B, 0x78,
+    0x8D, 0x59, 0x62, 0x57, 0x4E, 0xCC, 0x94, 0xFC, 0x02, 0x9F, 0xC0, 0x23,
+    0xCF, 0x08, 0xF1, 0x01, 0xBC, 0xF0, 0x2F, 0x48, 0xFB, 0x0C, 0x6E, 0x1A,
+    0x27, 0x4B, 0x1C, 0xAF, 0x64, 0x79, 0x89, 0xEF, 0xB9, 0xE7, 0xDC, 0xDE,
+    0x7B, 0x9C, 0xB8, 0x19, 0xC5, 0x22, 0x20, 0x31, 0x75, 0x38, 0x49, 0xE8,
+    0x91, 0x4B, 0xF9, 0xA7, 0xE9, 0xB1, 0xEB, 0x84, 0x34, 0x0D, 0x8E, 0xDC,
+    0xBB, 0xAF, 0xBF, 0xEE, 0x7E, 0xFE, 0x78, 0x0E, 0xB7, 0xBF, 0xDF, 0x7E,
+    0xBF, 0x70, 0xF1, 0xA8, 0x24, 0xF2, 0x90, 0x48, 0x3F, 0x4F, 0x96, 0x22,
+    0x4E, 0xB5, 0x66, 0x25, 0xE9, 0x4A, 0x48, 0x46, 0x38, 0x30, 0x12, 0xC1,
+    0xB3, 0xE8, 0x02, 0xE0, 0x54, 0xAF, 0xF1, 0x39, 0xE1, 0x8A, 0xC8, 0x7C,
+    0x84, 0xAA, 0xF0, 0xE9, 0x13, 0x8D, 0x9F, 0xD1, 0xA5, 0xB4, 0x26, 0x3C,
+    0x22, 0x83, 0xA8, 0x87, 0x8E, 0xD7, 0x92, 0xC5, 0x16, 0x6E, 0x5F, 0x7F,
+    0xAE, 0x38, 0xB5, 0x80, 0x71, 0x9F, 0x39, 0x56, 0x2B, 0x95, 0x66, 0x3D,
+    0xD8, 0xA7, 0xEB, 0x8C, 0x26, 0x4B, 0x2A, 0x7B, 0x99, 0x77, 0x41, 0x26,
+    0x6C, 0xF8, 0x85, 0xF8, 0x62, 0x17, 0x4C, 0x68, 0x60, 0x26, 0x50, 0xCB,
+    0xA2, 0x9A, 0xB7, 0x89, 0x1C, 0xB2, 0x5C, 0xCA, 0x23, 0xF7, 0x95, 0xDB,
+    0x72, 0xCE, 0xE6, 0x9A, 0xCD, 0x30, 0x9B, 0x5D, 0x43, 0xCD, 0xB2, 0x79,
+    0x65, 0xB3, 0xCA, 0xE6, 0x93, 0xCD, 0x21, 0x9B, 0x3B, 0x36, 0x63, 0x1E,
+    0xF6, 0x24, 0x24, 0xB9, 0x7E, 0x84, 0x60, 0x85, 0x7D, 0x05, 0x8F, 0x1C,
+    0x74, 0x5E, 0xAE, 0xAB, 0x24, 0xF6, 0x44, 0x0F, 0x5A, 0x28, 0x9A, 0x9A,
+    0xD8, 0x25, 0x0D, 0x79, 0x1F, 0x5D, 0x44, 0x4A, 0xF6, 0xC0, 0x33, 0xC9,
+    0x4C, 0xC8, 0x27, 0x99, 0x92, 0x6D, 0x10, 0x35, 0x7D, 0xB5, 0x7A, 0x6C,
+    0xED, 0x9A, 0x6E, 0xD6, 0xEC, 0xD4, 0x6C, 0xD3, 0x6C, 0xD1, 0x6C, 0xCE,
+    0xEC, 0xCB, 0x6C, 0xCA, 0xDE, 0x4F, 0x42, 0x61, 0x02, 0x46, 0x93, 0xFA,
+    0xDD, 0xD3, 0x21, 0x1E, 0x7B, 0xE0, 0x6E, 0x1D, 0xB4, 0x78, 0x78, 0x6E,
+    0x24, 0x50, 0xB7, 0x02, 0x20, 0x54, 0x12, 0x5D, 0x0D, 0x56, 0xF8, 0xF8,
+    0x64, 0x84, 0xCA, 0x7B, 0x95, 0xC0, 0xE3, 0x49, 0x13, 0xA2, 0x86, 0x58,
+    0x06, 0xC6, 0x19, 0x51, 0x35, 0x9E, 0xD1, 0x39, 0xC9, 0x32, 0x2A, 0xF9,
+    0x66, 0x4F, 0x9B, 0x48, 0x1F, 0x20, 0xD7, 0x2A, 0x8E, 0x5D, 0x7C, 0x0A,
+    0xD7, 0xAE, 0x33, 0x71, 0x3C, 0xB8, 0x9C, 0x8F, 0x70, 0x95, 0x03, 0x36,
+    0x54, 0xA3, 0x8E, 0x56, 0xC6, 0x82, 0xAF, 0x5C, 0xFC, 0x38, 0x4D, 0x42,
+    0x43, 0x2D, 0x19, 0xAA, 0x48, 0x23, 0x21, 0x33, 0xD0, 0x4C, 0x90, 0xE7,
+    0x21, 0xAB, 0x06, 0x75, 0x46, 0x04, 0x20, 0x63, 0x49, 0x6B, 0xE4, 0x56,
+    0xD4, 0x19, 0x79, 0x36, 0x3B, 0xF4, 0xBC, 0x43, 0xDF, 0x77, 0xAE, 0x46,
+    0xA8, 0xC5, 0x31, 0x0A, 0x74, 0x66, 0x7D, 0x94, 0x64, 0x33, 0x6A, 0xAD,
+    0x18, 0xC0, 0xD7, 0x83, 0x6E, 0x14, 0x3D, 0x3A, 0xEA, 0xCC, 0xA4, 0x8D,
+    0x5A, 0x00, 0x56, 0xEF, 0xF4, 0x34, 0xF7, 0xC2, 0x9B, 0x59, 0x92, 0xFA,
+    0xA7, 0x93, 0xB3, 0xDB, 0x4B, 0x12, 0xBD, 0x29, 0xAE, 0x2A, 0x63, 0xDA,
+    0x24, 0xD0, 0x71, 0x55, 0x1E, 0x89, 0xF7, 0xEE, 0x74, 0x62, 0xDD, 0x09,
+    0x60, 0xF0, 0x38, 0x06, 0x2E, 0x2E, 0x76, 0x8B, 0xE2, 0x60, 0xBF, 0x28,
+    0x8A, 0x11, 0xEA, 0xF0, 0x7A, 0x85, 0xB4, 0x30, 0x50, 0x52, 0x52, 0x1E,
+    0xE4, 0x2E, 0x7E, 0x56, 0x49, 0x0F, 0x0E, 0x06, 0x2A, 0xD7, 0x54, 0x06,
+    0x94, 0x67, 0xFA, 0x27, 0x77, 0x2C, 0x2A, 0x64, 0x74, 0xDE, 0x14, 0xAA,
+    0x87, 0xEB, 0x84, 0xBA, 0x6C, 0x48, 0x03, 0x96, 0x10, 0xD8, 0xEC, 0xFD,
+    0x5A, 0x5F, 0xA5, 0x4D, 0x75, 0xF3, 0x67, 0x2A, 0xD4, 0x9A, 0x95, 0x3B,
+    0xBD, 0x3B, 0x88, 0xDF, 0x74, 0xBD, 0x33, 0x88, 0x9E, 0x30, 0xAE, 0x52,
+    0x17, 0xEF, 0x0D, 0x22, 0x17, 0x54, 0x0A, 0x17, 0xBF, 0xEC, 0x73, 0x51,
+    0x77, 0x6C, 0x40, 0x6A, 0xDB, 0x1B, 0x27, 0xBA, 0x40, 0xFD, 0x7C, 0x6D,
+    0x02, 0x17, 0xFF, 0xF9, 0x0E, 0xE7, 0x44, 0x87, 0xD0, 0xAF, 0xA1, 0x25,
+    0x2C, 0x15, 0xE5, 0xC2, 0xC5, 0xD3, 0xE3, 0xF9, 0x60, 0x51, 0xDB, 0xF3,
+    0xBE, 0x04, 0x99, 0xCD, 0x96, 0xEF, 0x42, 0xBE, 0xA6, 0xD7, 0x24, 0x28,
+    0x0F, 0xBB, 0x7A, 0xA9, 0x6B, 0x79, 0x39, 0x7C, 0xDA, 0x84, 0xCE, 0x1C,
+    0xAC, 0x40, 0x6D, 0x66, 0x9D, 0x66, 0x9C, 0x09, 0xFE, 0x60, 0xFA, 0x44,
+    0x28, 0xC9, 0xA8, 0x74, 0xFC, 0x2C, 0xB4, 0xE6, 0xC7, 0x21, 0x7C, 0x50,
+    0x38, 0x73, 0xF6, 0x1F, 0xC2, 0x0C, 0x3E, 0x96, 0xE8, 0xED, 0x16, 0xC2,
+    0x58, 0x92, 0x25, 0xBC, 0x2E, 0x0F, 0x13, 0x16, 0x11, 0x61, 0xD6, 0xF4,
+    0x1B, 0x51, 0xA8, 0x1B, 0xE2, 0x4C, 0x45, 0x16, 0xB1, 0xA0, 0x9C, 0x63,
+    0xEF, 0xC3, 0x6B, 0xC7, 0xDB, 0x46, 0x85, 0x91, 0x83, 0x48, 0xD4, 0xD4,
+    0xF7, 0x5B, 0x7E, 0x14, 0x98, 0xAB, 0x72, 0x32, 0xE7, 0xED, 0x16, 0x92,
+    0x2F, 0x06, 0x90, 0xBC, 0x5C, 0xF1, 0xD5, 0x67, 0xB1, 0xE1, 0xE9, 0xE6,
+    0xD0, 0xFD, 0x9E, 0x95, 0x51, 0xF5, 0x19, 0x0B, 0xCB, 0x7F, 0x8E, 0x69,
+    0xAC, 0xD0};
+const uint8_t g_zhCN_Locale[] = {
+    0x78, 0x9C, 0xED, 0x56, 0x41, 0x4F, 0xD4, 0x40, 0x14, 0xBE, 0x9B, 0xF8,
+    0x1F, 0x9A, 0x46, 0x52, 0x4D, 0x58, 0x46, 0x8F, 0x90, 0xD2, 0x64, 0x03,
+    0x08, 0x06, 0xBB, 0x21, 0x96, 0x68, 0xE0, 0x62, 0xBA, 0xED, 0xB0, 0x2D,
+    0x6C, 0x3B, 0x64, 0xB6, 0x0D, 0x6E, 0x4F, 0x18, 0x82, 0x82, 0xC2, 0x45,
+    0x89, 0x9A, 0x80, 0xE1, 0x64, 0x3C, 0x28, 0x9E, 0x8C, 0x01, 0x22, 0xF1,
+    0xCF, 0xB0, 0xCB, 0x91, 0xBF, 0xE0, 0x9B, 0xED, 0xB4, 0xB4, 0xDD, 0xD9,
+    0xB5, 0x3F, 0xC0, 0x3D, 0xCD, 0xFB, 0xDE, 0xF7, 0x7D, 0xF3, 0xDE, 0xEB,
+    0x74, 0xB6, 0x6A, 0x93, 0x58, 0x66, 0x13, 0x4B, 0xBE, 0xE9, 0xE1, 0x49,
+    0x39, 0x72, 0x9E, 0x4F, 0xD5, 0x64, 0xC9, 0xC6, 0x2D, 0x6B, 0x52, 0xBE,
+    0x3C, 0x3D, 0xE9, 0x7E, 0x78, 0x7D, 0xF7, 0xEA, 0xC7, 0xE6, 0xE5, 0xC5,
+    0xFB, 0xEB, 0xDF, 0x7B, 0x10, 0x77, 0x0E, 0x2F, 0xEE, 0xC9, 0x9A, 0xCA,
+    0x14, 0xBE, 0x6D, 0x52, 0xA3, 0xED, 0xD5, 0x49, 0xB3, 0xC5, 0xC5, 0x0D,
+    0x8A, 0x1B, 0x84, 0xBA, 0xA6, 0x0F, 0x0C, 0x8F, 0xF8, 0x81, 0x53, 0x03,
+    0xB8, 0xC5, 0xD7, 0xDA, 0xE5, 0xE9, 0x66, 0xF7, 0x68, 0x47, 0x45, 0x71,
+    0x74, 0xFB, 0x56, 0x02, 0x9F, 0xEF, 0x09, 0xE1, 0xD3, 0x5D, 0x11, 0xDC,
+    0x39, 0x3C, 0x14, 0x9B, 0x1C, 0x08, 0xD9, 0xDB, 0x27, 0x62, 0xEF, 0x2D,
+    0x31, 0xFB, 0x9B, 0x90, 0x7D, 0xF6, 0x59, 0xC8, 0xDE, 0x7F, 0x39, 0x00,
+    0x1E, 0xD0, 0x28, 0xCB, 0x14, 0x7B, 0x45, 0x99, 0x31, 0x25, 0xC4, 0x5E,
+    0x24, 0x99, 0xF5, 0x3A, 0x9D, 0x94, 0x1F, 0xC8, 0xFF, 0xA7, 0x57, 0x7A,
+    0x7A, 0xB6, 0xD9, 0xE6, 0x07, 0x0E, 0x56, 0x5A, 0xF7, 0xD3, 0x71, 0xF7,
+    0xE8, 0xB8, 0xFB, 0xF1, 0x8B, 0x8A, 0x58, 0x18, 0xE7, 0x39, 0x0A, 0x7B,
+    0x88, 0xD0, 0xF3, 0x3D, 0x21, 0x77, 0x57, 0x80, 0xC2, 0x24, 0x85, 0x0E,
+    0x07, 0x22, 0xEE, 0xF6, 0x49, 0x8A, 0xA2, 0xB4, 0xC8, 0x4C, 0xC1, 0x99,
+    0x87, 0xDD, 0x53, 0x15, 0x6A, 0x2E, 0x56, 0x5B, 0xAC, 0xB3, 0x58, 0x61,
+    0xB1, 0xB6, 0x62, 0x55, 0x03, 0xEB, 0xF1, 0x30, 0x75, 0x6D, 0x17, 0x7B,
+    0xC9, 0x6B, 0xCB, 0x43, 0xD8, 0xE0, 0x4D, 0x67, 0x9F, 0x0D, 0x3E, 0x01,
+    0x32, 0x5C, 0x48, 0xBE, 0xED, 0x4B, 0xA2, 0xBC, 0x13, 0x20, 0x98, 0x9A,
+    0xDC, 0x15, 0x56, 0x50, 0xC1, 0xF7, 0xCE, 0xF6, 0x56, 0x67, 0x77, 0x5F,
+    0x45, 0x2C, 0x8C, 0xF3, 0x1C, 0x4D, 0x21, 0x94, 0x6A, 0x58, 0x50, 0xB8,
+    0x71, 0xE2, 0x5E, 0x02, 0xBC, 0x60, 0x06, 0x01, 0xA6, 0x7E, 0xEF, 0x99,
+    0xA7, 0x11, 0xBF, 0x8E, 0x56, 0xC2, 0x66, 0x53, 0xD6, 0x96, 0xE0, 0xA7,
+    0x74, 0xCE, 0x7E, 0x2A, 0xBA, 0x02, 0xA7, 0x47, 0x99, 0x56, 0x60, 0xBC,
+    0xCA, 0x0C, 0xFC, 0x58, 0xEF, 0xA9, 0xA4, 0xE0, 0xC7, 0x1D, 0x9A, 0xC4,
+    0x6F, 0x0C, 0x70, 0x28, 0xA1, 0xF6, 0xB0, 0x1D, 0x8B, 0x2B, 0x7A, 0x65,
+    0xBA, 0x04, 0xBF, 0xE5, 0x10, 0x1A, 0x30, 0x85, 0x90, 0x8F, 0x72, 0xED,
+    0x02, 0x10, 0xB8, 0x5E, 0xA6, 0xFD, 0x4C, 0x94, 0x6B, 0xBF, 0xEA, 0x38,
+    0x50, 0xEF, 0x2F, 0x45, 0xD7, 0x95, 0xCE, 0xCE, 0x2B, 0xC5, 0x30, 0x94,
+    0xAB, 0xAF, 0xEF, 0x14, 0x69, 0x59, 0x45, 0x19, 0x45, 0xC1, 0x2E, 0xD7,
+    0xBD, 0xD8, 0xA0, 0x84, 0xBC, 0xD7, 0x3E, 0xA8, 0x27, 0x74, 0x7D, 0xC2,
+    0x30, 0x4A, 0x08, 0x78, 0xFF, 0x55, 0xA6, 0xE8, 0xA3, 0xA3, 0x5C, 0xBB,
+    0x7C, 0x7E, 0x8B, 0x80, 0x25, 0x07, 0x62, 0xD6, 0xF4, 0x57, 0xD7, 0xE6,
+    0xBC, 0x96, 0x31, 0x33, 0xFD, 0x70, 0xE3, 0xD9, 0x0B, 0x67, 0x3E, 0x5A,
+    0x8E, 0x67, 0x96, 0x25, 0x81, 0xCE, 0x0F, 0xBD, 0x3A, 0xA6, 0x37, 0x83,
+    0xCB, 0xC5, 0xBC, 0x12, 0xC0, 0xE0, 0x00, 0x5B, 0xB2, 0x16, 0x8D, 0x46,
+    0xD1, 0xF8, 0x58, 0x14, 0x45, 0x2A, 0xCA, 0xF1, 0xFA, 0x8C, 0xB8, 0xD0,
+    0x0A, 0x29, 0xC5, 0xBE, 0xD5, 0x96, 0xB5, 0x3B, 0xB1, 0x74, 0x7C, 0xBC,
+    0xA4, 0x72, 0x1D, 0x53, 0x0B, 0xFB, 0x01, 0xDF, 0x72, 0x44, 0xA0, 0x42,
+    0x85, 0xCA, 0x53, 0xA3, 0xA4, 0xB9, 0x5C, 0xC8, 0x6D, 0x6D, 0x6C, 0xB9,
+    0x9E, 0x09, 0xE7, 0x60, 0x2C, 0xD1, 0xC7, 0xE9, 0xA2, 0x3A, 0xFD, 0x07,
+    0x27, 0xE1, 0xBA, 0xCB, 0x1E, 0xFB, 0x68, 0x29, 0x7E, 0x5A, 0xF5, 0x48,
+    0x29, 0xBA, 0xE7, 0xFA, 0x61, 0x4B, 0xD6, 0x2A, 0xA5, 0xC8, 0x11, 0xA6,
+    0x44, 0xD6, 0xEE, 0xF7, 0x73, 0x51, 0xBE, 0x6D, 0x40, 0x92, 0xB1, 0xA7,
+    0x93, 0xC8, 0x03, 0xC9, 0xF9, 0xEA, 0x05, 0xB2, 0x76, 0xFD, 0x07, 0xEE,
+    0xD7, 0x3C, 0xA3, 0xDF, 0x84, 0x6B, 0xDC, 0x16, 0x61, 0x0B, 0x59, 0x9B,
+    0xAA, 0x2D, 0x95, 0x16, 0x65, 0x87, 0xDE, 0x2F, 0x41, 0xC5, 0x6A, 0xD9,
+    0xCB, 0xD0, 0x5E, 0xC7, 0x2B, 0xA6, 0xC5, 0xEE, 0xC7, 0x64, 0xC9, 0xBD,
+    0xAA, 0x36, 0xA9, 0x63, 0xC9, 0x80, 0x57, 0x51, 0x32, 0x02, 0x5B, 0x7A,
+    0x2C, 0xA3, 0x2C, 0x9F, 0x93, 0xF4, 0x36, 0x7C, 0x75, 0xD9, 0xD2, 0x02,
+    0x0C, 0x4C, 0x98, 0x76, 0x7D, 0x97, 0xF8, 0x03, 0xD3, 0x53, 0x24, 0xA4,
+    0x2E, 0xA6, 0xCC, 0x5F, 0x98, 0x8F, 0x4B, 0x58, 0x70, 0xFF, 0x41, 0x98,
+    0xC3, 0x75, 0x8A, 0x37, 0x86, 0x10, 0xAA, 0xD4, 0xAC, 0xC3, 0x4B, 0x35,
+    0x98, 0xB0, 0xE8, 0x98, 0xAE, 0x30, 0x3D, 0x4F, 0xA2, 0x70, 0xCD, 0x94,
+    0x66, 0x49, 0xE0, 0xB8, 0x16, 0xEB, 0xA3, 0xF2, 0xF4, 0x91, 0xA4, 0x0F,
+    0xA3, 0x42, 0xCB, 0x96, 0x43, 0x12, 0xEA, 0x93, 0x21, 0x9B, 0x02, 0x73,
+    0xD8, 0x68, 0x39, 0xA9, 0x1D, 0xFA, 0x8D, 0x55, 0xD2, 0xE3, 0xF1, 0x7D,
+    0xD1, 0xCD, 0x33, 0x63, 0x51, 0xFC, 0x15, 0x0D, 0xCB, 0xBF, 0xC0, 0xE4,
+    0x3D, 0x40};
+const uint8_t g_zhTW_Locale[] = {
+    0x78, 0x9C, 0xED, 0x57, 0xCD, 0x4F, 0xD4, 0x40, 0x14, 0x3F, 0x63, 0xE2,
+    0xFF, 0x30, 0x69, 0x20, 0xD5, 0x04, 0xA8, 0x1E, 0x21, 0xA5, 0xC9, 0xC6,
+    0x45, 0x30, 0x58, 0x42, 0xEC, 0x46, 0x22, 0x17, 0x33, 0xDB, 0x0E, 0xDB,
+    0xC2, 0xB6, 0x43, 0x66, 0xDB, 0xC0, 0xF6, 0x24, 0x12, 0x14, 0x14, 0x62,
+    0xA2, 0xC4, 0x8F, 0x80, 0xE1, 0x64, 0x3C, 0x28, 0x89, 0x07, 0x0F, 0x2C,
+    0x51, 0xFF, 0x1A, 0x76, 0x39, 0xFA, 0x2F, 0x38, 0xD3, 0x2F, 0xFA, 0xB1,
+    0xB3, 0xD4, 0xC4, 0xA3, 0x7B, 0x9A, 0xF7, 0xDE, 0xEF, 0xF7, 0xE6, 0xBD,
+    0xDF, 0xBC, 0x7D, 0xD9, 0x95, 0x9B, 0x58, 0x87, 0x4D, 0x04, 0x1C, 0x68,
+    0xA3, 0x29, 0xC1, 0x37, 0x1F, 0xD7, 0x16, 0x05, 0x60, 0xA0, 0x96, 0x3E,
+    0x25, 0x9C, 0x9F, 0x9E, 0xF4, 0xDE, 0x3E, 0xBF, 0x71, 0xD1, 0xD9, 0x3C,
+    0xFF, 0xF9, 0xE6, 0xF7, 0x8F, 0xBD, 0xEE, 0xAB, 0x6F, 0xBD, 0xCE, 0xAF,
+    0x9B, 0x82, 0x72, 0xFD, 0x1A, 0x00, 0x32, 0x63, 0x39, 0x06, 0x24, 0x5A,
+    0xDB, 0xAE, 0xE3, 0x66, 0x2B, 0x4A, 0xD0, 0x20, 0xA8, 0x81, 0x89, 0x05,
+    0x1D, 0x86, 0x1A, 0x02, 0xB2, 0x8D, 0x1D, 0xD7, 0x9C, 0xA7, 0xA1, 0x16,
+    0xB3, 0x87, 0x42, 0x5B, 0x39, 0x3F, 0x7D, 0xD2, 0x3B, 0xDA, 0x91, 0xA5,
+    0xD0, 0x4A, 0x07, 0xCE, 0xF6, 0x38, 0x81, 0xD3, 0xDD, 0xFE, 0x81, 0xEE,
+    0xE1, 0x21, 0x2F, 0xD5, 0x01, 0x87, 0xB1, 0x7D, 0xC2, 0xBB, 0x63, 0x8B,
+    0xC7, 0xF8, 0xC2, 0x61, 0x74, 0x3E, 0x72, 0x18, 0xFB, 0x9B, 0xDC, 0x00,
+    0xB7, 0x79, 0x16, 0xCB, 0xF7, 0x0F, 0xA2, 0x73, 0x22, 0x61, 0x5A, 0x52,
+    0x00, 0xEB, 0x75, 0x32, 0x25, 0xDC, 0x16, 0xFE, 0x6B, 0xFB, 0x8F, 0xB4,
+    0x35, 0x60, 0x3B, 0x35, 0xAC, 0xD4, 0x52, 0x7A, 0xEF, 0x8F, 0x7B, 0x47,
+    0xC7, 0xBD, 0x77, 0x9F, 0x64, 0x89, 0x99, 0x39, 0x3F, 0xBD, 0xAF, 0xBF,
+    0xFF, 0x6C, 0x8F, 0x83, 0xDF, 0xED, 0xEB, 0xA7, 0x4A, 0x73, 0xF2, 0x1C,
+    0xF4, 0xC7, 0x6F, 0x9F, 0x24, 0x7E, 0x10, 0x9C, 0xFA, 0x34, 0x91, 0x1B,
+    0x8F, 0x80, 0x5D, 0xE8, 0xA3, 0xD8, 0x41, 0xB1, 0xF6, 0x62, 0xD5, 0xC5,
+    0x7A, 0x8B, 0x95, 0x0E, 0xAC, 0xD1, 0x46, 0xC4, 0x32, 0x2C, 0x64, 0xA7,
+    0x57, 0x43, 0xE4, 0xA2, 0xD7, 0xBD, 0xE8, 0xEE, 0xB3, 0x87, 0x8A, 0x1D,
+    0xF9, 0xF0, 0xCB, 0x42, 0x18, 0x5C, 0x9A, 0xA9, 0x4B, 0x10, 0x81, 0xA9,
+    0xFC, 0xD4, 0xA2, 0x35, 0x7D, 0xED, 0x6E, 0x6F, 0x75, 0x77, 0xF7, 0x65,
+    0x89, 0x99, 0x39, 0x7F, 0xE2, 0x04, 0xC1, 0x29, 0xE6, 0xD2, 0x65, 0x27,
+    0xE5, 0xB6, 0x5D, 0xE8, 0x35, 0xA0, 0x8B, 0x16, 0xA0, 0xEB, 0x22, 0xE2,
+    0x24, 0xD2, 0x27, 0x9E, 0x68, 0x21, 0x2E, 0x7B, 0xCD, 0xA6, 0xA0, 0x3C,
+    0xA2, 0x1F, 0xB1, 0xDB, 0xF9, 0x2E, 0xAA, 0x22, 0x9D, 0x41, 0xB1, 0x2A,
+    0xD2, 0x87, 0x10, 0xA7, 0xE9, 0x87, 0xE9, 0x92, 0x50, 0x78, 0x39, 0x9A,
+    0xD8, 0x69, 0x70, 0x72, 0x94, 0xE2, 0xDB, 0xC8, 0x08, 0xE9, 0x92, 0x2A,
+    0x55, 0x4B, 0x31, 0x5A, 0x26, 0x26, 0x2E, 0x9F, 0x03, 0x40, 0xC6, 0x13,
+    0xC9, 0xE1, 0x5A, 0x76, 0x4E, 0x8E, 0x94, 0x27, 0x23, 0x47, 0xC5, 0x34,
+    0xC5, 0xDE, 0x87, 0xA7, 0xA2, 0xAA, 0x8A, 0xDD, 0x9D, 0x67, 0xA2, 0xA6,
+    0x89, 0x17, 0x9F, 0x5F, 0x8B, 0x60, 0x49, 0x96, 0x52, 0x0C, 0x5E, 0x8A,
+    0x50, 0x8D, 0xFE, 0x29, 0x4A, 0x25, 0x08, 0xE4, 0xA8, 0x00, 0x73, 0x52,
+    0x55, 0x27, 0x35, 0xAD, 0x14, 0x25, 0xD2, 0x23, 0x24, 0xE5, 0x19, 0x4C,
+    0x8D, 0x5C, 0xEF, 0xD1, 0x70, 0xD4, 0xA8, 0x37, 0x9E, 0x98, 0x19, 0xE8,
+    0xAC, 0xAC, 0xCE, 0xDA, 0x2D, 0x6D, 0xBA, 0x7A, 0x77, 0x7D, 0x71, 0xC3,
+    0x9C, 0xF3, 0x97, 0x42, 0x11, 0xD3, 0xA0, 0x80, 0xE9, 0x78, 0x76, 0x1D,
+    0x91, 0xAC, 0x92, 0x19, 0x5F, 0x54, 0x14, 0xF5, 0xD1, 0x99, 0xD7, 0x05,
+    0xC5, 0x1F, 0xF5, 0xFD, 0x89, 0x71, 0xDF, 0xF7, 0x65, 0x29, 0x83, 0xE3,
+    0x53, 0x75, 0x8F, 0x10, 0xE4, 0xE8, 0x6D, 0x41, 0x19, 0x0E, 0xC9, 0x13,
+    0x13, 0xA5, 0xB9, 0x6B, 0x88, 0xE8, 0xC8, 0x71, 0xA3, 0x6B, 0x47, 0x8A,
+    0x3C, 0xA6, 0x47, 0xA1, 0x87, 0xA4, 0xAF, 0xCB, 0x56, 0x87, 0xB2, 0xAE,
+    0x28, 0xBD, 0x81, 0x74, 0xCB, 0x86, 0x74, 0x48, 0xC6, 0xE3, 0x2C, 0x61,
+    0x98, 0x4B, 0x68, 0x10, 0xEC, 0xAD, 0x59, 0x6C, 0x26, 0x46, 0x4B, 0x32,
+    0x92, 0x0E, 0x46, 0x4A, 0x12, 0x6C, 0xCB, 0xF1, 0x5A, 0x82, 0x32, 0x56,
+    0x12, 0xEE, 0x23, 0x82, 0x05, 0xE5, 0x56, 0x01, 0x7D, 0x29, 0x4C, 0xE6,
+    0xBD, 0xE3, 0xC7, 0xC8, 0x28, 0x93, 0x75, 0xC6, 0x63, 0x18, 0x18, 0x82,
+    0x32, 0x5F, 0x1B, 0xA6, 0x2B, 0x29, 0x83, 0x18, 0xC0, 0xB2, 0x5A, 0x98,
+    0x1D, 0x04, 0xA5, 0xB6, 0x58, 0xFD, 0x0B, 0x5A, 0xFA, 0x21, 0x0A, 0xA4,
+    0x60, 0x27, 0x16, 0xEA, 0x66, 0x4B, 0xA0, 0xBD, 0x86, 0x96, 0xA1, 0x1E,
+    0xAF, 0xE0, 0xD8, 0x8C, 0x72, 0x56, 0x0C, 0x5C, 0x47, 0x40, 0xA5, 0xAF,
+    0x05, 0x34, 0xD7, 0x00, 0xF7, 0x05, 0xA9, 0x2F, 0x4C, 0x6D, 0xD3, 0x9F,
+    0x90, 0x06, 0x58, 0xA0, 0x32, 0x72, 0x00, 0x96, 0x63, 0x61, 0x67, 0x00,
+    0xE0, 0x0E, 0xF6, 0x88, 0x85, 0x08, 0xBB, 0x85, 0x83, 0x08, 0x4B, 0x59,
+    0xB0, 0xAE, 0x84, 0xCC, 0xA2, 0x3A, 0x41, 0xEB, 0x03, 0x21, 0x15, 0x02,
+    0xEB, 0xF4, 0x8B, 0x38, 0x08, 0x52, 0x33, 0xA1, 0xC5, 0x01, 0xCC, 0x61,
+    0xDF, 0x5B, 0x85, 0x60, 0x06, 0xBB, 0xA6, 0xA5, 0xB3, 0x9E, 0xC6, 0x1E,
+    0xDE, 0x03, 0xEA, 0x60, 0x30, 0x15, 0x40, 0x37, 0x71, 0x0C, 0x7E, 0x30,
+    0xF0, 0x6A, 0x0D, 0x5F, 0x21, 0x77, 0xF4, 0x2A, 0x6D, 0xCF, 0x69, 0xAC,
+    0xE0, 0x00, 0x19, 0xDE, 0x1E, 0x2C, 0xB6, 0xD4, 0x7B, 0xCA, 0x52, 0xF8,
+    0x67, 0x41, 0xF9, 0x03, 0x11, 0xC2, 0x4A, 0xC9};
+const uint8_t g_zhHK_Locale[] = {
+    0x78, 0x9C, 0xA5, 0x57, 0x4D, 0x4F, 0x13, 0x41, 0x18, 0x3E, 0x63, 0xE2,
+    0x7F, 0x98, 0x6C, 0x20, 0x0B, 0x09, 0x50, 0x8A, 0x9F, 0x25, 0xCB, 0x26,
+    0x44, 0x90, 0x9A, 0x5A, 0x43, 0x2C, 0xD1, 0xC8, 0xC5, 0x6C, 0x77, 0x87,
+    0xEE, 0x42, 0x77, 0x87, 0x4C, 0xB7, 0xC1, 0x6E, 0x3C, 0x88, 0x04, 0xA5,
+    0x5A, 0x2E, 0x4A, 0x54, 0x02, 0x86, 0x78, 0x50, 0x0F, 0x48, 0xBC, 0x78,
+    0x68, 0x89, 0xC6, 0x3F, 0x43, 0x8B, 0x9E, 0xFC, 0x0B, 0xCE, 0xEC, 0x17,
+    0xFB, 0x35, 0x6D, 0x8D, 0x3D, 0xCD, 0xFB, 0xBC, 0xCF, 0xF3, 0xCE, 0xFB,
+    0x3E, 0x33, 0x3B, 0x01, 0xA1, 0x8C, 0x64, 0xA9, 0x0C, 0x81, 0x21, 0xE9,
+    0x70, 0x9A, 0xB3, 0xD4, 0x87, 0xD9, 0x1C, 0x07, 0x14, 0x58, 0x91, 0xA7,
+    0xB9, 0xD3, 0xE6, 0x71, 0xE7, 0xCD, 0xF3, 0xE1, 0xB3, 0xD6, 0xC6, 0xE9,
+    0x8F, 0xD7, 0x7F, 0xBE, 0x37, 0x7E, 0x7F, 0xDA, 0xEB, 0x34, 0xBF, 0x9E,
+    0xD5, 0x5B, 0xED, 0xED, 0xA3, 0x5F, 0x1F, 0x1A, 0x9D, 0xDD, 0x9F, 0xED,
+    0xC6, 0xC9, 0x08, 0x27, 0x5E, 0xBC, 0x00, 0x80, 0x40, 0x8B, 0x18, 0x8A,
+    0x84, 0x0B, 0x35, 0xBD, 0x88, 0xCA, 0x15, 0xB7, 0x5E, 0x09, 0xC3, 0x12,
+    0xC2, 0x9A, 0x64, 0x50, 0xD6, 0x00, 0x10, 0x74, 0x64, 0x98, 0xEA, 0x1D,
+    0x92, 0xAA, 0xD0, 0x78, 0xC0, 0x89, 0xC5, 0xD3, 0xE6, 0x93, 0xCE, 0xC1,
+    0xB6, 0x90, 0x72, 0xA2, 0x60, 0xE2, 0xA4, 0xC1, 0x48, 0x34, 0xEB, 0xC9,
+    0x89, 0xF6, 0xFE, 0x3E, 0xAB, 0xD4, 0x2E, 0x43, 0xB1, 0x75, 0xCC, 0xDA,
+    0x63, 0x93, 0xA5, 0x38, 0x62, 0x28, 0x5A, 0xEF, 0x19, 0x8A, 0x9D, 0x0D,
+    0x66, 0x82, 0x39, 0x3C, 0xCD, 0x45, 0xE7, 0x07, 0xEE, 0xDA, 0xB7, 0x30,
+    0x68, 0x29, 0x90, 0x8A, 0x45, 0x3C, 0xCD, 0xA5, 0xB9, 0x60, 0x95, 0x74,
+    0x72, 0xF1, 0xC9, 0x64, 0xF8, 0x52, 0x32, 0x7C, 0x39, 0x19, 0xBE, 0x92,
+    0x0C, 0x5F, 0x4D, 0x86, 0xAF, 0x25, 0xC3, 0xD7, 0x93, 0xE1, 0x4C, 0x32,
+    0x9C, 0x9E, 0x60, 0xE0, 0x8C, 0x39, 0xD3, 0x93, 0x3D, 0x0D, 0x54, 0xA4,
+    0x5A, 0xE0, 0x46, 0x92, 0x48, 0xEC, 0xBC, 0x3B, 0xEC, 0x1C, 0x1C, 0x76,
+    0xDE, 0x7E, 0x14, 0x52, 0x34, 0x8C, 0xE0, 0xE4, 0xC0, 0x92, 0xF1, 0x93,
+    0x06, 0x83, 0x5F, 0x4F, 0xC4, 0xC9, 0x55, 0x65, 0xD4, 0xD9, 0x4D, 0xE6,
+    0x6F, 0x1D, 0xFB, 0x38, 0xB0, 0x57, 0x09, 0x43, 0x44, 0xEE, 0x80, 0xAD,
+    0x8E, 0xCD, 0x11, 0x9F, 0x20, 0xDE, 0x7B, 0xBC, 0xEB, 0x78, 0xBF, 0xF1,
+    0x4E, 0xBB, 0xF6, 0xA8, 0x43, 0xAC, 0x29, 0x1A, 0xD4, 0x83, 0xDF, 0xBF,
+    0x0B, 0x91, 0xED, 0x5E, 0xB4, 0x77, 0xE8, 0x41, 0x79, 0x40, 0x34, 0xFD,
+    0x32, 0x96, 0x06, 0xE7, 0x61, 0x60, 0x13, 0x88, 0xA5, 0x40, 0x7D, 0x12,
+    0x91, 0x9E, 0xBE, 0xB4, 0xB7, 0x36, 0xDB, 0xF5, 0x1D, 0x21, 0x45, 0xC3,
+    0x08, 0xEE, 0x83, 0xC0, 0x5E, 0x79, 0x5A, 0xF2, 0xA2, 0xA5, 0x22, 0x4F,
+    0x9A, 0x83, 0x2A, 0x92, 0x09, 0x17, 0x24, 0xD3, 0x84, 0xD8, 0xF0, 0xAD,
+    0xF7, 0x11, 0xF7, 0xD5, 0x5B, 0xAE, 0x96, 0xCB, 0x9C, 0xF8, 0x80, 0xFC,
+    0xF8, 0x76, 0xEB, 0x1B, 0x9F, 0xE7, 0xC9, 0x1D, 0xE4, 0x67, 0x79, 0x72,
+    0x10, 0x3C, 0x98, 0x23, 0x3F, 0x6A, 0x8C, 0xAF, 0x61, 0x15, 0x29, 0x23,
+    0xA3, 0xC4, 0x28, 0xD2, 0x97, 0x5E, 0x87, 0xCA, 0xFF, 0xC8, 0x2B, 0x2A,
+    0xC2, 0x26, 0x2D, 0xD0, 0x53, 0x0E, 0x40, 0x08, 0x71, 0x7D, 0x32, 0x35,
+    0x3D, 0xE2, 0x53, 0x00, 0x09, 0xF9, 0x34, 0xA3, 0xAA, 0x7C, 0x67, 0xEF,
+    0x29, 0x9F, 0xCF, 0xF3, 0xED, 0xED, 0x67, 0x7C, 0xA1, 0xC0, 0x9F, 0x7D,
+    0x7E, 0xC5, 0x83, 0x25, 0x21, 0x15, 0x50, 0xB0, 0x4A, 0x38, 0x2E, 0x25,
+    0x97, 0xE8, 0xAB, 0x80, 0x6D, 0x13, 0xD1, 0x4F, 0xE5, 0xF3, 0x53, 0x85,
+    0x42, 0x5F, 0x12, 0xD7, 0x9A, 0x19, 0xAA, 0x89, 0x0A, 0xA8, 0x19, 0x91,
+    0xD1, 0xDD, 0x4B, 0xB3, 0x48, 0x50, 0xEF, 0x26, 0xCD, 0x4B, 0xC6, 0xCA,
+    0x6A, 0x56, 0xAF, 0x14, 0xE6, 0x66, 0x6F, 0xAE, 0xDF, 0x7F, 0xA4, 0xE6,
+    0xAC, 0x25, 0xC7, 0xC3, 0x20, 0xC9, 0x56, 0x1A, 0x55, 0xBD, 0x08, 0x71,
+    0xD8, 0xC8, 0x10, 0xE6, 0xF6, 0x44, 0x30, 0xF2, 0x2D, 0xC8, 0x9C, 0x68,
+    0x8D, 0x5A, 0x56, 0x66, 0xDC, 0xB2, 0x2C, 0x21, 0x15, 0xE2, 0xB1, 0xA5,
+    0x72, 0x15, 0x63, 0x68, 0xC8, 0x35, 0x4E, 0x1C, 0x74, 0xC4, 0x99, 0xCC,
+    0xE3, 0x61, 0x7F, 0x39, 0xD2, 0x77, 0x9D, 0x35, 0x88, 0x65, 0x68, 0x98,
+    0x6E, 0x0B, 0x43, 0x71, 0x1D, 0xF5, 0x26, 0x36, 0x8F, 0x3F, 0xE3, 0xF9,
+    0xD8, 0x03, 0x61, 0xC8, 0x2D, 0xAF, 0x40, 0x59, 0xD3, 0x25, 0x72, 0x5F,
+    0xC6, 0xBD, 0x2A, 0x4E, 0x9A, 0x29, 0x28, 0x61, 0x54, 0x5D, 0xD3, 0xE8,
+    0xF5, 0x18, 0xED, 0x53, 0xE1, 0x4F, 0x30, 0xD4, 0xA7, 0x40, 0xD7, 0x8C,
+    0x6A, 0x85, 0x13, 0xC7, 0xFA, 0xA4, 0x5B, 0x10, 0x23, 0x4E, 0x9C, 0x88,
+    0xB1, 0xCF, 0x8D, 0x09, 0x9D, 0xBD, 0x77, 0x30, 0x21, 0x67, 0xC2, 0xA0,
+    0x77, 0x23, 0xED, 0x80, 0x13, 0xB3, 0xB9, 0x41, 0xF2, 0x6C, 0x85, 0x18,
+    0x5D, 0x54, 0x5A, 0x05, 0xD1, 0x05, 0x95, 0xCD, 0xFE, 0x83, 0x2C, 0x78,
+    0x10, 0x31, 0x91, 0xFD, 0x6E, 0xC6, 0xFA, 0xA6, 0xEF, 0x41, 0x6D, 0x0D,
+    0x2E, 0x4B, 0xB2, 0xF7, 0x4C, 0x7B, 0xA1, 0x5B, 0x73, 0x46, 0x41, 0x45,
+    0x08, 0xF2, 0xE4, 0xB4, 0x40, 0xC1, 0x54, 0xC0, 0x6D, 0x2E, 0x95, 0x48,
+    0xCB, 0xD7, 0xC8, 0xDF, 0x92, 0x0A, 0x58, 0x20, 0x36, 0x32, 0x08, 0x9A,
+    0xA1, 0x21, 0xA3, 0x0B, 0xE1, 0x06, 0xAA, 0x62, 0x0D, 0x62, 0xBA, 0x0B,
+    0x83, 0xE1, 0xB4, 0xB2, 0xA0, 0xF5, 0xA4, 0x64, 0x61, 0x11, 0xC3, 0xF5,
+    0xAE, 0x94, 0x19, 0x2C, 0x15, 0xC9, 0x47, 0xD9, 0x8D, 0xB2, 0xA8, 0x4A,
+    0x1A, 0x83, 0x90, 0x43, 0x56, 0x75, 0x55, 0x02, 0xF3, 0xC8, 0x54, 0x35,
+    0x99, 0xCE, 0x34, 0x76, 0xEF, 0x16, 0xC8, 0x77, 0x27, 0x13, 0x03, 0x64,
+    0x15, 0x79, 0xE4, 0xBB, 0x5D, 0xB7, 0x2E, 0xA0, 0x1E, 0x76, 0xBB, 0xA7,
+    0x52, 0xAB, 0x1A, 0xA5, 0x15, 0x64, 0x33, 0x9D, 0xDD, 0xED, 0x47, 0x2E,
+    0x70, 0x9E, 0x42, 0xCA, 0xF9, 0x27, 0x42, 0xFC, 0x0B, 0xD9, 0x0E, 0x4B,
+    0xED};
+const uint8_t g_jaJP_Locale[] = {
+    0x78, 0x9C, 0xED, 0x56, 0xCB, 0x6E, 0xD3, 0x40, 0x14, 0x5D, 0x17, 0x89,
+    0x7F, 0x18, 0x59, 0x20, 0x83, 0xD4, 0xD6, 0x0D, 0xEF, 0x56, 0xAE, 0xA5,
+    0x8A, 0x96, 0x86, 0x16, 0xA3, 0x08, 0x57, 0xA0, 0x76, 0x83, 0x26, 0xF6,
+    0x34, 0x99, 0x36, 0x9E, 0xA9, 0x26, 0xB6, 0x4A, 0xBC, 0xE2, 0x21, 0x20,
+    0x48, 0x74, 0x01, 0x1B, 0x04, 0x44, 0x62, 0x55, 0x40, 0x02, 0x04, 0x8B,
+    0x6E, 0xD8, 0xD0, 0xAF, 0x49, 0x5A, 0x56, 0xFC, 0x02, 0x33, 0x7E, 0xC5,
+    0x8E, 0xED, 0xE0, 0xEE, 0xF1, 0x22, 0x99, 0x7B, 0x7C, 0xCE, 0xF5, 0xBD,
+    0xE7, 0x8E, 0x47, 0x56, 0x5B, 0xD4, 0x84, 0x2D, 0x04, 0x08, 0xB4, 0xD1,
+    0xBC, 0xB4, 0x05, 0xEF, 0xAF, 0xD4, 0x24, 0x60, 0xA1, 0xB6, 0x39, 0x2F,
+    0x0D, 0xDE, 0xEC, 0x1F, 0x7F, 0xFF, 0x76, 0x8E, 0xFF, 0x0D, 0x7A, 0x5F,
+    0xCF, 0x4B, 0xDA, 0xE9, 0x53, 0x00, 0xA8, 0x82, 0x4C, 0x2C, 0xC8, 0x8C,
+    0x8E, 0x5D, 0xA7, 0xAD, 0x76, 0xA8, 0x6B, 0x30, 0xD4, 0xA0, 0x0C, 0x43,
+    0x22, 0x58, 0x13, 0x40, 0xB5, 0x29, 0x71, 0x9A, 0xB7, 0xF9, 0xAD, 0xB6,
+    0x88, 0x27, 0x82, 0x58, 0xAB, 0x0C, 0x7A, 0x5D, 0x55, 0x09, 0xD6, 0x09,
+    0xF8, 0x42, 0x3E, 0x7C, 0x31, 0x1F, 0xBE, 0x94, 0x0F, 0x5F, 0xCE, 0x87,
+    0xAF, 0xE4, 0xC3, 0x57, 0xF3, 0xE1, 0x6B, 0xF9, 0xF0, 0x6C, 0x3E, 0x5C,
+    0x99, 0x29, 0xC0, 0x0B, 0xFA, 0xAC, 0x8C, 0x34, 0x0A, 0xC2, 0x75, 0xEC,
+    0x53, 0xD2, 0x37, 0x00, 0xEB, 0x75, 0x36, 0x2F, 0x55, 0xA4, 0xFF, 0x06,
+    0x9E, 0xC4, 0x40, 0x0B, 0x76, 0x12, 0xDB, 0x8E, 0x47, 0x9A, 0xD8, 0xBE,
+    0xEF, 0x7B, 0xFC, 0x57, 0x55, 0x44, 0x38, 0xC4, 0x7B, 0xDD, 0x5C, 0xFC,
+    0xE8, 0xD1, 0x97, 0x7C, 0xFE, 0x8F, 0x83, 0x82, 0x3C, 0x9F, 0x73, 0xF1,
+    0xDF, 0xCF, 0x5F, 0xE5, 0xE2, 0xFD, 0xDE, 0x87, 0x11, 0x1C, 0xF8, 0xAB,
+    0x9C, 0x26, 0x46, 0xF6, 0x40, 0xD8, 0x4D, 0xB6, 0x8F, 0x6C, 0x07, 0xD9,
+    0xDA, 0xB3, 0x55, 0x67, 0xEB, 0xCD, 0x56, 0x5A, 0x5C, 0xA3, 0x8D, 0x18,
+    0xB6, 0x30, 0xB2, 0x93, 0x2F, 0x79, 0x08, 0x69, 0xFD, 0xBD, 0x6E, 0xFF,
+    0xC5, 0x1E, 0x1F, 0x4E, 0x04, 0x64, 0x6F, 0xFF, 0x7A, 0x99, 0xBE, 0x0D,
+    0x86, 0x61, 0xE2, 0x21, 0x88, 0xC1, 0x44, 0x7E, 0x1E, 0x69, 0x47, 0x07,
+    0x0F, 0xFB, 0x4F, 0x9F, 0xF8, 0xD9, 0x45, 0x18, 0xE3, 0xC7, 0xFB, 0x87,
+    0x83, 0x77, 0x1F, 0x63, 0x10, 0xF8, 0xAB, 0x48, 0xCB, 0x8F, 0x2D, 0x65,
+    0xE4, 0xDC, 0x0A, 0x50, 0x0B, 0x3A, 0xA8, 0x06, 0x1D, 0x07, 0x31, 0x12,
+    0x5B, 0x1F, 0x23, 0xE1, 0xD1, 0xB6, 0xE9, 0xB6, 0x5A, 0x92, 0xB6, 0xCE,
+    0x2F, 0xB9, 0xFF, 0xF3, 0x40, 0xD6, 0x65, 0x6E, 0xB8, 0xBC, 0x28, 0xF3,
+    0x41, 0xC8, 0x4B, 0xFC, 0x12, 0xBE, 0xC4, 0x92, 0xA2, 0x1C, 0x2D, 0x4A,
+    0x1A, 0x05, 0x39, 0x4A, 0xE9, 0x6D, 0x64, 0x05, 0x72, 0x45, 0xD7, 0x95,
+    0xC5, 0xC5, 0x52, 0x9A, 0x76, 0x93, 0x32, 0x47, 0xA8, 0xF2, 0x35, 0x00,
+    0xA4, 0x90, 0xD0, 0x10, 0x07, 0xDB, 0x23, 0x86, 0x24, 0x90, 0x94, 0x21,
+    0x55, 0x79, 0xF0, 0xF6, 0xB1, 0xAC, 0xEB, 0x72, 0xBF, 0xFB, 0x4C, 0x36,
+    0x0C, 0xF9, 0xE8, 0xD3, 0x6B, 0x79, 0x43, 0x55, 0x12, 0xF4, 0x22, 0x7D,
+    0x60, 0x46, 0x75, 0x4E, 0xD7, 0xE7, 0x0C, 0x63, 0xAE, 0x9C, 0xC6, 0x37,
+    0x20, 0x94, 0x94, 0x12, 0x84, 0xDD, 0x0B, 0xC9, 0x28, 0x5F, 0x74, 0x3E,
+    0xD2, 0x67, 0xB8, 0x15, 0xD6, 0x38, 0x1A, 0xED, 0x8F, 0x65, 0x48, 0xB6,
+    0xB6, 0xAB, 0x76, 0xDB, 0x58, 0x5A, 0xBC, 0xB1, 0x7B, 0xEF, 0x41, 0x73,
+    0xD5, 0xDB, 0x08, 0x0C, 0x4B, 0x92, 0x7C, 0x25, 0x71, 0xED, 0x3A, 0x62,
+    0x69, 0xD7, 0x52, 0x58, 0x58, 0x12, 0xC7, 0xF8, 0x0E, 0x37, 0x25, 0xCD,
+    0x9B, 0xF4, 0xBC, 0xD9, 0x69, 0xCF, 0xF3, 0x54, 0x25, 0xC5, 0x2B, 0x96,
+    0x9A, 0x2E, 0x63, 0x88, 0x98, 0x1D, 0x49, 0x3B, 0xE3, 0x8B, 0x4B, 0x0B,
+    0x77, 0x10, 0x33, 0x11, 0x71, 0xC2, 0x67, 0x9E, 0xCD, 0xEA, 0x84, 0x19,
+    0x99, 0x06, 0xE2, 0xA6, 0x86, 0x7D, 0x4E, 0xA4, 0xA1, 0x30, 0xBD, 0x85,
+    0x4C, 0x6C, 0x43, 0xBE, 0x1B, 0xA6, 0xA3, 0x2C, 0xC1, 0xED, 0x42, 0x41,
+    0x83, 0x51, 0x77, 0x07, 0x8B, 0xF9, 0x4F, 0x96, 0x54, 0xC4, 0x1D, 0x9C,
+    0x2D, 0x29, 0xB0, 0x31, 0x71, 0xDB, 0x92, 0x36, 0x55, 0x92, 0xEE, 0x21,
+    0x46, 0x25, 0x6D, 0x26, 0xC3, 0x1E, 0x1A, 0x93, 0x1A, 0x76, 0x34, 0x89,
+    0x94, 0x33, 0x69, 0x30, 0xDA, 0x81, 0x7E, 0x20, 0x69, 0x7F, 0x0E, 0xF9,
+    0x89, 0x9D, 0x66, 0x8C, 0x51, 0xE1, 0x36, 0x15, 0x0B, 0x49, 0x5B, 0xA9,
+    0xAD, 0x9F, 0x40, 0x96, 0x1C, 0x44, 0x46, 0xE4, 0x1F, 0x7F, 0x99, 0xBA,
+    0xC5, 0xDB, 0xDE, 0xD9, 0x41, 0x9B, 0xD0, 0x8C, 0x4E, 0xDB, 0x28, 0x0C,
+    0x73, 0xAE, 0x52, 0xCF, 0xDD, 0x86, 0x60, 0x99, 0x3A, 0x4D, 0x6C, 0x82,
+    0x1A, 0xA3, 0x53, 0x77, 0x6F, 0x02, 0x5D, 0x52, 0xC6, 0x91, 0x75, 0x4C,
+    0xCC, 0x26, 0x8D, 0xC8, 0x77, 0x0A, 0xC8, 0x7A, 0x87, 0x7F, 0x2A, 0x5A,
+    0x82, 0x55, 0x44, 0xC0, 0x04, 0x53, 0x32, 0x86, 0x70, 0x9D, 0xBA, 0x0C,
+    0x23, 0x06, 0x0C, 0xC7, 0x2A, 0x60, 0x2C, 0x58, 0xB4, 0x8E, 0x40, 0x0D,
+    0xFF, 0x93, 0x52, 0x45, 0x75, 0x86, 0x76, 0xC7, 0x52, 0x16, 0x18, 0xAC,
+    0xF3, 0x17, 0x77, 0x1C, 0x65, 0xAD, 0x09, 0xF1, 0x58, 0x02, 0x6F, 0xA9,
+    0x21, 0x6A, 0x01, 0xB7, 0xC6, 0xD2, 0x0C, 0x5A, 0x8A, 0xA6, 0x77, 0x5C,
+    0xD2, 0xD8, 0xA2, 0x3E, 0x33, 0x18, 0x89, 0x7F, 0xAA, 0x25, 0xE6, 0xA9,
+    0x2A, 0xC1, 0x87, 0xBD, 0xF6, 0x17, 0x6C, 0x42, 0x08, 0x21};
+const uint8_t g_koKR_Locale[] = {
+    0x78, 0x9C, 0xED, 0x56, 0x4D, 0x6B, 0xD4, 0x40, 0x18, 0x3E, 0x57, 0xF0,
+    0x3F, 0x0C, 0xC1, 0x12, 0x85, 0x76, 0xB7, 0xEB, 0x77, 0x4B, 0x1A, 0x28,
+    0x6E, 0x6D, 0x65, 0x8D, 0x94, 0xA6, 0x58, 0xEC, 0x45, 0x66, 0x93, 0xE9,
+    0x26, 0xED, 0x26, 0x53, 0x26, 0x09, 0x75, 0x73, 0xAE, 0x52, 0xF0, 0xE2,
+    0xA1, 0x87, 0xEA, 0x6E, 0xB1, 0x07, 0x11, 0x2A, 0x88, 0x22, 0x22, 0x1E,
+    0x14, 0x7F, 0x8D, 0x62, 0x6D, 0x8A, 0x7F, 0xC1, 0xC9, 0xE7, 0xE6, 0x63,
+    0xB2, 0x4D, 0xEF, 0xEE, 0x61, 0x99, 0xF7, 0x99, 0xE7, 0x79, 0xF3, 0xBE,
+    0xCF, 0x4C, 0x5E, 0x22, 0x74, 0xB1, 0x02, 0xBB, 0x08, 0x98, 0xD0, 0x40,
+    0xB3, 0xDC, 0x26, 0x7E, 0xDC, 0x5A, 0xE6, 0x80, 0x8A, 0x2C, 0x65, 0x96,
+    0xFB, 0x35, 0x38, 0x38, 0xFE, 0x34, 0xF8, 0xFD, 0xE1, 0xFD, 0xE5, 0xE3,
+    0xD7, 0x47, 0x3F, 0xFB, 0xDF, 0xAF, 0x70, 0xE2, 0xC5, 0x0B, 0x00, 0x08,
+    0x3E, 0xDF, 0x54, 0x21, 0x91, 0x7B, 0x46, 0x1B, 0x77, 0xAD, 0x48, 0xDA,
+    0x21, 0xA8, 0x83, 0x89, 0x0E, 0x4D, 0x9F, 0x35, 0x06, 0x04, 0x03, 0x9B,
+    0xB6, 0xF6, 0x80, 0x6E, 0x59, 0x7E, 0x3C, 0x16, 0xC6, 0x62, 0xC3, 0xEB,
+    0xEF, 0x09, 0xF5, 0x70, 0x9D, 0x82, 0xAF, 0xB2, 0xE1, 0x6B, 0x6C, 0xF8,
+    0x3A, 0x1B, 0xBE, 0xC1, 0x86, 0x6F, 0xB2, 0xE1, 0x5B, 0x6C, 0xF8, 0x36,
+    0x1B, 0x9E, 0x66, 0xC3, 0x8D, 0xA9, 0x12, 0xBC, 0xA4, 0xCF, 0x46, 0xAE,
+    0x51, 0x10, 0xAD, 0x13, 0x9F, 0xD2, 0xBE, 0x01, 0xD8, 0x6E, 0x93, 0x59,
+    0xAE, 0xC1, 0xFD, 0x37, 0xF0, 0x3C, 0x06, 0xAA, 0xB0, 0x97, 0xBA, 0x76,
+    0x34, 0x12, 0xBD, 0x83, 0x6F, 0xDE, 0xAB, 0x3D, 0xFA, 0x2F, 0xD4, 0xFD,
+    0x70, 0x88, 0xF7, 0xF7, 0x98, 0xF8, 0xE9, 0x4B, 0x36, 0xEE, 0xED, 0xEE,
+    0x33, 0xF1, 0x93, 0x77, 0x47, 0x4C, 0xFC, 0xCF, 0xD7, 0x5D, 0x76, 0xFE,
+    0x67, 0x87, 0x39, 0x1C, 0x04, 0x2B, 0x46, 0x13, 0xB9, 0x3B, 0x10, 0x75,
+    0x53, 0xEC, 0xA3, 0xD8, 0x41, 0xB1, 0xF6, 0x62, 0xD5, 0xC5, 0x7A, 0x8B,
+    0x95, 0x96, 0xD7, 0x68, 0x20, 0xA2, 0xAB, 0x3A, 0x32, 0xD2, 0x2F, 0x79,
+    0x04, 0x89, 0xDE, 0xFE, 0x1B, 0xEF, 0x70, 0x87, 0x1E, 0x4E, 0x0C, 0x14,
+    0xB6, 0x4F, 0xFB, 0xB9, 0x6D, 0x30, 0x0C, 0x53, 0x0F, 0x41, 0x04, 0xA6,
+    0xF2, 0xD3, 0x88, 0x56, 0xF9, 0xD1, 0xEB, 0xBF, 0x08, 0xB2, 0xFB, 0x61,
+    0x82, 0x7B, 0x3B, 0x03, 0xBA, 0x95, 0x80, 0x20, 0x58, 0xC5, 0x5A, 0x3A,
+    0xB6, 0xEA, 0xB9, 0xB9, 0x15, 0xA2, 0x2A, 0xB4, 0xD1, 0x12, 0xB4, 0x6D,
+    0x44, 0xCC, 0xC4, 0xFA, 0x04, 0x89, 0x46, 0xDB, 0xBA, 0xD3, 0xED, 0x72,
+    0xE2, 0x23, 0xFA, 0xE3, 0x4F, 0x9E, 0xEE, 0xF0, 0x40, 0xE2, 0xA9, 0xE3,
+    0x3C, 0x68, 0xF2, 0xF4, 0x28, 0x78, 0x30, 0x4F, 0x7F, 0xBE, 0x35, 0x89,
+    0xAA, 0x2C, 0x4D, 0x17, 0x9B, 0x9D, 0xD2, 0x34, 0x95, 0x32, 0x18, 0x48,
+    0x0D, 0x13, 0xD4, 0x80, 0x24, 0xD5, 0x40, 0xB3, 0x59, 0x49, 0x65, 0x69,
+    0x98, 0xD8, 0xBE, 0xAE, 0x4C, 0x05, 0x40, 0x06, 0x89, 0x9C, 0xB1, 0x75,
+    0x23, 0xE7, 0x4C, 0x0A, 0xC9, 0x38, 0x33, 0x07, 0x34, 0x8D, 0xF7, 0x9E,
+    0x0F, 0x68, 0x4B, 0x12, 0x7F, 0xF2, 0x85, 0xB6, 0x26, 0xCB, 0xBC, 0xF7,
+    0x79, 0x97, 0x07, 0x6B, 0x42, 0x3D, 0x25, 0x2A, 0xCB, 0x12, 0x1A, 0x53,
+    0x9A, 0xA5, 0x52, 0x8E, 0xC0, 0x1A, 0x9A, 0x62, 0x46, 0x92, 0x66, 0x64,
+    0xB9, 0x92, 0x24, 0xF2, 0x25, 0x14, 0xE5, 0x15, 0xBE, 0x27, 0x39, 0x07,
+    0xA2, 0xDB, 0xB2, 0x42, 0xD1, 0xF8, 0x0A, 0x2D, 0x40, 0x73, 0x63, 0x73,
+    0xD1, 0xB0, 0xE4, 0xF9, 0xE6, 0xDD, 0xED, 0xD5, 0x27, 0x5A, 0xCB, 0x5D,
+    0x0B, 0xAD, 0x4C, 0x93, 0x02, 0xA5, 0xE9, 0x18, 0x6D, 0x44, 0xB2, 0x7E,
+    0x66, 0xB0, 0xA8, 0x28, 0x8A, 0xD1, 0x97, 0x40, 0xE1, 0x44, 0x77, 0xC2,
+    0x75, 0xA7, 0x6B, 0xAE, 0xEB, 0x0A, 0xF5, 0x0C, 0xAF, 0x5C, 0xAA, 0x38,
+    0x84, 0x20, 0x53, 0xE9, 0x71, 0xE2, 0xA5, 0x40, 0x5C, 0x59, 0xB8, 0x85,
+    0x88, 0x82, 0x4C, 0x3B, 0x7A, 0xE6, 0x78, 0x51, 0xE7, 0x9B, 0x51, 0x68,
+    0x20, 0x69, 0x6A, 0xD8, 0xE7, 0x58, 0x16, 0x8A, 0xD2, 0xAB, 0x48, 0xD1,
+    0x0D, 0x48, 0xEF, 0x49, 0x2D, 0xCE, 0x12, 0x6E, 0x97, 0x0A, 0x3A, 0x04,
+    0x3B, 0x5B, 0xBA, 0x7F, 0x27, 0x26, 0x2A, 0x2A, 0x92, 0x0E, 0xC6, 0x2B,
+    0x0A, 0x0C, 0xDD, 0x74, 0x2C, 0x4E, 0x9C, 0xAC, 0x48, 0x77, 0x11, 0xC1,
+    0x9C, 0x38, 0x55, 0x60, 0x0F, 0x8D, 0xC9, 0x1C, 0x76, 0x7C, 0x12, 0x19,
+    0x67, 0xB2, 0x60, 0x7C, 0x07, 0x83, 0x80, 0x13, 0xFF, 0xFE, 0x78, 0x4B,
+    0x07, 0x54, 0x86, 0x31, 0x42, 0xA5, 0x5B, 0xD8, 0x5F, 0x70, 0x62, 0x6B,
+    0x79, 0xF5, 0x1C, 0xB2, 0xF4, 0x41, 0x14, 0x44, 0xC1, 0x84, 0x2C, 0xD4,
+    0xED, 0xCF, 0x81, 0xDE, 0x16, 0x5A, 0x87, 0x4A, 0x3C, 0x90, 0xE3, 0x30,
+    0xCA, 0x39, 0xA7, 0xE2, 0x36, 0x02, 0x52, 0xCF, 0x31, 0x3B, 0x1B, 0x18,
+    0xC8, 0xB6, 0x0A, 0x24, 0xAE, 0xCE, 0x64, 0x4A, 0x3D, 0xFA, 0x75, 0xA8,
+    0x82, 0x25, 0xEA, 0x64, 0x09, 0x41, 0x37, 0x75, 0x6C, 0x8E, 0x20, 0xDC,
+    0xC1, 0x0E, 0xD1, 0x11, 0xF1, 0x9F, 0x52, 0xC2, 0x08, 0xAB, 0x59, 0xD2,
+    0xCF, 0xA4, 0x2C, 0xA2, 0x36, 0x41, 0xDB, 0x23, 0x29, 0x73, 0x04, 0xB6,
+    0xE9, 0x8B, 0x38, 0x8A, 0xB2, 0xA2, 0x41, 0xBD, 0x84, 0xD0, 0xC2, 0xAE,
+    0xB3, 0x09, 0xC1, 0x02, 0xB6, 0x35, 0x5D, 0xF1, 0x7B, 0x9A, 0x7C, 0x78,
+    0xAF, 0xD4, 0x9A, 0x88, 0x4C, 0x0D, 0x50, 0x34, 0x1C, 0x93, 0x97, 0x47,
+    0x3E, 0x9A, 0x72, 0x3B, 0x81, 0xDD, 0xF7, 0x47, 0xD2, 0x64, 0x9C, 0xA1,
+    0x05, 0x53, 0x2D, 0x75, 0x9E, 0x42, 0x3D, 0xFC, 0xFC, 0x17, 0xFF, 0x01,
+    0xDC, 0xF1, 0x18, 0xD3};
+const uint8_t g_esES_Locale[] = {
+    0x78, 0x9C, 0x9D, 0x56, 0xCF, 0x6B, 0xD4, 0x40, 0x14, 0xBE, 0x0B, 0xFE,
+    0x0F, 0x21, 0x58, 0x56, 0xA1, 0xDD, 0xD1, 0x63, 0xCB, 0x36, 0x50, 0xDA,
+    0xDA, 0x95, 0x1A, 0x59, 0x9A, 0xAA, 0xD8, 0x8B, 0x4C, 0x92, 0xE9, 0xEE,
+    0xB4, 0xC9, 0xCC, 0x32, 0x49, 0x2C, 0x9B, 0xA3, 0xE0, 0x41, 0x10, 0x0B,
+    0xDE, 0x8A, 0x27, 0x0F, 0x1E, 0x04, 0x8B, 0x77, 0x51, 0x3C, 0xF4, 0x3F,
+    0x11, 0x6A, 0xEB, 0xC9, 0x7F, 0xC1, 0x37, 0x9B, 0x49, 0x36, 0x3F, 0x66,
+    0xD7, 0x60, 0x4E, 0xF3, 0xBE, 0xF7, 0x7D, 0x2F, 0xEF, 0x7D, 0x93, 0x4C,
+    0xD2, 0x0B, 0xB8, 0x87, 0x03, 0x62, 0x30, 0x1C, 0x92, 0x75, 0x93, 0x44,
+    0xCF, 0xB7, 0x1D, 0xD3, 0xF0, 0x49, 0xE4, 0xAD, 0x9B, 0xD7, 0x1F, 0x7F,
+    0x5C, 0x9D, 0x9E, 0x5F, 0xBD, 0x3E, 0xBB, 0xFE, 0x72, 0x7E, 0xBB, 0x08,
+    0xFE, 0x7C, 0x7B, 0x73, 0xF9, 0xFE, 0xFB, 0xEF, 0xB3, 0x57, 0xBF, 0xDE,
+    0xBE, 0xBB, 0xFC, 0x7A, 0x7A, 0xC7, 0xB4, 0x7A, 0xB2, 0x00, 0xF3, 0xB1,
+    0x70, 0x26, 0xA1, 0xCB, 0x83, 0x48, 0xD5, 0x1A, 0x0A, 0x32, 0xE4, 0x82,
+    0x62, 0x06, 0x8C, 0x90, 0xB3, 0x78, 0xF4, 0x08, 0xE0, 0x48, 0xAD, 0x2D,
+    0xC2, 0x88, 0xE0, 0x3D, 0x94, 0x05, 0x37, 0x6F, 0x28, 0xF4, 0x90, 0xB8,
+    0x42, 0x87, 0x87, 0x58, 0xA4, 0x4D, 0x14, 0xBB, 0x82, 0x06, 0x1A, 0xEE,
+    0xA4, 0x49, 0x3D, 0x4A, 0x18, 0xD5, 0xA1, 0x81, 0x06, 0xC5, 0x43, 0x1E,
+    0xC5, 0x4D, 0x38, 0x22, 0xE3, 0x98, 0x92, 0x10, 0x1A, 0x6C, 0xA4, 0xB8,
+    0x17, 0x27, 0x3A, 0x9C, 0xF1, 0x17, 0x73, 0x14, 0x3E, 0xF5, 0x1A, 0x19,
+    0x54, 0x72, 0x29, 0x27, 0x4E, 0x23, 0x03, 0xBB, 0xAE, 0x58, 0x37, 0xEF,
+    0x99, 0x25, 0xF3, 0x74, 0xD6, 0xE9, 0x6C, 0xD3, 0x99, 0xA6, 0xB3, 0x4C,
+    0xE7, 0x98, 0xCE, 0x2F, 0x9D, 0x5B, 0x3A, 0xAB, 0x74, 0x1E, 0xE9, 0xFC,
+    0xD1, 0x39, 0x33, 0xDF, 0x13, 0x1F, 0x4F, 0xD4, 0x53, 0x04, 0x2B, 0xCB,
+    0xE7, 0x21, 0x65, 0xF2, 0xF6, 0x32, 0xC8, 0xB2, 0x56, 0x90, 0x30, 0x12,
+    0x55, 0x10, 0x30, 0x21, 0xAE, 0x43, 0xF4, 0xE2, 0x93, 0xF0, 0x78, 0x50,
+    0x83, 0x8F, 0x12, 0xF2, 0xA2, 0x06, 0xC1, 0xFE, 0x89, 0x7A, 0xC1, 0xE8,
+    0xE2, 0x83, 0x8B, 0xFD, 0xD9, 0x6D, 0x51, 0xD1, 0x55, 0xA9, 0xC3, 0xD2,
+    0x9E, 0xA9, 0x56, 0xEB, 0x6D, 0xD6, 0x9B, 0x6C, 0x74, 0x58, 0xEF, 0xAD,
+    0xDE, 0x58, 0xA3, 0x29, 0x7D, 0x47, 0x21, 0x11, 0xD4, 0x87, 0x87, 0x2D,
+    0x7F, 0xFD, 0x54, 0x68, 0x6D, 0xD8, 0xE0, 0x6E, 0x1E, 0x94, 0x78, 0xD6,
+    0xA0, 0x96, 0x40, 0xD5, 0x0A, 0x80, 0x10, 0x81, 0x55, 0x35, 0x58, 0x59,
+    0xB8, 0xBB, 0xD9, 0xED, 0x21, 0xB9, 0xCA, 0x52, 0x96, 0x5F, 0x06, 0x50,
+    0x41, 0x96, 0x41, 0xED, 0xA8, 0xC8, 0xBA, 0x8F, 0xC9, 0x00, 0xC7, 0x31,
+    0x18, 0x3D, 0xDD, 0xD7, 0x22, 0x52, 0xE7, 0xC8, 0x61, 0x12, 0x04, 0xA6,
+    0xB5, 0x0D, 0x97, 0xB1, 0xD5, 0x81, 0xA3, 0xC9, 0xE8, 0xD8, 0x70, 0x65,
+    0xAB, 0x67, 0x70, 0xC9, 0x69, 0x0B, 0x4D, 0xAD, 0xA0, 0x2A, 0x11, 0x70,
+    0x36, 0x34, 0xAD, 0xFF, 0x55, 0x87, 0xC4, 0x07, 0xF1, 0x16, 0xB2, 0x6D,
+    0xD4, 0x52, 0x11, 0x8D, 0xB8, 0x88, 0x67, 0x9A, 0x86, 0x02, 0x55, 0x66,
+    0x06, 0x20, 0xA6, 0x61, 0xC9, 0x83, 0x52, 0x54, 0xF1, 0xA0, 0xDF, 0xEF,
+    0xF4, 0xA1, 0xFD, 0x0E, 0x5C, 0x0E, 0x9C, 0xD2, 0x07, 0x3D, 0x54, 0x62,
+    0xD6, 0xCA, 0x54, 0x26, 0xEF, 0xF7, 0xD7, 0x6C, 0x7B, 0xCD, 0x71, 0x5A,
+    0x49, 0xA6, 0xE3, 0x2A, 0x41, 0x0B, 0xBA, 0x9A, 0x55, 0x0A, 0x1A, 0x6C,
+    0x54, 0x99, 0x4B, 0x59, 0xB5, 0x0F, 0x58, 0xBE, 0xFD, 0x3B, 0x89, 0x1D,
+    0x1F, 0x8F, 0xC2, 0xC8, 0xD9, 0xDE, 0xBA, 0x7F, 0xF2, 0x14, 0x8F, 0x76,
+    0xD3, 0x83, 0xCC, 0x9C, 0x32, 0x09, 0x74, 0x2C, 0x09, 0x5D, 0x22, 0x66,
+    0x0E, 0x55, 0x62, 0xD5, 0x08, 0x60, 0xF0, 0x9C, 0x7A, 0xA6, 0x95, 0x2E,
+    0xA7, 0xE9, 0x6A, 0x37, 0x4D, 0xD3, 0x1E, 0xAA, 0xF0, 0x1A, 0x85, 0x94,
+    0xD0, 0x4B, 0x84, 0x20, 0xCC, 0x9B, 0xE4, 0xCA, 0xD5, 0x55, 0xE3, 0x56,
+    0x4B, 0xE9, 0x98, 0x08, 0x8F, 0xB0, 0x58, 0x29, 0x97, 0x34, 0x2A, 0x54,
+    0x6B, 0xBD, 0x28, 0x94, 0x4F, 0x57, 0x09, 0x55, 0x59, 0x9F, 0x78, 0x34,
+    0xC4, 0xB0, 0xE3, 0xCB, 0xB9, 0x3E, 0x4B, 0xD7, 0xD5, 0xC5, 0x97, 0x96,
+    0x27, 0x63, 0x2A, 0x37, 0xBA, 0xDB, 0x8A, 0x5F, 0x74, 0xBD, 0xD4, 0x8A,
+    0x0E, 0x87, 0x6C, 0x12, 0x99, 0xD6, 0x4A, 0x2B, 0x72, 0x0A, 0x9F, 0x6F,
+    0xD3, 0xBA, 0xDB, 0xE4, 0xA2, 0xEA, 0xD8, 0x80, 0xE4, 0xBE, 0x17, 0x4E,
+    0x54, 0x81, 0xFC, 0xF9, 0x9A, 0x06, 0xA6, 0xF5, 0xF3, 0xE5, 0x67, 0x38,
+    0x3E, 0x2A, 0x8C, 0x66, 0x11, 0xA5, 0xA1, 0x11, 0x97, 0x0B, 0x38, 0x35,
+    0x1E, 0xEF, 0xB5, 0x16, 0x95, 0x4D, 0x6F, 0x4A, 0x50, 0xBD, 0x5B, 0xF9,
+    0x32, 0x4C, 0xC6, 0xE4, 0x10, 0x7B, 0xF2, 0x1C, 0xCC, 0x97, 0xAA, 0x96,
+    0x3D, 0x81, 0x1F, 0x1F, 0xDF, 0x18, 0x80, 0x17, 0xA8, 0xCC, 0xCC, 0xD3,
+    0x14, 0xFE, 0x46, 0xD8, 0xDC, 0xF4, 0x26, 0x4F, 0x04, 0x7C, 0x77, 0x0C,
+    0x27, 0xF6, 0xB5, 0xF9, 0x0D, 0x9F, 0xBB, 0xC4, 0x18, 0xD0, 0x7F, 0x10,
+    0xFA, 0xF2, 0x67, 0xEA, 0x64, 0x01, 0x61, 0x43, 0x60, 0x17, 0x5E, 0x98,
+    0xF9, 0x84, 0xFD, 0x11, 0xA6, 0xDA, 0xF4, 0x2E, 0x4F, 0x93, 0x63, 0x6C,
+    0xEC, 0xF0, 0x78, 0x44, 0x3D, 0x39, 0xC7, 0xCA, 0x93, 0x07, 0x86, 0xBD,
+    0x88, 0x0A, 0x23, 0x7B, 0x23, 0x9E, 0x53, 0xF7, 0x16, 0xDC, 0x14, 0x98,
+    0x43, 0x39, 0x99, 0xF1, 0x70, 0x01, 0xC9, 0xE1, 0x2D, 0x48, 0xF6, 0x24,
+    0x61, 0xC3, 0x23, 0x3E, 0xE5, 0xA9, 0xE6, 0xD0, 0x6C, 0xCF, 0x64, 0x94,
+    0xFD, 0xFC, 0xC2, 0xF2, 0x2F, 0x7C, 0xDC, 0xCC, 0x2F,
+};
+const uint8_t g_esLA_Locale[] = {
+    0x78, 0x9C, 0x9D, 0x56, 0xCD, 0x4E, 0xDC, 0x30, 0x10, 0x3E, 0x53, 0xA9,
+    0xEF, 0x60, 0x45, 0x45, 0x80, 0x04, 0x9B, 0xF6, 0xB8, 0x28, 0x44, 0x5A,
+    0x01, 0xA5, 0x15, 0x0D, 0x5A, 0x75, 0x51, 0x4B, 0xB9, 0x54, 0x4E, 0x62,
+    0x36, 0x86, 0xC4, 0x5E, 0x39, 0x09, 0x68, 0xA3, 0xBE, 0x40, 0x4F, 0x3D,
+    0xF4, 0xD4, 0x63, 0x2B, 0x21, 0xB5, 0x07, 0xD4, 0x47, 0xE8, 0x81, 0x67,
+    0x41, 0xF0, 0x18, 0x9D, 0xFC, 0x6E, 0x12, 0x3B, 0xE9, 0xD2, 0x9C, 0x3C,
+    0xDF, 0x7C, 0x9F, 0x77, 0xE6, 0xB3, 0x33, 0x1B, 0xC3, 0xE7, 0x0E, 0xF6,
+    0x09, 0x62, 0x38, 0x20, 0x3B, 0x1A, 0x09, 0x3F, 0x5A, 0x27, 0x1A, 0x72,
+    0x49, 0xE8, 0xEC, 0x68, 0x0F, 0xD7, 0x7F, 0xEE, 0xBF, 0xDC, 0xDC, 0x7F,
+    0xFE, 0xF6, 0xF0, 0xFB, 0x66, 0xFD, 0xEE, 0xC7, 0x4F, 0x88, 0xEF, 0xBE,
+    0x5E, 0x6F, 0x68, 0xE6, 0xD3, 0x27, 0x08, 0x19, 0xA9, 0x8A, 0xB9, 0x58,
+    0x4C, 0xE6, 0x81, 0xCD, 0xFD, 0xB0, 0xD8, 0x60, 0x2A, 0xC8, 0x94, 0x0B,
+    0x8A, 0x59, 0xCA, 0x5A, 0x41, 0x46, 0xC0, 0x59, 0xE4, 0x1D, 0x41, 0x2A,
+    0x4C, 0xE3, 0x95, 0x3C, 0x36, 0x09, 0x23, 0x82, 0x1B, 0x7A, 0x1E, 0xD4,
+    0xF0, 0x33, 0x62, 0x0B, 0x75, 0x26, 0xC0, 0x22, 0x51, 0xE1, 0xD8, 0x16,
+    0xD4, 0x57, 0xF2, 0xE7, 0x2A, 0xFA, 0x79, 0xCC, 0xA8, 0x1A, 0xF7, 0x95,
+    0x38, 0x9E, 0xF2, 0x30, 0x52, 0x25, 0x42, 0x32, 0x8B, 0x28, 0x09, 0xA0,
+    0x5C, 0x45, 0x92, 0x3B, 0x51, 0xAC, 0xCE, 0x30, 0x7E, 0xD9, 0xA9, 0x72,
+    0xA9, 0x23, 0xE5, 0x50, 0xB1, 0xAE, 0x1C, 0xAC, 0x3B, 0x8A, 0xB0, 0x6D,
+    0x8B, 0x1D, 0xED, 0x85, 0xD6, 0xB2, 0x56, 0x6D, 0xAC, 0xDA, 0x54, 0xB5,
+    0xA5, 0x6A, 0x43, 0xD5, 0x7E, 0xAA, 0xDD, 0x54, 0x7B, 0xA9, 0x36, 0x52,
+    0xED, 0xA0, 0xDA, 0x3D, 0xB5, 0x6F, 0xFD, 0x8E, 0xB9, 0x78, 0x5E, 0xBB,
+    0x81, 0x10, 0x99, 0x2E, 0x0F, 0x28, 0x4B, 0xCB, 0x49, 0x83, 0x0A, 0xF5,
+    0x63, 0x46, 0xC2, 0x16, 0x06, 0x16, 0x45, 0x32, 0x48, 0x6F, 0x7F, 0x09,
+    0x87, 0xFB, 0x52, 0xE2, 0x3C, 0x26, 0x97, 0x12, 0x08, 0x27, 0x2E, 0xE4,
+    0x8D, 0xC3, 0xDB, 0xEF, 0x36, 0x76, 0x17, 0x25, 0xA0, 0x6C, 0xA5, 0xA8,
+    0xBA, 0x75, 0xCA, 0x45, 0xF9, 0x72, 0xE9, 0x72, 0xE1, 0x8A, 0xAA, 0xE5,
+    0x7A, 0xE5, 0x62, 0x15, 0x85, 0x76, 0x57, 0x19, 0x10, 0x41, 0x5D, 0xB8,
+    0xB6, 0xF5, 0x57, 0xBC, 0x80, 0xCC, 0x91, 0x05, 0x67, 0x51, 0x06, 0xCD,
+    0xD4, 0xB8, 0x95, 0x42, 0x8B, 0xB0, 0xB6, 0x39, 0x11, 0xB8, 0xB6, 0x2F,
+    0x44, 0x26, 0x1E, 0xEC, 0x0E, 0x0C, 0x3D, 0x5D, 0x55, 0x90, 0x5B, 0x87,
+    0x50, 0xB6, 0x2A, 0x45, 0x30, 0xA5, 0xF4, 0xD6, 0x98, 0xCA, 0x51, 0x17,
+    0x47, 0x64, 0x8C, 0xA3, 0x08, 0x0E, 0xA6, 0x72, 0xBB, 0x42, 0x8A, 0x49,
+    0x76, 0x16, 0xFB, 0xBE, 0x66, 0xEE, 0xC3, 0x83, 0xF6, 0xD6, 0x60, 0x22,
+    0xA2, 0x35, 0x0B, 0x9E, 0x7C, 0xF5, 0x01, 0x9E, 0xD4, 0x89, 0x4A, 0xD3,
+    0xB5, 0x89, 0xCF, 0xD9, 0x54, 0x33, 0xFF, 0x5F, 0x1F, 0x10, 0x17, 0xE4,
+    0x7B, 0xBA, 0x65, 0xE9, 0x4B, 0x6B, 0x42, 0x8F, 0x8B, 0x68, 0xA1, 0x6A,
+    0x6B, 0x10, 0x6A, 0x20, 0x85, 0x23, 0x11, 0x0D, 0x5A, 0x8E, 0xD4, 0x90,
+    0x86, 0x23, 0x9E, 0xB7, 0x6D, 0x59, 0xDB, 0x93, 0x09, 0x1A, 0xA1, 0x53,
+    0x43, 0xAF, 0xB1, 0xBA, 0x64, 0xB9, 0x07, 0x8F, 0x96, 0x65, 0xAD, 0x2F,
+    0x54, 0x4B, 0x69, 0x8A, 0xD6, 0x33, 0x95, 0x2C, 0x49, 0x3B, 0x6F, 0xF5,
+    0x59, 0xDC, 0x85, 0x63, 0x40, 0xCB, 0x0B, 0x72, 0x10, 0x5B, 0xD1, 0x85,
+    0x17, 0x84, 0x93, 0xFD, 0xBD, 0x97, 0x57, 0xEF, 0xB1, 0x77, 0x98, 0x9C,
+    0xE6, 0x86, 0xD5, 0x49, 0x99, 0x92, 0xC5, 0x81, 0x4D, 0x44, 0xD3, 0xB5,
+    0x06, 0x56, 0x54, 0x05, 0x18, 0xDC, 0x6D, 0x47, 0x33, 0x93, 0xCD, 0x24,
+    0x19, 0x0E, 0x92, 0x24, 0x31, 0xF4, 0x06, 0xAF, 0x5B, 0xEA, 0xC4, 0x42,
+    0x10, 0xE6, 0xCC, 0x35, 0xF3, 0x59, 0x2E, 0x1E, 0x0E, 0x3F, 0xAD, 0x57,
+    0xCB, 0x8D, 0xA5, 0xF7, 0x99, 0x11, 0xE1, 0x10, 0x16, 0x15, 0x25, 0xAC,
+    0xCA, 0xBA, 0xD4, 0x1B, 0xA9, 0x9F, 0xAA, 0xC7, 0x45, 0xDB, 0x2B, 0x4D,
+    0xA8, 0xD8, 0xDE, 0x25, 0x0E, 0x0D, 0x30, 0x5C, 0x8E, 0x41, 0xB9, 0x4B,
+    0x9E, 0xEE, 0x14, 0x4C, 0x05, 0x8F, 0x67, 0x34, 0xBD, 0x17, 0x9B, 0x4B,
+    0x2A, 0xAA, 0x0E, 0x56, 0x97, 0x14, 0xC0, 0x84, 0x8F, 0x43, 0xCD, 0xDC,
+    0x5A, 0x92, 0x9E, 0xC0, 0x77, 0x87, 0x66, 0x3E, 0x97, 0xD8, 0x0B, 0x63,
+    0x1A, 0x67, 0x5F, 0x1E, 0x4C, 0xC3, 0x99, 0x26, 0x58, 0xDE, 0xC9, 0x2C,
+    0x80, 0x03, 0x84, 0x59, 0xD4, 0xC8, 0xF7, 0x68, 0x68, 0xC8, 0xD3, 0x85,
+    0x66, 0x5A, 0x27, 0x47, 0x8F, 0x90, 0xD5, 0x8F, 0x41, 0x12, 0x65, 0xC3,
+    0x50, 0xAA, 0x3A, 0x7D, 0xF5, 0xE7, 0x33, 0x72, 0x86, 0x9D, 0x72, 0xE8,
+    0x96, 0x61, 0xB1, 0xA7, 0x35, 0x87, 0xAF, 0x39, 0x17, 0x8D, 0xC1, 0x1D,
+    0x5D, 0x4D, 0xA0, 0xF0, 0x49, 0xC5, 0x7A, 0x08, 0xBB, 0x3C, 0x16, 0xF0,
+    0x17, 0x88, 0x26, 0x91, 0xDB, 0xC1, 0x18, 0xB9, 0xDC, 0x26, 0x68, 0x4C,
+    0xFF, 0x49, 0x79, 0x95, 0x7E, 0x1F, 0x5E, 0xF5, 0x52, 0x46, 0x02, 0xDB,
+    0xF0, 0xAE, 0xF5, 0x51, 0x8E, 0x3D, 0x4C, 0x3B, 0x08, 0x87, 0x3C, 0x89,
+    0x2F, 0x30, 0x3A, 0xE0, 0x91, 0x47, 0x9D, 0xB4, 0xA7, 0xAD, 0x77, 0xAF,
+    0x91, 0xD5, 0x4F, 0x06, 0x03, 0x1C, 0x8F, 0x97, 0xE4, 0xB7, 0xBD, 0x3F,
+    0x0D, 0xDC, 0x69, 0xDA, 0x25, 0x7A, 0xD3, 0x4B, 0x9B, 0xF0, 0xA5, 0x68,
+    0xD6, 0x3C, 0x66, 0xD3, 0x73, 0x9E, 0x31, 0xF3, 0x22, 0xB3, 0x11, 0x57,
+    0x3B, 0x4F, 0x43, 0xCF, 0x3F, 0xEF, 0xCD, 0xBF, 0xC4, 0xB5, 0xD4, 0x04};
+const uint8_t g_deDE_Loacale[] = {
+    0x78, 0x9C, 0x95, 0x56, 0x4D, 0x6F, 0xD4, 0x30, 0x10, 0xBD, 0x23, 0xF1,
+    0x1F, 0xAC, 0x88, 0xAA, 0x20, 0xB5, 0x1B, 0x38, 0xB6, 0xDA, 0x46, 0x5A,
+    0x75, 0xFB, 0x41, 0x4B, 0xCA, 0xAA, 0x69, 0x41, 0xF4, 0x82, 0xBC, 0x89,
+    0xBB, 0x71, 0x9B, 0xD8, 0x2B, 0xC7, 0x69, 0xB5, 0x39, 0xF2, 0x37, 0xB8,
+    0x72, 0x04, 0x71, 0xE4, 0x04, 0x17, 0xFE, 0x09, 0x52, 0x25, 0x7E, 0x06,
+    0x93, 0x8D, 0x93, 0x26, 0xB6, 0xBB, 0x0D, 0xB9, 0xAC, 0xE7, 0xCD, 0x7B,
+    0xB3, 0x33, 0xCF, 0x89, 0x93, 0x61, 0xC2, 0x43, 0x9C, 0x10, 0xC4, 0x70,
+    0x4A, 0x76, 0x9C, 0x88, 0x7C, 0x1C, 0xEF, 0x39, 0x28, 0x22, 0x59, 0xB8,
+    0xE3, 0xDC, 0xFD, 0xFA, 0xF1, 0xF7, 0xFB, 0xB7, 0xE7, 0xF0, 0x73, 0xF7,
+    0xF9, 0xE7, 0x0B, 0xC7, 0x1B, 0x96, 0x44, 0x16, 0x61, 0x11, 0x2C, 0xD2,
+    0x29, 0x4F, 0x32, 0xA5, 0x99, 0x09, 0x32, 0xE3, 0x82, 0x62, 0x06, 0x8C,
+    0x94, 0x33, 0x19, 0x9F, 0x00, 0x9C, 0xA9, 0xB5, 0x77, 0x84, 0x59, 0x8E,
+    0xC5, 0xD0, 0xAD, 0xA2, 0xA7, 0x4F, 0x14, 0xBC, 0x4F, 0xA6, 0xC2, 0x86,
+    0xFB, 0xBF, 0xBF, 0x88, 0xC2, 0x40, 0x47, 0x73, 0x41, 0x13, 0x93, 0x8B,
+    0xA9, 0x81, 0x1D, 0xE5, 0xCC, 0x06, 0x26, 0x26, 0x38, 0xCA, 0x67, 0x79,
+    0x26, 0x0D, 0x38, 0x20, 0x73, 0x49, 0xD2, 0x29, 0x31, 0x5B, 0x7B, 0x7B,
+    0x2D, 0xB9, 0x0D, 0x3F, 0xE1, 0x37, 0x76, 0xC1, 0x98, 0x14, 0x7A, 0xC2,
+    0x6D, 0x19, 0x54, 0xF3, 0x96, 0x11, 0xC2, 0xD3, 0xA9, 0xD8, 0x71, 0x5E,
+    0x39, 0x2D, 0xDF, 0x6C, 0xA6, 0x99, 0x26, 0xD8, 0xED, 0xEA, 0x6B, 0x96,
+    0xCD, 0x2B, 0x9B, 0x55, 0x36, 0x9F, 0x6C, 0x0E, 0xD9, 0xDC, 0xB1, 0x19,
+    0xF3, 0xB0, 0x27, 0x11, 0x5E, 0xA8, 0x1B, 0x08, 0x56, 0x5E, 0xC0, 0x19,
+    0x93, 0x18, 0xFE, 0xBE, 0x0C, 0xAA, 0xAC, 0xE7, 0x73, 0x03, 0x1A, 0x53,
+    0xC2, 0x32, 0x83, 0x47, 0xA5, 0xBC, 0xE5, 0x61, 0xDC, 0x65, 0x42, 0x41,
+    0x22, 0x0C, 0xEE, 0xBE, 0x20, 0x54, 0xC7, 0x02, 0x9C, 0x76, 0x78, 0x6E,
+    0xD3, 0x5A, 0xAB, 0xCD, 0xD6, 0xC6, 0x55, 0xFD, 0x6A, 0xAD, 0x6A, 0x6D,
+    0x6A, 0x0D, 0x6A, 0xAD, 0x69, 0x2D, 0x69, 0xDD, 0xD8, 0x1B, 0x49, 0x89,
+    0xA0, 0x11, 0x25, 0x69, 0xFD, 0xD4, 0xA9, 0xD0, 0x1B, 0xF9, 0xE0, 0x6C,
+    0x1D, 0xB4, 0x78, 0xDE, 0x44, 0x4B, 0xB8, 0xDD, 0x0A, 0x80, 0x10, 0x81,
+    0x55, 0x35, 0x58, 0x79, 0x37, 0x03, 0xB4, 0x1B, 0x8B, 0xC1, 0xD0, 0x2D,
+    0x83, 0x2A, 0xEB, 0x31, 0x0D, 0x73, 0x1B, 0x49, 0x19, 0x68, 0xE7, 0x44,
+    0x35, 0x81, 0x24, 0x13, 0x2C, 0x25, 0x11, 0x6C, 0xB9, 0xB3, 0x4D, 0xA4,
+    0x0E, 0x91, 0xCB, 0x3C, 0x49, 0x1C, 0x6F, 0x0F, 0xAE, 0x0D, 0x34, 0x1E,
+    0x20, 0x1F, 0x2E, 0xF4, 0x01, 0xAE, 0x72, 0xD6, 0x86, 0xAB, 0x15, 0x52,
+    0xD2, 0x84, 0xB3, 0x99, 0xE3, 0xFD, 0xA7, 0x28, 0x25, 0x11, 0x68, 0xC6,
+    0x03, 0xDF, 0x1F, 0xF4, 0x54, 0x64, 0x31, 0x17, 0xF2, 0x5E, 0x63, 0x28,
+    0xDC, 0xCE, 0x88, 0x00, 0x48, 0x9A, 0xB6, 0x46, 0x6E, 0x45, 0x9D, 0x91,
+    0x0F, 0xB7, 0x7D, 0x7F, 0x1D, 0x9D, 0xC7, 0x02, 0xAD, 0x5F, 0x0C, 0xDD,
+    0x16, 0x4B, 0x2B, 0xD1, 0x19, 0xF6, 0xB0, 0x54, 0x6D, 0x07, 0x01, 0xEA,
+    0x23, 0x59, 0x8E, 0x5A, 0x2B, 0x7A, 0xF0, 0xD5, 0xA0, 0x4B, 0x85, 0x41,
+    0x77, 0x3B, 0x53, 0x29, 0xA3, 0xCE, 0x00, 0xAB, 0xF7, 0xFA, 0xE0, 0xCA,
+    0x97, 0xD7, 0x87, 0x69, 0x16, 0xEC, 0x8D, 0xF7, 0x6F, 0xDF, 0xE3, 0xF8,
+    0xB8, 0xB8, 0xA8, 0xAC, 0x69, 0x93, 0x40, 0xC7, 0xF2, 0xF2, 0x68, 0xBC,
+    0xF7, 0xA7, 0x13, 0xAB, 0x4E, 0x00, 0x83, 0x5B, 0x33, 0x74, 0xBC, 0x62,
+    0xA3, 0x28, 0xB6, 0x06, 0x45, 0x01, 0xC7, 0x46, 0x87, 0x67, 0x14, 0x52,
+    0xC2, 0x30, 0x17, 0x82, 0xB0, 0x70, 0x51, 0x2B, 0xB7, 0xB6, 0xD0, 0xB3,
+    0x9E, 0xD2, 0x39, 0x11, 0x21, 0x61, 0x52, 0x29, 0xD7, 0x2C, 0x2A, 0x57,
+    0x6B, 0xBD, 0x29, 0x54, 0x4F, 0xD7, 0x09, 0x9B, 0x17, 0x6B, 0x48, 0x53,
+    0x0C, 0xFB, 0xBD, 0x51, 0xEB, 0xAB, 0xB4, 0xAE, 0x6E, 0xDE, 0xA9, 0x3C,
+    0x9F, 0xD3, 0x72, 0xAB, 0x07, 0xBD, 0xF8, 0x4D, 0xD7, 0x6B, 0xBD, 0xE8,
+    0x29, 0x65, 0x79, 0xE6, 0x78, 0x9B, 0xBD, 0xC8, 0x05, 0x11, 0xDC, 0xF1,
+    0x5E, 0x9A, 0x5C, 0xB7, 0x3B, 0x36, 0x20, 0xB5, 0xEF, 0x8D, 0x13, 0x5D,
+    0xA0, 0xBE, 0xC1, 0x96, 0x81, 0xE3, 0xFD, 0xF9, 0xF4, 0x15, 0xCE, 0x8A,
+    0x0E, 0xC3, 0x2C, 0xA2, 0x34, 0x34, 0xE3, 0xE5, 0x02, 0x8E, 0x88, 0xF3,
+    0xD3, 0xDE, 0xA2, 0xB6, 0xE9, 0xA6, 0xC4, 0xD5, 0xBB, 0x2D, 0x9F, 0x86,
+    0xC5, 0x9C, 0x5C, 0xE2, 0xB0, 0x3C, 0xFA, 0xEA, 0xA5, 0xAA, 0xE5, 0x2F,
+    0xE0, 0x13, 0x27, 0x42, 0x13, 0xF0, 0xC2, 0x6D, 0x33, 0xEB, 0x34, 0x65,
+    0x94, 0xB3, 0x07, 0xD3, 0xBB, 0x3C, 0x17, 0x94, 0x08, 0x14, 0xC8, 0xC8,
+    0x9A, 0x1F, 0x45, 0xF0, 0x69, 0x81, 0x26, 0xF4, 0x11, 0xC2, 0x21, 0x7C,
+    0x35, 0x91, 0xDB, 0x15, 0x84, 0x91, 0xC0, 0x53, 0x78, 0x60, 0x1E, 0x26,
+    0x9C, 0xC5, 0x98, 0x5A, 0xD3, 0xC7, 0xBC, 0xC8, 0xAF, 0x31, 0x3A, 0xE0,
+    0x32, 0xA6, 0x61, 0x39, 0xC7, 0xE6, 0xBB, 0xD7, 0xC8, 0x5F, 0x45, 0x85,
+    0x91, 0xC3, 0x98, 0xD7, 0xD4, 0xD3, 0x15, 0x7F, 0x0A, 0xCC, 0x59, 0x39,
+    0x19, 0x7A, 0xB3, 0x82, 0x04, 0x6F, 0xFA, 0xC7, 0x49, 0xFE, 0x22, 0x67,
+    0xB3, 0x2B, 0xBE, 0xE4, 0xA9, 0xE6, 0xDC, 0xFB, 0x3D, 0x2B, 0xA3, 0xEA,
+    0x73, 0x16, 0x96, 0xFF, 0x00, 0x29, 0x27, 0xAF, 0x17,
+};
+const uint8_t g_frFR_Locale[] = {
+    0x78, 0x9C, 0x95, 0x56, 0x4D, 0x6F, 0xD3, 0x40, 0x10, 0xBD, 0x23, 0xF1,
+    0x1F, 0x56, 0x16, 0x55, 0x41, 0x6A, 0xBD, 0x70, 0x4C, 0x95, 0x5A, 0xAA,
+    0xFA, 0x15, 0x28, 0x46, 0x51, 0x53, 0x40, 0xF4, 0x82, 0x36, 0xF6, 0x36,
+    0xDE, 0xD4, 0xDE, 0x8D, 0xD6, 0x76, 0x4A, 0x7C, 0xE4, 0x3F, 0x70, 0xE2,
+    0xC2, 0xB5, 0x12, 0x88, 0x03, 0x47, 0xC4, 0x85, 0xFE, 0x13, 0x24, 0x10,
+    0x3F, 0x83, 0x71, 0xBC, 0x76, 0xED, 0x5D, 0x27, 0xB8, 0xBE, 0x64, 0xE7,
+    0xCD, 0x7B, 0xE3, 0x99, 0xB7, 0xF6, 0xC6, 0xFD, 0x50, 0x78, 0x24, 0xA4,
+    0x88, 0x93, 0x88, 0xEE, 0x5A, 0x17, 0xF2, 0xED, 0xD1, 0xA9, 0x85, 0x7C,
+    0x1A, 0x7B, 0xBB, 0xD6, 0x9F, 0x6F, 0x1F, 0xFE, 0x7E, 0xFD, 0xF2, 0x10,
+    0x7E, 0x7E, 0x7F, 0xFC, 0xF1, 0xC8, 0x72, 0xFA, 0x39, 0x91, 0xFB, 0x44,
+    0x8E, 0x16, 0xD1, 0x58, 0x84, 0xB1, 0xD2, 0x4C, 0x24, 0x9D, 0x08, 0xC9,
+    0x08, 0x07, 0x46, 0x24, 0x78, 0x12, 0xBC, 0x00, 0x38, 0x56, 0x6B, 0x67,
+    0x4A, 0xF8, 0x9C, 0x51, 0xD9, 0xC7, 0x45, 0x78, 0xFF, 0x9E, 0xC2, 0x2F,
+    0x6E, 0xAE, 0xE7, 0xB2, 0x2D, 0x11, 0x11, 0x19, 0x1B, 0x20, 0x01, 0x6E,
+    0xD8, 0x42, 0x65, 0x06, 0x36, 0x4D, 0x19, 0x6F, 0x03, 0xC3, 0x90, 0x26,
+    0x66, 0x59, 0x71, 0xF3, 0xDD, 0x44, 0x63, 0x3A, 0x4B, 0x68, 0x34, 0x96,
+    0xD4, 0xC8, 0x08, 0x2F, 0x11, 0x6D, 0x38, 0x17, 0xF3, 0x76, 0x81, 0x7F,
+    0x73, 0xED, 0xE9, 0x19, 0x5C, 0x33, 0xA9, 0x24, 0x2E, 0x23, 0x44, 0xC6,
+    0x63, 0xB9, 0x6B, 0x3D, 0xB1, 0xEA, 0xDE, 0xD9, 0xED, 0xCE, 0x99, 0xF0,
+    0x2A, 0xDF, 0xDA, 0x98, 0x77, 0xB0, 0xCD, 0x94, 0xAF, 0x36, 0xCD, 0xE4,
+    0x82, 0x61, 0x26, 0x08, 0x6E, 0x99, 0x60, 0xEE, 0x94, 0xBD, 0xDA, 0x25,
+    0x9F, 0x2C, 0xD4, 0x63, 0x05, 0x2B, 0xC7, 0x67, 0x11, 0xE1, 0x5E, 0x00,
+    0xAE, 0xE6, 0x51, 0x91, 0x76, 0xC2, 0x94, 0xFB, 0xAC, 0x81, 0x80, 0x25,
+    0x3A, 0x42, 0xA5, 0x27, 0xA9, 0x06, 0x4E, 0x69, 0xAA, 0x21, 0x73, 0x78,
+    0xCC, 0x0D, 0x5A, 0x0C, 0xF7, 0xAF, 0x41, 0xB8, 0x6A, 0xA9, 0xD6, 0x5E,
+    0x6D, 0x0B, 0x55, 0x9F, 0xB6, 0xDE, 0xA3, 0xAD, 0xB7, 0x68, 0xEB, 0x1D,
+    0xDA, 0x7A, 0x77, 0xB6, 0xDE, 0x9C, 0xAD, 0x37, 0x66, 0xB7, 0xB7, 0x05,
+    0xC5, 0x98, 0xCF, 0x68, 0x54, 0xBE, 0x91, 0x2A, 0x74, 0xF6, 0x5C, 0xF0,
+    0xB7, 0x0C, 0x6A, 0x3C, 0x67, 0xA8, 0x25, 0x70, 0xB3, 0x02, 0x20, 0x54,
+    0x12, 0x55, 0x0D, 0x56, 0xF0, 0x7C, 0xD9, 0xE8, 0x99, 0xBD, 0xBD, 0x0F,
+    0xF7, 0xCF, 0xC3, 0x22, 0xEF, 0x90, 0x99, 0x8E, 0xE2, 0x4A, 0x96, 0x07,
+    0xDA, 0x39, 0x52, 0xCC, 0x91, 0xD0, 0x21, 0x49, 0x12, 0x2A, 0xF9, 0x72,
+    0x8F, 0xAB, 0xA8, 0x3C, 0x98, 0xD2, 0x30, 0xB4, 0x9C, 0x43, 0xB8, 0xD0,
+    0x01, 0x72, 0xE1, 0x42, 0x6F, 0xE0, 0xCA, 0xA7, 0xAD, 0x98, 0x5A, 0x19,
+    0x25, 0x0C, 0x05, 0x9F, 0x58, 0xCE, 0xDD, 0x34, 0xB0, 0xCF, 0x4A, 0x82,
+    0x3A, 0xF1, 0xE3, 0x40, 0xC8, 0x04, 0x14, 0x07, 0xD8, 0x75, 0x71, 0x8B,
+    0x02, 0x37, 0xA6, 0x03, 0x20, 0x61, 0x51, 0x6D, 0xDA, 0x5A, 0xD4, 0x98,
+    0x76, 0x30, 0xD8, 0x44, 0x01, 0xDA, 0x84, 0x2E, 0xCE, 0xFB, 0xB8, 0x46,
+    0xD2, 0x2A, 0x34, 0x06, 0x1D, 0x0C, 0x76, 0x5C, 0x77, 0x67, 0x34, 0xEA,
+    0x24, 0x59, 0xCE, 0x59, 0x2A, 0x3A, 0xF0, 0xD5, 0x9C, 0x4B, 0x85, 0x41,
+    0xC7, 0x8D, 0xA1, 0x94, 0x4F, 0x67, 0x80, 0x95, 0xBB, 0x7C, 0x4C, 0xDC,
+    0xE9, 0xE5, 0x20, 0x8A, 0x47, 0x87, 0x07, 0x47, 0x57, 0xAF, 0xDF, 0x05,
+    0x27, 0xD9, 0x79, 0xE1, 0x4C, 0x9D, 0x04, 0x3A, 0x9E, 0x46, 0x63, 0x2A,
+    0x6F, 0xED, 0x69, 0xC4, 0xAA, 0x13, 0xC0, 0xE0, 0xC1, 0xF4, 0x2C, 0x27,
+    0xDB, 0xCA, 0xB2, 0x9E, 0x9D, 0x65, 0x59, 0x1F, 0x37, 0x78, 0x46, 0x21,
+    0x25, 0xF4, 0x52, 0x29, 0x29, 0xF7, 0x16, 0xA5, 0xB2, 0xD7, 0x43, 0x0F,
+    0x3A, 0x4A, 0x67, 0x70, 0x76, 0x50, 0x9E, 0x28, 0xE5, 0x46, 0x8B, 0x0A,
+    0x6B, 0xAD, 0x57, 0x85, 0xCA, 0xE9, 0x1A, 0xA1, 0x2A, 0xEB, 0x53, 0x0F,
+    0x4E, 0x33, 0xD8, 0xEE, 0xAD, 0x52, 0x5F, 0xA4, 0x75, 0x75, 0xF5, 0x6F,
+    0x2B, 0xD2, 0x19, 0xCB, 0xB7, 0xFA, 0xE7, 0xA7, 0x4E, 0x82, 0xAA, 0xED,
+    0x8D, 0x4E, 0xF4, 0x88, 0xF1, 0x34, 0xB6, 0x9C, 0xED, 0x4E, 0xE4, 0x8C,
+    0x4A, 0x61, 0x39, 0x8F, 0x4D, 0x2E, 0x6E, 0xCE, 0x0D, 0x48, 0x69, 0x7C,
+    0x65, 0x45, 0x13, 0x28, 0x9F, 0xB0, 0x65, 0x60, 0x39, 0xBF, 0xDE, 0x7F,
+    0x86, 0x63, 0xA2, 0xC1, 0x30, 0x8B, 0x28, 0x0D, 0x8B, 0x45, 0xBE, 0x80,
+    0xD3, 0xE1, 0xE5, 0x69, 0x67, 0x51, 0xDD, 0x75, 0x53, 0x82, 0xF5, 0x6E,
+    0xF3, 0xD7, 0x61, 0x31, 0xA3, 0x17, 0xC4, 0xCB, 0x4F, 0xBE, 0x72, 0xA9,
+    0x6A, 0xB9, 0x0B, 0xF8, 0xFA, 0xF1, 0xD1, 0x10, 0xBC, 0xC0, 0x75, 0x66,
+    0x99, 0x66, 0x9C, 0x09, 0xBE, 0x32, 0xBD, 0x2F, 0xD2, 0xFC, 0x3B, 0x08,
+    0x8D, 0x12, 0xBF, 0x35, 0xBF, 0xE7, 0x8B, 0x31, 0x45, 0x43, 0xF6, 0x1F,
+    0xC2, 0x80, 0xC2, 0x57, 0xC6, 0xD5, 0x1A, 0xC2, 0x9E, 0x24, 0x63, 0x78,
+    0x63, 0x56, 0x13, 0xCE, 0x02, 0xC2, 0x5A, 0xD3, 0x27, 0x22, 0x4B, 0x2F,
+    0x09, 0x3A, 0x16, 0x49, 0xC0, 0xBC, 0x7C, 0x8E, 0xED, 0x57, 0x4F, 0x91,
+    0xBB, 0x8E, 0x0A, 0x23, 0x7B, 0x81, 0x28, 0xA9, 0xA7, 0x6B, 0x6E, 0x0A,
+    0xCC, 0x49, 0x3E, 0x19, 0x7A, 0xBE, 0x86, 0x34, 0x12, 0x1D, 0x48, 0xEE,
+    0x22, 0xE5, 0x93, 0xA9, 0x58, 0xF2, 0x54, 0x73, 0xF8, 0x76, 0xCF, 0xF2,
+    0xA8, 0xF8, 0xD2, 0x85, 0xE5, 0x3F, 0x5D, 0x49, 0xBE, 0x1B};
+const uint8_t g_itIT_Locale[] = {
+    0x78, 0x9C, 0x95, 0x56, 0xD1, 0x6A, 0xD4, 0x40, 0x14, 0x7D, 0x17, 0xFC,
+    0x87, 0x21, 0x58, 0x50, 0x68, 0x3B, 0xFA, 0xD8, 0x92, 0x06, 0x4A, 0x5B,
+    0xBB, 0xA5, 0x46, 0x96, 0xEE, 0xAA, 0xD8, 0x17, 0x99, 0x64, 0xA6, 0xD9,
+    0xB1, 0xC9, 0xCC, 0x32, 0x49, 0x5A, 0x92, 0x47, 0xF1, 0xC1, 0x37, 0x7F,
+    0x42, 0x10, 0x41, 0xF1, 0x23, 0xFC, 0x13, 0xA1, 0xE2, 0x67, 0x78, 0xB3,
+    0x99, 0xA4, 0xC9, 0x64, 0xBA, 0xA6, 0x79, 0xD9, 0xB9, 0xE7, 0x9E, 0x73,
+    0x73, 0xEF, 0x99, 0x64, 0x36, 0x6E, 0x2C, 0x43, 0x12, 0x33, 0x24, 0x48,
+    0xC2, 0xF6, 0x1C, 0x9E, 0xBD, 0x3B, 0x99, 0x3B, 0x88, 0xB2, 0x34, 0xDC,
+    0x73, 0xFE, 0x7C, 0xFC, 0x7C, 0xF3, 0xE5, 0xEB, 0xCD, 0xA7, 0x6F, 0x7F,
+    0x7F, 0xFE, 0x78, 0xDC, 0x06, 0x4F, 0x1C, 0xCF, 0xAD, 0x14, 0x82, 0x12,
+    0x35, 0x2B, 0x92, 0x40, 0xC6, 0xA9, 0x16, 0x47, 0x8A, 0x45, 0x52, 0x71,
+    0x22, 0x80, 0x91, 0x48, 0x91, 0x2D, 0x5E, 0x02, 0x9C, 0xEA, 0xB5, 0x17,
+    0x31, 0x21, 0x08, 0x97, 0x2E, 0xAE, 0xC3, 0x87, 0x0F, 0x34, 0x7E, 0xC1,
+    0x82, 0x40, 0xD9, 0x12, 0x09, 0x51, 0xE5, 0x10, 0x25, 0x4B, 0xC5, 0x63,
+    0x66, 0x21, 0x47, 0x91, 0xA5, 0x46, 0xC4, 0xF3, 0x48, 0x0C, 0xE1, 0x38,
+    0x8F, 0x62, 0x0B, 0x9B, 0x44, 0x32, 0xCD, 0x86, 0x70, 0xCA, 0xB2, 0x8C,
+    0x25, 0x81, 0x1A, 0xDE, 0x55, 0x66, 0x99, 0xB4, 0xE1, 0x42, 0x5E, 0xD9,
+    0x05, 0x94, 0x87, 0x66, 0x02, 0x77, 0xAC, 0x6A, 0x78, 0xAB, 0x08, 0x11,
+    0x30, 0x66, 0xCF, 0x79, 0xE6, 0x74, 0x1C, 0xB4, 0xB9, 0x67, 0x33, 0xCE,
+    0x66, 0x9B, 0xCD, 0x33, 0x9B, 0x61, 0x36, 0xB7, 0x6C, 0x56, 0xD9, 0x7C,
+    0xB2, 0x39, 0x64, 0x73, 0xC7, 0x66, 0xCC, 0xDD, 0x9E, 0x50, 0x52, 0xE8,
+    0x47, 0x09, 0x56, 0x1E, 0x95, 0x09, 0x13, 0x3C, 0x24, 0x2E, 0xAE, 0xA2,
+    0x3A, 0x0D, 0x3D, 0x0A, 0x46, 0x7F, 0x7D, 0xEF, 0x61, 0xE0, 0x43, 0x36,
+    0x04, 0x99, 0x0A, 0x65, 0x3C, 0x80, 0xE1, 0xE1, 0xB9, 0x1A, 0x80, 0x57,
+    0x4C, 0x30, 0x65, 0x82, 0x29, 0x09, 0x48, 0xF5, 0x90, 0x68, 0x08, 0xB7,
+    0xCD, 0x75, 0x1A, 0xED, 0x6C, 0x9D, 0xEE, 0xD8, 0x6C, 0xD6, 0x6C, 0xD4,
+    0xEC, 0xD1, 0x6C, 0xCE, 0xEC, 0xCB, 0x6C, 0xC9, 0xDE, 0x0F, 0x14, 0xE2,
+    0x94, 0xB3, 0xA4, 0x79, 0x11, 0x75, 0xE8, 0xED, 0xFB, 0x60, 0x71, 0x13,
+    0x74, 0x78, 0xDE, 0xD4, 0x48, 0xE0, 0x7E, 0x05, 0x40, 0x98, 0x22, 0xBA,
+    0x1A, 0xAC, 0x3C, 0x72, 0xE0, 0xE2, 0xEA, 0xB7, 0x4E, 0x78, 0xF4, 0x36,
+    0xC4, 0x2D, 0xB1, 0x0A, 0x8C, 0x03, 0xA3, 0x6E, 0x3C, 0x63, 0x53, 0x02,
+    0x6F, 0x96, 0x12, 0xAB, 0x8D, 0x6D, 0x23, 0x7D, 0x9A, 0x5C, 0xE4, 0x71,
+    0xEC, 0x78, 0x47, 0x70, 0xA1, 0x43, 0xE4, 0xC3, 0x85, 0xDE, 0xC2, 0x55,
+    0xCD, 0xD7, 0x32, 0x8D, 0x32, 0x5A, 0x18, 0x4B, 0x11, 0x39, 0xDE, 0xE1,
+    0xFD, 0x44, 0x09, 0xA3, 0x95, 0x06, 0x83, 0x04, 0x8F, 0x12, 0xA4, 0x0B,
+    0xA9, 0x32, 0x2D, 0xB1, 0x29, 0x70, 0x6F, 0x3E, 0x00, 0x32, 0x9E, 0x74,
+    0xE6, 0xED, 0x44, 0xBD, 0x79, 0x27, 0x93, 0x5D, 0xDF, 0xDF, 0x9D, 0xCD,
+    0xD0, 0xB9, 0x8B, 0x3B, 0x1C, 0xA3, 0x40, 0x6F, 0xD2, 0xFB, 0x28, 0x56,
+    0x63, 0x36, 0xF7, 0x18, 0xC1, 0xD7, 0x53, 0xAE, 0x14, 0x03, 0x3A, 0xEE,
+    0x8D, 0xA4, 0x5D, 0x9A, 0x03, 0xD6, 0xEC, 0xF2, 0x71, 0xE1, 0xD3, 0xCB,
+    0x49, 0x92, 0xCE, 0x8E, 0x0E, 0x9F, 0x5F, 0xBF, 0x21, 0x8B, 0xD3, 0xF2,
+    0xBC, 0xF6, 0xA5, 0x4B, 0x02, 0x9D, 0xC8, 0x93, 0x80, 0xA9, 0x5B, 0x73,
+    0x7A, 0xB1, 0xEE, 0x04, 0x30, 0x78, 0x14, 0x43, 0xC7, 0x2B, 0x37, 0xCB,
+    0x72, 0x67, 0xBB, 0x2C, 0x4B, 0x17, 0xF7, 0x78, 0x83, 0x42, 0x5A, 0x18,
+    0xE6, 0x4A, 0x31, 0x11, 0x16, 0x8E, 0xF7, 0x08, 0xD5, 0xDA, 0x9D, 0x9D,
+    0x91, 0xD2, 0x25, 0x9C, 0x15, 0x4C, 0x64, 0xFA, 0x9E, 0x1B, 0x16, 0x15,
+    0x36, 0x5A, 0x6F, 0x0B, 0x35, 0xD3, 0xF5, 0x42, 0x5D, 0x96, 0xB2, 0x90,
+    0x27, 0x04, 0x36, 0x7B, 0xB3, 0xD1, 0xD7, 0x69, 0x53, 0xDD, 0xFE, 0xAD,
+    0xCA, 0x7C, 0xC9, 0xAB, 0x9D, 0xDE, 0x1E, 0xC5, 0x6F, 0xBB, 0xDE, 0x18,
+    0x45, 0x4F, 0xB8, 0xC8, 0x53, 0xC7, 0xDB, 0x1A, 0x45, 0x2E, 0x99, 0x92,
+    0x8E, 0xF7, 0x74, 0xC8, 0xC5, 0xFD, 0xB1, 0x01, 0x69, 0x7C, 0x6F, 0x9D,
+    0xE8, 0x03, 0xCD, 0x03, 0xB6, 0x0A, 0x1C, 0xEF, 0xF7, 0x07, 0x38, 0x65,
+    0xFB, 0x8C, 0x61, 0x91, 0xE6, 0x23, 0x25, 0x95, 0xD5, 0x02, 0x0E, 0x87,
+    0x57, 0x67, 0xA3, 0x45, 0x5D, 0xD3, 0x87, 0x12, 0x6C, 0x76, 0x5B, 0xBD,
+    0x0D, 0xC5, 0x92, 0x5D, 0x90, 0xB0, 0x3A, 0xEA, 0x9A, 0xA5, 0xAE, 0xE5,
+    0x17, 0xF0, 0x95, 0x43, 0xD1, 0x14, 0xBC, 0xC0, 0x5D, 0x66, 0x93, 0xE6,
+    0x82, 0x4B, 0x71, 0x67, 0xFA, 0x40, 0xE6, 0x8A, 0x33, 0x85, 0x66, 0x19,
+    0xB5, 0xE6, 0xF7, 0xA9, 0x0C, 0x18, 0x9A, 0xF2, 0xFF, 0x10, 0x26, 0x0C,
+    0xBE, 0x23, 0xAE, 0xD7, 0x10, 0xF6, 0x15, 0x09, 0xE0, 0x85, 0xB9, 0x9B,
+    0x30, 0x5F, 0x10, 0x6E, 0x4D, 0x9F, 0xCA, 0x32, 0xBF, 0x24, 0xE8, 0x58,
+    0x66, 0x0B, 0x1E, 0x56, 0x73, 0x6C, 0xBD, 0x3E, 0x41, 0xFE, 0x3A, 0x2A,
+    0x8C, 0x1C, 0x2E, 0x64, 0x43, 0x3D, 0x5B, 0x73, 0x53, 0x60, 0x46, 0xD5,
+    0x64, 0xE8, 0xC5, 0x1A, 0xD2, 0x4C, 0x8E, 0x20, 0xF9, 0x45, 0x2E, 0xA2,
+    0xF7, 0x72, 0xC5, 0xD3, 0xCD, 0xE1, 0xDB, 0x3D, 0xAB, 0xA2, 0xFA, 0xD3,
+    0x16, 0x96, 0xFF, 0x00, 0x20, 0x8B, 0xBE, 0xF7};
+const uint8_t g_ptBR_Locale[] = {
+    0x78, 0x9C, 0x9D, 0x56, 0x3D, 0x6F, 0xD4, 0x40, 0x10, 0xAD, 0x83, 0xC4,
+    0x7F, 0x58, 0x59, 0x89, 0x0E, 0xA4, 0x24, 0x86, 0x92, 0xC8, 0x67, 0xE9,
+    0x92, 0x0B, 0x39, 0x94, 0x18, 0x9D, 0xCE, 0x11, 0x88, 0x34, 0x68, 0x6D,
+    0xEF, 0xD9, 0x9B, 0xD8, 0xBB, 0xC7, 0xDA, 0x4E, 0xB0, 0x6B, 0x1A, 0x3A,
+    0x28, 0x29, 0x53, 0x20, 0x2A, 0x44, 0x83, 0x44, 0x49, 0x91, 0xDF, 0x82,
+    0xB8, 0x9F, 0xC1, 0xFA, 0xF3, 0xFC, 0xB1, 0x36, 0x06, 0x37, 0xDE, 0x99,
+    0x79, 0x6F, 0x3D, 0xF3, 0x76, 0x76, 0x64, 0xC5, 0xA5, 0x26, 0x74, 0x11,
+    0x20, 0xD0, 0x43, 0x63, 0x69, 0x15, 0xBC, 0x3E, 0x5C, 0x48, 0xC0, 0x42,
+    0xBE, 0x39, 0x96, 0xD6, 0x1F, 0x6F, 0xD7, 0x1F, 0xDE, 0xFD, 0x7E, 0xFF,
+    0x69, 0xFD, 0xED, 0xEB, 0x83, 0x5F, 0x3F, 0xBE, 0xAF, 0x3F, 0xFF, 0x7C,
+    0x28, 0xA9, 0xF7, 0xEF, 0x01, 0xA0, 0x24, 0x14, 0x62, 0x41, 0xA6, 0x47,
+    0x9E, 0x41, 0x5D, 0x3F, 0x67, 0xDB, 0x0C, 0xD9, 0x94, 0x61, 0x48, 0x12,
+    0xD4, 0x16, 0x50, 0x3C, 0x4A, 0x02, 0xE7, 0x39, 0x0F, 0xF9, 0x89, 0xBD,
+    0x95, 0xD9, 0xEA, 0x25, 0x24, 0x08, 0x33, 0xAA, 0xC8, 0x99, 0x59, 0x89,
+    0x2C, 0xD1, 0x35, 0x62, 0x1D, 0x31, 0x0F, 0xB2, 0xBB, 0x2F, 0xA2, 0x00,
+    0x34, 0x18, 0x76, 0x85, 0x04, 0x2C, 0x82, 0x5F, 0x86, 0xC4, 0x11, 0xFB,
+    0x5D, 0xA1, 0x1F, 0xDA, 0xD4, 0x0F, 0x44, 0x01, 0x1F, 0x05, 0xC8, 0x33,
+    0x84, 0xB9, 0xD2, 0x30, 0x08, 0xC5, 0x11, 0x42, 0xAF, 0xBB, 0x48, 0x16,
+    0x8A, 0x9B, 0x21, 0x90, 0xAF, 0x4B, 0x09, 0xAB, 0x92, 0x02, 0x68, 0x18,
+    0x6C, 0x2C, 0x3D, 0x96, 0x1A, 0xDA, 0x8A, 0x75, 0x15, 0x2B, 0x2A, 0x96,
+    0x53, 0x2C, 0xA6, 0x58, 0x4B, 0xB1, 0x92, 0x62, 0x1D, 0xC5, 0x22, 0x8A,
+    0xF5, 0x13, 0x6B, 0x27, 0x96, 0xAD, 0x5F, 0x31, 0x0B, 0x46, 0x95, 0x16,
+    0xE4, 0x96, 0x6A, 0x51, 0x0F, 0x93, 0x24, 0x9D, 0xC4, 0x28, 0xBD, 0x3E,
+    0xB2, 0x43, 0xDE, 0xD2, 0x7B, 0x4B, 0xDE, 0x80, 0xB0, 0x11, 0x0B, 0x10,
+    0x6F, 0x3E, 0x71, 0xE8, 0x4D, 0x08, 0x59, 0xD0, 0x15, 0xC2, 0xA4, 0x23,
+    0xE4, 0xA3, 0xB7, 0x5D, 0x91, 0xBB, 0x5B, 0x03, 0x5A, 0x9B, 0xE4, 0x40,
+    0xBA, 0x12, 0xD4, 0xD3, 0x38, 0xFF, 0xBC, 0xB0, 0x76, 0x51, 0xED, 0x52,
+    0xDA, 0x15, 0xB4, 0x13, 0x6F, 0xE7, 0x2B, 0xC8, 0xB3, 0x3B, 0x49, 0x0F,
+    0x31, 0x6C, 0x61, 0xE4, 0x55, 0x2F, 0x7F, 0xEE, 0x52, 0x27, 0x1A, 0x3F,
+    0xA4, 0xC2, 0xA8, 0x87, 0xE6, 0x8D, 0x10, 0xD8, 0x98, 0x95, 0xCD, 0x11,
+    0x83, 0x95, 0x7D, 0xB9, 0xA5, 0x1E, 0x1E, 0x29, 0x72, 0xF2, 0x2E, 0x1D,
+    0x93, 0x69, 0xE9, 0x00, 0xE9, 0xAA, 0x20, 0xF0, 0xD9, 0x25, 0x37, 0x86,
+    0x57, 0xE6, 0xB5, 0x60, 0x80, 0xE6, 0x30, 0xE0, 0xF2, 0x90, 0x52, 0xE8,
+    0xD2, 0x93, 0xCF, 0xB7, 0x65, 0xE8, 0xBA, 0x92, 0x7A, 0xCC, 0x9F, 0x5D,
+    0x30, 0x1D, 0xF1, 0x29, 0x09, 0x46, 0x1A, 0x7F, 0xB2, 0xD5, 0x2B, 0xFE,
+    0x24, 0x32, 0x94, 0xA4, 0xAE, 0x5D, 0x5C, 0x4A, 0x6C, 0x49, 0xFD, 0x7F,
+    0xBE, 0x87, 0x2C, 0x4E, 0x9F, 0xCA, 0x9A, 0x26, 0x0F, 0xE6, 0xF8, 0x0E,
+    0x65, 0xC1, 0x86, 0xD5, 0xE4, 0x00, 0x50, 0xF3, 0xE4, 0x92, 0x04, 0xD8,
+    0x6B, 0x48, 0x52, 0xF1, 0xD4, 0x24, 0x99, 0xCD, 0x46, 0x0E, 0x2F, 0x65,
+    0xC4, 0xEF, 0xD5, 0x48, 0xD7, 0x47, 0xFE, 0x08, 0x5C, 0x28, 0x72, 0x05,
+    0xDC, 0xC5, 0xCE, 0xA4, 0x48, 0xC9, 0x19, 0x77, 0x38, 0x35, 0x55, 0x61,
+    0x36, 0x3B, 0xD0, 0xB4, 0x03, 0x5D, 0x1F, 0xC4, 0xC8, 0x35, 0x48, 0x39,
+    0x4D, 0x42, 0x22, 0x40, 0xA3, 0xDC, 0xBC, 0x27, 0xCE, 0xB9, 0xB7, 0x68,
+    0x94, 0x93, 0x48, 0xB3, 0xAE, 0x66, 0x9E, 0xAF, 0x1F, 0x4F, 0x9F, 0xDE,
+    0xBC, 0x84, 0xCE, 0x69, 0x7C, 0x91, 0xE9, 0x56, 0x05, 0xA5, 0x4C, 0x12,
+    0x7A, 0x06, 0x62, 0x75, 0xF1, 0x6A, 0xBE, 0x3C, 0x27, 0xEE, 0xE3, 0xFD,
+    0x6D, 0x4A, 0x6A, 0xBC, 0x1B, 0xC7, 0x4F, 0xF6, 0xE3, 0x98, 0x0F, 0xB3,
+    0x1A, 0xAE, 0x9B, 0x6A, 0x86, 0x8C, 0x21, 0x62, 0x46, 0x92, 0xBA, 0x0D,
+    0x0A, 0xF6, 0x60, 0xF2, 0x0A, 0x31, 0x13, 0x91, 0x20, 0xFF, 0xEE, 0x4E,
+    0x9B, 0x97, 0x08, 0xD2, 0x2A, 0xA2, 0x2C, 0x6C, 0x53, 0xEB, 0x56, 0xDD,
+    0x95, 0x6F, 0x6F, 0x21, 0x13, 0x7B, 0x90, 0x37, 0xC6, 0x6E, 0xB1, 0x4B,
+    0x16, 0xEE, 0x24, 0xD8, 0x8C, 0x86, 0x2B, 0x9C, 0x34, 0xC3, 0xFE, 0x40,
+    0x46, 0x59, 0xC1, 0xCE, 0x40, 0x02, 0xEF, 0xAF, 0xD0, 0x97, 0xD4, 0xBD,
+    0x81, 0xF0, 0x18, 0x31, 0x2A, 0xA9, 0x8F, 0x5A, 0xE8, 0x8D, 0x30, 0xB5,
+    0x03, 0x2F, 0x4E, 0xA3, 0xA6, 0x4C, 0xDD, 0x59, 0xB4, 0x61, 0x6A, 0x48,
+    0xEA, 0x62, 0x9B, 0x4F, 0xA2, 0x1A, 0xA0, 0x87, 0x84, 0x7D, 0x9A, 0x2C,
+    0x24, 0xF5, 0x70, 0x71, 0xF6, 0x0F, 0xB4, 0xEA, 0x39, 0xB4, 0x48, 0xE9,
+    0x28, 0x6C, 0xA5, 0x9D, 0xDC, 0xFB, 0x68, 0x85, 0x96, 0xD0, 0x2C, 0xC6,
+    0x6D, 0x61, 0xE6, 0x7B, 0x6A, 0x11, 0xFF, 0xC3, 0xB3, 0xC0, 0x9C, 0xCB,
+    0x23, 0x8B, 0x01, 0x98, 0x60, 0x4A, 0x7A, 0x00, 0x47, 0x34, 0x64, 0x18,
+    0x31, 0xA0, 0x07, 0x56, 0x07, 0x62, 0x62, 0x51, 0x03, 0x81, 0x39, 0xFE,
+    0x2B, 0x64, 0x86, 0x0C, 0x86, 0x6E, 0x7A, 0x21, 0x13, 0x06, 0x0D, 0x7E,
+    0xC3, 0xFA, 0x20, 0xE7, 0x0E, 0xC4, 0x1D, 0x80, 0x53, 0x1A, 0x87, 0x57,
+    0x10, 0x9C, 0xD0, 0xC0, 0xC1, 0x66, 0x52, 0xD3, 0xDE, 0x8B, 0x67, 0x40,
+    0xEB, 0x07, 0x73, 0x01, 0x4C, 0x87, 0x16, 0xE0, 0x45, 0xEF, 0xA7, 0x39,
+    0xD6, 0x4E, 0xAA, 0x04, 0x67, 0xBD, 0x30, 0x9D, 0x0E, 0x82, 0x69, 0x51,
+    0x48, 0xEC, 0x4B, 0x9A, 0x22, 0xB3, 0x24, 0xD3, 0xC1, 0x56, 0x39, 0x4F,
+    0x45, 0xCE, 0xFE, 0xF7, 0xD5, 0x3F, 0x30, 0xBB, 0xD9, 0x9B};
+const uint8_t g_nlNL_Locale[] = {
+    0x78, 0x9C, 0x95, 0x56, 0x4D, 0x4F, 0xDC, 0x30, 0x10, 0x3D, 0x53, 0xA9,
+    0xFF, 0xC1, 0x8A, 0x8A, 0x68, 0x25, 0x96, 0x2D, 0x47, 0x50, 0x88, 0xB4,
+    0x05, 0x0A, 0x15, 0x04, 0xAD, 0x58, 0xDA, 0xAA, 0x5C, 0x2A, 0x6F, 0x62,
+    0x76, 0xBD, 0x24, 0xF6, 0xCA, 0x89, 0x41, 0xC9, 0xB1, 0x52, 0x8F, 0xFD,
+    0x27, 0xAD, 0xDA, 0x5B, 0xFF, 0x4F, 0xA5, 0x4A, 0xFC, 0x8C, 0x8E, 0xF3,
+    0x45, 0x12, 0x3B, 0x69, 0xC8, 0x05, 0xCF, 0x9B, 0xF7, 0xBC, 0x33, 0xCF,
+    0xCE, 0x10, 0x3B, 0xE0, 0x1E, 0x0E, 0x08, 0x62, 0x38, 0x24, 0x07, 0x16,
+    0x0B, 0x3E, 0x5F, 0x9C, 0x5B, 0xC8, 0x27, 0x91, 0x77, 0x60, 0x3D, 0x7C,
+    0xFB, 0xFD, 0xF7, 0xEB, 0xAF, 0x87, 0x9F, 0x3F, 0x5E, 0xE6, 0xAB, 0x57,
+    0x96, 0xF3, 0xFC, 0x19, 0x42, 0xB6, 0xE2, 0x33, 0x1F, 0x8B, 0x59, 0x12,
+    0xCE, 0x79, 0x10, 0x15, 0xD2, 0x85, 0x20, 0x0B, 0x2E, 0x28, 0x66, 0x8A,
+    0xB5, 0x81, 0xEC, 0x90, 0xB3, 0x78, 0x79, 0x01, 0xA9, 0x48, 0xC5, 0x1B,
+    0x79, 0xEC, 0xAC, 0x30, 0x93, 0x58, 0x50, 0x7B, 0x9C, 0x87, 0xB5, 0xCC,
+    0x0D, 0x99, 0x8B, 0x8E, 0x54, 0x88, 0xB1, 0x88, 0x0D, 0x38, 0x5E, 0x0B,
+    0x1A, 0x98, 0xF8, 0xC4, 0xB4, 0xCB, 0x4A, 0x32, 0x33, 0x1C, 0x98, 0x60,
+    0x2C, 0x17, 0x32, 0x8A, 0x65, 0x64, 0x48, 0x45, 0x64, 0x1D, 0x93, 0x70,
+    0x4E, 0x84, 0x21, 0xC7, 0x6F, 0x63, 0x6E, 0xCE, 0x30, 0x7E, 0xD7, 0x25,
+    0xF2, 0x89, 0xD7, 0x4E, 0xA1, 0x62, 0x5D, 0x19, 0x58, 0x37, 0x14, 0xE1,
+    0xF9, 0x5C, 0x1C, 0x58, 0xBB, 0x56, 0xCB, 0x59, 0xB3, 0xAB, 0x26, 0x83,
+    0xBA, 0xEC, 0x7C, 0x8A, 0x99, 0x66, 0x2F, 0xCD, 0x56, 0x9A, 0x5D, 0x34,
+    0xFB, 0x67, 0xF6, 0xCE, 0x6C, 0x5B, 0xBF, 0x63, 0x3E, 0x4E, 0x6A, 0x17,
+    0x10, 0x22, 0x27, 0xE5, 0x70, 0x71, 0xA1, 0x1A, 0xB5, 0xAE, 0x40, 0xB8,
+    0x5E, 0x06, 0xD4, 0xA7, 0x2C, 0xD2, 0xD1, 0x7B, 0x4E, 0x4C, 0xB0, 0x0F,
+    0xFB, 0x12, 0xA1, 0xE3, 0x77, 0x82, 0xAE, 0x74, 0x34, 0xC5, 0x71, 0x93,
+    0x8C, 0xB2, 0x95, 0xA1, 0xF2, 0xD6, 0x49, 0xE7, 0x2D, 0x68, 0xE5, 0x6B,
+    0x95, 0x6B, 0x45, 0x6B, 0xE5, 0x6A, 0x75, 0x6A, 0x25, 0x76, 0x17, 0x17,
+    0x12, 0x41, 0x7D, 0x4A, 0xC2, 0xFA, 0xCB, 0x5D, 0x40, 0xCE, 0xC4, 0x85,
+    0x63, 0x28, 0x83, 0x66, 0x6A, 0xDA, 0x4A, 0xA1, 0xC7, 0xB0, 0xB6, 0x39,
+    0x11, 0xB8, 0xB6, 0x2F, 0x44, 0xCE, 0x9B, 0x43, 0x7B, 0xAC, 0xFE, 0x56,
+    0xC0, 0xE4, 0xA8, 0x02, 0x50, 0xB6, 0x2A, 0x05, 0x30, 0x9B, 0xC6, 0xAD,
+    0xE1, 0x94, 0xA3, 0x3E, 0x18, 0x3E, 0xC5, 0x31, 0xB8, 0xCE, 0x2A, 0x83,
+    0x2B, 0xA4, 0x98, 0x5F, 0x37, 0x32, 0x08, 0x2C, 0xE7, 0x18, 0x1E, 0x74,
+    0x84, 0x5C, 0x78, 0xD0, 0x27, 0x78, 0x54, 0xEF, 0x15, 0xB3, 0x4B, 0x1A,
+    0x70, 0xB6, 0xB0, 0x9C, 0xA7, 0xAA, 0x42, 0xE2, 0x83, 0x68, 0x04, 0x9A,
+    0xD1, 0x60, 0x4D, 0xB4, 0xE4, 0x22, 0xCE, 0x54, 0x23, 0x5D, 0x81, 0x50,
+    0x03, 0x29, 0x7A, 0x8F, 0x69, 0xD8, 0xEA, 0xBD, 0x86, 0x34, 0x7A, 0x3F,
+    0xDD, 0x77, 0xDD, 0xFD, 0xD9, 0x6C, 0x0B, 0x49, 0x29, 0xB6, 0xD0, 0xB5,
+    0x3D, 0xAE, 0x11, 0xBB, 0x94, 0x79, 0xEB, 0x85, 0x72, 0xA0, 0x26, 0x6B,
+    0xBC, 0x90, 0x0C, 0x12, 0x14, 0x5D, 0x2B, 0x49, 0x9B, 0xAF, 0x7A, 0x6E,
+    0x75, 0x58, 0x9C, 0xF7, 0x15, 0xA0, 0xE5, 0x25, 0x38, 0x49, 0x5C, 0xFF,
+    0xF6, 0x34, 0x8C, 0x66, 0xC7, 0x47, 0x6F, 0xEF, 0x3F, 0xE2, 0xE5, 0x59,
+    0x7A, 0x9D, 0x5B, 0x55, 0x27, 0x65, 0x4A, 0x26, 0xD5, 0x20, 0x6E, 0xFA,
+    0xD5, 0xC0, 0xCA, 0x7F, 0x94, 0x52, 0xDD, 0x5D, 0xCF, 0x72, 0xD2, 0xED,
+    0x34, 0xDD, 0xDB, 0x49, 0xD3, 0xD4, 0x1E, 0x37, 0x78, 0xDD, 0x52, 0x4F,
+    0x0A, 0x41, 0x98, 0x97, 0x58, 0xCE, 0x0B, 0x94, 0xAB, 0xF7, 0xF6, 0xA2,
+    0xC1, 0xEA, 0x35, 0x11, 0x1E, 0x61, 0x71, 0xF1, 0xC3, 0x9B, 0xBA, 0x4E,
+    0x39, 0xA2, 0x75, 0x51, 0x75, 0xF6, 0xD8, 0xEC, 0x46, 0x13, 0x2A, 0xB6,
+    0x87, 0x99, 0x4A, 0x43, 0x0C, 0x97, 0x61, 0xBB, 0xDC, 0x25, 0x4F, 0x77,
+    0x0A, 0x16, 0x82, 0xCB, 0x35, 0x55, 0x97, 0x60, 0x67, 0xA0, 0xA2, 0xEA,
+    0x60, 0x73, 0xA0, 0x20, 0xA4, 0x4C, 0x46, 0x96, 0x33, 0x1A, 0x48, 0x4F,
+    0x89, 0xE0, 0x96, 0xF3, 0x5A, 0x63, 0x3F, 0x1A, 0xD3, 0x38, 0xF1, 0xF2,
+    0x38, 0x1A, 0xCE, 0x34, 0xC1, 0xF2, 0x1A, 0x66, 0x81, 0xE5, 0xFC, 0xF9,
+    0xF2, 0x1D, 0xE6, 0x4C, 0x83, 0xD1, 0xA3, 0xA2, 0x11, 0x57, 0x0B, 0x18,
+    0x2D, 0xEF, 0x2F, 0x9F, 0x20, 0xAB, 0x1F, 0x84, 0x26, 0xCA, 0x06, 0x9D,
+    0x56, 0xB7, 0x7A, 0xD9, 0x93, 0x35, 0xB9, 0xC1, 0x5E, 0x39, 0x4C, 0xCB,
+    0xB0, 0xD8, 0xD3, 0x4D, 0xE0, 0xFB, 0xCC, 0x47, 0x53, 0xF0, 0x67, 0x6C,
+    0x26, 0x50, 0x46, 0x39, 0xEB, 0x21, 0x1C, 0x72, 0x29, 0x28, 0x11, 0x68,
+    0x16, 0xFB, 0x1D, 0x8C, 0x89, 0x0F, 0xDF, 0x3F, 0x68, 0x4A, 0xFF, 0x4B,
+    0x39, 0x85, 0xEF, 0x3D, 0x72, 0xDF, 0x4B, 0x99, 0x08, 0x3C, 0x87, 0x77,
+    0xAC, 0x8F, 0x72, 0xB5, 0xC4, 0xB4, 0x83, 0x70, 0xC6, 0x53, 0x79, 0x8B,
+    0xD1, 0x09, 0x8F, 0x97, 0xD4, 0x53, 0x3D, 0x8D, 0x3E, 0xBC, 0x43, 0x6E,
+    0x3F, 0x19, 0x0C, 0xF0, 0x96, 0xBC, 0x24, 0x5F, 0xF6, 0xFE, 0x34, 0x70,
+    0x17, 0xAA, 0x4B, 0x74, 0xDE, 0x4B, 0x9B, 0xF1, 0x41, 0x34, 0x37, 0x91,
+    0x6C, 0xB1, 0xE2, 0x19, 0x33, 0x2F, 0x32, 0x1B, 0x6D, 0xB5, 0xF3, 0xB4,
+    0xC7, 0xF9, 0xA7, 0xBA, 0xF3, 0x0F, 0xD5, 0xFA, 0xC0, 0xFA};
+const uint8_t g_ruRU_Locale[] = {
+    0x78, 0x9C, 0xAD, 0x57, 0x4D, 0x4F, 0x13, 0x41, 0x18, 0x3E, 0x63, 0xE2,
+    0x7F, 0x98, 0x6C, 0x24, 0x68, 0x02, 0xAD, 0x1E, 0x25, 0x65, 0x13, 0x22,
+    0x0A, 0x06, 0xD7, 0x90, 0x16, 0x34, 0x72, 0x31, 0xDB, 0xDD, 0xA1, 0x5D,
+    0xE8, 0xEE, 0x90, 0xE9, 0x6E, 0xB0, 0x7B, 0x2A, 0x85, 0xE8, 0x05, 0x25,
+    0xE1, 0xA0, 0x47, 0xF4, 0xE4, 0xC9, 0x50, 0xBE, 0x12, 0x82, 0xB6, 0x24,
+    0xFE, 0x82, 0xD9, 0xFF, 0x60, 0xD4, 0x9F, 0xE1, 0x3B, 0xFB, 0xD1, 0xEE,
+    0xB7, 0xC5, 0xD8, 0x1E, 0x3A, 0xF3, 0x3E, 0xCF, 0xF3, 0xCE, 0xFB, 0xB5,
+    0xD3, 0xB6, 0xD4, 0x20, 0x8A, 0xDC, 0xC0, 0xC8, 0x90, 0x75, 0x3C, 0x23,
+    0x50, 0xEB, 0x65, 0x79, 0x45, 0x40, 0x2A, 0x6E, 0x2A, 0x33, 0xC2, 0x8F,
+    0xAB, 0xDD, 0xDF, 0x47, 0x5F, 0x6E, 0xC3, 0xC7, 0xAF, 0xDE, 0x87, 0x9F,
+    0xEF, 0x8F, 0xEE, 0x08, 0xE2, 0xCD, 0x1B, 0x08, 0x95, 0x38, 0xDF, 0x50,
+    0x65, 0x5A, 0x69, 0xE9, 0x55, 0xD2, 0x68, 0xFA, 0xD2, 0x1A, 0xC5, 0x35,
+    0x42, 0x35, 0xD9, 0xE0, 0xAC, 0x31, 0x54, 0xD2, 0x89, 0x61, 0xD6, 0x9F,
+    0x02, 0xD4, 0xE4, 0xFB, 0x31, 0x6F, 0x2F, 0x3A, 0xFB, 0xAC, 0xC7, 0x4E,
+    0x58, 0xD7, 0x69, 0x3B, 0xFB, 0xA5, 0xA2, 0x67, 0x0B, 0xC3, 0xBB, 0xEC,
+    0x9C, 0x9D, 0x38, 0x6D, 0xD6, 0x65, 0x5F, 0x53, 0x09, 0xEC, 0x9B, 0xAB,
+    0xED, 0xB0, 0x6E, 0x1A, 0xD8, 0x65, 0x57, 0xA0, 0x3D, 0xCF, 0xD3, 0xA6,
+    0x02, 0x17, 0xCE, 0x3B, 0xD6, 0xCB, 0x86, 0x32, 0xDC, 0x75, 0x21, 0x91,
+    0x53, 0x67, 0xC7, 0xD9, 0xCE, 0x08, 0xC7, 0xD9, 0x86, 0x50, 0x7A, 0x4E,
+    0x07, 0x72, 0x3E, 0xCE, 0xC8, 0x97, 0xF5, 0xD9, 0x65, 0x3E, 0xA1, 0xC7,
+    0xFA, 0x79, 0xF0, 0x19, 0x1C, 0x71, 0x09, 0x91, 0xC4, 0x09, 0xC8, 0x5F,
+    0x0F, 0x1A, 0x10, 0x6E, 0x08, 0x92, 0xAB, 0x55, 0x3A, 0x23, 0xDC, 0x13,
+    0x92, 0x9D, 0x29, 0xE4, 0x34, 0x25, 0x0D, 0x1B, 0xA1, 0x1F, 0x99, 0xB2,
+    0xFF, 0xDD, 0x8A, 0xD4, 0xD8, 0xFD, 0x1E, 0xA4, 0x06, 0xE1, 0x16, 0x3F,
+    0x15, 0xF1, 0xAB, 0x9E, 0x8A, 0xB9, 0x25, 0x2F, 0xE4, 0xD7, 0x5A, 0x95,
+    0x5B, 0xA1, 0xD1, 0x87, 0x9D, 0x08, 0x01, 0xF6, 0x21, 0x98, 0x4B, 0x3E,
+    0x9F, 0x7E, 0x50, 0x7B, 0xEC, 0xBC, 0x54, 0xE4, 0xD8, 0x90, 0x74, 0x05,
+    0x31, 0xF5, 0x00, 0x3C, 0x73, 0x87, 0x78, 0x0F, 0xD6, 0x17, 0xEC, 0x32,
+    0x4E, 0x3A, 0x81, 0x72, 0xF7, 0xC1, 0x4F, 0x1A, 0x08, 0xC3, 0xD8, 0x76,
+    0xF5, 0xDD, 0x38, 0xF0, 0x06, 0xCE, 0xED, 0x40, 0x14, 0xE7, 0x40, 0x38,
+    0x4D, 0x9C, 0xEB, 0xEC, 0x03, 0x08, 0x0E, 0x9D, 0xD7, 0x49, 0xE5, 0xB6,
+    0xB3, 0xC3, 0x8E, 0xE1, 0xDD, 0xF7, 0xDA, 0xEC, 0x83, 0xC8, 0x5D, 0xA5,
+    0xE4, 0x1C, 0x9B, 0x2E, 0xD7, 0xFF, 0x81, 0xB3, 0x1D, 0x3F, 0xF2, 0x90,
+    0xF5, 0xE2, 0xA6, 0x03, 0xA7, 0x13, 0x37, 0x7D, 0x72, 0xDA, 0x71, 0xD3,
+    0xE7, 0x24, 0xEB, 0x30, 0x45, 0xC8, 0x8E, 0xB3, 0x43, 0xD5, 0x31, 0xD5,
+    0x54, 0x0D, 0xEB, 0xE1, 0xEB, 0xC9, 0x37, 0x89, 0xB3, 0x12, 0xB4, 0x33,
+    0xD8, 0x44, 0xA1, 0xA5, 0x18, 0x84, 0x86, 0xDB, 0x90, 0x73, 0x4C, 0xE5,
+    0x90, 0x5F, 0xD8, 0xF1, 0x91, 0xE9, 0x23, 0xD6, 0x2B, 0x38, 0x6F, 0x61,
+    0x6C, 0xB8, 0x61, 0x88, 0x44, 0x8D, 0xC8, 0x5D, 0x05, 0x6A, 0xB8, 0x6A,
+    0x8B, 0xB1, 0xBB, 0xD6, 0xB3, 0xAA, 0xB2, 0x89, 0x97, 0x64, 0xD3, 0xC4,
+    0xD4, 0x18, 0xD4, 0x7E, 0x60, 0xF1, 0xAF, 0xE3, 0x35, 0xAB, 0xD1, 0x10,
+    0xC4, 0x39, 0x24, 0xC1, 0x0B, 0xBD, 0x80, 0x17, 0x9A, 0x80, 0x27, 0x64,
+    0x82, 0x57, 0x62, 0x40, 0xCD, 0xD2, 0x36, 0x88, 0x51, 0xFB, 0x57, 0xAD,
+    0x8E, 0x55, 0x90, 0xCE, 0x15, 0x24, 0xA9, 0xC0, 0x95, 0x23, 0x69, 0x9A,
+    0x75, 0x42, 0xCD, 0xA1, 0x2A, 0xAE, 0x41, 0x28, 0x62, 0xF1, 0x8B, 0x60,
+    0x6A, 0x7A, 0xAC, 0x08, 0x21, 0x4B, 0xA4, 0x08, 0x0B, 0xD3, 0x92, 0x34,
+    0x5D, 0xA9, 0xA0, 0xD5, 0x52, 0x31, 0x44, 0xC9, 0xD2, 0x78, 0xC9, 0x5F,
+    0x4F, 0xE3, 0x26, 0xED, 0x4B, 0x46, 0x12, 0xF8, 0x19, 0x73, 0x49, 0x9C,
+    0xCF, 0xB3, 0x8D, 0xE5, 0xE6, 0xB7, 0x7C, 0x19, 0xAC, 0xC1, 0x1C, 0xCC,
+    0xCB, 0xC6, 0xFA, 0xC6, 0x82, 0xDE, 0xAC, 0x3C, 0x9C, 0x7B, 0xB4, 0xF5,
+    0xFC, 0x55, 0x7D, 0xD1, 0x5E, 0xF5, 0x8A, 0x14, 0x26, 0xB9, 0x4A, 0xC3,
+    0xD2, 0xAB, 0x98, 0x46, 0x2B, 0x15, 0xB1, 0xF9, 0x21, 0x81, 0x0D, 0x66,
+    0x59, 0x11, 0x44, 0x7B, 0xD2, 0xB6, 0xEF, 0x17, 0x6C, 0xDB, 0x2E, 0x15,
+    0x23, 0xBC, 0x6C, 0xA9, 0x62, 0x51, 0x8A, 0x0D, 0xA5, 0x35, 0xD4, 0xDE,
+    0x1A, 0x59, 0xBB, 0x89, 0xA9, 0x82, 0x0D, 0xD3, 0x97, 0x8E, 0x27, 0x75,
+    0xBC, 0x1E, 0x89, 0x1C, 0x06, 0x79, 0x0D, 0x53, 0x1D, 0x8B, 0x9A, 0x7C,
+    0xF7, 0x2A, 0x56, 0x34, 0x5D, 0x86, 0x21, 0x98, 0x0C, 0xBC, 0x78, 0x70,
+    0xA6, 0xA0, 0x46, 0x89, 0xB5, 0xA9, 0xF1, 0x11, 0xF8, 0xFE, 0x71, 0x44,
+    0xC9, 0x20, 0x85, 0xF1, 0x11, 0x05, 0xBA, 0x66, 0x58, 0x4D, 0x41, 0x9C,
+    0x1A, 0x91, 0x6E, 0x63, 0x4A, 0x04, 0xF1, 0x6E, 0x82, 0x3D, 0xAC, 0x4C,
+    0xA4, 0xE1, 0x41, 0x37, 0x22, 0xA5, 0x89, 0x1A, 0x83, 0x29, 0x74, 0x37,
+    0x82, 0xE8, 0x7E, 0x47, 0x47, 0x19, 0x39, 0x2A, 0xAD, 0x49, 0xF8, 0x42,
+    0x10, 0xCB, 0x2B, 0xE5, 0x6B, 0xC8, 0xC2, 0x9D, 0x48, 0x88, 0xDC, 0xAB,
+    0x2E, 0x11, 0x37, 0x7F, 0xCA, 0x5B, 0x9B, 0x78, 0x4D, 0x56, 0x82, 0xBB,
+    0x35, 0xD8, 0xFA, 0x3E, 0xA5, 0x16, 0xFC, 0xE0, 0x54, 0xD1, 0x12, 0xD4,
+    0xA7, 0x98, 0x4E, 0xD0, 0x0C, 0x8D, 0x18, 0x39, 0x84, 0x07, 0xC4, 0xA2,
+    0x1A, 0xA6, 0xA8, 0x62, 0xAA, 0x19, 0x8C, 0x59, 0x95, 0x54, 0x31, 0x5A,
+    0xD2, 0xFE, 0x4A, 0x59, 0xC0, 0x55, 0x8A, 0xB7, 0x72, 0x29, 0xB3, 0x54,
+    0xAE, 0xC2, 0x23, 0x96, 0x47, 0x59, 0xAE, 0xCB, 0x5A, 0x06, 0x61, 0x91,
+    0xD8, 0xD6, 0x86, 0x8C, 0xE6, 0x89, 0x59, 0xD7, 0x14, 0x9E, 0xD3, 0xD4,
+    0xB3, 0xC7, 0x48, 0xCA, 0x27, 0x43, 0x01, 0x94, 0x3A, 0x09, 0xC8, 0xE5,
+    0xDC, 0xA3, 0x81, 0x5B, 0xE3, 0x59, 0xA2, 0x27, 0xB9, 0xB4, 0x0A, 0x19,
+    0x89, 0x26, 0xB5, 0x2C, 0xA3, 0xB6, 0x4E, 0x5C, 0xA6, 0x17, 0xA4, 0x7B,
+    0xB3, 0x85, 0xFA, 0x59, 0x2A, 0x7A, 0xFF, 0x3D, 0xC4, 0x3F, 0xDE, 0xCB,
+    0x8B, 0xC4};
+static IFX_Locale* XFA_GetLocaleFromBuffer(const uint8_t* pBuf, int nBufLen) {
+  if (pBuf == NULL || nBufLen <= 0) {
+    return NULL;
+  }
+  CFX_GEModule* pGeModule = CFX_GEModule::Get();
+  if (!pGeModule) {
+    return NULL;
+  }
+  CCodec_ModuleMgr* pCodecMgr = pGeModule->GetCodecModule();
+  if (!pCodecMgr) {
+    return NULL;
+  }
+  CXML_Element* pLocale = NULL;
+  uint8_t* pOut = NULL;
+  FX_DWORD dwSize;
+  pCodecMgr->GetFlateModule()->FlateOrLZWDecode(FALSE, pBuf, nBufLen, TRUE, 0,
+                                                0, 0, 0, 0, pOut, dwSize);
+  if (pOut) {
+    pLocale = CXML_Element::Parse(pOut, dwSize);
+    FX_Free(pOut);
+  }
+  if (pLocale) {
+    return new CXFA_XMLLocale(pLocale);
+  }
+  return NULL;
+}
+static FX_WORD XFA_GetLanguage(CFX_WideString wsLanguage) {
+  FX_WORD dwLangueID = XFA_LANGID_en_US;
+  if (wsLanguage.GetLength() < 2) {
+    return dwLangueID;
+  }
+  wsLanguage.MakeLower();
+  FX_DWORD dwIDFirst = wsLanguage.GetAt(0) << 8 | wsLanguage.GetAt(1);
+  FX_DWORD dwIDSecond = wsLanguage.GetLength() >= 5
+                            ? wsLanguage.GetAt(3) << 8 | wsLanguage.GetAt(4)
+                            : 0;
+  switch (dwIDFirst) {
+    case FXBSTR_ID(0, 0, 'z', 'h'): {
+      if (dwIDSecond == FXBSTR_ID(0, 0, 'c', 'n')) {
+        dwLangueID = XFA_LANGID_zh_CN;
+      } else if (dwIDSecond == FXBSTR_ID(0, 0, 't', 'w')) {
+        dwLangueID = XFA_LANGID_zh_TW;
+      } else if (dwIDSecond == FXBSTR_ID(0, 0, 'h', 'k')) {
+        dwLangueID = XFA_LANGID_zh_HK;
+      }
+    } break;
+    case FXBSTR_ID(0, 0, 'j', 'a'):
+      dwLangueID = XFA_LANGID_ja_JP;
+      break;
+    case FXBSTR_ID(0, 0, 'k', 'o'):
+      dwLangueID = XFA_LANGID_ko_KR;
+      break;
+    case FXBSTR_ID(0, 0, 'e', 'n'): {
+      if (dwIDSecond == FXBSTR_ID(0, 0, 'g', 'b')) {
+        dwLangueID = XFA_LANGID_en_GB;
+      } else {
+        dwLangueID = XFA_LANGID_en_US;
+      }
+    } break;
+    case FXBSTR_ID(0, 0, 'd', 'e'):
+      dwLangueID = XFA_LANGID_de_DE;
+      break;
+    case FXBSTR_ID(0, 0, 'f', 'r'):
+      dwLangueID = XFA_LANGID_fr_FR;
+      break;
+    case FXBSTR_ID(0, 0, 'e', 's'): {
+      if (dwIDSecond == FXBSTR_ID(0, 0, 'e', 's')) {
+        dwLangueID = XFA_LANGID_es_ES;
+      } else {
+        dwLangueID = XFA_LANGID_es_LA;
+      }
+    } break;
+    case FXBSTR_ID(0, 0, 'i', 't'):
+      dwLangueID = XFA_LANGID_it_IT;
+      break;
+    case FXBSTR_ID(0, 0, 'p', 't'):
+      dwLangueID = XFA_LANGID_pt_BR;
+      break;
+    case FXBSTR_ID(0, 0, 'n', 'l'):
+      dwLangueID = XFA_LANGID_nl_NL;
+      break;
+    case FXBSTR_ID(0, 0, 'r', 'u'):
+      dwLangueID = XFA_LANGID_ru_RU;
+      break;
+  }
+  return dwLangueID;
+}
+CXFA_LocaleMgr::CXFA_LocaleMgr(CXFA_Node* pLocaleSet, CFX_WideString wsDeflcid)
+    : m_dwLocaleFlags(0x00) {
+  m_dwDeflcid = XFA_GetLanguage(wsDeflcid);
+  CXFA_Node* pNodeLocale = NULL;
+  if (pLocaleSet &&
+      (pNodeLocale = pLocaleSet->GetNodeItem(XFA_NODEITEM_FirstChild))) {
+    while (pNodeLocale) {
+      m_LocaleArray.Add(new CXFA_NodeLocale(pNodeLocale));
+      pNodeLocale = pNodeLocale->GetNodeItem(XFA_NODEITEM_NextSibling);
+    }
+  }
+  m_pDefLocale = GetLocaleByName(wsDeflcid);
+}
+CXFA_LocaleMgr::~CXFA_LocaleMgr() {
+  int32_t iCount = m_LocaleArray.GetSize();
+  for (int32_t i = 0; i < iCount; i++) {
+    ((IFX_Locale*)m_LocaleArray[i])->Release();
+  }
+  int32_t iXmls = m_XMLLocaleArray.GetSize();
+  for (int32_t j = 0; j < iXmls; j++) {
+    ((IFX_Locale*)m_XMLLocaleArray[j])->Release();
+  }
+}
+void CXFA_LocaleMgr::Release() {
+  delete this;
+}
+FX_WORD CXFA_LocaleMgr::GetDefLocaleID() {
+  return m_dwDeflcid;
+}
+IFX_Locale* CXFA_LocaleMgr::GetDefLocale() {
+  if (m_pDefLocale) {
+    return m_pDefLocale;
+  } else if (m_LocaleArray.GetSize()) {
+    return (IFX_Locale*)m_LocaleArray[0];
+  } else if (m_XMLLocaleArray.GetSize()) {
+    return (IFX_Locale*)m_XMLLocaleArray[0];
+  }
+  m_pDefLocale = GetLocale(m_dwDeflcid);
+  if (m_pDefLocale)
+    m_XMLLocaleArray.Add(m_pDefLocale);
+  return m_pDefLocale;
+}
+IFX_Locale* CXFA_LocaleMgr::GetLocale(FX_WORD lcid) {
+  IFX_Locale* pLocal = NULL;
+  switch (lcid) {
+    case XFA_LANGID_zh_CN:
+      pLocal = XFA_GetLocaleFromBuffer(g_zhCN_Locale, sizeof(g_zhCN_Locale));
+      break;
+    case XFA_LANGID_zh_TW:
+      pLocal = XFA_GetLocaleFromBuffer(g_zhTW_Locale, sizeof(g_zhTW_Locale));
+      break;
+    case XFA_LANGID_zh_HK:
+      pLocal = XFA_GetLocaleFromBuffer(g_zhHK_Locale, sizeof(g_zhHK_Locale));
+      break;
+    case XFA_LANGID_ja_JP:
+      pLocal = XFA_GetLocaleFromBuffer(g_jaJP_Locale, sizeof(g_jaJP_Locale));
+      break;
+    case XFA_LANGID_ko_KR:
+      pLocal = XFA_GetLocaleFromBuffer(g_koKR_Locale, sizeof(g_koKR_Locale));
+      break;
+    case XFA_LANGID_en_GB:
+      pLocal = XFA_GetLocaleFromBuffer(g_enGB_Locale, sizeof(g_enGB_Locale));
+      break;
+    case XFA_LANGID_es_LA:
+      pLocal = XFA_GetLocaleFromBuffer(g_esLA_Locale, sizeof(g_esLA_Locale));
+      break;
+    case XFA_LANGID_es_ES:
+      pLocal = XFA_GetLocaleFromBuffer(g_esES_Locale, sizeof(g_esES_Locale));
+      break;
+    case XFA_LANGID_de_DE:
+      pLocal = XFA_GetLocaleFromBuffer(g_deDE_Loacale, sizeof(g_deDE_Loacale));
+      break;
+    case XFA_LANGID_fr_FR:
+      pLocal = XFA_GetLocaleFromBuffer(g_frFR_Locale, sizeof(g_frFR_Locale));
+      break;
+    case XFA_LANGID_it_IT:
+      pLocal = XFA_GetLocaleFromBuffer(g_itIT_Locale, sizeof(g_itIT_Locale));
+      break;
+    case XFA_LANGID_pt_BR:
+      pLocal = XFA_GetLocaleFromBuffer(g_ptBR_Locale, sizeof(g_ptBR_Locale));
+      break;
+    case XFA_LANGID_nl_NL:
+      pLocal = XFA_GetLocaleFromBuffer(g_nlNL_Locale, sizeof(g_nlNL_Locale));
+      break;
+    case XFA_LANGID_ru_RU:
+      pLocal = XFA_GetLocaleFromBuffer(g_ruRU_Locale, sizeof(g_ruRU_Locale));
+      break;
+    case XFA_LANGID_en_US:
+    default:
+      pLocal = XFA_GetLocaleFromBuffer(g_enUS_Locale, sizeof(g_enUS_Locale));
+      break;
+  }
+  return pLocal;
+}
+IFX_Locale* CXFA_LocaleMgr::GetLocaleByName(
+    const CFX_WideStringC& wsLocaleName) {
+  int32_t iCount = m_LocaleArray.GetSize();
+  int32_t i = 0;
+  for (i = 0; i < iCount; i++) {
+    IFX_Locale* pLocale = ((IFX_Locale*)m_LocaleArray[i]);
+    if (pLocale->GetName() == wsLocaleName) {
+      return pLocale;
+    }
+  }
+  int32_t iLen = wsLocaleName.GetLength();
+  if (iLen < 2) {
+    return NULL;
+  }
+  iCount = m_XMLLocaleArray.GetSize();
+  for (i = 0; i < iCount; i++) {
+    IFX_Locale* pLocale = ((IFX_Locale*)m_XMLLocaleArray[i]);
+    if (pLocale->GetName() == wsLocaleName) {
+      return pLocale;
+    }
+  }
+  FX_WORD dwLangueID = XFA_GetLanguage(wsLocaleName);
+  IFX_Locale* pLocale = GetLocale(dwLangueID);
+  if (pLocale)
+    m_XMLLocaleArray.Add(pLocale);
+  return pLocale;
+}
+void CXFA_LocaleMgr::SetDefLocale(IFX_Locale* pLocale) {
+  m_pDefLocale = pLocale;
+}
+CFX_WideStringC CXFA_LocaleMgr::GetConfigLocaleName(CXFA_Node* pConfig) {
+  if (!(m_dwLocaleFlags & 0x01)) {
+    m_wsConfigLocale.Empty();
+    if (pConfig) {
+      CXFA_Node* pChildfConfig =
+          pConfig->GetFirstChildByClass(XFA_ELEMENT_Acrobat);
+      if (!pChildfConfig) {
+        pChildfConfig = pConfig->GetFirstChildByClass(XFA_ELEMENT_Present);
+      }
+      CXFA_Node* pCommon =
+          pChildfConfig
+              ? pChildfConfig->GetFirstChildByClass(XFA_ELEMENT_Common)
+              : NULL;
+      CXFA_Node* pLocale =
+          pCommon ? pCommon->GetFirstChildByClass(XFA_ELEMENT_Locale) : NULL;
+      if (pLocale) {
+        pLocale->TryCData(XFA_ATTRIBUTE_Value, m_wsConfigLocale, FALSE);
+      }
+    }
+    m_dwLocaleFlags |= 0x01;
+  }
+  return m_wsConfigLocale;
+}
+static CXFA_TimeZoneProvider* g_pProvider = NULL;
+IXFA_TimeZoneProvider* IXFA_TimeZoneProvider::Create() {
+  FXSYS_assert(!g_pProvider);
+  g_pProvider = new CXFA_TimeZoneProvider();
+  return g_pProvider;
+}
+IXFA_TimeZoneProvider* IXFA_TimeZoneProvider::Get() {
+  if (!g_pProvider) {
+    g_pProvider = new CXFA_TimeZoneProvider();
+  }
+  return g_pProvider;
+}
+void IXFA_TimeZoneProvider::Destroy() {
+  delete g_pProvider;
+  g_pProvider = NULL;
+}
+#include <time.h>
+CXFA_TimeZoneProvider::CXFA_TimeZoneProvider() {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+  _tzset();
+  m_tz.tzHour = (int8_t)(_timezone / 3600 * -1);
+  m_tz.tzMinute = (int8_t)((FXSYS_abs(_timezone) % 3600) / 60);
+#else
+  tzset();
+  m_tz.tzHour = (int8_t)(timezone / 3600 * -1);
+  m_tz.tzMinute = (int8_t)((FXSYS_abs((int)timezone) % 3600) / 60);
+#endif
+}
+CXFA_TimeZoneProvider::~CXFA_TimeZoneProvider() {}
+void CXFA_TimeZoneProvider::SetTimeZone(FX_TIMEZONE& tz) {
+  m_tz = tz;
+}
+void CXFA_TimeZoneProvider::GetTimeZone(FX_TIMEZONE& tz) {
+  tz = m_tz;
+}
diff --git a/xfa/fxfa/parser/xfa_localemgr.h b/xfa/fxfa/parser/xfa_localemgr.h
new file mode 100644
index 0000000..e296fc4
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_localemgr.h
@@ -0,0 +1,78 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_LOCALEMGR_H_
+#define XFA_FXFA_PARSER_XFA_LOCALEMGR_H_
+
+#include "xfa/fgas/localization/fgas_datetime.h"
+#include "xfa/fgas/localization/fgas_locale.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/include/fxfa/fxfa_objectacc.h"
+
+class CXFA_Node;
+class IFX_Locale;
+
+#define XFA_LANGID_zh_CN 0x0804
+#define XFA_LANGID_zh_TW 0x0404
+#define XFA_LANGID_zh_HK 0x0c04
+#define XFA_LANGID_ja_JP 0x0411
+#define XFA_LANGID_ko_KR 0x0412
+#define XFA_LANGID_en_US 0x0409
+#define XFA_LANGID_en_GB 0x0809
+#define XFA_LANGID_es_ES 0x0c0a
+#define XFA_LANGID_es_LA 0x080a
+#define XFA_LANGID_de_DE 0x0407
+#define XFA_LANGID_fr_FR 0x040c
+#define XFA_LANGID_it_IT 0x0410
+#define XFA_LANGID_pt_BR 0x0416
+#define XFA_LANGID_nl_NL 0x0413
+#define XFA_LANGID_ru_RU 0x0419
+
+class CXFA_LocaleMgr : public IFX_LocaleMgr {
+ public:
+  CXFA_LocaleMgr(CXFA_Node* pLocaleSet, CFX_WideString wsDeflcid);
+  virtual void Release();
+  virtual FX_WORD GetDefLocaleID();
+  virtual IFX_Locale* GetDefLocale();
+  virtual IFX_Locale* GetLocale(FX_WORD lcid);
+  virtual IFX_Locale* GetLocaleByName(const CFX_WideStringC& wsLocaleName);
+  ~CXFA_LocaleMgr();
+  void SetDefLocale(IFX_Locale* pLocale);
+  CFX_WideStringC GetConfigLocaleName(CXFA_Node* pConfig);
+
+ protected:
+  CFX_PtrArray m_LocaleArray;
+  CFX_PtrArray m_XMLLocaleArray;
+  IFX_Locale* m_pDefLocale;
+  CFX_WideString m_wsConfigLocale;
+  FX_WORD m_dwDeflcid;
+  FX_WORD m_dwLocaleFlags;
+};
+
+class IXFA_TimeZoneProvider {
+ public:
+  static IXFA_TimeZoneProvider* Create();
+  static IXFA_TimeZoneProvider* Get();
+  static void Destroy();
+
+  virtual ~IXFA_TimeZoneProvider() {}
+
+  virtual void SetTimeZone(FX_TIMEZONE& tz) = 0;
+
+  virtual void GetTimeZone(FX_TIMEZONE& tz) = 0;
+};
+class CXFA_TimeZoneProvider : public IXFA_TimeZoneProvider {
+ public:
+  CXFA_TimeZoneProvider();
+  virtual ~CXFA_TimeZoneProvider();
+  virtual void SetTimeZone(FX_TIMEZONE& tz);
+  virtual void GetTimeZone(FX_TIMEZONE& tz);
+
+ private:
+  FX_TIMEZONE m_tz;
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_LOCALEMGR_H_
diff --git a/xfa/fxfa/parser/xfa_localevalue.cpp b/xfa/fxfa/parser/xfa_localevalue.cpp
new file mode 100644
index 0000000..8b3efa5
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_localevalue.cpp
@@ -0,0 +1,981 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_localevalue.h"
+
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+static const FX_DOUBLE fraction_scales[] = {0.1,
+                                            0.01,
+                                            0.001,
+                                            0.0001,
+                                            0.00001,
+                                            0.000001,
+                                            0.0000001,
+                                            0.00000001,
+                                            0.000000001,
+                                            0.0000000001,
+                                            0.00000000001,
+                                            0.000000000001,
+                                            0.0000000000001,
+                                            0.00000000000001,
+                                            0.000000000000001,
+                                            0.0000000000000001};
+CXFA_LocaleValue::CXFA_LocaleValue() {
+  m_dwType = XFA_VT_NULL;
+  m_bValid = TRUE;
+  m_pLocaleMgr = NULL;
+}
+CXFA_LocaleValue::CXFA_LocaleValue(const CXFA_LocaleValue& value) {
+  m_dwType = XFA_VT_NULL;
+  m_bValid = TRUE;
+  m_pLocaleMgr = NULL;
+  *this = value;
+}
+CXFA_LocaleValue::CXFA_LocaleValue(FX_DWORD dwType,
+                                   CXFA_LocaleMgr* pLocaleMgr) {
+  m_dwType = dwType;
+  m_bValid = (m_dwType != XFA_VT_NULL);
+  m_pLocaleMgr = pLocaleMgr;
+}
+CXFA_LocaleValue::CXFA_LocaleValue(FX_DWORD dwType,
+                                   const CFX_WideString& wsValue,
+                                   CXFA_LocaleMgr* pLocaleMgr) {
+  m_wsValue = wsValue;
+  m_dwType = dwType;
+  m_pLocaleMgr = pLocaleMgr;
+  m_bValid = ValidateCanonicalValue(wsValue, dwType);
+}
+CXFA_LocaleValue::CXFA_LocaleValue(FX_DWORD dwType,
+                                   const CFX_WideString& wsValue,
+                                   const CFX_WideString& wsFormat,
+                                   IFX_Locale* pLocale,
+                                   CXFA_LocaleMgr* pLocaleMgr) {
+  m_pLocaleMgr = pLocaleMgr;
+  m_bValid = TRUE;
+  m_dwType = dwType;
+  m_bValid = ParsePatternValue(wsValue, wsFormat, pLocale);
+}
+CXFA_LocaleValue& CXFA_LocaleValue::operator=(const CXFA_LocaleValue& value) {
+  m_wsValue = value.m_wsValue;
+  m_dwType = value.m_dwType;
+  m_bValid = value.m_bValid;
+  m_pLocaleMgr = value.m_pLocaleMgr;
+  return *this;
+}
+CXFA_LocaleValue::~CXFA_LocaleValue() {}
+static FX_LOCALECATEGORY XFA_ValugeCategory(FX_LOCALECATEGORY eCategory,
+                                            FX_DWORD dwValueType) {
+  if (eCategory == FX_LOCALECATEGORY_Unknown) {
+    switch (dwValueType) {
+      case XFA_VT_BOOLEAN:
+      case XFA_VT_INTEGER:
+      case XFA_VT_DECIMAL:
+      case XFA_VT_FLOAT:
+        return FX_LOCALECATEGORY_Num;
+      case XFA_VT_TEXT:
+        return FX_LOCALECATEGORY_Text;
+      case XFA_VT_DATE:
+        return FX_LOCALECATEGORY_Date;
+      case XFA_VT_TIME:
+        return FX_LOCALECATEGORY_Time;
+      case XFA_VT_DATETIME:
+        return FX_LOCALECATEGORY_DateTime;
+    }
+  }
+  return eCategory;
+}
+FX_BOOL CXFA_LocaleValue::ValidateValue(const CFX_WideString& wsValue,
+                                        const CFX_WideString& wsPattern,
+                                        IFX_Locale* pLocale,
+                                        CFX_WideString* pMatchFormat) {
+  CFX_WideString wsOutput;
+  IFX_Locale* locale = m_pLocaleMgr->GetDefLocale();
+  if (pLocale) {
+    m_pLocaleMgr->SetDefLocale(pLocale);
+  }
+  IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE);
+  CFX_WideStringArray wsPatterns;
+  pFormat->SplitFormatString(wsPattern, wsPatterns);
+  FX_BOOL bRet = FALSE;
+  int32_t iCount = wsPatterns.GetSize();
+  int32_t i = 0;
+  for (; i < iCount && !bRet; i++) {
+    CFX_WideString wsFormat = wsPatterns[i];
+    FX_LOCALECATEGORY eCategory = pFormat->GetCategory(wsFormat);
+    eCategory = XFA_ValugeCategory(eCategory, m_dwType);
+    switch (eCategory) {
+      case FX_LOCALECATEGORY_Null:
+        bRet = pFormat->ParseNull(wsValue, wsFormat);
+        if (!bRet) {
+          bRet = wsValue.IsEmpty();
+        }
+        break;
+      case FX_LOCALECATEGORY_Zero:
+        bRet = pFormat->ParseZero(wsValue, wsFormat);
+        if (!bRet) {
+          bRet = wsValue == FX_WSTRC(L"0");
+        }
+        break;
+      case FX_LOCALECATEGORY_Num: {
+        CFX_WideString fNum;
+        bRet = pFormat->ParseNum(wsValue, wsFormat, fNum);
+        if (!bRet) {
+          bRet = pFormat->FormatNum(wsValue, wsFormat, wsOutput);
+        }
+        break;
+      }
+      case FX_LOCALECATEGORY_Text:
+        bRet = pFormat->ParseText(wsValue, wsFormat, wsOutput);
+        wsOutput.Empty();
+        if (!bRet) {
+          bRet = pFormat->FormatText(wsValue, wsFormat, wsOutput);
+        }
+        break;
+      case FX_LOCALECATEGORY_Date: {
+        CFX_Unitime dt;
+        bRet = ValidateCanonicalDate(wsValue, dt);
+        if (!bRet) {
+          bRet = pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Date,
+                                        dt);
+          if (!bRet) {
+            bRet = pFormat->FormatDateTime(wsValue, wsFormat, wsOutput,
+                                           FX_DATETIMETYPE_Date);
+          }
+        }
+        break;
+      }
+      case FX_LOCALECATEGORY_Time: {
+        CFX_Unitime dt;
+        bRet =
+            pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Time, dt);
+        if (!bRet) {
+          bRet = pFormat->FormatDateTime(wsValue, wsFormat, wsOutput,
+                                         FX_DATETIMETYPE_Time);
+        }
+        break;
+      }
+      case FX_LOCALECATEGORY_DateTime: {
+        CFX_Unitime dt;
+        bRet = pFormat->ParseDateTime(wsValue, wsFormat,
+                                      FX_DATETIMETYPE_DateTime, dt);
+        if (!bRet) {
+          bRet = pFormat->FormatDateTime(wsValue, wsFormat, wsOutput,
+                                         FX_DATETIMETYPE_DateTime);
+        }
+        break;
+      }
+      default:
+        bRet = FALSE;
+        break;
+    }
+  }
+  if (bRet && pMatchFormat) {
+    *pMatchFormat = wsPatterns[i - 1];
+  }
+  pFormat->Release();
+  if (pLocale) {
+    m_pLocaleMgr->SetDefLocale(locale);
+  }
+  return bRet;
+}
+CFX_WideString CXFA_LocaleValue::GetValue() const {
+  return m_wsValue;
+}
+FX_DWORD CXFA_LocaleValue::GetType() const {
+  return m_dwType;
+}
+void CXFA_LocaleValue::SetValue(const CFX_WideString& wsValue,
+                                FX_DWORD dwType) {
+  m_wsValue = wsValue;
+  m_dwType = dwType;
+}
+CFX_WideString CXFA_LocaleValue::GetText() const {
+  if (m_bValid && m_dwType == XFA_VT_TEXT) {
+    return m_wsValue;
+  }
+  return CFX_WideString();
+}
+FX_FLOAT CXFA_LocaleValue::GetNum() const {
+  if (m_bValid && (m_dwType == XFA_VT_BOOLEAN || m_dwType == XFA_VT_INTEGER ||
+                   m_dwType == XFA_VT_DECIMAL || m_dwType == XFA_VT_FLOAT)) {
+    int64_t nIntegral = 0;
+    FX_DWORD dwFractional = 0;
+    int32_t nExponent = 0;
+    int cc = 0;
+    FX_BOOL bNegative = FALSE, bExpSign = FALSE;
+    const FX_WCHAR* str = (const FX_WCHAR*)m_wsValue;
+    int len = m_wsValue.GetLength();
+    while (XFA_IsSpace(str[cc]) && cc < len) {
+      cc++;
+    }
+    if (cc >= len) {
+      return 0;
+    }
+    if (str[0] == '+') {
+      cc++;
+    } else if (str[0] == '-') {
+      bNegative = TRUE;
+      cc++;
+    }
+    int nIntegralLen = 0;
+    while (cc < len) {
+      if (str[cc] == '.' || !XFA_IsDigit(str[cc]) || nIntegralLen > 17) {
+        break;
+      }
+      nIntegral = nIntegral * 10 + str[cc] - '0';
+      cc++;
+      nIntegralLen++;
+    }
+    nIntegral = bNegative ? -nIntegral : nIntegral;
+    int scale = 0;
+    double fraction = 0.0;
+    if (cc < len && str[cc] == '.') {
+      cc++;
+      while (cc < len) {
+        fraction += fraction_scales[scale] * (str[cc] - '0');
+        scale++;
+        cc++;
+        if (scale == sizeof fraction_scales / sizeof(double) ||
+            !XFA_IsDigit(str[cc])) {
+          break;
+        }
+      }
+      dwFractional = (FX_DWORD)(fraction * 4294967296.0);
+    }
+    if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) {
+      cc++;
+      if (cc < len) {
+        if (str[cc] == '+') {
+          cc++;
+        } else if (str[cc] == '-') {
+          bExpSign = TRUE;
+          cc++;
+        }
+      }
+      while (cc < len) {
+        if (str[cc] == '.' || !XFA_IsDigit(str[cc])) {
+          break;
+        }
+        nExponent = nExponent * 10 + str[cc] - '0';
+        cc++;
+      }
+      nExponent = bExpSign ? -nExponent : nExponent;
+    }
+    FX_FLOAT fValue = (FX_FLOAT)(dwFractional / 4294967296.0);
+    fValue = nIntegral + (nIntegral >= 0 ? fValue : -fValue);
+    if (nExponent != 0) {
+      fValue *= FXSYS_pow(10, (FX_FLOAT)nExponent);
+    }
+    return fValue;
+  }
+  return 0;
+}
+FX_DOUBLE CXFA_LocaleValue::GetDoubleNum() const {
+  if (m_bValid && (m_dwType == XFA_VT_BOOLEAN || m_dwType == XFA_VT_INTEGER ||
+                   m_dwType == XFA_VT_DECIMAL || m_dwType == XFA_VT_FLOAT)) {
+    int64_t nIntegral = 0;
+    FX_DWORD dwFractional = 0;
+    int32_t nExponent = 0;
+    int32_t cc = 0;
+    FX_BOOL bNegative = FALSE, bExpSign = FALSE;
+    const FX_WCHAR* str = (const FX_WCHAR*)m_wsValue;
+    int len = m_wsValue.GetLength();
+    while (XFA_IsSpace(str[cc]) && cc < len) {
+      cc++;
+    }
+    if (cc >= len) {
+      return 0;
+    }
+    if (str[0] == '+') {
+      cc++;
+    } else if (str[0] == '-') {
+      bNegative = TRUE;
+      cc++;
+    }
+    int32_t nIntegralLen = 0;
+    while (cc < len) {
+      if (str[cc] == '.' || !XFA_IsDigit(str[cc]) || nIntegralLen > 17) {
+        break;
+      }
+      nIntegral = nIntegral * 10 + str[cc] - '0';
+      cc++;
+      nIntegralLen++;
+    }
+    nIntegral = bNegative ? -nIntegral : nIntegral;
+    int32_t scale = 0;
+    FX_DOUBLE fraction = 0.0;
+    if (cc < len && str[cc] == '.') {
+      cc++;
+      while (cc < len) {
+        fraction += fraction_scales[scale] * (str[cc] - '0');
+        scale++;
+        cc++;
+        if (scale == sizeof fraction_scales / sizeof(FX_DOUBLE) ||
+            !XFA_IsDigit(str[cc])) {
+          break;
+        }
+      }
+      dwFractional = (FX_DWORD)(fraction * 4294967296.0);
+    }
+    if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) {
+      cc++;
+      if (cc < len) {
+        if (str[cc] == '+') {
+          cc++;
+        } else if (str[cc] == '-') {
+          bExpSign = TRUE;
+          cc++;
+        }
+      }
+      while (cc < len) {
+        if (str[cc] == '.' || !XFA_IsDigit(str[cc])) {
+          break;
+        }
+        nExponent = nExponent * 10 + str[cc] - '0';
+        cc++;
+      }
+      nExponent = bExpSign ? -nExponent : nExponent;
+    }
+    FX_DOUBLE dValue = (dwFractional / 4294967296.0);
+    dValue = nIntegral + (nIntegral >= 0 ? dValue : -dValue);
+    if (nExponent != 0) {
+      dValue *= FXSYS_pow(10, (FX_FLOAT)nExponent);
+    }
+    return dValue;
+  }
+  return 0;
+}
+CFX_Unitime CXFA_LocaleValue::GetDate() const {
+  if (m_bValid && m_dwType == XFA_VT_DATE) {
+    CFX_Unitime dt;
+    FX_DateFromCanonical(m_wsValue, dt);
+    return dt;
+  }
+  return CFX_Unitime();
+}
+CFX_Unitime CXFA_LocaleValue::GetTime() const {
+  if (m_bValid && m_dwType == XFA_VT_TIME) {
+    CFX_Unitime dt(0);
+    FXSYS_assert(m_pLocaleMgr);
+    FX_TimeFromCanonical(m_wsValue, dt, m_pLocaleMgr->GetDefLocale());
+    return dt;
+  }
+  return CFX_Unitime();
+}
+CFX_Unitime CXFA_LocaleValue::GetDateTime() const {
+  if (m_bValid && m_dwType == XFA_VT_DATETIME) {
+    int32_t index = m_wsValue.Find('T');
+    CFX_Unitime dt;
+    FX_DateFromCanonical(m_wsValue.Left(index), dt);
+    FXSYS_assert(m_pLocaleMgr);
+    FX_TimeFromCanonical(m_wsValue.Right(m_wsValue.GetLength() - index - 1), dt,
+                         m_pLocaleMgr->GetDefLocale());
+    return dt;
+  }
+  return CFX_Unitime();
+}
+FX_BOOL CXFA_LocaleValue::SetText(const CFX_WideString& wsText) {
+  m_dwType = XFA_VT_TEXT;
+  m_wsValue = wsText;
+  return TRUE;
+}
+FX_BOOL CXFA_LocaleValue::SetText(const CFX_WideString& wsText,
+                                  const CFX_WideString& wsFormat,
+                                  IFX_Locale* pLocale) {
+  m_dwType = XFA_VT_TEXT;
+  return m_bValid = ParsePatternValue(wsText, wsFormat, pLocale);
+}
+FX_BOOL CXFA_LocaleValue::SetNum(FX_FLOAT fNum) {
+  m_dwType = XFA_VT_FLOAT;
+  m_wsValue.Format(L"%.8g", (FX_DOUBLE)fNum);
+  return TRUE;
+}
+FX_BOOL CXFA_LocaleValue::SetNum(const CFX_WideString& wsNum,
+                                 const CFX_WideString& wsFormat,
+                                 IFX_Locale* pLocale) {
+  m_dwType = XFA_VT_FLOAT;
+  return m_bValid = ParsePatternValue(wsNum, wsFormat, pLocale);
+}
+FX_BOOL CXFA_LocaleValue::SetDate(const CFX_Unitime& d) {
+  m_dwType = XFA_VT_DATE;
+  m_wsValue.Format(L"%04d-%02d-%02d", d.GetYear(), d.GetMonth(), d.GetDay());
+  return TRUE;
+}
+FX_BOOL CXFA_LocaleValue::SetDate(const CFX_WideString& wsDate,
+                                  const CFX_WideString& wsFormat,
+                                  IFX_Locale* pLocale) {
+  m_dwType = XFA_VT_DATE;
+  return m_bValid = ParsePatternValue(wsDate, wsFormat, pLocale);
+}
+FX_BOOL CXFA_LocaleValue::SetTime(const CFX_Unitime& t) {
+  m_dwType = XFA_VT_TIME;
+  m_wsValue.Format(L"%02d:%02d:%02d", t.GetHour(), t.GetMinute(),
+                   t.GetSecond());
+  if (t.GetMillisecond() > 0) {
+    CFX_WideString wsTemp;
+    wsTemp.Format(L"%:03d", t.GetMillisecond());
+    m_wsValue += wsTemp;
+  }
+  return TRUE;
+}
+FX_BOOL CXFA_LocaleValue::SetTime(const CFX_WideString& wsTime,
+                                  const CFX_WideString& wsFormat,
+                                  IFX_Locale* pLocale) {
+  m_dwType = XFA_VT_TIME;
+  return m_bValid = ParsePatternValue(wsTime, wsFormat, pLocale);
+}
+FX_BOOL CXFA_LocaleValue::SetDateTime(const CFX_Unitime& dt) {
+  m_dwType = XFA_VT_DATETIME;
+  m_wsValue.Format(L"%04d-%02d-%02dT%02d:%02d:%02d", dt.GetYear(),
+                   dt.GetMonth(), dt.GetDay(), dt.GetHour(), dt.GetMinute(),
+                   dt.GetSecond());
+  if (dt.GetMillisecond() > 0) {
+    CFX_WideString wsTemp;
+    wsTemp.Format(L"%:03d", dt.GetMillisecond());
+    m_wsValue += wsTemp;
+  }
+  return TRUE;
+}
+FX_BOOL CXFA_LocaleValue::SetDateTime(const CFX_WideString& wsDateTime,
+                                      const CFX_WideString& wsFormat,
+                                      IFX_Locale* pLocale) {
+  m_dwType = XFA_VT_DATETIME;
+  return m_bValid = ParsePatternValue(wsDateTime, wsFormat, pLocale);
+}
+FX_BOOL CXFA_LocaleValue::FormatPatterns(CFX_WideString& wsResult,
+                                         const CFX_WideString& wsFormat,
+                                         IFX_Locale* pLocale,
+                                         XFA_VALUEPICTURE eValueType) const {
+  wsResult.Empty();
+  FX_BOOL bRet = FALSE;
+  IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE);
+  CFX_WideStringArray wsPatterns;
+  pFormat->SplitFormatString(wsFormat, wsPatterns);
+  int32_t iCount = wsPatterns.GetSize();
+  for (int32_t i = 0; i < iCount; i++) {
+    bRet = FormatSinglePattern(wsResult, wsPatterns[i], pLocale, eValueType);
+    if (bRet) {
+      break;
+    }
+  }
+  pFormat->Release();
+  return bRet;
+}
+FX_BOOL CXFA_LocaleValue::FormatSinglePattern(
+    CFX_WideString& wsResult,
+    const CFX_WideString& wsFormat,
+    IFX_Locale* pLocale,
+    XFA_VALUEPICTURE eValueType) const {
+  IFX_Locale* locale = m_pLocaleMgr->GetDefLocale();
+  if (pLocale) {
+    m_pLocaleMgr->SetDefLocale(pLocale);
+  }
+  wsResult.Empty();
+  FX_BOOL bRet = FALSE;
+  IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE);
+  FX_LOCALECATEGORY eCategory = pFormat->GetCategory(wsFormat);
+  eCategory = XFA_ValugeCategory(eCategory, m_dwType);
+  switch (eCategory) {
+    case FX_LOCALECATEGORY_Null:
+      if (m_wsValue.IsEmpty()) {
+        bRet = pFormat->FormatNull(wsFormat, wsResult);
+      }
+      break;
+    case FX_LOCALECATEGORY_Zero:
+      if (m_wsValue == FX_WSTRC(L"0")) {
+        bRet = pFormat->FormatZero(wsFormat, wsResult);
+      }
+      break;
+    case FX_LOCALECATEGORY_Num:
+      bRet = pFormat->FormatNum(m_wsValue, wsFormat, wsResult);
+      break;
+    case FX_LOCALECATEGORY_Text:
+      bRet = pFormat->FormatText(m_wsValue, wsFormat, wsResult);
+      break;
+    case FX_LOCALECATEGORY_Date:
+      bRet = pFormat->FormatDateTime(m_wsValue, wsFormat, wsResult,
+                                     FX_DATETIMETYPE_Date);
+      break;
+    case FX_LOCALECATEGORY_Time:
+      bRet = pFormat->FormatDateTime(m_wsValue, wsFormat, wsResult,
+                                     FX_DATETIMETYPE_Time);
+      break;
+    case FX_LOCALECATEGORY_DateTime:
+      bRet = pFormat->FormatDateTime(m_wsValue, wsFormat, wsResult,
+                                     FX_DATETIMETYPE_DateTime);
+      break;
+    default:
+      wsResult = m_wsValue;
+      bRet = TRUE;
+  }
+  pFormat->Release();
+  if (!bRet && (eCategory != FX_LOCALECATEGORY_Num ||
+                eValueType != XFA_VALUEPICTURE_Display)) {
+    wsResult = m_wsValue;
+  }
+  if (pLocale) {
+    m_pLocaleMgr->SetDefLocale(locale);
+  }
+  return bRet;
+}
+static FX_BOOL XFA_ValueSplitDateTime(const CFX_WideString& wsDateTime,
+                                      CFX_WideString& wsDate,
+                                      CFX_WideString& wsTime) {
+  wsDate = L"";
+  wsTime = L"";
+  if (wsDateTime.IsEmpty()) {
+    return FALSE;
+  }
+  int nSplitIndex = -1;
+  nSplitIndex = wsDateTime.Find('T');
+  if (nSplitIndex < 0) {
+    nSplitIndex = wsDateTime.Find(' ');
+  }
+  if (nSplitIndex < 0) {
+    return FALSE;
+  }
+  wsDate = wsDateTime.Left(nSplitIndex);
+  wsTime = wsDateTime.Right(wsDateTime.GetLength() - nSplitIndex - 1);
+  return TRUE;
+}
+FX_BOOL CXFA_LocaleValue::ValidateCanonicalValue(const CFX_WideString& wsValue,
+                                                 FX_DWORD dwVType) {
+  if (wsValue.IsEmpty()) {
+    return TRUE;
+  }
+  CFX_Unitime dt;
+  switch (dwVType) {
+    case XFA_VT_DATE: {
+      if (ValidateCanonicalDate(wsValue, dt)) {
+        return TRUE;
+      }
+      CFX_WideString wsDate, wsTime;
+      if (XFA_ValueSplitDateTime(wsValue, wsDate, wsTime) &&
+          ValidateCanonicalDate(wsDate, dt)) {
+        return TRUE;
+      }
+      return FALSE;
+    }
+    case XFA_VT_TIME: {
+      if (ValidateCanonicalTime(wsValue)) {
+        return TRUE;
+      }
+      CFX_WideString wsDate, wsTime;
+      if (XFA_ValueSplitDateTime(wsValue, wsDate, wsTime) &&
+          ValidateCanonicalTime(wsTime)) {
+        return TRUE;
+      }
+      return FALSE;
+    }
+    case XFA_VT_DATETIME: {
+      CFX_WideString wsDate, wsTime;
+      if (XFA_ValueSplitDateTime(wsValue, wsDate, wsTime) &&
+          ValidateCanonicalDate(wsDate, dt) && ValidateCanonicalTime(wsTime)) {
+        return TRUE;
+      }
+    } break;
+  }
+  return TRUE;
+}
+FX_BOOL CXFA_LocaleValue::ValidateCanonicalDate(const CFX_WideString& wsDate,
+                                                CFX_Unitime& unDate) {
+  const FX_WORD LastDay[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+  const FX_WORD wCountY = 4, wCountM = 2, wCountD = 2;
+  int nLen = wsDate.GetLength();
+  if (nLen < wCountY || nLen > wCountY + wCountM + wCountD + 2) {
+    return FALSE;
+  }
+  const bool bSymbol = wsDate.Find(0x2D) != -1;
+  FX_WORD wYear = 0;
+  FX_WORD wMonth = 0;
+  FX_WORD wDay = 0;
+  const FX_WCHAR* pDate = (const FX_WCHAR*)wsDate;
+  int nIndex = 0, nStart = 0;
+  while (pDate[nIndex] != '\0' && nIndex < wCountY) {
+    if (!XFA_IsDigit(pDate[nIndex])) {
+      return FALSE;
+    }
+    wYear = (pDate[nIndex] - '0') + wYear * 10;
+    nIndex++;
+  }
+  if (bSymbol) {
+    if (pDate[nIndex] != 0x2D) {
+      return FALSE;
+    }
+    nIndex++;
+  }
+  nStart = nIndex;
+  while (pDate[nIndex] != '\0' && nIndex - nStart < wCountM && nIndex < nLen) {
+    if (!XFA_IsDigit(pDate[nIndex])) {
+      return FALSE;
+    }
+    wMonth = (pDate[nIndex] - '0') + wMonth * 10;
+    nIndex++;
+  }
+  if (bSymbol) {
+    if (pDate[nIndex] != 0x2D) {
+      return FALSE;
+    }
+    nIndex++;
+  }
+  nStart = nIndex;
+  while (pDate[nIndex] != '\0' && nIndex - nStart < wCountD && nIndex < nLen) {
+    if (!XFA_IsDigit(pDate[nIndex])) {
+      return FALSE;
+    }
+    wDay = (pDate[nIndex] - '0') + wDay * 10;
+    nIndex++;
+  }
+  if (nIndex != nLen) {
+    return FALSE;
+  }
+  if (wYear < 1900 || wYear > 2029) {
+    return FALSE;
+  }
+  if (wMonth < 1 || wMonth > 12) {
+    if (wMonth == 0 && nLen == wCountY) {
+      return TRUE;
+    }
+    return FALSE;
+  }
+  if (wDay < 1) {
+    if (wDay == 0 && (nLen == wCountY + wCountM)) {
+      return TRUE;
+    }
+    return FALSE;
+  }
+  if (wMonth == 2) {
+    if (wYear % 400 == 0 || (wYear % 100 != 0 && wYear % 4 == 0)) {
+      if (wDay > 29) {
+        return FALSE;
+      }
+    } else {
+      if (wDay > 28) {
+        return FALSE;
+      }
+    }
+  } else if (wDay > LastDay[wMonth - 1]) {
+    return FALSE;
+  }
+  CFX_Unitime ut;
+  ut.Set(wYear, static_cast<uint8_t>(wMonth), static_cast<uint8_t>(wDay));
+  unDate = unDate + ut;
+  return TRUE;
+}
+FX_BOOL CXFA_LocaleValue::ValidateCanonicalTime(const CFX_WideString& wsTime) {
+  int nLen = wsTime.GetLength();
+  if (nLen < 2)
+    return FALSE;
+  const FX_WORD wCountH = 2;
+  const FX_WORD wCountM = 2;
+  const FX_WORD wCountS = 2;
+  const FX_WORD wCountF = 3;
+  const bool bSymbol = wsTime.Find(':') != -1;
+  FX_WORD wHour = 0;
+  FX_WORD wMinute = 0;
+  FX_WORD wSecond = 0;
+  FX_WORD wFraction = 0;
+  const FX_WCHAR* pTime = (const FX_WCHAR*)wsTime;
+  int nIndex = 0;
+  int nStart = 0;
+  while (nIndex - nStart < wCountH && pTime[nIndex]) {
+    if (!XFA_IsDigit(pTime[nIndex]))
+      return FALSE;
+    wHour = pTime[nIndex] - '0' + wHour * 10;
+    nIndex++;
+  }
+  if (bSymbol) {
+    if (nIndex < nLen && pTime[nIndex] != ':')
+      return FALSE;
+    nIndex++;
+  }
+  nStart = nIndex;
+  while (nIndex - nStart < wCountM && nIndex < nLen && pTime[nIndex]) {
+    if (!XFA_IsDigit(pTime[nIndex]))
+      return FALSE;
+    wMinute = pTime[nIndex] - '0' + wMinute * 10;
+    nIndex++;
+  }
+  if (bSymbol) {
+    if (nIndex < nLen && pTime[nIndex] != ':')
+      return FALSE;
+    nIndex++;
+  }
+  nStart = nIndex;
+  while (nIndex - nStart < wCountS && nIndex < nLen && pTime[nIndex]) {
+    if (!XFA_IsDigit(pTime[nIndex]))
+      return FALSE;
+    wSecond = pTime[nIndex] - '0' + wSecond * 10;
+    nIndex++;
+  }
+  if (wsTime.Find('.') > 0) {
+    if (pTime[nIndex] != '.')
+      return FALSE;
+    nIndex++;
+    nStart = nIndex;
+    while (nIndex - nStart < wCountF && nIndex < nLen && pTime[nIndex]) {
+      if (!XFA_IsDigit(pTime[nIndex]))
+        return FALSE;
+      wFraction = pTime[nIndex] - '0' + wFraction * 10;
+      nIndex++;
+    }
+  }
+  if (nIndex < nLen) {
+    if (pTime[nIndex] == 'Z') {
+      nIndex++;
+    } else if (pTime[nIndex] == '-' || pTime[nIndex] == '+') {
+      int16_t nOffsetH = 0;
+      int16_t nOffsetM = 0;
+      nIndex++;
+      nStart = nIndex;
+      while (nIndex - nStart < wCountH && nIndex < nLen && pTime[nIndex]) {
+        if (!XFA_IsDigit(pTime[nIndex]))
+          return FALSE;
+        nOffsetH = pTime[nIndex] - '0' + nOffsetH * 10;
+        nIndex++;
+      }
+      if (bSymbol) {
+        if (nIndex < nLen && pTime[nIndex] != ':')
+          return FALSE;
+        nIndex++;
+      }
+      nStart = nIndex;
+      while (nIndex - nStart < wCountM && nIndex < nLen && pTime[nIndex]) {
+        if (!XFA_IsDigit(pTime[nIndex]))
+          return FALSE;
+        nOffsetM = pTime[nIndex] - '0' + nOffsetM * 10;
+        nIndex++;
+      }
+      if (nOffsetH > 12 || nOffsetM >= 60)
+        return FALSE;
+    }
+  }
+  return nIndex == nLen && wHour < 24 && wMinute < 60 && wSecond < 60 &&
+         wFraction <= 999;
+}
+FX_BOOL CXFA_LocaleValue::ValidateCanonicalDateTime(
+    const CFX_WideString& wsDateTime) {
+  CFX_WideString wsDate, wsTime;
+  if (wsDateTime.IsEmpty()) {
+    return FALSE;
+  }
+  int nSplitIndex = -1;
+  nSplitIndex = wsDateTime.Find('T');
+  if (nSplitIndex < 0) {
+    nSplitIndex = wsDateTime.Find(' ');
+  }
+  if (nSplitIndex < 0) {
+    return FALSE;
+  }
+  wsDate = wsDateTime.Left(nSplitIndex);
+  wsTime = wsDateTime.Right(wsDateTime.GetLength() - nSplitIndex - 1);
+  CFX_Unitime dt;
+  return ValidateCanonicalDate(wsDate, dt) && ValidateCanonicalTime(wsTime);
+}
+FX_BOOL CXFA_LocaleValue::ParsePatternValue(const CFX_WideString& wsValue,
+                                            const CFX_WideString& wsPattern,
+                                            IFX_Locale* pLocale) {
+  IFX_Locale* locale = m_pLocaleMgr->GetDefLocale();
+  if (pLocale) {
+    m_pLocaleMgr->SetDefLocale(pLocale);
+  }
+  IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE);
+  CFX_WideStringArray wsPatterns;
+  pFormat->SplitFormatString(wsPattern, wsPatterns);
+  FX_BOOL bRet = FALSE;
+  int32_t iCount = wsPatterns.GetSize();
+  for (int32_t i = 0; i < iCount && !bRet; i++) {
+    CFX_WideString wsFormat = wsPatterns[i];
+    FX_LOCALECATEGORY eCategory = pFormat->GetCategory(wsFormat);
+    eCategory = XFA_ValugeCategory(eCategory, m_dwType);
+    switch (eCategory) {
+      case FX_LOCALECATEGORY_Null:
+        bRet = pFormat->ParseNull(wsValue, wsFormat);
+        if (bRet) {
+          m_wsValue.Empty();
+        }
+        break;
+      case FX_LOCALECATEGORY_Zero:
+        bRet = pFormat->ParseZero(wsValue, wsFormat);
+        if (bRet) {
+          m_wsValue = FX_WSTRC(L"0");
+        }
+        break;
+      case FX_LOCALECATEGORY_Num: {
+        CFX_WideString fNum;
+        bRet = pFormat->ParseNum(wsValue, wsFormat, fNum);
+        if (bRet) {
+          m_wsValue = fNum;
+        }
+        break;
+      }
+      case FX_LOCALECATEGORY_Text:
+        bRet = pFormat->ParseText(wsValue, wsFormat, m_wsValue);
+        break;
+      case FX_LOCALECATEGORY_Date: {
+        CFX_Unitime dt;
+        bRet = ValidateCanonicalDate(wsValue, dt);
+        if (!bRet) {
+          bRet = pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Date,
+                                        dt);
+        }
+        if (bRet) {
+          SetDate(dt);
+        }
+        break;
+      }
+      case FX_LOCALECATEGORY_Time: {
+        CFX_Unitime dt;
+        bRet =
+            pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Time, dt);
+        if (bRet) {
+          SetTime(dt);
+        }
+        break;
+      }
+      case FX_LOCALECATEGORY_DateTime: {
+        CFX_Unitime dt;
+        bRet = pFormat->ParseDateTime(wsValue, wsFormat,
+                                      FX_DATETIMETYPE_DateTime, dt);
+        if (bRet) {
+          SetDateTime(dt);
+        }
+        break;
+      }
+      default:
+        m_wsValue = wsValue;
+        bRet = TRUE;
+        break;
+    }
+  }
+  if (!bRet) {
+    m_wsValue = wsValue;
+  }
+  pFormat->Release();
+  if (pLocale) {
+    m_pLocaleMgr->SetDefLocale(locale);
+  }
+  return bRet;
+}
+void CXFA_LocaleValue::GetNumbericFormat(CFX_WideString& wsFormat,
+                                         int32_t nIntLen,
+                                         int32_t nDecLen,
+                                         FX_BOOL bSign) {
+  FXSYS_assert(wsFormat.IsEmpty());
+  FXSYS_assert(nIntLen >= -1 && nDecLen >= -1);
+  int32_t nTotalLen = (nIntLen >= 0 ? nIntLen : 2) + (bSign ? 1 : 0) +
+                      (nDecLen >= 0 ? nDecLen : 2) + (nDecLen == 0 ? 0 : 1);
+  FX_WCHAR* lpBuf = wsFormat.GetBuffer(nTotalLen);
+  int32_t nPos = 0;
+  if (bSign) {
+    lpBuf[nPos++] = L's';
+  }
+  if (nIntLen == -1) {
+    lpBuf[nPos++] = L'z';
+    lpBuf[nPos++] = L'*';
+  } else {
+    while (nIntLen) {
+      lpBuf[nPos++] = L'z';
+      nIntLen--;
+    }
+  }
+  if (nDecLen != 0) {
+    lpBuf[nPos++] = L'.';
+  }
+  if (nDecLen == -1) {
+    lpBuf[nPos++] = L'z';
+    lpBuf[nPos++] = L'*';
+  } else {
+    while (nDecLen) {
+      lpBuf[nPos++] = L'z';
+      nDecLen--;
+    }
+  }
+  wsFormat.ReleaseBuffer(nTotalLen);
+}
+FX_BOOL CXFA_LocaleValue::ValidateNumericTemp(CFX_WideString& wsNumeric,
+                                              CFX_WideString& wsFormat,
+                                              IFX_Locale* pLocale,
+                                              int32_t* pos) {
+  if (wsFormat.IsEmpty() || wsNumeric.IsEmpty()) {
+    return TRUE;
+  }
+  const FX_WCHAR* pNum = wsNumeric.c_str();
+  const FX_WCHAR* pFmt = wsFormat.c_str();
+  int32_t n = 0, nf = 0;
+  FX_WCHAR c = pNum[n];
+  FX_WCHAR cf = pFmt[nf];
+  if (cf == L's') {
+    if (c == L'-' || c == L'+') {
+      ++n;
+    }
+    ++nf;
+  }
+  FX_BOOL bLimit = TRUE;
+  int32_t nCount = wsNumeric.GetLength();
+  int32_t nCountFmt = wsFormat.GetLength();
+  while (n < nCount && (bLimit ? nf < nCountFmt : TRUE) &&
+         XFA_IsDigit(c = pNum[n])) {
+    if (bLimit == TRUE) {
+      if ((cf = pFmt[nf]) == L'*') {
+        bLimit = FALSE;
+      } else if (cf == L'z') {
+        nf++;
+      } else {
+        return FALSE;
+      }
+    }
+    n++;
+  }
+  if (n == nCount) {
+    return TRUE;
+  }
+  if (nf == nCountFmt) {
+    return FALSE;
+  }
+  while (nf < nCountFmt && (cf = pFmt[nf]) != L'.') {
+    FXSYS_assert(cf == L'z' || cf == L'*');
+    ++nf;
+  }
+  CFX_WideString wsDecimalSymbol;
+  if (pLocale) {
+    pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDecimalSymbol);
+  } else {
+    wsDecimalSymbol = CFX_WideString(L'.');
+  }
+  if (pFmt[nf] != L'.') {
+    return FALSE;
+  }
+  if (wsDecimalSymbol != CFX_WideStringC(c) && c != L'.') {
+    return FALSE;
+  }
+  ++nf;
+  ++n;
+  bLimit = TRUE;
+  while (n < nCount && (bLimit ? nf < nCountFmt : TRUE) &&
+         XFA_IsDigit(c = pNum[n])) {
+    if (bLimit == TRUE) {
+      if ((cf = pFmt[nf]) == L'*') {
+        bLimit = FALSE;
+      } else if (cf == L'z') {
+        nf++;
+      } else {
+        return FALSE;
+      }
+    }
+    n++;
+  }
+  return n == nCount;
+}
diff --git a/xfa/fxfa/parser/xfa_localevalue.h b/xfa/fxfa/parser/xfa_localevalue.h
new file mode 100644
index 0000000..5906858
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_localevalue.h
@@ -0,0 +1,112 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_LOCALEVALUE_H_
+#define XFA_FXFA_PARSER_XFA_LOCALEVALUE_H_
+
+#include "xfa/include/fxfa/fxfa_objectacc.h"
+
+class IFX_Locale;
+class CFX_Unitime;
+class CXFA_LocaleMgr;
+
+#define XFA_VT_NULL 0
+#define XFA_VT_BOOLEAN 1
+#define XFA_VT_INTEGER 2
+#define XFA_VT_DECIMAL 4
+#define XFA_VT_FLOAT 8
+#define XFA_VT_TEXT 16
+#define XFA_VT_DATE 32
+#define XFA_VT_TIME 64
+#define XFA_VT_DATETIME 128
+
+class CXFA_LocaleValue {
+ public:
+  CXFA_LocaleValue();
+  CXFA_LocaleValue(const CXFA_LocaleValue& value);
+  CXFA_LocaleValue(FX_DWORD dwType, CXFA_LocaleMgr* pLocaleMgr);
+  CXFA_LocaleValue(FX_DWORD dwType,
+                   const CFX_WideString& wsValue,
+                   CXFA_LocaleMgr* pLocaleMgr);
+  CXFA_LocaleValue(FX_DWORD dwType,
+                   const CFX_WideString& wsValue,
+                   const CFX_WideString& wsFormat,
+                   IFX_Locale* pLocale,
+                   CXFA_LocaleMgr* pLocaleMgr);
+  ~CXFA_LocaleValue();
+  CXFA_LocaleValue& operator=(const CXFA_LocaleValue& value);
+
+  FX_BOOL ValidateValue(const CFX_WideString& wsValue,
+                        const CFX_WideString& wsPattern,
+                        IFX_Locale* pLocale,
+                        CFX_WideString* pMatchFormat = NULL);
+  FX_BOOL FormatPatterns(CFX_WideString& wsResult,
+                         const CFX_WideString& wsFormat,
+                         IFX_Locale* pLocale,
+                         XFA_VALUEPICTURE eValueType) const;
+  FX_BOOL FormatSinglePattern(CFX_WideString& wsResult,
+                              const CFX_WideString& wsFormat,
+                              IFX_Locale* pLocale,
+                              XFA_VALUEPICTURE eValueType) const;
+  FX_BOOL ValidateCanonicalValue(const CFX_WideString& wsValue,
+                                 FX_DWORD dwVType);
+  FX_BOOL ValidateCanonicalDate(const CFX_WideString& wsDate,
+                                CFX_Unitime& unDate);
+  FX_BOOL ValidateCanonicalTime(const CFX_WideString& wsTime);
+  FX_BOOL ValidateCanonicalDateTime(const CFX_WideString& wsDateTime);
+  void GetNumbericFormat(CFX_WideString& wsFormat,
+                         int32_t nIntLen,
+                         int32_t nDecLen,
+                         FX_BOOL bSign = TRUE);
+  FX_BOOL ValidateNumericTemp(CFX_WideString& wsNumeric,
+                              CFX_WideString& wsFormat,
+                              IFX_Locale* pLocale = NULL,
+                              int32_t* pos = NULL);
+
+  CFX_WideString GetValue() const;
+  FX_DWORD GetType() const;
+  void SetValue(const CFX_WideString& wsValue, FX_DWORD dwType);
+  CFX_WideString GetText() const;
+  FX_FLOAT GetNum() const;
+  FX_DOUBLE GetDoubleNum() const;
+  CFX_Unitime GetDate() const;
+  CFX_Unitime GetTime() const;
+  CFX_Unitime GetDateTime() const;
+  FX_BOOL SetText(const CFX_WideString& wsText);
+  FX_BOOL SetText(const CFX_WideString& wsText,
+                  const CFX_WideString& wsFormat,
+                  IFX_Locale* pLocale);
+  FX_BOOL SetNum(FX_FLOAT fNum);
+  FX_BOOL SetNum(const CFX_WideString& wsNum,
+                 const CFX_WideString& wsFormat,
+                 IFX_Locale* pLocale);
+  FX_BOOL SetDate(const CFX_Unitime& d);
+  FX_BOOL SetDate(const CFX_WideString& wsDate,
+                  const CFX_WideString& wsFormat,
+                  IFX_Locale* pLocale);
+  FX_BOOL SetTime(const CFX_Unitime& t);
+  FX_BOOL SetTime(const CFX_WideString& wsTime,
+                  const CFX_WideString& wsFormat,
+                  IFX_Locale* pLocale);
+  FX_BOOL SetDateTime(const CFX_Unitime& dt);
+  FX_BOOL SetDateTime(const CFX_WideString& wsDateTime,
+                      const CFX_WideString& wsFormat,
+                      IFX_Locale* pLocale);
+  bool IsNull() const { return m_dwType == XFA_VT_NULL; }
+  FX_BOOL IsEmpty() const { return m_wsValue.IsEmpty(); }
+  FX_BOOL IsValid() const { return m_bValid; }
+
+ protected:
+  FX_BOOL ParsePatternValue(const CFX_WideString& wsValue,
+                            const CFX_WideString& wsPattern,
+                            IFX_Locale* pLocale);
+  CXFA_LocaleMgr* m_pLocaleMgr;
+  CFX_WideString m_wsValue;
+  FX_DWORD m_dwType;
+  FX_BOOL m_bValid;
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_LOCALEVALUE_H_
diff --git a/xfa/fxfa/parser/xfa_object.h b/xfa/fxfa/parser/xfa_object.h
new file mode 100644
index 0000000..1dba001
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_object.h
@@ -0,0 +1,803 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_OBJECT_H_
+#define XFA_FXFA_PARSER_XFA_OBJECT_H_
+
+#include "xfa/fde/xml/fde_xml.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+class CXFA_Document;
+class CXFA_Node;
+class CXFA_NodeList;
+class CXFA_OrdinaryObject;
+
+enum XFA_OBJECTTYPE {
+  XFA_OBJECTTYPE_OrdinaryObject = 0x0,
+  XFA_OBJECTTYPE_OrdinaryList = 0x1,
+  XFA_OBJECTTYPE_NodeList = 0x2,
+  XFA_OBJECTTYPE_Node = 0x4,
+  XFA_OBJECTTYPE_NodeC = 0x5,
+  XFA_OBJECTTYPE_NodeV = 0x6,
+  XFA_OBJECTTYPE_ModelNode = 0x8,
+  XFA_OBJECTTYPE_TextNode = 0x9,
+  XFA_OBJECTTYPE_ContainerNode = 0xA,
+  XFA_OBJECTTYPE_ContentNode = 0xB,
+  XFA_OBJECTTYPE_VariablesThis = 0xC,
+  XFA_OBJECTTYPEMASK = 0xF,
+  XFA_NODEFLAG_Initialized = 0x00020,
+  XFA_NODEFLAG_HasRemoved = 0x00200,
+  XFA_NODEFLAG_NeedsInitApp = 0x00400,
+  XFA_NODEFLAG_BindFormItems = 0x00800,
+  XFA_NODEFLAG_UserInteractive = 0x01000,
+  XFA_NODEFLAG_SkipDataBinding = 0x02000,
+  XFA_NODEFLAG_OwnXMLNode = 0x04000,
+  XFA_NODEFLAG_UnusedNode = 0x08000,
+  XFA_NODEFLAG_LayoutGeneratedNode = 0x10000,
+};
+class CXFA_Object {
+ public:
+  CXFA_Object(CXFA_Document* pDocument, FX_DWORD uFlags);
+  CXFA_Document* GetDocument() const { return m_pDocument; }
+  FX_DWORD GetFlag() const { return m_uFlags; }
+  XFA_OBJECTTYPE GetObjectType() const {
+    return (XFA_OBJECTTYPE)(m_uFlags & XFA_OBJECTTYPEMASK);
+  }
+
+  FX_BOOL IsNode() const {
+    return (m_uFlags & XFA_OBJECTTYPEMASK) >= XFA_OBJECTTYPE_Node;
+  }
+  FX_BOOL IsOrdinaryObject() const {
+    return (m_uFlags & XFA_OBJECTTYPEMASK) == XFA_OBJECTTYPE_OrdinaryObject;
+  }
+  FX_BOOL IsNodeList() const {
+    return (m_uFlags & XFA_OBJECTTYPEMASK) == XFA_OBJECTTYPE_NodeList;
+  }
+  FX_BOOL IsOrdinaryList() const {
+    return (m_uFlags & XFA_OBJECTTYPEMASK) == XFA_OBJECTTYPE_OrdinaryList;
+  }
+  FX_BOOL IsContentNode() const {
+    return (m_uFlags & XFA_OBJECTTYPEMASK) == XFA_OBJECTTYPE_ContentNode;
+  }
+  FX_BOOL IsContainerNode() const {
+    return (m_uFlags & XFA_OBJECTTYPEMASK) == XFA_OBJECTTYPE_ContainerNode;
+  }
+
+  CXFA_Node* AsNode();
+  CXFA_OrdinaryObject* AsOrdinaryObject();
+  CXFA_NodeList* AsNodeList();
+
+  const CXFA_Node* AsNode() const;
+  const CXFA_OrdinaryObject* AsOrdinaryObject() const;
+  const CXFA_NodeList* AsNodeList() const;
+
+  XFA_ELEMENT GetClassID() const;
+  void GetClassName(CFX_WideStringC& wsName) const;
+  uint32_t GetClassHashCode() const;
+  void Script_ObjectClass_ClassName(FXJSE_HVALUE hValue,
+                                    FX_BOOL bSetting,
+                                    XFA_ATTRIBUTE eAttribute);
+  void ThrowScriptErrorMessage(int32_t iStringID, ...);
+
+ protected:
+  CXFA_Document* const m_pDocument;
+  FX_DWORD m_uFlags;
+};
+
+#define XFA_NODEFILTER_Children 0x01
+#define XFA_NODEFILTER_Properties 0x02
+#define XFA_NODEFILTER_OneOfProperty 0x04
+#define XFA_CLONEFLAG_Content 0x01
+enum XFA_NODEITEM {
+  XFA_NODEITEM_Parent,
+  XFA_NODEITEM_FirstChild,
+  XFA_NODEITEM_NextSibling,
+  XFA_NODEITEM_PrevSibling,
+};
+enum XFA_SOM_MESSAGETYPE {
+  XFA_SOM_ValidationMessage,
+  XFA_SOM_FormatMessage,
+  XFA_SOM_MandatoryMessage
+};
+
+typedef CFX_ArrayTemplate<CXFA_Node*> CXFA_NodeArray;
+typedef CFX_StackTemplate<CXFA_Node*> CXFA_NodeStack;
+typedef CXFA_PtrSetTemplate<CXFA_Node*> CXFA_NodeSet;
+typedef void (*PD_CALLBACK_DUPLICATEDATA)(void*& pData);
+
+struct XFA_MAPDATABLOCKCALLBACKINFO {
+  PD_CALLBACK_FREEDATA pFree;
+  PD_CALLBACK_DUPLICATEDATA pCopy;
+};
+
+struct XFA_MAPDATABLOCK {
+  uint8_t* GetData() const { return (uint8_t*)this + sizeof(XFA_MAPDATABLOCK); }
+  XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo;
+  int32_t iBytes;
+};
+
+struct XFA_MAPMODULEDATA {
+  CFX_MapPtrToPtr m_ValueMap;
+  CFX_MapPtrTemplate<void*, XFA_MAPDATABLOCK*> m_BufferMap;
+};
+
+#define XFA_CalcRefCount (void*)(uintptr_t) FXBSTR_ID('X', 'F', 'A', 'R')
+#define XFA_CalcData (void*)(uintptr_t) FXBSTR_ID('X', 'F', 'A', 'C')
+#define XFA_LAYOUTITEMKEY (void*)(uintptr_t) FXBSTR_ID('L', 'Y', 'I', 'M')
+class CXFA_Node : public CXFA_Object {
+ public:
+  XFA_ELEMENT GetClassID() const { return (XFA_ELEMENT)m_eNodeClass; }
+  FX_DWORD GetPacketID() const { return m_ePacket; }
+  FX_BOOL HasFlag(FX_DWORD dwFlag) const;
+  void SetFlag(FX_DWORD dwFlag, FX_BOOL bOn = TRUE, FX_BOOL bNotify = TRUE);
+  FX_BOOL IsAttributeInXML();
+  FX_BOOL IsFormContainer() {
+    return m_ePacket == XFA_XDPPACKET_Form && IsContainerNode();
+  }
+  void SetXMLMappingNode(IFDE_XMLNode* pXMLNode) { m_pXMLNode = pXMLNode; }
+  IFDE_XMLNode* GetXMLMappingNode() const { return m_pXMLNode; }
+  IFDE_XMLNode* CreateXMLMappingNode();
+  FX_BOOL IsNeedSavingXMLNode();
+  FX_DWORD GetNameHash() const { return m_dwNameHash; }
+  bool IsUnnamed() const { return m_dwNameHash == 0; }
+  CXFA_Node* GetModelNode();
+  void UpdateNameHash();
+  FX_BOOL HasAttribute(XFA_ATTRIBUTE eAttr, FX_BOOL bCanInherit = FALSE);
+  FX_BOOL SetAttribute(XFA_ATTRIBUTE eAttr,
+                       const CFX_WideStringC& wsValue,
+                       FX_BOOL bNotify = FALSE);
+  FX_BOOL GetAttribute(XFA_ATTRIBUTE eAttr,
+                       CFX_WideString& wsValue,
+                       FX_BOOL bUseDefault = TRUE);
+  FX_BOOL SetAttribute(const CFX_WideStringC& wsAttr,
+                       const CFX_WideStringC& wsValue,
+                       FX_BOOL bNotify = FALSE);
+  FX_BOOL GetAttribute(const CFX_WideStringC& wsAttr,
+                       CFX_WideString& wsValue,
+                       FX_BOOL bUseDefault = TRUE);
+  FX_BOOL RemoveAttribute(const CFX_WideStringC& wsAttr);
+  FX_BOOL SetContent(const CFX_WideString& wsContent,
+                     const CFX_WideString& wsXMLValue,
+                     FX_BOOL bNotify = FALSE,
+                     FX_BOOL bScriptModify = FALSE,
+                     FX_BOOL bSyncData = TRUE);
+  FX_BOOL TryContent(CFX_WideString& wsContent,
+                     FX_BOOL bScriptModify = FALSE,
+                     FX_BOOL bProto = TRUE);
+  CFX_WideString GetContent();
+
+  FX_BOOL TryNamespace(CFX_WideString& wsNamespace);
+
+  FX_BOOL SetBoolean(XFA_ATTRIBUTE eAttr,
+                     FX_BOOL bValue,
+                     FX_BOOL bNotify = FALSE) {
+    return SetValue(eAttr, XFA_ATTRIBUTETYPE_Boolean, (void*)(uintptr_t)bValue,
+                    bNotify);
+  }
+  FX_BOOL TryBoolean(XFA_ATTRIBUTE eAttr,
+                     FX_BOOL& bValue,
+                     FX_BOOL bUseDefault = TRUE);
+  FX_BOOL GetBoolean(XFA_ATTRIBUTE eAttr) {
+    FX_BOOL bValue;
+    return TryBoolean(eAttr, bValue, TRUE) ? bValue : FALSE;
+  }
+  FX_BOOL SetInteger(XFA_ATTRIBUTE eAttr,
+                     int32_t iValue,
+                     FX_BOOL bNotify = FALSE) {
+    return SetValue(eAttr, XFA_ATTRIBUTETYPE_Integer, (void*)(uintptr_t)iValue,
+                    bNotify);
+  }
+  FX_BOOL TryInteger(XFA_ATTRIBUTE eAttr,
+                     int32_t& iValue,
+                     FX_BOOL bUseDefault = TRUE);
+  int32_t GetInteger(XFA_ATTRIBUTE eAttr) {
+    int32_t iValue;
+    return TryInteger(eAttr, iValue, TRUE) ? iValue : 0;
+  }
+  FX_BOOL SetEnum(XFA_ATTRIBUTE eAttr,
+                  XFA_ATTRIBUTEENUM eValue,
+                  FX_BOOL bNotify = FALSE) {
+    return SetValue(eAttr, XFA_ATTRIBUTETYPE_Enum, (void*)(uintptr_t)eValue,
+                    bNotify);
+  }
+  FX_BOOL TryEnum(XFA_ATTRIBUTE eAttr,
+                  XFA_ATTRIBUTEENUM& eValue,
+                  FX_BOOL bUseDefault = TRUE);
+  XFA_ATTRIBUTEENUM GetEnum(XFA_ATTRIBUTE eAttr) {
+    XFA_ATTRIBUTEENUM eValue;
+    return TryEnum(eAttr, eValue, TRUE) ? eValue : XFA_ATTRIBUTEENUM_Unknown;
+  }
+  FX_BOOL SetCData(XFA_ATTRIBUTE eAttr,
+                   const CFX_WideString& wsValue,
+                   FX_BOOL bNotify = FALSE,
+                   FX_BOOL bScriptModify = FALSE);
+  FX_BOOL SetAttributeValue(const CFX_WideString& wsValue,
+                            const CFX_WideString& wsXMLValue,
+                            FX_BOOL bNotify = FALSE,
+                            FX_BOOL bScriptModify = FALSE);
+  FX_BOOL TryCData(XFA_ATTRIBUTE eAttr,
+                   CFX_WideString& wsValue,
+                   FX_BOOL bUseDefault = TRUE,
+                   FX_BOOL bProto = TRUE);
+  FX_BOOL TryCData(XFA_ATTRIBUTE eAttr,
+                   CFX_WideStringC& wsValue,
+                   FX_BOOL bUseDefault = TRUE,
+                   FX_BOOL bProto = TRUE);
+  CFX_WideStringC GetCData(XFA_ATTRIBUTE eAttr) {
+    CFX_WideStringC wsValue;
+    return TryCData(eAttr, wsValue) ? wsValue : CFX_WideStringC();
+  }
+  FX_BOOL SetMeasure(XFA_ATTRIBUTE eAttr,
+                     CXFA_Measurement mValue,
+                     FX_BOOL bNotify = FALSE);
+  FX_BOOL TryMeasure(XFA_ATTRIBUTE eAttr,
+                     CXFA_Measurement& mValue,
+                     FX_BOOL bUseDefault = TRUE) const;
+  CXFA_Measurement GetMeasure(XFA_ATTRIBUTE eAttr) const;
+  FX_BOOL SetObject(XFA_ATTRIBUTE eAttr,
+                    void* pData,
+                    XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo = NULL);
+  FX_BOOL TryObject(XFA_ATTRIBUTE eAttr, void*& pData);
+  void* GetObject(XFA_ATTRIBUTE eAttr) {
+    void* pData;
+    return TryObject(eAttr, pData) ? pData : NULL;
+  }
+  FX_BOOL SetUserData(void* pKey,
+                      void* pData,
+                      XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo = NULL);
+  FX_BOOL TryUserData(void* pKey, void*& pData, FX_BOOL bProtoAlso = FALSE);
+  void* GetUserData(void* pKey, FX_BOOL bProtoAlso = FALSE) {
+    void* pData;
+    return TryUserData(pKey, pData, bProtoAlso) ? pData : NULL;
+  }
+  CXFA_Node* GetProperty(int32_t index,
+                         XFA_ELEMENT eProperty,
+                         FX_BOOL bCreateProperty = TRUE);
+  int32_t CountChildren(XFA_ELEMENT eElement, FX_BOOL bOnlyChild = FALSE);
+  CXFA_Node* GetChild(int32_t index,
+                      XFA_ELEMENT eElement,
+                      FX_BOOL bOnlyChild = FALSE);
+  int32_t InsertChild(int32_t index, CXFA_Node* pNode);
+  FX_BOOL InsertChild(CXFA_Node* pNode, CXFA_Node* pBeforeNode = NULL);
+  FX_BOOL RemoveChild(CXFA_Node* pNode, FX_BOOL bNotify = TRUE);
+  CXFA_Node* Clone(FX_BOOL bRecursive);
+  CXFA_Node* GetNodeItem(XFA_NODEITEM eItem) const;
+  CXFA_Node* GetNodeItem(XFA_NODEITEM eItem, XFA_OBJECTTYPE eType) const;
+  int32_t GetNodeList(CXFA_NodeArray& nodes,
+                      FX_DWORD dwTypeFilter = XFA_NODEFILTER_Children |
+                                              XFA_NODEFILTER_Properties,
+                      XFA_ELEMENT eElementFilter = XFA_ELEMENT_UNKNOWN,
+                      int32_t iLevel = 1);
+  CXFA_Node* CreateSamePacketNode(XFA_ELEMENT eElement,
+                                  FX_DWORD dwFlags = XFA_NODEFLAG_Initialized);
+  CXFA_Node* CloneTemplateToForm(FX_BOOL bRecursive);
+  CXFA_Node* GetTemplateNode() const;
+  void SetTemplateNode(CXFA_Node* pTemplateNode);
+  CXFA_Node* GetDataDescriptionNode();
+  void SetDataDescriptionNode(CXFA_Node* pDataDescriptionNode);
+  CXFA_Node* GetBindData();
+  int32_t GetBindItems(CXFA_NodeArray& formItems);
+  int32_t AddBindItem(CXFA_Node* pFormNode);
+  int32_t RemoveBindItem(CXFA_Node* pFormNode);
+  FX_BOOL HasBindItem();
+  CXFA_WidgetData* GetWidgetData();
+  CXFA_WidgetData* GetContainerWidgetData();
+  FX_BOOL GetLocaleName(CFX_WideString& wsLocaleName);
+  XFA_ATTRIBUTEENUM GetIntact();
+  CXFA_Node* GetFirstChildByName(const CFX_WideStringC& wsNodeName) const;
+  CXFA_Node* GetFirstChildByName(FX_DWORD dwNodeNameHash) const;
+  CXFA_Node* GetFirstChildByClass(XFA_ELEMENT eNodeClass) const;
+  CXFA_Node* GetNextSameNameSibling(FX_DWORD dwNodeNameHash) const;
+  CXFA_Node* GetNextSameNameSibling(const CFX_WideStringC& wsNodeName) const;
+  CXFA_Node* GetNextSameClassSibling(XFA_ELEMENT eNodeClass) const;
+  int32_t GetNodeSameNameIndex() const;
+  int32_t GetNodeSameClassIndex() const;
+  void GetSOMExpression(CFX_WideString& wsSOMExpression);
+  CXFA_Node* GetInstanceMgrOfSubform();
+
+  CXFA_Node* GetOccurNode();
+  void Script_TreeClass_ResolveNode(CFXJSE_Arguments* pArguments);
+  void Script_TreeClass_ResolveNodes(CFXJSE_Arguments* pArguments);
+  void Script_Som_ResolveNodeList(FXJSE_HVALUE hValue,
+                                  CFX_WideString wsExpression,
+                                  FX_DWORD dwFlag,
+                                  CXFA_Node* refNode = NULL);
+  void Script_TreeClass_All(FXJSE_HVALUE hValue,
+                            FX_BOOL bSetting,
+                            XFA_ATTRIBUTE eAttribute);
+  void Script_TreeClass_Nodes(FXJSE_HVALUE hValue,
+                              FX_BOOL bSetting,
+                              XFA_ATTRIBUTE eAttribute);
+  void Script_TreeClass_ClassAll(FXJSE_HVALUE hValue,
+                                 FX_BOOL bSetting,
+                                 XFA_ATTRIBUTE eAttribute);
+  void Script_TreeClass_Parent(FXJSE_HVALUE hValue,
+                               FX_BOOL bSetting,
+                               XFA_ATTRIBUTE eAttribute);
+  void Script_TreeClass_Index(FXJSE_HVALUE hValue,
+                              FX_BOOL bSetting,
+                              XFA_ATTRIBUTE eAttribute);
+  void Script_TreeClass_ClassIndex(FXJSE_HVALUE hValue,
+                                   FX_BOOL bSetting,
+                                   XFA_ATTRIBUTE eAttribute);
+  void Script_TreeClass_SomExpression(FXJSE_HVALUE hValue,
+                                      FX_BOOL bSetting,
+                                      XFA_ATTRIBUTE eAttribute);
+  void Script_NodeClass_ApplyXSL(CFXJSE_Arguments* pArguments);
+  void Script_NodeClass_AssignNode(CFXJSE_Arguments* pArguments);
+  void Script_NodeClass_Clone(CFXJSE_Arguments* pArguments);
+  void Script_NodeClass_GetAttribute(CFXJSE_Arguments* pArguments);
+  void Script_NodeClass_GetElement(CFXJSE_Arguments* pArguments);
+  void Script_NodeClass_IsPropertySpecified(CFXJSE_Arguments* pArguments);
+  void Script_NodeClass_LoadXML(CFXJSE_Arguments* pArguments);
+  void Script_NodeClass_SaveFilteredXML(CFXJSE_Arguments* pArguments);
+  void Script_NodeClass_SaveXML(CFXJSE_Arguments* pArguments);
+  void Script_NodeClass_SetAttribute(CFXJSE_Arguments* pArguments);
+  void Script_NodeClass_SetElement(CFXJSE_Arguments* pArguments);
+  void Script_NodeClass_Ns(FXJSE_HVALUE hValue,
+                           FX_BOOL bSetting,
+                           XFA_ATTRIBUTE eAttribute);
+  void Script_NodeClass_Model(FXJSE_HVALUE hValue,
+                              FX_BOOL bSetting,
+                              XFA_ATTRIBUTE eAttribute);
+  void Script_NodeClass_IsContainer(FXJSE_HVALUE hValue,
+                                    FX_BOOL bSetting,
+                                    XFA_ATTRIBUTE eAttribute);
+  void Script_NodeClass_IsNull(FXJSE_HVALUE hValue,
+                               FX_BOOL bSetting,
+                               XFA_ATTRIBUTE eAttribute);
+  void Script_NodeClass_OneOfChild(FXJSE_HVALUE hValue,
+                                   FX_BOOL bSetting,
+                                   XFA_ATTRIBUTE eAttribute);
+  void Script_ContainerClass_GetDelta(CFXJSE_Arguments* pArguments);
+  void Script_ContainerClass_GetDeltas(CFXJSE_Arguments* pArguments);
+  void Script_ModelClass_ClearErrorList(CFXJSE_Arguments* pArguments);
+  void Script_ModelClass_CreateNode(CFXJSE_Arguments* pArguments);
+  void Script_ModelClass_IsCompatibleNS(CFXJSE_Arguments* pArguments);
+  void Script_ModelClass_Context(FXJSE_HVALUE hValue,
+                                 FX_BOOL bSetting,
+                                 XFA_ATTRIBUTE eAttribute);
+  void Script_ModelClass_AliasNode(FXJSE_HVALUE hValue,
+                                   FX_BOOL bSetting,
+                                   XFA_ATTRIBUTE eAttribute);
+  void Script_WsdlConnection_Execute(CFXJSE_Arguments* pArguments);
+  void Script_Delta_Restore(CFXJSE_Arguments* pArguments);
+  void Script_Delta_CurrentValue(FXJSE_HVALUE hValue,
+                                 FX_BOOL bSetting,
+                                 XFA_ATTRIBUTE eAttribute);
+  void Script_Delta_SavedValue(FXJSE_HVALUE hValue,
+                               FX_BOOL bSetting,
+                               XFA_ATTRIBUTE eAttribute);
+  void Script_Delta_Target(FXJSE_HVALUE hValue,
+                           FX_BOOL bSetting,
+                           XFA_ATTRIBUTE eAttribute);
+  void Script_Attribute_SendAttributeChangeMessage(void* eAttribute,
+                                                   void* eValue,
+                                                   FX_BOOL bScriptModify);
+  void Script_Attribute_Integer(FXJSE_HVALUE hValue,
+                                FX_BOOL bSetting,
+                                XFA_ATTRIBUTE eAttribute);
+  void Script_Attribute_IntegerRead(FXJSE_HVALUE hValue,
+                                    FX_BOOL bSetting,
+                                    XFA_ATTRIBUTE eAttribute);
+  void Script_Attribute_BOOL(FXJSE_HVALUE hValue,
+                             FX_BOOL bSetting,
+                             XFA_ATTRIBUTE eAttribute);
+  void Script_Attribute_BOOLRead(FXJSE_HVALUE hValue,
+                                 FX_BOOL bSetting,
+                                 XFA_ATTRIBUTE eAttribute);
+  void Script_Attribute_String(FXJSE_HVALUE hValue,
+                               FX_BOOL bSetting,
+                               XFA_ATTRIBUTE eAttribute);
+  void Script_Attribute_StringRead(FXJSE_HVALUE hValue,
+                                   FX_BOOL bSetting,
+                                   XFA_ATTRIBUTE eAttribute);
+  void Script_Som_ValidationMessage(FXJSE_HVALUE hValue,
+                                    FX_BOOL bSetting,
+                                    XFA_ATTRIBUTE eAttribute);
+  void Script_Field_Length(FXJSE_HVALUE hValue,
+                           FX_BOOL bSetting,
+                           XFA_ATTRIBUTE eAttribute);
+  void Script_Som_DefaultValue(FXJSE_HVALUE hValue,
+                               FX_BOOL bSetting,
+                               XFA_ATTRIBUTE eAttribute);
+  void Script_Som_DefaultValue_Read(FXJSE_HVALUE hValue,
+                                    FX_BOOL bSetting,
+                                    XFA_ATTRIBUTE eAttribute);
+  void Script_Boolean_Value(FXJSE_HVALUE hValue,
+                            FX_BOOL bSetting,
+                            XFA_ATTRIBUTE eAttribute);
+  void Script_Som_Message(FXJSE_HVALUE hValue,
+                          FX_BOOL bSetting,
+                          XFA_SOM_MESSAGETYPE iMessageType);
+  void Script_Som_BorderColor(FXJSE_HVALUE hValue,
+                              FX_BOOL bSetting,
+                              XFA_ATTRIBUTE eAttribute);
+  void Script_Som_BorderWidth(FXJSE_HVALUE hValue,
+                              FX_BOOL bSetting,
+                              XFA_ATTRIBUTE eAttribute);
+  void Script_Som_FillColor(FXJSE_HVALUE hValue,
+                            FX_BOOL bSetting,
+                            XFA_ATTRIBUTE eAttribute);
+  void Script_Som_DataNode(FXJSE_HVALUE hValue,
+                           FX_BOOL bSetting,
+                           XFA_ATTRIBUTE eAttribute);
+  void Script_Som_FontColor(FXJSE_HVALUE hValue,
+                            FX_BOOL bSetting,
+                            XFA_ATTRIBUTE eAttribute);
+  void Script_Som_Mandatory(FXJSE_HVALUE hValue,
+                            FX_BOOL bSetting,
+                            XFA_ATTRIBUTE eAttribute);
+  void Script_Som_MandatoryMessage(FXJSE_HVALUE hValue,
+                                   FX_BOOL bSetting,
+                                   XFA_ATTRIBUTE eAttribute);
+  void Script_Som_InstanceIndex(FXJSE_HVALUE hValue,
+                                FX_BOOL bSetting,
+                                XFA_ATTRIBUTE eAttribute);
+  void Script_Draw_DefaultValue(FXJSE_HVALUE hValue,
+                                FX_BOOL bSetting,
+                                XFA_ATTRIBUTE eAttribute);
+  void Script_Field_DefaultValue(FXJSE_HVALUE hValue,
+                                 FX_BOOL bSetting,
+                                 XFA_ATTRIBUTE eAttribute);
+  void Script_Field_EditValue(FXJSE_HVALUE hValue,
+                              FX_BOOL bSetting,
+                              XFA_ATTRIBUTE eAttribute);
+  void Script_Field_FormatMessage(FXJSE_HVALUE hValue,
+                                  FX_BOOL bSetting,
+                                  XFA_ATTRIBUTE eAttribute);
+  void Script_Field_FormattedValue(FXJSE_HVALUE hValue,
+                                   FX_BOOL bSetting,
+                                   XFA_ATTRIBUTE eAttribute);
+  void Script_Field_ParentSubform(FXJSE_HVALUE hValue,
+                                  FX_BOOL bSetting,
+                                  XFA_ATTRIBUTE eAttribute);
+  void Script_Field_SelectedIndex(FXJSE_HVALUE hValue,
+                                  FX_BOOL bSetting,
+                                  XFA_ATTRIBUTE eAttribute);
+  void Script_Field_ClearItems(CFXJSE_Arguments* pArguments);
+  void Script_Field_ExecEvent(CFXJSE_Arguments* pArguments);
+  void Script_Field_ExecInitialize(CFXJSE_Arguments* pArguments);
+  void Script_Field_DeleteItem(CFXJSE_Arguments* pArguments);
+  void Script_Field_GetSaveItem(CFXJSE_Arguments* pArguments);
+  void Script_Field_BoundItem(CFXJSE_Arguments* pArguments);
+  void Script_Field_GetItemState(CFXJSE_Arguments* pArguments);
+  void Script_Field_ExecCalculate(CFXJSE_Arguments* pArguments);
+  void Script_Field_SetItems(CFXJSE_Arguments* pArguments);
+  void Script_Field_GetDisplayItem(CFXJSE_Arguments* pArguments);
+  void Script_Field_SetItemState(CFXJSE_Arguments* pArguments);
+  void Script_Field_AddItem(CFXJSE_Arguments* pArguments);
+  void Script_Field_ExecValidate(CFXJSE_Arguments* pArguments);
+  void Script_ExclGroup_DefaultAndRawValue(FXJSE_HVALUE hValue,
+                                           FX_BOOL bSetting,
+                                           XFA_ATTRIBUTE eAttribute);
+  void Script_ExclGroup_ErrorText(FXJSE_HVALUE hValue,
+                                  FX_BOOL bSetting,
+                                  XFA_ATTRIBUTE eAttribute);
+  void Script_ExclGroup_Transient(FXJSE_HVALUE hValue,
+                                  FX_BOOL bSetting,
+                                  XFA_ATTRIBUTE eAttribute);
+  void Script_ExclGroup_ExecEvent(CFXJSE_Arguments* pArguments);
+  void Script_ExclGroup_SelectedMember(CFXJSE_Arguments* pArguments);
+  void Script_ExclGroup_ExecInitialize(CFXJSE_Arguments* pArguments);
+  void Script_ExclGroup_ExecCalculate(CFXJSE_Arguments* pArguments);
+  void Script_ExclGroup_ExecValidate(CFXJSE_Arguments* pArguments);
+  void Script_Subform_InstanceManager(FXJSE_HVALUE hValue,
+                                      FX_BOOL bSetting,
+                                      XFA_ATTRIBUTE eAttribute);
+  void Script_Subform_Locale(FXJSE_HVALUE hValue,
+                             FX_BOOL bSetting,
+                             XFA_ATTRIBUTE eAttribute);
+  void Script_Subform_ExecEvent(CFXJSE_Arguments* pArguments);
+  void Script_Subform_ExecInitialize(CFXJSE_Arguments* pArguments);
+  void Script_Subform_ExecCalculate(CFXJSE_Arguments* pArguments);
+  void Script_Subform_ExecValidate(CFXJSE_Arguments* pArguments);
+  void Script_Subform_GetInvalidObjects(CFXJSE_Arguments* pArguments);
+
+  int32_t Subform_and_SubformSet_InstanceIndex();
+  void Script_Template_FormNodes(CFXJSE_Arguments* pArguments);
+  void Script_Template_Remerge(CFXJSE_Arguments* pArguments);
+  void Script_Template_ExecInitialize(CFXJSE_Arguments* pArguments);
+  void Script_Template_CreateNode(CFXJSE_Arguments* pArguments);
+  void Script_Template_Recalculate(CFXJSE_Arguments* pArguments);
+  void Script_Template_ExecCalculate(CFXJSE_Arguments* pArguments);
+  void Script_Template_ExecValidate(CFXJSE_Arguments* pArguments);
+  void Script_Manifest_Evaluate(CFXJSE_Arguments* pArguments);
+  void Script_InstanceManager_Count(FXJSE_HVALUE hValue,
+                                    FX_BOOL bSetting,
+                                    XFA_ATTRIBUTE eAttribute);
+  void Script_InstanceManager_Max(FXJSE_HVALUE hValue,
+                                  FX_BOOL bSetting,
+                                  XFA_ATTRIBUTE eAttribute);
+  void Script_InstanceManager_Min(FXJSE_HVALUE hValue,
+                                  FX_BOOL bSetting,
+                                  XFA_ATTRIBUTE eAttribute);
+  void Script_InstanceManager_MoveInstance(CFXJSE_Arguments* pArguments);
+  void Script_InstanceManager_RemoveInstance(CFXJSE_Arguments* pArguments);
+  void Script_InstanceManager_SetInstances(CFXJSE_Arguments* pArguments);
+  void Script_InstanceManager_AddInstance(CFXJSE_Arguments* pArguments);
+  void Script_InstanceManager_InsertInstance(CFXJSE_Arguments* pArguments);
+  int32_t InstanceManager_SetInstances(int32_t iCount);
+  int32_t InstanceManager_MoveInstance(int32_t iTo, int32_t iFrom);
+  void Script_Occur_Max(FXJSE_HVALUE hValue,
+                        FX_BOOL bSetting,
+                        XFA_ATTRIBUTE eAttribute);
+  void Script_Occur_Min(FXJSE_HVALUE hValue,
+                        FX_BOOL bSetting,
+                        XFA_ATTRIBUTE eAttribute);
+  void Script_Desc_Metadata(CFXJSE_Arguments* pArguments);
+  void Script_Form_FormNodes(CFXJSE_Arguments* pArguments);
+  void Script_Form_Remerge(CFXJSE_Arguments* pArguments);
+  void Script_Form_ExecInitialize(CFXJSE_Arguments* pArguments);
+  void Script_Form_Recalculate(CFXJSE_Arguments* pArguments);
+  void Script_Form_ExecCalculate(CFXJSE_Arguments* pArguments);
+  void Script_Form_ExecValidate(CFXJSE_Arguments* pArguments);
+  void Script_Form_Checksum(FXJSE_HVALUE hValue,
+                            FX_BOOL bSetting,
+                            XFA_ATTRIBUTE eAttribute);
+  void Script_Packet_GetAttribute(CFXJSE_Arguments* pArguments);
+  void Script_Packet_SetAttribute(CFXJSE_Arguments* pArguments);
+  void Script_Packet_RemoveAttribute(CFXJSE_Arguments* pArguments);
+  void Script_Packet_Content(FXJSE_HVALUE hValue,
+                             FX_BOOL bSetting,
+                             XFA_ATTRIBUTE eAttribute);
+  void Script_Source_Next(CFXJSE_Arguments* pArguments);
+  void Script_Source_CancelBatch(CFXJSE_Arguments* pArguments);
+  void Script_Source_First(CFXJSE_Arguments* pArguments);
+  void Script_Source_UpdateBatch(CFXJSE_Arguments* pArguments);
+  void Script_Source_Previous(CFXJSE_Arguments* pArguments);
+  void Script_Source_IsBOF(CFXJSE_Arguments* pArguments);
+  void Script_Source_IsEOF(CFXJSE_Arguments* pArguments);
+  void Script_Source_Cancel(CFXJSE_Arguments* pArguments);
+  void Script_Source_Update(CFXJSE_Arguments* pArguments);
+  void Script_Source_Open(CFXJSE_Arguments* pArguments);
+  void Script_Source_Delete(CFXJSE_Arguments* pArguments);
+  void Script_Source_AddNew(CFXJSE_Arguments* pArguments);
+  void Script_Source_Requery(CFXJSE_Arguments* pArguments);
+  void Script_Source_Resync(CFXJSE_Arguments* pArguments);
+  void Script_Source_Close(CFXJSE_Arguments* pArguments);
+  void Script_Source_Last(CFXJSE_Arguments* pArguments);
+  void Script_Source_HasDataChanged(CFXJSE_Arguments* pArguments);
+  void Script_Source_Db(FXJSE_HVALUE hValue,
+                        FX_BOOL bSetting,
+                        XFA_ATTRIBUTE eAttribute);
+  void Script_Xfa_This(FXJSE_HVALUE hValue,
+                       FX_BOOL bSetting,
+                       XFA_ATTRIBUTE eAttribute);
+  void Script_Handler_Version(FXJSE_HVALUE hValue,
+                              FX_BOOL bSetting,
+                              XFA_ATTRIBUTE eAttribute);
+  void Script_SubmitFormat_Mode(FXJSE_HVALUE hValue,
+                                FX_BOOL bSetting,
+                                XFA_ATTRIBUTE eAttribute);
+  void Script_Extras_Type(FXJSE_HVALUE hValue,
+                          FX_BOOL bSetting,
+                          XFA_ATTRIBUTE eAttribute);
+  void Script_Encrypt_Format(FXJSE_HVALUE hValue,
+                             FX_BOOL bSetting,
+                             XFA_ATTRIBUTE eAttribute);
+  void Script_Script_Stateless(FXJSE_HVALUE hValue,
+                               FX_BOOL bSetting,
+                               XFA_ATTRIBUTE eAttribute);
+
+ protected:
+  CXFA_Node(CXFA_Document* pDoc, FX_WORD ePacket, XFA_ELEMENT eElement);
+  ~CXFA_Node();
+  friend class CXFA_Document;
+  CXFA_Node* Deprecated_GetPrevSibling();
+  FX_BOOL SetValue(XFA_ATTRIBUTE eAttr,
+                   XFA_ATTRIBUTETYPE eType,
+                   void* pValue,
+                   FX_BOOL bNotify);
+  FX_BOOL GetValue(XFA_ATTRIBUTE eAttr,
+                   XFA_ATTRIBUTETYPE eType,
+                   FX_BOOL bUseDefault,
+                   void*& pValue);
+  void OnRemoved(CXFA_Node* pParent, CXFA_Node* pRemoved, FX_BOOL bNotify);
+  void OnChanging(XFA_ATTRIBUTE eAttr, void* pNewValue, FX_BOOL bNotify);
+  void OnChanged(XFA_ATTRIBUTE eAttr,
+                 void* pNewValue,
+                 FX_BOOL bNotify,
+                 FX_BOOL bScriptModify = FALSE);
+  int32_t execSingleEventByName(const CFX_WideStringC& wsEventName,
+                                XFA_ELEMENT eElementType);
+  FX_BOOL SetScriptContent(const CFX_WideString& wsContent,
+                           const CFX_WideString& wsXMLValue,
+                           FX_BOOL bNotify = TRUE,
+                           FX_BOOL bScriptModify = FALSE,
+                           FX_BOOL bSyncData = TRUE);
+  CFX_WideString GetScriptContent(FX_BOOL bScriptModify = FALSE);
+  XFA_MAPMODULEDATA* CreateMapModuleData();
+  XFA_MAPMODULEDATA* GetMapModuleData() const;
+  void SetMapModuleValue(void* pKey, void* pValue);
+  FX_BOOL GetMapModuleValue(void* pKey, void*& pValue);
+  void SetMapModuleString(void* pKey, const CFX_WideStringC& wsValue);
+  FX_BOOL GetMapModuleString(void* pKey, CFX_WideStringC& wsValue);
+  void SetMapModuleBuffer(void* pKey,
+                          void* pValue,
+                          int32_t iBytes,
+                          XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo = NULL);
+  FX_BOOL GetMapModuleBuffer(void* pKey,
+                             void*& pValue,
+                             int32_t& iBytes,
+                             FX_BOOL bProtoAlso = TRUE) const;
+  FX_BOOL HasMapModuleKey(void* pKey, FX_BOOL bProtoAlso = FALSE);
+  void RemoveMapModuleKey(void* pKey = NULL);
+  void MergeAllData(void* pDstModule, FX_BOOL bUseSrcAttr = TRUE);
+  void MoveBufferMapData(CXFA_Node* pDstModule, void* pKey);
+  void MoveBufferMapData(CXFA_Node* pSrcModule,
+                         CXFA_Node* pDstModule,
+                         void* pKey,
+                         FX_BOOL bRecursive = FALSE);
+
+  CXFA_Node* m_pNext;
+  CXFA_Node* m_pChild;
+  CXFA_Node* m_pLastChild;
+  CXFA_Node* m_pParent;
+  IFDE_XMLNode* m_pXMLNode;
+  XFA_ELEMENT m_eNodeClass;
+  FX_WORD m_ePacket;
+  FX_DWORD m_dwNameHash;
+  CXFA_Node* m_pAuxNode;
+  XFA_MAPMODULEDATA* m_pMapModuleData;
+};
+class CXFA_OrdinaryObject : public CXFA_Object {
+ public:
+  CXFA_OrdinaryObject(CXFA_Document* pDocument, XFA_ELEMENT eElement)
+      : CXFA_Object(pDocument, XFA_OBJECTTYPE_OrdinaryObject),
+        m_uScriptHash(0) {
+    m_eNodeClass = eElement;
+  }
+  XFA_ELEMENT GetClassID() const { return (XFA_ELEMENT)m_eNodeClass; }
+  uint32_t GetScriptObjHash() { return m_uScriptHash; }
+
+ protected:
+  XFA_ELEMENT m_eNodeClass;
+  uint32_t m_uScriptHash;
+};
+class CXFA_ThisProxy : public CXFA_Object {
+ public:
+  CXFA_ThisProxy(CXFA_Node* pThisNode, CXFA_Node* pScriptNode)
+      : CXFA_Object(pThisNode->GetDocument(), XFA_OBJECTTYPE_VariablesThis),
+        m_pThisNode(NULL),
+        m_pScriptNode(NULL) {
+    m_pThisNode = pThisNode;
+    m_pScriptNode = pScriptNode;
+  }
+  virtual ~CXFA_ThisProxy() {}
+  CXFA_Node* GetThisNode() { return m_pThisNode; }
+  CXFA_Node* GetScriptNode() { return m_pScriptNode; }
+
+ private:
+  CXFA_Node* m_pThisNode;
+  CXFA_Node* m_pScriptNode;
+};
+class CXFA_NodeList : public CXFA_Object {
+ public:
+  explicit CXFA_NodeList(CXFA_Document* pDocument);
+  virtual ~CXFA_NodeList() {}
+  XFA_ELEMENT GetClassID() const { return XFA_ELEMENT_NodeList; }
+  CXFA_Node* NamedItem(const CFX_WideStringC& wsName);
+  virtual int32_t GetLength() = 0;
+  virtual FX_BOOL Append(CXFA_Node* pNode) = 0;
+  virtual FX_BOOL Insert(CXFA_Node* pNewNode, CXFA_Node* pBeforeNode) = 0;
+  virtual FX_BOOL Remove(CXFA_Node* pNode) = 0;
+  virtual CXFA_Node* Item(int32_t iIndex) = 0;
+
+  void Script_ListClass_Append(CFXJSE_Arguments* pArguments);
+  void Script_ListClass_Insert(CFXJSE_Arguments* pArguments);
+  void Script_ListClass_Remove(CFXJSE_Arguments* pArguments);
+  void Script_ListClass_Item(CFXJSE_Arguments* pArguments);
+
+  void Script_TreelistClass_NamedItem(CFXJSE_Arguments* pArguments);
+  void Script_ListClass_Length(FXJSE_HVALUE hValue,
+                               FX_BOOL bSetting,
+                               XFA_ATTRIBUTE eAttribute);
+};
+class CXFA_ArrayNodeList : public CXFA_NodeList {
+ public:
+  explicit CXFA_ArrayNodeList(CXFA_Document* pDocument);
+  void SetArrayNodeList(const CXFA_NodeArray& srcArray);
+  virtual int32_t GetLength();
+  virtual FX_BOOL Append(CXFA_Node* pNode);
+  virtual FX_BOOL Insert(CXFA_Node* pNewNode, CXFA_Node* pBeforeNode);
+  virtual FX_BOOL Remove(CXFA_Node* pNode);
+  virtual CXFA_Node* Item(int32_t iIndex);
+
+ protected:
+  CXFA_NodeArray m_array;
+};
+class CXFA_AttachNodeList : public CXFA_NodeList {
+ public:
+  CXFA_AttachNodeList(CXFA_Document* pDocument, CXFA_Node* pAttachNode);
+
+  virtual int32_t GetLength();
+  virtual FX_BOOL Append(CXFA_Node* pNode);
+  virtual FX_BOOL Insert(CXFA_Node* pNewNode, CXFA_Node* pBeforeNode);
+  virtual FX_BOOL Remove(CXFA_Node* pNode);
+  virtual CXFA_Node* Item(int32_t iIndex);
+
+ protected:
+  CXFA_Node* m_pAttachNode;
+};
+class CXFA_TraverseStrategy_XFAContainerNode {
+ public:
+  static CXFA_Node* GetFirstChild(CXFA_Node* pTemplateNode,
+                                  void* pUserData = NULL) {
+    return pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild,
+                                      XFA_OBJECTTYPE_ContainerNode);
+  }
+  static CXFA_Node* GetNextSibling(CXFA_Node* pTemplateNode,
+                                   void* pUserData = NULL) {
+    return pTemplateNode->GetNodeItem(XFA_NODEITEM_NextSibling,
+                                      XFA_OBJECTTYPE_ContainerNode);
+  }
+  static CXFA_Node* GetParent(CXFA_Node* pTemplateNode,
+                              void* pUserData = NULL) {
+    return pTemplateNode->GetNodeItem(XFA_NODEITEM_Parent,
+                                      XFA_OBJECTTYPE_ContainerNode);
+  }
+};
+typedef CXFA_NodeIteratorTemplate<CXFA_Node,
+                                  CXFA_TraverseStrategy_XFAContainerNode>
+    CXFA_ContainerIterator;
+class CXFA_TraverseStrategy_XFANode {
+ public:
+  static inline CXFA_Node* GetFirstChild(CXFA_Node* pTemplateNode) {
+    return pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+  }
+  static inline CXFA_Node* GetNextSibling(CXFA_Node* pTemplateNode) {
+    return pTemplateNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+  }
+  static inline CXFA_Node* GetParent(CXFA_Node* pTemplateNode) {
+    return pTemplateNode->GetNodeItem(XFA_NODEITEM_Parent);
+  }
+};
+typedef CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode>
+    CXFA_NodeIterator;
+
+inline CXFA_Node* CXFA_Object::AsNode() {
+  return IsNode() ? static_cast<CXFA_Node*>(this) : nullptr;
+}
+inline CXFA_OrdinaryObject* CXFA_Object::AsOrdinaryObject() {
+  return IsOrdinaryObject() ? static_cast<CXFA_OrdinaryObject*>(this) : nullptr;
+}
+inline CXFA_NodeList* CXFA_Object::AsNodeList() {
+  return IsNodeList() ? static_cast<CXFA_NodeList*>(this) : nullptr;
+}
+
+inline const CXFA_Node* CXFA_Object::AsNode() const {
+  return IsNode() ? static_cast<const CXFA_Node*>(this) : nullptr;
+}
+inline const CXFA_OrdinaryObject* CXFA_Object::AsOrdinaryObject() const {
+  return IsOrdinaryObject() ? static_cast<const CXFA_OrdinaryObject*>(this)
+                            : nullptr;
+}
+inline const CXFA_NodeList* CXFA_Object::AsNodeList() const {
+  return IsNodeList() ? static_cast<const CXFA_NodeList*>(this) : nullptr;
+}
+
+inline CXFA_Node* ToNode(CXFA_Object* pObj) {
+  return pObj ? pObj->AsNode() : nullptr;
+}
+inline CXFA_OrdinaryObject* ToOrdinaryObject(CXFA_Object* pObj) {
+  return pObj ? pObj->AsOrdinaryObject() : nullptr;
+}
+inline CXFA_NodeList* ToNodeList(CXFA_Object* pObj) {
+  return pObj ? pObj->AsNodeList() : nullptr;
+}
+
+inline const CXFA_Node* ToNode(const CXFA_Object* pObj) {
+  return pObj ? pObj->AsNode() : nullptr;
+}
+inline const CXFA_OrdinaryObject* ToOrdinaryObject(const CXFA_Object* pObj) {
+  return pObj ? pObj->AsOrdinaryObject() : nullptr;
+}
+inline const CXFA_NodeList* ToNodeList(const CXFA_Object* pObj) {
+  return pObj ? pObj->AsNodeList() : nullptr;
+}
+
+#endif  // XFA_FXFA_PARSER_XFA_OBJECT_H_
diff --git a/xfa/fxfa/parser/xfa_object_imp.cpp b/xfa/fxfa/parser/xfa_object_imp.cpp
new file mode 100644
index 0000000..83bf800
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_object_imp.cpp
@@ -0,0 +1,5408 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_object.h"
+
+#include "core/include/fxcrt/fx_ext.h"
+#include "xfa/fgas/crt/fgas_codepage.h"
+#include "xfa/fgas/crt/fgas_system.h"
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_basic_imp.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_document_layout_imp.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+CXFA_Object::CXFA_Object(CXFA_Document* pDocument, FX_DWORD uFlags)
+    : m_pDocument(pDocument), m_uFlags(uFlags) {}
+void CXFA_Object::GetClassName(CFX_WideStringC& wsName) const {
+  wsName = XFA_GetElementByID(GetClassID())->pName;
+}
+uint32_t CXFA_Object::GetClassHashCode() const {
+  return XFA_GetElementByID(GetClassID())->uHash;
+}
+XFA_ELEMENT CXFA_Object::GetClassID() const {
+  if (IsNode()) {
+    return AsNode()->GetClassID();
+  }
+  if (IsOrdinaryObject()) {
+    return AsOrdinaryObject()->GetClassID();
+  }
+  if (IsNodeList()) {
+    return AsNodeList()->GetClassID();
+  }
+  if (IsOrdinaryList()) {
+    return XFA_ELEMENT_List;
+  }
+  ASSERT(FALSE);
+  return (XFA_ELEMENT)0;
+}
+void CXFA_Object::Script_ObjectClass_ClassName(FXJSE_HVALUE hValue,
+                                               FX_BOOL bSetting,
+                                               XFA_ATTRIBUTE eAttribute) {
+  if (!bSetting) {
+    CFX_WideStringC className;
+    GetClassName(className);
+    FXJSE_Value_SetUTF8String(
+        hValue, FX_UTF8Encode(className.GetPtr(), className.GetLength()));
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  }
+}
+void CXFA_Object::ThrowScriptErrorMessage(int32_t iStringID, ...) {
+  IXFA_AppProvider* pAppProvider = m_pDocument->GetNotify()->GetAppProvider();
+  FXSYS_assert(pAppProvider);
+  CFX_WideString wsFormat;
+  pAppProvider->LoadString(iStringID, wsFormat);
+  CFX_WideString wsMessage;
+  va_list arg_ptr;
+  va_start(arg_ptr, iStringID);
+  wsMessage.FormatV((const FX_WCHAR*)wsFormat, arg_ptr);
+  va_end(arg_ptr);
+  FXJSE_ThrowMessage("", FX_UTF8Encode(wsMessage, wsMessage.GetLength()));
+}
+
+static void XFA_DeleteWideString(void* pData) {
+  delete static_cast<CFX_WideString*>(pData);
+}
+
+static void XFA_CopyWideString(void*& pData) {
+  if (pData) {
+    CFX_WideString* pNewData = new CFX_WideString(*(CFX_WideString*)pData);
+    pData = pNewData;
+  }
+}
+static XFA_MAPDATABLOCKCALLBACKINFO deleteWideStringCallBack = {
+    XFA_DeleteWideString, XFA_CopyWideString};
+static XFA_OBJECTTYPE XFA_GetElementObjectType(XFA_ELEMENT eElement) {
+  return (XFA_OBJECTTYPE)XFA_GetElementByID(eElement)->eObjectType;
+}
+CXFA_Node::CXFA_Node(CXFA_Document* pDoc, FX_WORD ePacket, XFA_ELEMENT eElement)
+    : CXFA_Object(pDoc, XFA_GetElementObjectType(eElement)),
+      m_pNext(nullptr),
+      m_pChild(nullptr),
+      m_pLastChild(nullptr),
+      m_pParent(nullptr),
+      m_pXMLNode(nullptr),
+      m_eNodeClass(eElement),
+      m_ePacket(ePacket),
+      m_dwNameHash(0),
+      m_pAuxNode(nullptr),
+      m_pMapModuleData(nullptr) {
+  ASSERT(m_pDocument);
+}
+CXFA_Node::~CXFA_Node() {
+  FXSYS_assert(m_pParent == NULL);
+  RemoveMapModuleKey();
+  CXFA_Node *pNext, *pNode = m_pChild;
+  while (pNode) {
+    pNext = pNode->m_pNext;
+    pNode->m_pParent = NULL;
+    delete pNode;
+    pNode = pNext;
+  }
+  if (m_pXMLNode && HasFlag(XFA_NODEFLAG_OwnXMLNode)) {
+    m_pXMLNode->Release();
+  }
+}
+CXFA_Node* CXFA_Node::Clone(FX_BOOL bRecursive) {
+  IXFA_ObjFactory* pFactory = m_pDocument->GetParser()->GetFactory();
+  CXFA_Node* pClone = pFactory->CreateNode(m_ePacket, m_eNodeClass);
+  if (!pClone) {
+    return NULL;
+  }
+  MergeAllData(pClone);
+  pClone->UpdateNameHash();
+  if (IsNeedSavingXMLNode()) {
+    IFDE_XMLNode* pCloneXML = NULL;
+    if (IsAttributeInXML()) {
+      CFX_WideString wsName;
+      GetAttribute(XFA_ATTRIBUTE_Name, wsName, FALSE);
+      IFDE_XMLElement* pCloneXMLElement = IFDE_XMLElement::Create(wsName);
+      CFX_WideStringC wsValue = GetCData(XFA_ATTRIBUTE_Value);
+      if (!wsValue.IsEmpty()) {
+        pCloneXMLElement->SetTextData(wsValue);
+      }
+      pCloneXML = pCloneXMLElement;
+      pCloneXMLElement = NULL;
+      pClone->SetEnum(XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTEENUM_Unknown);
+    } else {
+      pCloneXML = m_pXMLNode->Clone(FALSE);
+    }
+    pClone->SetXMLMappingNode(pCloneXML);
+    pClone->SetFlag(XFA_NODEFLAG_OwnXMLNode, TRUE, FALSE);
+  }
+  if (bRecursive) {
+    for (CXFA_Node* pChild = GetNodeItem(XFA_NODEITEM_FirstChild); pChild;
+         pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+      pClone->InsertChild(pChild->Clone(bRecursive));
+    }
+  }
+  pClone->SetFlag(XFA_NODEFLAG_Initialized);
+  pClone->SetObject(XFA_ATTRIBUTE_BindingNode, NULL);
+  return pClone;
+}
+CXFA_Node* CXFA_Node::GetNodeItem(XFA_NODEITEM eItem) const {
+  switch (eItem) {
+    case XFA_NODEITEM_NextSibling:
+      return m_pNext;
+    case XFA_NODEITEM_FirstChild:
+      return m_pChild;
+    case XFA_NODEITEM_Parent:
+      return m_pParent;
+    case XFA_NODEITEM_PrevSibling:
+      if (m_pParent) {
+        CXFA_Node* pSibling = m_pParent->m_pChild;
+        CXFA_Node* pPrev = NULL;
+        while (pSibling && pSibling != this) {
+          pPrev = pSibling;
+          pSibling = pSibling->m_pNext;
+        }
+        return pPrev;
+      }
+      return NULL;
+    default:
+      break;
+  }
+  return NULL;
+}
+CXFA_Node* CXFA_Node::GetNodeItem(XFA_NODEITEM eItem,
+                                  XFA_OBJECTTYPE eType) const {
+  CXFA_Node* pNode = NULL;
+  switch (eItem) {
+    case XFA_NODEITEM_NextSibling:
+      pNode = m_pNext;
+      if (eType != XFA_OBJECTTYPEMASK) {
+        while (pNode && pNode->GetObjectType() != eType) {
+          pNode = pNode->m_pNext;
+        }
+      }
+      break;
+    case XFA_NODEITEM_FirstChild:
+      pNode = m_pChild;
+      if (eType != XFA_OBJECTTYPEMASK) {
+        while (pNode && pNode->GetObjectType() != eType) {
+          pNode = pNode->m_pNext;
+        }
+      }
+      break;
+    case XFA_NODEITEM_Parent:
+      pNode = m_pParent;
+      if (eType != XFA_OBJECTTYPEMASK) {
+        while (pNode && pNode->GetObjectType() != eType) {
+          pNode = pNode->m_pParent;
+        }
+      }
+      break;
+    case XFA_NODEITEM_PrevSibling:
+      if (m_pParent) {
+        CXFA_Node* pSibling = m_pParent->m_pChild;
+        while (pSibling && pSibling != this) {
+          if (eType == XFA_OBJECTTYPEMASK ||
+              eType == pSibling->GetObjectType()) {
+            pNode = pSibling;
+          }
+          pSibling = pSibling->m_pNext;
+        }
+      }
+      break;
+    default:
+      break;
+  }
+  return pNode;
+}
+int32_t CXFA_Node::GetNodeList(CXFA_NodeArray& nodes,
+                               FX_DWORD dwTypeFilter,
+                               XFA_ELEMENT eElementFilter,
+                               int32_t iLevel) {
+  if (--iLevel < 0) {
+    return nodes.GetSize();
+  }
+  if (eElementFilter != XFA_ELEMENT_UNKNOWN) {
+    CXFA_Node* pChild = m_pChild;
+    while (pChild) {
+      if (pChild->GetClassID() == eElementFilter) {
+        nodes.Add(pChild);
+        if (iLevel > 0) {
+          GetNodeList(nodes, dwTypeFilter, eElementFilter, iLevel);
+        }
+      }
+      pChild = pChild->m_pNext;
+    }
+  } else if (dwTypeFilter ==
+             (XFA_NODEFILTER_Children | XFA_NODEFILTER_Properties)) {
+    CXFA_Node* pChild = m_pChild;
+    while (pChild) {
+      nodes.Add(pChild);
+      if (iLevel > 0) {
+        GetNodeList(nodes, dwTypeFilter, eElementFilter, iLevel);
+      }
+      pChild = pChild->m_pNext;
+    }
+  } else if (dwTypeFilter != 0) {
+    FX_BOOL bFilterChildren = (dwTypeFilter & XFA_NODEFILTER_Children) != 0;
+    FX_BOOL bFilterProperties = (dwTypeFilter & XFA_NODEFILTER_Properties) != 0;
+    FX_BOOL bFilterOneOfProperties =
+        (dwTypeFilter & XFA_NODEFILTER_OneOfProperty) != 0;
+    CXFA_Node* pChild = m_pChild;
+    while (pChild) {
+      const XFA_PROPERTY* pProperty = XFA_GetPropertyOfElement(
+          GetClassID(), pChild->GetClassID(), XFA_XDPPACKET_UNKNOWN);
+      if (pProperty) {
+        if (bFilterProperties) {
+          nodes.Add(pChild);
+        } else if (bFilterOneOfProperties &&
+                   (pProperty->uFlags & XFA_PROPERTYFLAG_OneOf)) {
+          nodes.Add(pChild);
+        } else if (bFilterChildren &&
+                   (pChild->GetClassID() == XFA_ELEMENT_Variables ||
+                    pChild->GetClassID() == XFA_ELEMENT_PageSet)) {
+          nodes.Add(pChild);
+        }
+      } else {
+        if (bFilterChildren) {
+          nodes.Add(pChild);
+        }
+      }
+      pChild = pChild->m_pNext;
+    }
+    if (bFilterOneOfProperties && nodes.GetSize() < 1) {
+      int32_t iProperties = 0;
+      const XFA_PROPERTY* pProperty =
+          XFA_GetElementProperties(GetClassID(), iProperties);
+      if (pProperty == NULL || iProperties < 1) {
+        return 0;
+      }
+      for (int32_t i = 0; i < iProperties; i++) {
+        if (pProperty[i].uFlags & XFA_PROPERTYFLAG_DefaultOneOf) {
+          IXFA_ObjFactory* pFactory = m_pDocument->GetParser()->GetFactory();
+          const XFA_PACKETINFO* pPacket = XFA_GetPacketByID(GetPacketID());
+          CXFA_Node* pNewNode =
+              pFactory->CreateNode(pPacket, (XFA_ELEMENT)pProperty[i].eName);
+          if (!pNewNode) {
+            break;
+          }
+          InsertChild(pNewNode, NULL);
+          pNewNode->SetFlag(XFA_NODEFLAG_Initialized);
+          nodes.Add(pNewNode);
+          break;
+        }
+      }
+    }
+  }
+  return nodes.GetSize();
+}
+CXFA_Node* CXFA_Node::CreateSamePacketNode(XFA_ELEMENT eElement,
+                                           FX_DWORD dwFlags) {
+  IXFA_ObjFactory* pFactory = m_pDocument->GetParser()->GetFactory();
+  CXFA_Node* pNode = pFactory->CreateNode(m_ePacket, eElement);
+  pNode->SetFlag(dwFlags);
+  return pNode;
+}
+CXFA_Node* CXFA_Node::CloneTemplateToForm(FX_BOOL bRecursive) {
+  FXSYS_assert(m_ePacket == XFA_XDPPACKET_Template);
+  IXFA_ObjFactory* pFactory = m_pDocument->GetParser()->GetFactory();
+  CXFA_Node* pClone = pFactory->CreateNode(XFA_XDPPACKET_Form, m_eNodeClass);
+  if (!pClone) {
+    return NULL;
+  }
+  pClone->SetTemplateNode(this);
+  pClone->UpdateNameHash();
+  pClone->SetXMLMappingNode(GetXMLMappingNode());
+  if (bRecursive) {
+    for (CXFA_Node* pChild = GetNodeItem(XFA_NODEITEM_FirstChild); pChild;
+         pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+      pClone->InsertChild(pChild->CloneTemplateToForm(bRecursive));
+    }
+  }
+  pClone->SetFlag(XFA_NODEFLAG_Initialized);
+  return pClone;
+}
+
+CXFA_Node* CXFA_Node::GetTemplateNode() const {
+  return m_pAuxNode;
+}
+
+void CXFA_Node::SetTemplateNode(CXFA_Node* pTemplateNode) {
+  m_pAuxNode = pTemplateNode;
+}
+CXFA_Node* CXFA_Node::GetBindData() {
+  ASSERT(GetPacketID() == XFA_XDPPACKET_Form);
+  return static_cast<CXFA_Node*>(GetObject(XFA_ATTRIBUTE_BindingNode));
+}
+int32_t CXFA_Node::GetBindItems(CXFA_NodeArray& formItems) {
+  if (m_uFlags & XFA_NODEFLAG_BindFormItems) {
+    CXFA_NodeArray* pItems = NULL;
+    TryObject(XFA_ATTRIBUTE_BindingNode, (void*&)pItems);
+    formItems.Copy(*pItems);
+    return formItems.GetSize();
+  }
+  CXFA_Node* pFormNode =
+      static_cast<CXFA_Node*>(GetObject(XFA_ATTRIBUTE_BindingNode));
+  if (pFormNode) {
+    formItems.Add(pFormNode);
+  }
+  return formItems.GetSize();
+}
+
+static void XFA_DataNodeDeleteBindItem(void* pData) {
+  delete static_cast<CXFA_NodeArray*>(pData);
+}
+
+static XFA_MAPDATABLOCKCALLBACKINFO deleteBindItemCallBack = {
+    XFA_DataNodeDeleteBindItem, NULL};
+int32_t CXFA_Node::AddBindItem(CXFA_Node* pFormNode) {
+  ASSERT(pFormNode);
+  if (m_uFlags & XFA_NODEFLAG_BindFormItems) {
+    CXFA_NodeArray* pItems = NULL;
+    TryObject(XFA_ATTRIBUTE_BindingNode, (void*&)pItems);
+    ASSERT(pItems);
+    if (pItems->Find(pFormNode) < 0) {
+      pItems->Add(pFormNode);
+    }
+    return pItems->GetSize();
+  }
+  CXFA_Node* pOldFormItem =
+      static_cast<CXFA_Node*>(GetObject(XFA_ATTRIBUTE_BindingNode));
+  if (!pOldFormItem) {
+    SetObject(XFA_ATTRIBUTE_BindingNode, pFormNode);
+    return 1;
+  } else if (pOldFormItem == pFormNode) {
+    return 1;
+  }
+  CXFA_NodeArray* pItems = new CXFA_NodeArray;
+  SetObject(XFA_ATTRIBUTE_BindingNode, pItems, &deleteBindItemCallBack);
+  pItems->Add(pOldFormItem);
+  pItems->Add(pFormNode);
+  m_uFlags |= XFA_NODEFLAG_BindFormItems;
+  return 2;
+}
+int32_t CXFA_Node::RemoveBindItem(CXFA_Node* pFormNode) {
+  if (m_uFlags & XFA_NODEFLAG_BindFormItems) {
+    CXFA_NodeArray* pItems = NULL;
+    TryObject(XFA_ATTRIBUTE_BindingNode, (void*&)pItems);
+    ASSERT(pItems);
+    int32_t iIndex = pItems->Find(pFormNode);
+    int32_t iCount = pItems->GetSize();
+    if (iIndex >= 0) {
+      if (iIndex != iCount - 1) {
+        pItems->SetAt(iIndex, pItems->GetAt(iCount - 1));
+      }
+      pItems->RemoveAt(iCount - 1);
+      if (iCount == 2) {
+        CXFA_Node* pLastFormNode = pItems->GetAt(0);
+        SetObject(XFA_ATTRIBUTE_BindingNode, pLastFormNode);
+        m_uFlags &= ~XFA_NODEFLAG_BindFormItems;
+      }
+      iCount--;
+    }
+    return iCount;
+  }
+  CXFA_Node* pOldFormItem =
+      static_cast<CXFA_Node*>(GetObject(XFA_ATTRIBUTE_BindingNode));
+  if (pOldFormItem == pFormNode) {
+    SetObject(XFA_ATTRIBUTE_BindingNode, NULL);
+    pOldFormItem = NULL;
+  }
+  return pOldFormItem == NULL ? 0 : 1;
+}
+FX_BOOL CXFA_Node::HasBindItem() {
+  return (GetPacketID() == XFA_XDPPACKET_Datasets) &&
+         GetObject(XFA_ATTRIBUTE_BindingNode) != NULL;
+}
+CXFA_WidgetData* CXFA_Node::GetWidgetData() {
+  return (CXFA_WidgetData*)GetObject(XFA_ATTRIBUTE_WidgetData);
+}
+CXFA_WidgetData* CXFA_Node::GetContainerWidgetData() {
+  if (GetPacketID() != XFA_XDPPACKET_Form) {
+    return NULL;
+  }
+  XFA_ELEMENT classID = GetClassID();
+  if (classID == XFA_ELEMENT_ExclGroup) {
+    return NULL;
+  }
+  CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
+  if (pParentNode && pParentNode->GetClassID() == XFA_ELEMENT_ExclGroup) {
+    return NULL;
+  }
+  if (classID == XFA_ELEMENT_Field) {
+    CXFA_WidgetData* pFieldWidgetData = GetWidgetData();
+    if (pFieldWidgetData &&
+        pFieldWidgetData->GetChoiceListOpen() ==
+            XFA_ATTRIBUTEENUM_MultiSelect) {
+      return NULL;
+    } else {
+      CFX_WideString wsPicture;
+      if (pFieldWidgetData) {
+        pFieldWidgetData->GetPictureContent(wsPicture,
+                                            XFA_VALUEPICTURE_DataBind);
+      }
+      if (!wsPicture.IsEmpty()) {
+        return pFieldWidgetData;
+      }
+      CXFA_Node* pDataNode = GetBindData();
+      if (!pDataNode) {
+        return NULL;
+      }
+      pFieldWidgetData = NULL;
+      CXFA_NodeArray formNodes;
+      pDataNode->GetBindItems(formNodes);
+      for (int32_t i = 0; i < formNodes.GetSize(); i++) {
+        CXFA_Node* pFormNode = formNodes.GetAt(i);
+        if (!pFormNode || pFormNode->HasFlag(XFA_NODEFLAG_HasRemoved)) {
+          continue;
+        }
+        pFieldWidgetData = pFormNode->GetWidgetData();
+        if (pFieldWidgetData) {
+          pFieldWidgetData->GetPictureContent(wsPicture,
+                                              XFA_VALUEPICTURE_DataBind);
+        }
+        if (!wsPicture.IsEmpty()) {
+          break;
+        }
+        pFieldWidgetData = NULL;
+      }
+      return pFieldWidgetData;
+    }
+  }
+  CXFA_Node* pGrandNode =
+      pParentNode ? pParentNode->GetNodeItem(XFA_NODEITEM_Parent) : NULL;
+  CXFA_Node* pValueNode =
+      (pParentNode && pParentNode->GetClassID() == XFA_ELEMENT_Value)
+          ? pParentNode
+          : NULL;
+  if (!pValueNode) {
+    pValueNode = (pGrandNode && pGrandNode->GetClassID() == XFA_ELEMENT_Value)
+                     ? pGrandNode
+                     : NULL;
+  }
+  CXFA_Node* pParentOfValueNode =
+      pValueNode ? pValueNode->GetNodeItem(XFA_NODEITEM_Parent) : NULL;
+  return pParentOfValueNode ? pParentOfValueNode->GetContainerWidgetData()
+                            : NULL;
+}
+FX_BOOL CXFA_Node::GetLocaleName(CFX_WideString& wsLocaleName) {
+  CXFA_Node* pForm = GetDocument()->GetXFAObject(XFA_HASHCODE_Form)->AsNode();
+  CXFA_Node* pTopSubform = pForm->GetFirstChildByClass(XFA_ELEMENT_Subform);
+  FXSYS_assert(pTopSubform);
+  CXFA_Node* pLocaleNode = this;
+  FX_BOOL bLocale = FALSE;
+  do {
+    bLocale = pLocaleNode->TryCData(XFA_ATTRIBUTE_Locale, wsLocaleName, FALSE);
+    if (!bLocale) {
+      pLocaleNode = pLocaleNode->GetNodeItem(XFA_NODEITEM_Parent);
+    }
+  } while (pLocaleNode && pLocaleNode != pTopSubform && !bLocale);
+  if (bLocale) {
+    return bLocale;
+  }
+  CXFA_Node* pConfig = ToNode(GetDocument()->GetXFAObject(XFA_HASHCODE_Config));
+  wsLocaleName = GetDocument()->GetLocalMgr()->GetConfigLocaleName(pConfig);
+  if (!wsLocaleName.IsEmpty()) {
+    bLocale = TRUE;
+  }
+  if (bLocale) {
+    return bLocale;
+  }
+  if (pTopSubform) {
+    bLocale = pTopSubform->TryCData(XFA_ATTRIBUTE_Locale, wsLocaleName, FALSE);
+  }
+  if (bLocale) {
+    return bLocale;
+  }
+  IFX_Locale* pLocale = GetDocument()->GetLocalMgr()->GetDefLocale();
+  if (pLocale) {
+    wsLocaleName = pLocale->GetName();
+    bLocale = TRUE;
+  }
+  return bLocale;
+}
+XFA_ATTRIBUTEENUM CXFA_Node::GetIntact() {
+  XFA_ELEMENT eElement = GetClassID();
+  CXFA_Node* pKeep = GetFirstChildByClass(XFA_ELEMENT_Keep);
+  XFA_ATTRIBUTEENUM eLayoutType = GetEnum(XFA_ATTRIBUTE_Layout);
+  if (pKeep) {
+    XFA_ATTRIBUTEENUM eIntact;
+    if (pKeep->TryEnum(XFA_ATTRIBUTE_Intact, eIntact, FALSE)) {
+      if (eIntact == XFA_ATTRIBUTEENUM_None &&
+          eLayoutType == XFA_ATTRIBUTEENUM_Row &&
+          m_pDocument->GetCurVersionMode() < XFA_VERSION_208) {
+        CXFA_Node* pPreviewRow =
+            GetNodeItem(XFA_NODEITEM_PrevSibling, XFA_OBJECTTYPE_ContainerNode);
+        if (pPreviewRow &&
+            pPreviewRow->GetEnum(XFA_ATTRIBUTE_Layout) ==
+                XFA_ATTRIBUTEENUM_Row) {
+          XFA_ATTRIBUTEENUM eValue;
+          if (pKeep->TryEnum(XFA_ATTRIBUTE_Previous, eValue, FALSE)) {
+            if (eValue == XFA_ATTRIBUTEENUM_ContentArea ||
+                eValue == XFA_ATTRIBUTEENUM_PageArea) {
+              return XFA_ATTRIBUTEENUM_ContentArea;
+            }
+          }
+          CXFA_Node* pKeep =
+              pPreviewRow->GetFirstChildByClass(XFA_ELEMENT_Keep);
+          if (pKeep) {
+            if (pKeep->TryEnum(XFA_ATTRIBUTE_Next, eValue, FALSE)) {
+              if (eValue == XFA_ATTRIBUTEENUM_ContentArea ||
+                  eValue == XFA_ATTRIBUTEENUM_PageArea) {
+                return XFA_ATTRIBUTEENUM_ContentArea;
+              }
+            }
+          }
+        }
+      }
+      return eIntact;
+    }
+  }
+  switch (eElement) {
+    case XFA_ELEMENT_Subform:
+      switch (eLayoutType) {
+        case XFA_ATTRIBUTEENUM_Position:
+        case XFA_ATTRIBUTEENUM_Row:
+          return XFA_ATTRIBUTEENUM_ContentArea;
+        case XFA_ATTRIBUTEENUM_Tb:
+        case XFA_ATTRIBUTEENUM_Table:
+        case XFA_ATTRIBUTEENUM_Lr_tb:
+        case XFA_ATTRIBUTEENUM_Rl_tb:
+          return XFA_ATTRIBUTEENUM_None;
+        default:
+          break;
+      }
+      break;
+    case XFA_ELEMENT_Field: {
+      CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
+      if (!pParentNode || pParentNode->GetClassID() == XFA_ELEMENT_PageArea) {
+        return XFA_ATTRIBUTEENUM_ContentArea;
+      }
+      if (pParentNode->GetIntact() == XFA_ATTRIBUTEENUM_None) {
+        XFA_ATTRIBUTEENUM eParLayout =
+            pParentNode->GetEnum(XFA_ATTRIBUTE_Layout);
+        if (eParLayout == XFA_ATTRIBUTEENUM_Position ||
+            eParLayout == XFA_ATTRIBUTEENUM_Row ||
+            eParLayout == XFA_ATTRIBUTEENUM_Table) {
+          return XFA_ATTRIBUTEENUM_None;
+        }
+        XFA_VERSION version = m_pDocument->GetCurVersionMode();
+        if (eParLayout == XFA_ATTRIBUTEENUM_Tb && version < XFA_VERSION_208) {
+          CXFA_Measurement measureH;
+          if (TryMeasure(XFA_ATTRIBUTE_H, measureH, FALSE)) {
+            return XFA_ATTRIBUTEENUM_ContentArea;
+          }
+        }
+        return XFA_ATTRIBUTEENUM_None;
+      }
+      return XFA_ATTRIBUTEENUM_ContentArea;
+    }
+    case XFA_ELEMENT_Draw:
+      return XFA_ATTRIBUTEENUM_ContentArea;
+    default:
+      break;
+  }
+  return XFA_ATTRIBUTEENUM_None;
+}
+CXFA_Node* CXFA_Node::GetDataDescriptionNode() {
+  if (m_ePacket == XFA_XDPPACKET_Datasets) {
+    return m_pAuxNode;
+  }
+  return NULL;
+}
+void CXFA_Node::SetDataDescriptionNode(CXFA_Node* pDataDescriptionNode) {
+  FXSYS_assert(m_ePacket == XFA_XDPPACKET_Datasets);
+  m_pAuxNode = pDataDescriptionNode;
+}
+void CXFA_Node::Script_TreeClass_ResolveNode(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"resolveNode");
+    return;
+  }
+  CFX_WideString wsExpression;
+  CFX_ByteString bsExpression = pArguments->GetUTF8String(0);
+  wsExpression =
+      CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+  IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+  if (!pScriptContext) {
+    return;
+  }
+  CXFA_Node* refNode = this;
+  if (refNode->GetClassID() == XFA_ELEMENT_Xfa) {
+    refNode = ToNode(pScriptContext->GetThisObject());
+  }
+  FX_DWORD dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
+                    XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
+                    XFA_RESOLVENODE_Siblings;
+  XFA_RESOLVENODE_RS resoveNodeRS;
+  int32_t iRet = pScriptContext->ResolveObjects(refNode, wsExpression,
+                                                resoveNodeRS, dwFlag);
+  if (iRet < 1) {
+    return FXJSE_Value_SetNull(pArguments->GetReturnValue());
+  }
+  FXJSE_HVALUE hValue = NULL;
+  if (resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
+    CXFA_Object* pNode = resoveNodeRS.nodes[0];
+    hValue = pScriptContext->GetJSValueFromMap(pNode);
+    FXJSE_Value_Set(pArguments->GetReturnValue(), hValue);
+  } else {
+    const XFA_SCRIPTATTRIBUTEINFO* lpAttributeInfo =
+        resoveNodeRS.pScriptAttribute;
+    if (lpAttributeInfo && lpAttributeInfo->eValueType == XFA_SCRIPT_Object) {
+      hValue = FXJSE_Value_Create(pScriptContext->GetRuntime());
+      (resoveNodeRS.nodes[0]->*(lpAttributeInfo->lpfnCallback))(
+          hValue, FALSE, (XFA_ATTRIBUTE)lpAttributeInfo->eAttribute);
+      FXJSE_Value_Set(pArguments->GetReturnValue(), hValue);
+      FXJSE_Value_Release(hValue);
+    } else {
+      FXJSE_Value_SetNull(pArguments->GetReturnValue());
+    }
+  }
+}
+void CXFA_Node::Script_TreeClass_ResolveNodes(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"resolveNodes");
+    return;
+  }
+  CFX_WideString wsExpression;
+  CFX_ByteString bsExpression = pArguments->GetUTF8String(0);
+  wsExpression =
+      CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (!hValue) {
+    return;
+  }
+  FX_DWORD dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
+                    XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
+                    XFA_RESOLVENODE_Siblings;
+  CXFA_Node* refNode = this;
+  if (refNode->GetClassID() == XFA_ELEMENT_Xfa) {
+    refNode = ToNode(m_pDocument->GetScriptContext()->GetThisObject());
+  }
+  Script_Som_ResolveNodeList(hValue, wsExpression, dwFlag, refNode);
+}
+void CXFA_Node::Script_Som_ResolveNodeList(FXJSE_HVALUE hValue,
+                                           CFX_WideString wsExpression,
+                                           FX_DWORD dwFlag,
+                                           CXFA_Node* refNode) {
+  IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+  if (!pScriptContext) {
+    return;
+  }
+  XFA_RESOLVENODE_RS resoveNodeRS;
+  if (refNode == NULL) {
+    refNode = this;
+  }
+  pScriptContext->ResolveObjects(refNode, wsExpression, resoveNodeRS, dwFlag);
+  CXFA_ArrayNodeList* pNodeList = new CXFA_ArrayNodeList(m_pDocument);
+  if (resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
+    for (int32_t i = 0; i < resoveNodeRS.nodes.GetSize(); i++) {
+      if (resoveNodeRS.nodes[i]->IsNode())
+        pNodeList->Append(resoveNodeRS.nodes[i]->AsNode());
+    }
+  } else {
+    CXFA_HVALUEArray hValueArray(pScriptContext->GetRuntime());
+    if (resoveNodeRS.GetAttributeResult(hValueArray) > 0) {
+      CXFA_ObjArray objectArray;
+      hValueArray.GetAttributeObject(objectArray);
+      for (int32_t i = 0; i < objectArray.GetSize(); i++) {
+        if (objectArray[i]->IsNode())
+          pNodeList->Append(objectArray[i]->AsNode());
+      }
+    }
+  }
+  FXJSE_Value_SetObject(hValue, (CXFA_Object*)pNodeList,
+                        pScriptContext->GetJseNormalClass());
+}
+void CXFA_Node::Script_TreeClass_All(FXJSE_HVALUE hValue,
+                                     FX_BOOL bSetting,
+                                     XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  } else {
+    FX_DWORD dwFlag = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_ALL;
+    CFX_WideString wsName;
+    GetAttribute(XFA_ATTRIBUTE_Name, wsName);
+    CFX_WideString wsExpression = wsName + FX_WSTRC(L"[*]");
+    Script_Som_ResolveNodeList(hValue, wsExpression, dwFlag);
+  }
+}
+void CXFA_Node::Script_TreeClass_Nodes(FXJSE_HVALUE hValue,
+                                       FX_BOOL bSetting,
+                                       XFA_ATTRIBUTE eAttribute) {
+  IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+  if (!pScriptContext) {
+    return;
+  }
+  if (bSetting) {
+    IXFA_AppProvider* pAppProvider = m_pDocument->GetNotify()->GetAppProvider();
+    FXSYS_assert(pAppProvider);
+    CFX_WideString wsMessage;
+    pAppProvider->LoadString(XFA_IDS_Unable_TO_SET, wsMessage);
+    FXJSE_ThrowMessage("", FX_UTF8Encode(wsMessage, wsMessage.GetLength()));
+  } else {
+    CXFA_AttachNodeList* pNodeList = new CXFA_AttachNodeList(m_pDocument, this);
+    FXJSE_Value_SetObject(hValue, (CXFA_Object*)pNodeList,
+                          pScriptContext->GetJseNormalClass());
+  }
+}
+void CXFA_Node::Script_TreeClass_ClassAll(FXJSE_HVALUE hValue,
+                                          FX_BOOL bSetting,
+                                          XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  } else {
+    FX_DWORD dwFlag = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_ALL;
+    CFX_WideStringC wsName;
+    GetClassName(wsName);
+    CFX_WideString wsExpression = FX_WSTRC(L"#") + wsName + FX_WSTRC(L"[*]");
+    Script_Som_ResolveNodeList(hValue, wsExpression, dwFlag);
+  }
+}
+void CXFA_Node::Script_TreeClass_Parent(FXJSE_HVALUE hValue,
+                                        FX_BOOL bSetting,
+                                        XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  } else {
+    CXFA_Node* pParent = GetNodeItem(XFA_NODEITEM_Parent);
+    if (pParent) {
+      FXJSE_Value_Set(
+          hValue, m_pDocument->GetScriptContext()->GetJSValueFromMap(pParent));
+    } else {
+      FXJSE_Value_SetNull(hValue);
+    }
+  }
+}
+void CXFA_Node::Script_TreeClass_Index(FXJSE_HVALUE hValue,
+                                       FX_BOOL bSetting,
+                                       XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  } else {
+    FXJSE_Value_SetInteger(hValue, GetNodeSameNameIndex());
+  }
+}
+void CXFA_Node::Script_TreeClass_ClassIndex(FXJSE_HVALUE hValue,
+                                            FX_BOOL bSetting,
+                                            XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  } else {
+    FXJSE_Value_SetInteger(hValue, GetNodeSameClassIndex());
+  }
+}
+void CXFA_Node::Script_TreeClass_SomExpression(FXJSE_HVALUE hValue,
+                                               FX_BOOL bSetting,
+                                               XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  } else {
+    CFX_WideString wsSOMExpression;
+    GetSOMExpression(wsSOMExpression);
+    FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsSOMExpression));
+  }
+}
+void CXFA_Node::Script_NodeClass_ApplyXSL(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"applyXSL");
+    return;
+  }
+  CFX_WideString wsExpression;
+  CFX_ByteString bsExpression = pArguments->GetUTF8String(0);
+  wsExpression =
+      CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+}
+void CXFA_Node::Script_NodeClass_AssignNode(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength < 1 || iLength > 3) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"assignNode");
+    return;
+  }
+  CFX_WideString wsExpression;
+  CFX_WideString wsValue;
+  int32_t iAction = 0;
+  if (iLength >= 1) {
+    CFX_ByteString bsExpression = pArguments->GetUTF8String(0);
+    wsExpression =
+        CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+  }
+  if (iLength >= 2) {
+    CFX_ByteString bsValue = pArguments->GetUTF8String(1);
+    wsValue = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+  }
+  if (iLength >= 3) {
+    iAction = pArguments->GetInt32(2);
+  }
+}
+void CXFA_Node::Script_NodeClass_Clone(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"clone");
+    return;
+  }
+  FX_BOOL bClone = TRUE;
+  bClone = pArguments->GetInt32(0) == 0 ? FALSE : TRUE;
+  CXFA_Node* pCloneNode = Clone(bClone);
+  FXJSE_Value_Set(
+      pArguments->GetReturnValue(),
+      m_pDocument->GetScriptContext()->GetJSValueFromMap(pCloneNode));
+}
+void CXFA_Node::Script_NodeClass_GetAttribute(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"getAttribute");
+    return;
+  }
+  CFX_WideString wsExpression;
+  CFX_ByteString bsExpression = pArguments->GetUTF8String(0);
+  wsExpression =
+      CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+  CFX_WideString wsValue;
+  GetAttribute(wsExpression, wsValue);
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsValue));
+  }
+}
+void CXFA_Node::Script_NodeClass_GetElement(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength < 1 || iLength > 2) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"getElement");
+    return;
+  }
+  CFX_WideString wsExpression;
+  int32_t iValue = 0;
+  if (iLength >= 1) {
+    CFX_ByteString bsExpression = pArguments->GetUTF8String(0);
+    wsExpression =
+        CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+  }
+  if (iLength >= 2) {
+    iValue = pArguments->GetInt32(1);
+  }
+  const XFA_ELEMENTINFO* pElementInfo = XFA_GetElementByName(wsExpression);
+  CXFA_Node* pNode = GetProperty(iValue, pElementInfo->eName);
+  FXJSE_Value_Set(pArguments->GetReturnValue(),
+                  m_pDocument->GetScriptContext()->GetJSValueFromMap(pNode));
+}
+void CXFA_Node::Script_NodeClass_IsPropertySpecified(
+    CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength < 1 || iLength > 3) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"isPropertySpecified");
+    return;
+  }
+  CFX_WideString wsExpression;
+  FX_BOOL bParent = TRUE;
+  int32_t iIndex = 0;
+  if (iLength >= 1) {
+    CFX_ByteString bsExpression = pArguments->GetUTF8String(0);
+    wsExpression =
+        CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+  }
+  if (iLength >= 2) {
+    bParent = pArguments->GetInt32(1) == 0 ? FALSE : TRUE;
+  }
+  if (iLength >= 3) {
+    iIndex = pArguments->GetInt32(2);
+  }
+  FX_BOOL bHas = FALSE;
+  const XFA_ATTRIBUTEINFO* pAttributeInfo =
+      XFA_GetAttributeByName(wsExpression);
+  CFX_WideString wsValue;
+  if (pAttributeInfo) {
+    bHas = HasAttribute(pAttributeInfo->eName);
+  }
+  if (!bHas) {
+    const XFA_ELEMENTINFO* pElementInfo = XFA_GetElementByName(wsExpression);
+    bHas = (GetProperty(iIndex, pElementInfo->eName) != NULL);
+  }
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetBoolean(hValue, bHas);
+  }
+}
+void CXFA_Node::Script_NodeClass_LoadXML(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength < 1 || iLength > 3) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"loadXML");
+    return;
+  }
+  CFX_WideString wsExpression;
+  FX_BOOL bIgnoreRoot = TRUE;
+  FX_BOOL bOverwrite = 0;
+  if (iLength >= 1) {
+    CFX_ByteString bsExpression = pArguments->GetUTF8String(0);
+    wsExpression =
+        CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+    if (wsExpression.IsEmpty()) {
+      return;
+    }
+  }
+  if (iLength >= 2) {
+    bIgnoreRoot = pArguments->GetInt32(1) == 0 ? FALSE : TRUE;
+  }
+  if (iLength >= 3) {
+    bOverwrite = pArguments->GetInt32(2) == 0 ? FALSE : TRUE;
+  }
+  IXFA_Parser* pParser = IXFA_Parser::Create(m_pDocument);
+  if (!pParser) {
+    return;
+  }
+  IFDE_XMLNode* pXMLNode = NULL;
+  int32_t iParserStatus = pParser->ParseXMLData(wsExpression, pXMLNode, NULL);
+  if (iParserStatus != XFA_PARSESTATUS_Done || !pXMLNode) {
+    pParser->Release();
+    pParser = NULL;
+    return;
+  }
+  if (bIgnoreRoot && (pXMLNode->GetType() != FDE_XMLNODE_Element ||
+                      XFA_RecognizeRichText((IFDE_XMLElement*)pXMLNode))) {
+    bIgnoreRoot = FALSE;
+  }
+  CXFA_Node* pFakeRoot = Clone(FALSE);
+  CFX_WideStringC wsContentType = GetCData(XFA_ATTRIBUTE_ContentType);
+  if (!wsContentType.IsEmpty()) {
+    pFakeRoot->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
+  }
+  IFDE_XMLNode* pFakeXMLRoot = pFakeRoot->GetXMLMappingNode();
+  if (!pFakeXMLRoot) {
+    IFDE_XMLNode* pThisXMLRoot = GetXMLMappingNode();
+    pFakeXMLRoot = pThisXMLRoot ? pThisXMLRoot->Clone(FALSE) : NULL;
+  }
+  if (!pFakeXMLRoot) {
+    CFX_WideStringC wsClassName;
+    GetClassName(wsClassName);
+    pFakeXMLRoot = IFDE_XMLElement::Create(wsClassName);
+  }
+  if (bIgnoreRoot) {
+    IFDE_XMLNode* pXMLChild = pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild);
+    while (pXMLChild) {
+      IFDE_XMLNode* pXMLSibling =
+          pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling);
+      pXMLNode->RemoveChildNode(pXMLChild);
+      pFakeXMLRoot->InsertChildNode(pXMLChild);
+      pXMLChild = pXMLSibling;
+    }
+  } else {
+    IFDE_XMLNode* pXMLParent = pXMLNode->GetNodeItem(IFDE_XMLNode::Parent);
+    if (pXMLParent) {
+      pXMLParent->RemoveChildNode(pXMLNode);
+    }
+    pFakeXMLRoot->InsertChildNode(pXMLNode);
+  }
+  pParser->ConstructXFANode(pFakeRoot, pFakeXMLRoot);
+  pFakeRoot = pParser->GetRootNode();
+  if (pFakeRoot) {
+    if (bOverwrite) {
+      CXFA_Node* pChild = GetNodeItem(XFA_NODEITEM_FirstChild);
+      CXFA_Node* pNewChild = pFakeRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
+      int32_t index = 0;
+      while (pNewChild) {
+        CXFA_Node* pItem = pNewChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+        pFakeRoot->RemoveChild(pNewChild);
+        InsertChild(index++, pNewChild);
+        pNewChild->SetFlag(XFA_NODEFLAG_Initialized);
+        pNewChild = pItem;
+      }
+      while (pChild) {
+        CXFA_Node* pItem = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+        RemoveChild(pChild);
+        pFakeRoot->InsertChild(pChild);
+        pChild = pItem;
+      }
+      if (GetPacketID() == XFA_XDPPACKET_Form &&
+          GetClassID() == XFA_ELEMENT_ExData) {
+        IFDE_XMLNode* pTempXMLNode = GetXMLMappingNode();
+        SetXMLMappingNode(pFakeXMLRoot);
+        SetFlag(XFA_NODEFLAG_OwnXMLNode, TRUE, FALSE);
+        if (pTempXMLNode &&
+            pTempXMLNode->GetNodeItem(IFDE_XMLNode::Parent) == NULL) {
+          pFakeXMLRoot = pTempXMLNode;
+        } else {
+          pFakeXMLRoot = NULL;
+        }
+      }
+      MoveBufferMapData(pFakeRoot, this, XFA_CalcData, TRUE);
+    } else {
+      CXFA_Node* pChild = pFakeRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
+      while (pChild) {
+        CXFA_Node* pItem = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+        pFakeRoot->RemoveChild(pChild);
+        InsertChild(pChild);
+        pChild->SetFlag(XFA_NODEFLAG_Initialized);
+        pChild = pItem;
+      }
+    }
+    if (pFakeXMLRoot) {
+      pFakeRoot->SetXMLMappingNode(pFakeXMLRoot);
+      pFakeRoot->SetFlag(XFA_NODEFLAG_OwnXMLNode, TRUE, FALSE);
+    }
+    pFakeRoot->SetFlag(XFA_NODEFLAG_HasRemoved, TRUE, FALSE);
+  } else {
+    if (pFakeXMLRoot) {
+      pFakeXMLRoot->Release();
+      pFakeXMLRoot = NULL;
+    }
+  }
+  pParser->Release();
+  pParser = NULL;
+}
+void CXFA_Node::Script_NodeClass_SaveFilteredXML(CFXJSE_Arguments* pArguments) {
+}
+
+void CXFA_Node::Script_NodeClass_SaveXML(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength < 0 || iLength > 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"saveXML");
+    return;
+  }
+  FX_BOOL bPrettyMode = FALSE;
+  if (iLength == 1) {
+    CFX_ByteString bsPretty = pArguments->GetUTF8String(0);
+    if (!bsPretty.Equal("pretty")) {
+      ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+      return;
+    }
+    bPrettyMode = TRUE;
+  }
+  CFX_ByteStringC bsXMLHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+  if (GetPacketID() == XFA_XDPPACKET_Form) {
+    IFX_MemoryStream* pMemoryStream = FX_CreateMemoryStream(TRUE);
+    IFX_Stream* pStream = IFX_Stream::CreateStream(
+        (IFX_FileWrite*)pMemoryStream,
+        FX_STREAMACCESS_Text | FX_STREAMACCESS_Write | FX_STREAMACCESS_Append);
+    if (!pStream) {
+      FXJSE_Value_SetUTF8String(pArguments->GetReturnValue(), bsXMLHeader);
+      pMemoryStream->Release();
+      pMemoryStream = NULL;
+      return;
+    }
+    pStream->SetCodePage(FX_CODEPAGE_UTF8);
+    pStream->WriteData(bsXMLHeader.GetPtr(), bsXMLHeader.GetLength());
+    XFA_DataExporter_RegenerateFormFile(this, pStream, NULL, TRUE);
+    FXJSE_Value_SetUTF8String(
+        pArguments->GetReturnValue(),
+        CFX_ByteStringC(pMemoryStream->GetBuffer(), pMemoryStream->GetSize()));
+    pStream->Release();
+    pStream = NULL;
+    if (pMemoryStream) {
+      pMemoryStream->Release();
+      pMemoryStream = NULL;
+    }
+    return;
+  }
+  if (GetPacketID() == XFA_XDPPACKET_Datasets) {
+    IFDE_XMLNode* pElement = GetXMLMappingNode();
+    if (!pElement || pElement->GetType() != FDE_XMLNODE_Element) {
+      FXJSE_Value_SetUTF8String(pArguments->GetReturnValue(), bsXMLHeader);
+      return;
+    }
+    XFA_DataExporter_DealWithDataGroupNode(this);
+    IFX_MemoryStream* pMemoryStream = FX_CreateMemoryStream(TRUE);
+    IFX_Stream* pStream = IFX_Stream::CreateStream(
+        (IFX_FileWrite*)pMemoryStream,
+        FX_STREAMACCESS_Text | FX_STREAMACCESS_Write | FX_STREAMACCESS_Append);
+    if (pStream) {
+      pStream->SetCodePage(FX_CODEPAGE_UTF8);
+      pStream->WriteData(bsXMLHeader.GetPtr(), bsXMLHeader.GetLength());
+      pElement->SaveXMLNode(pStream);
+      FXJSE_Value_SetUTF8String(pArguments->GetReturnValue(),
+                                CFX_ByteStringC(pMemoryStream->GetBuffer(),
+                                                pMemoryStream->GetSize()));
+      pStream->Release();
+      pStream = NULL;
+    }
+    if (pMemoryStream) {
+      pMemoryStream->Release();
+      pMemoryStream = NULL;
+    }
+    return;
+  }
+  FXJSE_Value_SetUTF8String(pArguments->GetReturnValue(), "");
+}
+
+void CXFA_Node::Script_NodeClass_SetAttribute(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 2) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"setAttribute");
+    return;
+  }
+  CFX_WideString wsAttribute;
+  CFX_WideString wsAttributeValue;
+  CFX_ByteString bsAttributeValue = pArguments->GetUTF8String(0);
+  CFX_ByteString bsAttribute = pArguments->GetUTF8String(1);
+  wsAttributeValue =
+      CFX_WideString::FromUTF8(bsAttributeValue, bsAttributeValue.GetLength());
+  wsAttribute = CFX_WideString::FromUTF8(bsAttribute, bsAttribute.GetLength());
+  SetAttribute(wsAttribute, wsAttributeValue, TRUE);
+}
+void CXFA_Node::Script_NodeClass_SetElement(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 1 && iLength != 2) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"setElement");
+    return;
+  }
+  CXFA_Node* pNode = NULL;
+  CFX_WideString wsName;
+  if (iLength >= 1) {
+    pNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
+  }
+  if (iLength >= 2) {
+    CFX_ByteString bsName = pArguments->GetUTF8String(1);
+    wsName = CFX_WideString::FromUTF8(bsName, bsName.GetLength());
+  }
+}
+void CXFA_Node::Script_NodeClass_Ns(FXJSE_HVALUE hValue,
+                                    FX_BOOL bSetting,
+                                    XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  } else {
+    CFX_WideString wsNameSpace;
+    TryNamespace(wsNameSpace);
+    FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsNameSpace));
+  }
+}
+void CXFA_Node::Script_NodeClass_Model(FXJSE_HVALUE hValue,
+                                       FX_BOOL bSetting,
+                                       XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  } else {
+    FXJSE_Value_Set(hValue, m_pDocument->GetScriptContext()->GetJSValueFromMap(
+                                GetModelNode()));
+  }
+}
+void CXFA_Node::Script_NodeClass_IsContainer(FXJSE_HVALUE hValue,
+                                             FX_BOOL bSetting,
+                                             XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  } else {
+    FXJSE_Value_SetBoolean(hValue, IsContainerNode());
+  }
+}
+void CXFA_Node::Script_NodeClass_IsNull(FXJSE_HVALUE hValue,
+                                        FX_BOOL bSetting,
+                                        XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  } else {
+    if (GetClassID() == XFA_ELEMENT_Subform) {
+      FXJSE_Value_SetBoolean(hValue, FALSE);
+      return;
+    }
+    CFX_WideString strValue;
+    FXJSE_Value_SetBoolean(hValue, !TryContent(strValue) || strValue.IsEmpty());
+  }
+}
+void CXFA_Node::Script_NodeClass_OneOfChild(FXJSE_HVALUE hValue,
+                                            FX_BOOL bSetting,
+                                            XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  } else {
+    CXFA_NodeArray properts;
+    int32_t iSize = GetNodeList(properts, XFA_NODEFILTER_OneOfProperty);
+    if (iSize > 0) {
+      FXJSE_Value_Set(
+          hValue,
+          m_pDocument->GetScriptContext()->GetJSValueFromMap(properts[0]));
+    }
+  }
+}
+void CXFA_Node::Script_ContainerClass_GetDelta(CFXJSE_Arguments* pArguments) {}
+void CXFA_Node::Script_ContainerClass_GetDeltas(CFXJSE_Arguments* pArguments) {
+  CXFA_ArrayNodeList* pFormNodes = new CXFA_ArrayNodeList(m_pDocument);
+  FXJSE_Value_SetObject(pArguments->GetReturnValue(), (CXFA_Object*)pFormNodes,
+                        m_pDocument->GetScriptContext()->GetJseNormalClass());
+}
+void CXFA_Node::Script_ModelClass_ClearErrorList(CFXJSE_Arguments* pArguments) {
+}
+void CXFA_Node::Script_ModelClass_CreateNode(CFXJSE_Arguments* pArguments) {
+  Script_Template_CreateNode(pArguments);
+}
+void CXFA_Node::Script_ModelClass_IsCompatibleNS(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength < 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"isCompatibleNS");
+    return;
+  }
+  CFX_WideString wsNameSpace;
+  if (iLength >= 1) {
+    CFX_ByteString bsNameSpace = pArguments->GetUTF8String(0);
+    wsNameSpace =
+        CFX_WideString::FromUTF8(bsNameSpace, bsNameSpace.GetLength());
+  }
+  CFX_WideString wsNodeNameSpace;
+  TryNamespace(wsNodeNameSpace);
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetBoolean(hValue, wsNodeNameSpace.Equal(wsNameSpace));
+  }
+}
+void CXFA_Node::Script_ModelClass_Context(FXJSE_HVALUE hValue,
+                                          FX_BOOL bSetting,
+                                          XFA_ATTRIBUTE eAttribute) {}
+void CXFA_Node::Script_ModelClass_AliasNode(FXJSE_HVALUE hValue,
+                                            FX_BOOL bSetting,
+                                            XFA_ATTRIBUTE eAttribute) {}
+void CXFA_Node::Script_Attribute_Integer(FXJSE_HVALUE hValue,
+                                         FX_BOOL bSetting,
+                                         XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    SetInteger(eAttribute, FXJSE_Value_ToInteger(hValue), TRUE);
+  } else {
+    FXJSE_Value_SetInteger(hValue, GetInteger(eAttribute));
+  }
+}
+void CXFA_Node::Script_Attribute_IntegerRead(FXJSE_HVALUE hValue,
+                                             FX_BOOL bSetting,
+                                             XFA_ATTRIBUTE eAttribute) {
+  if (!bSetting) {
+    FXJSE_Value_SetInteger(hValue, GetInteger(eAttribute));
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  }
+}
+void CXFA_Node::Script_Attribute_BOOL(FXJSE_HVALUE hValue,
+                                      FX_BOOL bSetting,
+                                      XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    SetBoolean(eAttribute, FXJSE_Value_ToBoolean(hValue), TRUE);
+  } else {
+    FXJSE_Value_SetUTF8String(hValue, GetBoolean(eAttribute) ? "1" : "0");
+  }
+}
+void CXFA_Node::Script_Attribute_BOOLRead(FXJSE_HVALUE hValue,
+                                          FX_BOOL bSetting,
+                                          XFA_ATTRIBUTE eAttribute) {
+  if (!bSetting) {
+    FXJSE_Value_SetUTF8String(hValue, GetBoolean(eAttribute) ? "1" : "0");
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  }
+}
+void CXFA_Node::Script_Attribute_SendAttributeChangeMessage(
+    void* eAttribute,
+    void* eValue,
+    FX_BOOL bScriptModify) {
+  CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
+  if (!pLayoutPro) {
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  FX_DWORD dwPacket = GetPacketID();
+  if (dwPacket & XFA_XDPPACKET_Form) {
+    FX_BOOL bNeedFindContainer = FALSE;
+    XFA_ELEMENT eType = GetClassID();
+    switch (eType) {
+      case XFA_ELEMENT_Caption:
+        bNeedFindContainer = TRUE;
+        pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute,
+                             eValue, this, GetNodeItem(XFA_NODEITEM_Parent));
+        break;
+      case XFA_ELEMENT_Font:
+      case XFA_ELEMENT_Para: {
+        bNeedFindContainer = TRUE;
+        CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
+        if (pParentNode->GetClassID() == XFA_ELEMENT_Caption) {
+          pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute,
+                               eValue, pParentNode,
+                               pParentNode->GetNodeItem(XFA_NODEITEM_Parent));
+        } else {
+          pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute,
+                               eValue, this, pParentNode);
+        }
+      } break;
+      case XFA_ELEMENT_Margin: {
+        bNeedFindContainer = TRUE;
+        CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
+        XFA_ELEMENT eParentType = pParentNode->GetClassID();
+        if (pParentNode->IsContainerNode()) {
+          pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute,
+                               eValue, this, pParentNode);
+        } else if (eParentType == XFA_ELEMENT_Caption) {
+          pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute,
+                               eValue, pParentNode,
+                               pParentNode->GetNodeItem(XFA_NODEITEM_Parent));
+        } else {
+          CXFA_Node* pNode = pParentNode->GetNodeItem(XFA_NODEITEM_Parent);
+          if (pNode && pNode->GetClassID() == XFA_ELEMENT_Ui) {
+            pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute,
+                                 eValue, pNode,
+                                 pNode->GetNodeItem(XFA_NODEITEM_Parent));
+          }
+        }
+      } break;
+      case XFA_ELEMENT_Comb: {
+        CXFA_Node* pEditNode = GetNodeItem(XFA_NODEITEM_Parent);
+        XFA_ELEMENT eUIType = pEditNode->GetClassID();
+        if (pEditNode && (eUIType == XFA_ELEMENT_DateTimeEdit ||
+                          eUIType == XFA_ELEMENT_NumericEdit ||
+                          eUIType == XFA_ELEMENT_TextEdit)) {
+          CXFA_Node* pUINode = pEditNode->GetNodeItem(XFA_NODEITEM_Parent);
+          if (pUINode) {
+            pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute,
+                                 eValue, pUINode,
+                                 pUINode->GetNodeItem(XFA_NODEITEM_Parent));
+          }
+        }
+      } break;
+      case XFA_ELEMENT_Button:
+      case XFA_ELEMENT_Barcode:
+      case XFA_ELEMENT_ChoiceList:
+      case XFA_ELEMENT_DateTimeEdit:
+      case XFA_ELEMENT_NumericEdit:
+      case XFA_ELEMENT_PasswordEdit:
+      case XFA_ELEMENT_TextEdit: {
+        CXFA_Node* pUINode = GetNodeItem(XFA_NODEITEM_Parent);
+        if (pUINode) {
+          pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute,
+                               eValue, pUINode,
+                               pUINode->GetNodeItem(XFA_NODEITEM_Parent));
+        }
+      } break;
+      case XFA_ELEMENT_CheckButton: {
+        bNeedFindContainer = TRUE;
+        CXFA_Node* pUINode = GetNodeItem(XFA_NODEITEM_Parent);
+        if (pUINode) {
+          pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute,
+                               eValue, pUINode,
+                               pUINode->GetNodeItem(XFA_NODEITEM_Parent));
+        }
+      } break;
+      case XFA_ELEMENT_Keep:
+      case XFA_ELEMENT_Bookend:
+      case XFA_ELEMENT_Break:
+      case XFA_ELEMENT_BreakAfter:
+      case XFA_ELEMENT_BreakBefore:
+      case XFA_ELEMENT_Overflow:
+        bNeedFindContainer = TRUE;
+        break;
+      case XFA_ELEMENT_Area:
+      case XFA_ELEMENT_Draw:
+      case XFA_ELEMENT_ExclGroup:
+      case XFA_ELEMENT_Field:
+      case XFA_ELEMENT_Subform:
+      case XFA_ELEMENT_SubformSet:
+        pLayoutPro->AddChangedContainer(this);
+        pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute,
+                             eValue, this, this);
+        break;
+      case XFA_ELEMENT_Sharptext:
+      case XFA_ELEMENT_Sharpxml:
+      case XFA_ELEMENT_SharpxHTML: {
+        CXFA_Node* pTextNode = GetNodeItem(XFA_NODEITEM_Parent);
+        if (!pTextNode) {
+          return;
+        }
+        CXFA_Node* pValueNode = pTextNode->GetNodeItem(XFA_NODEITEM_Parent);
+        if (!pValueNode) {
+          return;
+        }
+        XFA_ELEMENT eType = pValueNode->GetClassID();
+        if (eType == XFA_ELEMENT_Value) {
+          bNeedFindContainer = TRUE;
+          CXFA_Node* pNode = pValueNode->GetNodeItem(XFA_NODEITEM_Parent);
+          if (pNode && pNode->IsContainerNode()) {
+            if (bScriptModify) {
+              pValueNode = pNode;
+            }
+            pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute,
+                                 eValue, pValueNode, pNode);
+          } else {
+            pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute,
+                                 eValue, pNode,
+                                 pNode->GetNodeItem(XFA_NODEITEM_Parent));
+          }
+        } else {
+          if (eType == XFA_ELEMENT_Items) {
+            CXFA_Node* pNode = pValueNode->GetNodeItem(XFA_NODEITEM_Parent);
+            if (pNode && pNode->IsContainerNode()) {
+              pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute,
+                                   eValue, pValueNode, pNode);
+            }
+          }
+        }
+      } break;
+      default:
+        break;
+    }
+    if (bNeedFindContainer) {
+      CXFA_Node* pParent = this;
+      while (pParent) {
+        if (pParent->IsContainerNode()) {
+          break;
+        }
+        pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent);
+      }
+      if (pParent) {
+        pLayoutPro->AddChangedContainer(pParent);
+      }
+    }
+  } else {
+    pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute, eValue,
+                         this, this);
+  }
+}
+void CXFA_Node::Script_Attribute_String(FXJSE_HVALUE hValue,
+                                        FX_BOOL bSetting,
+                                        XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    CFX_ByteString szValue;
+    FXJSE_Value_ToUTF8String(hValue, szValue);
+    CFX_WideString wsValue =
+        CFX_WideString::FromUTF8(szValue, szValue.GetLength());
+    SetAttribute(eAttribute, wsValue, TRUE);
+    if (eAttribute == XFA_ATTRIBUTE_Use && GetClassID() == XFA_ELEMENT_Desc) {
+      CFX_WideString wsUseVal = wsValue, wsID, wsSOM;
+      CXFA_Node* pTemplateNode =
+          ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Template));
+      CXFA_Node* pProtoRoot =
+          pTemplateNode->GetFirstChildByClass(XFA_ELEMENT_Subform)
+              ->GetFirstChildByClass(XFA_ELEMENT_Proto);
+      if (!wsUseVal.IsEmpty()) {
+        if (wsUseVal[0] == '#') {
+          wsID = CFX_WideString((const FX_WCHAR*)wsUseVal + 1,
+                                wsUseVal.GetLength() - 1);
+        } else {
+          wsSOM =
+              CFX_WideString((const FX_WCHAR*)wsUseVal, wsUseVal.GetLength());
+        }
+      }
+      CXFA_Node* pProtoNode = NULL;
+      if (!wsSOM.IsEmpty()) {
+        FX_DWORD dwFlag = XFA_RESOLVENODE_Children |
+                          XFA_RESOLVENODE_Attributes |
+                          XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
+                          XFA_RESOLVENODE_Siblings;
+        XFA_RESOLVENODE_RS resoveNodeRS;
+        int32_t iRet = m_pDocument->GetScriptContext()->ResolveObjects(
+            pProtoRoot, wsSOM, resoveNodeRS, dwFlag);
+        if (iRet > 0 && resoveNodeRS.nodes[0]->IsNode()) {
+          pProtoNode = resoveNodeRS.nodes[0]->AsNode();
+        }
+      } else if (!wsID.IsEmpty()) {
+        pProtoNode = m_pDocument->GetNodeByID(pProtoRoot, wsID);
+      }
+      if (pProtoNode) {
+        CXFA_Node* pHeadChild = GetNodeItem(XFA_NODEITEM_FirstChild);
+        while (pHeadChild) {
+          CXFA_Node* pSibling =
+              pHeadChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+          RemoveChild(pHeadChild);
+          pHeadChild = pSibling;
+        }
+        CXFA_Node* pProtoForm = pProtoNode->CloneTemplateToForm(TRUE);
+        pHeadChild = pProtoForm->GetNodeItem(XFA_NODEITEM_FirstChild);
+        while (pHeadChild) {
+          CXFA_Node* pSibling =
+              pHeadChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+          pProtoForm->RemoveChild(pHeadChild);
+          InsertChild(pHeadChild);
+          pHeadChild = pSibling;
+        }
+        m_pDocument->RemovePurgeNode(pProtoForm);
+        delete pProtoForm;
+      }
+    }
+  } else {
+    CFX_WideString wsValue;
+    GetAttribute(eAttribute, wsValue);
+    FXJSE_Value_SetUTF8String(hValue,
+                              FX_UTF8Encode(wsValue, wsValue.GetLength()));
+  }
+}
+void CXFA_Node::Script_Attribute_StringRead(FXJSE_HVALUE hValue,
+                                            FX_BOOL bSetting,
+                                            XFA_ATTRIBUTE eAttribute) {
+  if (!bSetting) {
+    CFX_WideString wsValue;
+    GetAttribute(eAttribute, wsValue);
+    FXJSE_Value_SetUTF8String(hValue,
+                              FX_UTF8Encode(wsValue, wsValue.GetLength()));
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  }
+}
+void CXFA_Node::Script_WsdlConnection_Execute(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if ((argc == 0) || (argc == 1)) {
+    FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), FALSE);
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"execute");
+  }
+}
+void CXFA_Node::Script_Delta_Restore(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"restore");
+  }
+}
+void CXFA_Node::Script_Delta_CurrentValue(FXJSE_HVALUE hValue,
+                                          FX_BOOL bSetting,
+                                          XFA_ATTRIBUTE eAttribute) {}
+void CXFA_Node::Script_Delta_SavedValue(FXJSE_HVALUE hValue,
+                                        FX_BOOL bSetting,
+                                        XFA_ATTRIBUTE eAttribute) {}
+void CXFA_Node::Script_Delta_Target(FXJSE_HVALUE hValue,
+                                    FX_BOOL bSetting,
+                                    XFA_ATTRIBUTE eAttribute) {}
+void CXFA_Node::Script_Som_Message(FXJSE_HVALUE hValue,
+                                   FX_BOOL bSetting,
+                                   XFA_SOM_MESSAGETYPE iMessageType) {
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    return;
+  }
+  FX_BOOL bNew = FALSE;
+  CXFA_Validate validate = pWidgetData->GetValidate();
+  if (!validate) {
+    validate = pWidgetData->GetValidate(TRUE);
+    bNew = TRUE;
+  }
+  if (bSetting) {
+    CFX_ByteString bsMessage;
+    FXJSE_Value_ToUTF8String(hValue, bsMessage);
+    switch (iMessageType) {
+      case XFA_SOM_ValidationMessage:
+        validate.SetScriptMessageText(
+            CFX_WideString::FromUTF8(bsMessage, bsMessage.GetLength()));
+        break;
+      case XFA_SOM_FormatMessage:
+        validate.SetFormatMessageText(
+            CFX_WideString::FromUTF8(bsMessage, bsMessage.GetLength()));
+        break;
+      case XFA_SOM_MandatoryMessage:
+        validate.SetNullMessageText(
+            CFX_WideString::FromUTF8(bsMessage, bsMessage.GetLength()));
+        break;
+      default:
+        break;
+    }
+    if (!bNew) {
+      IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+      if (!pNotify) {
+        return;
+      }
+      pNotify->AddCalcValidate(this);
+    }
+  } else {
+    CFX_WideString wsMessage;
+    switch (iMessageType) {
+      case XFA_SOM_ValidationMessage:
+        validate.GetScriptMessageText(wsMessage);
+        break;
+      case XFA_SOM_FormatMessage:
+        validate.GetFormatMessageText(wsMessage);
+        break;
+      case XFA_SOM_MandatoryMessage:
+        validate.GetNullMessageText(wsMessage);
+        break;
+      default:
+        break;
+    }
+    FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsMessage));
+  }
+}
+void CXFA_Node::Script_Som_ValidationMessage(FXJSE_HVALUE hValue,
+                                             FX_BOOL bSetting,
+                                             XFA_ATTRIBUTE eAttribute) {
+  Script_Som_Message(hValue, bSetting, XFA_SOM_ValidationMessage);
+}
+void CXFA_Node::Script_Field_Length(FXJSE_HVALUE hValue,
+                                    FX_BOOL bSetting,
+                                    XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  } else {
+    CXFA_WidgetData* pWidgetData = GetWidgetData();
+    if (!pWidgetData) {
+      FXJSE_Value_SetInteger(hValue, 0);
+      return;
+    }
+    FXJSE_Value_SetInteger(hValue, pWidgetData->CountChoiceListItems(TRUE));
+  }
+}
+void CXFA_Node::Script_Som_DefaultValue(FXJSE_HVALUE hValue,
+                                        FX_BOOL bSetting,
+                                        XFA_ATTRIBUTE eAttribute) {
+  XFA_ELEMENT classID = GetClassID();
+  if (classID == XFA_ELEMENT_Field) {
+    Script_Field_DefaultValue(hValue, bSetting, eAttribute);
+    return;
+  } else if (classID == XFA_ELEMENT_Draw) {
+    Script_Draw_DefaultValue(hValue, bSetting, eAttribute);
+    return;
+  } else if (classID == XFA_ELEMENT_Boolean) {
+    Script_Boolean_Value(hValue, bSetting, eAttribute);
+    return;
+  }
+  if (bSetting) {
+    CFX_ByteString newValue;
+    if (!(FXJSE_Value_IsNull(hValue) || FXJSE_Value_IsUndefined(hValue))) {
+      FXJSE_Value_ToUTF8String(hValue, newValue);
+    }
+    CFX_WideString wsNewValue =
+        CFX_WideString::FromUTF8(newValue, newValue.GetLength());
+    CFX_WideString wsFormatValue(wsNewValue);
+    CXFA_WidgetData* pContainerWidgetData = NULL;
+    if (GetPacketID() == XFA_XDPPACKET_Datasets) {
+      CXFA_NodeArray formNodes;
+      GetBindItems(formNodes);
+      CFX_WideString wsPicture;
+      for (int32_t i = 0; i < formNodes.GetSize(); i++) {
+        CXFA_Node* pFormNode = formNodes.GetAt(i);
+        if (!pFormNode || pFormNode->HasFlag(XFA_NODEFLAG_HasRemoved)) {
+          continue;
+        }
+        pContainerWidgetData = pFormNode->GetContainerWidgetData();
+        if (pContainerWidgetData) {
+          pContainerWidgetData->GetPictureContent(wsPicture,
+                                                  XFA_VALUEPICTURE_DataBind);
+        }
+        if (!wsPicture.IsEmpty()) {
+          break;
+        }
+        pContainerWidgetData = NULL;
+      }
+    } else if (GetPacketID() == XFA_XDPPACKET_Form) {
+      pContainerWidgetData = GetContainerWidgetData();
+    }
+    if (pContainerWidgetData) {
+      pContainerWidgetData->GetFormatDataValue(wsNewValue, wsFormatValue);
+    }
+    SetScriptContent(wsNewValue, wsFormatValue, TRUE, TRUE);
+  } else {
+    CFX_WideString content = GetScriptContent(TRUE);
+    if (content.IsEmpty() && classID != XFA_ELEMENT_Text &&
+        classID != XFA_ELEMENT_SubmitUrl) {
+      FXJSE_Value_SetNull(hValue);
+    } else if (classID == XFA_ELEMENT_Integer) {
+      FXJSE_Value_SetInteger(hValue, FXSYS_wtoi(content));
+    } else if (classID == XFA_ELEMENT_Float || classID == XFA_ELEMENT_Decimal) {
+      CFX_Decimal decimal(content);
+      FXJSE_Value_SetFloat(hValue, (FX_FLOAT)(double)decimal);
+    } else {
+      FXJSE_Value_SetUTF8String(hValue,
+                                FX_UTF8Encode(content, content.GetLength()));
+    }
+  }
+}
+void CXFA_Node::Script_Som_DefaultValue_Read(FXJSE_HVALUE hValue,
+                                             FX_BOOL bSetting,
+                                             XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+    return;
+  }
+  CFX_WideString content = GetScriptContent(TRUE);
+  if (content.IsEmpty()) {
+    FXJSE_Value_SetNull(hValue);
+  } else {
+    FXJSE_Value_SetUTF8String(hValue,
+                              FX_UTF8Encode(content, content.GetLength()));
+  }
+}
+void CXFA_Node::Script_Boolean_Value(FXJSE_HVALUE hValue,
+                                     FX_BOOL bSetting,
+                                     XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    CFX_ByteString newValue;
+    if (!(FXJSE_Value_IsNull(hValue) || FXJSE_Value_IsUndefined(hValue))) {
+      FXJSE_Value_ToUTF8String(hValue, newValue);
+    }
+    int32_t iValue = FXSYS_atoi(newValue);
+    CFX_WideString wsNewValue = (iValue == 0) ? FX_WSTRC(L"0") : FX_WSTRC(L"1");
+    CFX_WideString wsFormatValue(wsNewValue);
+    CXFA_WidgetData* pContainerWidgetData = GetContainerWidgetData();
+    if (pContainerWidgetData) {
+      pContainerWidgetData->GetFormatDataValue(wsNewValue, wsFormatValue);
+    }
+    SetScriptContent(wsNewValue, wsFormatValue, TRUE, TRUE);
+  } else {
+    CFX_WideString wsValue = GetScriptContent(TRUE);
+    FXJSE_Value_SetBoolean(hValue, wsValue.Equal(FX_WSTRC(L"1")));
+  }
+}
+struct XFA_ExecEventParaInfo {
+ public:
+  uint32_t m_uHash;
+  const FX_WCHAR* m_lpcEventName;
+  XFA_EVENTTYPE m_eventType;
+  uint32_t m_validFlags;
+};
+static const XFA_ExecEventParaInfo gs_eventParaInfos[] = {
+    {0x02a6c55a, L"postSubmit", XFA_EVENT_PostSubmit, 0},
+    {0x0ab466bb, L"preSubmit", XFA_EVENT_PreSubmit, 0},
+    {0x109d7ce7, L"mouseEnter", XFA_EVENT_MouseEnter, 5},
+    {0x17fad373, L"postPrint", XFA_EVENT_PostPrint, 0},
+    {0x1bfc72d9, L"preOpen", XFA_EVENT_PreOpen, 7},
+    {0x2196a452, L"initialize", XFA_EVENT_Initialize, 1},
+    {0x27410f03, L"mouseExit", XFA_EVENT_MouseExit, 5},
+    {0x33c43dec, L"docClose", XFA_EVENT_DocClose, 0},
+    {0x361fa1b6, L"preSave", XFA_EVENT_PreSave, 0},
+    {0x36f1c6d8, L"preSign", XFA_EVENT_PreSign, 6},
+    {0x4731d6ba, L"exit", XFA_EVENT_Exit, 2},
+    {0x56bf456b, L"docReady", XFA_EVENT_DocReady, 0},
+    {0x7233018a, L"validate", XFA_EVENT_Validate, 1},
+    {0x8808385e, L"indexChange", XFA_EVENT_IndexChange, 3},
+    {0x891f4606, L"change", XFA_EVENT_Change, 4},
+    {0x9528a7b4, L"prePrint", XFA_EVENT_PrePrint, 0},
+    {0x9f693b21, L"mouseDown", XFA_EVENT_MouseDown, 5},
+    {0xcdce56b3, L"full", XFA_EVENT_Full, 4},
+    {0xd576d08e, L"mouseUp", XFA_EVENT_MouseUp, 5},
+    {0xd95657a6, L"click", XFA_EVENT_Click, 4},
+    {0xdbfbe02e, L"calculate", XFA_EVENT_Calculate, 1},
+    {0xe25fa7b8, L"postOpen", XFA_EVENT_PostOpen, 7},
+    {0xe28dce7e, L"enter", XFA_EVENT_Enter, 2},
+    {0xfc82d695, L"postSave", XFA_EVENT_PostSave, 0},
+    {0xfd54fbb7, L"postSign", XFA_EVENT_PostSign, 6},
+};
+const XFA_ExecEventParaInfo* GetEventParaInfoByName(
+    const CFX_WideStringC& wsEventName) {
+  int32_t iLength = wsEventName.GetLength();
+  uint32_t uHash = FX_HashCode_String_GetW(wsEventName.GetPtr(), iLength);
+  const XFA_ExecEventParaInfo* eventParaInfo = NULL;
+  int32_t iStart = 0,
+          iEnd = (sizeof(gs_eventParaInfos) / sizeof(gs_eventParaInfos[0])) - 1;
+  int32_t iMid = (iStart + iEnd) / 2;
+  do {
+    iMid = (iStart + iEnd) / 2;
+    eventParaInfo = &gs_eventParaInfos[iMid];
+    if (uHash == eventParaInfo->m_uHash) {
+      return eventParaInfo;
+    } else if (uHash < eventParaInfo->m_uHash) {
+      iEnd = iMid - 1;
+    } else {
+      iStart = iMid + 1;
+    }
+  } while (iStart <= iEnd);
+  return NULL;
+}
+void XFA_STRING_TO_RGB(CFX_WideString& strRGB,
+                       int32_t& r,
+                       int32_t& g,
+                       int32_t& b) {
+  r = 0;
+  g = 0;
+  b = 0;
+  FX_WCHAR zero = '0';
+  int32_t iIndex = 0;
+  int32_t iLen = strRGB.GetLength();
+  for (int32_t i = 0; i < iLen; ++i) {
+    FX_WCHAR ch = strRGB.GetAt(i);
+    if (ch == L',') {
+      ++iIndex;
+    }
+    if (iIndex > 2) {
+      break;
+    }
+    int32_t iValue = ch - zero;
+    if (iValue >= 0 && iValue <= 9) {
+      switch (iIndex) {
+        case 0:
+          r = r * 10 + iValue;
+          break;
+        case 1:
+          g = g * 10 + iValue;
+          break;
+        default:
+          b = b * 10 + iValue;
+          break;
+      }
+    }
+  }
+}
+void CXFA_Node::Script_Som_BorderColor(FXJSE_HVALUE hValue,
+                                       FX_BOOL bSetting,
+                                       XFA_ATTRIBUTE eAttribute) {
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    return;
+  }
+  CXFA_Border border = pWidgetData->GetBorder(TRUE);
+  int32_t iSize = border.CountEdges();
+  CFX_WideString strColor;
+  if (bSetting) {
+    CFX_ByteString bsValue;
+    FXJSE_Value_ToUTF8String(hValue, bsValue);
+    strColor = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+    int32_t r = 0, g = 0, b = 0;
+    XFA_STRING_TO_RGB(strColor, r, g, b);
+    FX_ARGB rgb = ArgbEncode(100, r, g, b);
+    for (int32_t i = 0; i < iSize; ++i) {
+      CXFA_Edge edge = border.GetEdge(i);
+      edge.SetColor(rgb);
+    }
+  } else {
+    CXFA_Edge edge = border.GetEdge(0);
+    FX_ARGB color = edge.GetColor();
+    int32_t a, r, g, b;
+    ArgbDecode(color, a, r, g, b);
+    strColor.Format(L"%d,%d,%d", r, g, b);
+    FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(strColor));
+  }
+}
+void CXFA_Node::Script_Som_BorderWidth(FXJSE_HVALUE hValue,
+                                       FX_BOOL bSetting,
+                                       XFA_ATTRIBUTE eAttribute) {
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    return;
+  }
+  CXFA_Border border = pWidgetData->GetBorder(TRUE);
+  int32_t iSize = border.CountEdges();
+  CFX_WideString wsThickness;
+  if (bSetting) {
+    CFX_ByteString bsValue;
+    FXJSE_Value_ToUTF8String(hValue, bsValue);
+    wsThickness = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+    for (int32_t i = 0; i < iSize; ++i) {
+      CXFA_Edge edge = border.GetEdge(i);
+      CXFA_Measurement thickness(wsThickness);
+      edge.SetMSThickness(thickness);
+    }
+  } else {
+    CXFA_Edge edge = border.GetEdge(0);
+    CXFA_Measurement thickness = edge.GetMSThickness();
+    thickness.ToString(wsThickness);
+    FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsThickness));
+  }
+}
+void CXFA_Node::Script_Som_FillColor(FXJSE_HVALUE hValue,
+                                     FX_BOOL bSetting,
+                                     XFA_ATTRIBUTE eAttribute) {
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    return;
+  }
+  CXFA_Border border = pWidgetData->GetBorder(TRUE);
+  CXFA_Fill borderfill = border.GetFill(TRUE);
+  CXFA_Node* pNode = borderfill.GetNode();
+  if (!pNode) {
+    return;
+  }
+  CFX_WideString wsColor;
+  if (bSetting) {
+    CFX_ByteString bsValue;
+    FXJSE_Value_ToUTF8String(hValue, bsValue);
+    wsColor = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+    int32_t r, g, b;
+    XFA_STRING_TO_RGB(wsColor, r, g, b);
+    FX_ARGB color = ArgbEncode(0xff, r, g, b);
+    borderfill.SetColor(color);
+  } else {
+    FX_ARGB color = borderfill.GetColor();
+    int32_t a, r, g, b;
+    ArgbDecode(color, a, r, g, b);
+    wsColor.Format(L"%d,%d,%d", r, g, b);
+    FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsColor));
+  }
+}
+void CXFA_Node::Script_Som_DataNode(FXJSE_HVALUE hValue,
+                                    FX_BOOL bSetting,
+                                    XFA_ATTRIBUTE eAttribute) {
+  if (!bSetting) {
+    CXFA_Node* pDataNode = GetBindData();
+    if (pDataNode) {
+      FXJSE_Value_Set(
+          hValue,
+          m_pDocument->GetScriptContext()->GetJSValueFromMap(pDataNode));
+    } else {
+      FXJSE_Value_SetNull(hValue);
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  }
+}
+void CXFA_Node::Script_Draw_DefaultValue(FXJSE_HVALUE hValue,
+                                         FX_BOOL bSetting,
+                                         XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    if (FXJSE_Value_IsUTF8String(hValue)) {
+      CXFA_WidgetData* pWidgetData = GetWidgetData();
+      FXSYS_assert(pWidgetData);
+      XFA_ELEMENT uiType = pWidgetData->GetUIType();
+      if (uiType == XFA_ELEMENT_Text) {
+        CFX_ByteString newValue;
+        FXJSE_Value_ToUTF8String(hValue, newValue);
+        CFX_WideString wsNewValue =
+            CFX_WideString::FromUTF8(newValue, newValue.GetLength());
+        CFX_WideString wsFormatValue(wsNewValue);
+        SetScriptContent(wsNewValue, wsFormatValue, TRUE, TRUE);
+      } else if (uiType != XFA_ELEMENT_Image) {
+      }
+    }
+  } else {
+    CFX_WideString content = GetScriptContent(TRUE);
+    if (content.IsEmpty()) {
+      FXJSE_Value_SetNull(hValue);
+    } else {
+      FXJSE_Value_SetUTF8String(hValue,
+                                FX_UTF8Encode(content, content.GetLength()));
+    }
+  }
+}
+void CXFA_Node::Script_Field_DefaultValue(FXJSE_HVALUE hValue,
+                                          FX_BOOL bSetting,
+                                          XFA_ATTRIBUTE eAttribute) {
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    return;
+  }
+  if (bSetting) {
+    if (FXJSE_Value_IsNull(hValue)) {
+      pWidgetData->m_bPreNull = pWidgetData->m_bIsNull;
+      pWidgetData->m_bIsNull = TRUE;
+    } else {
+      pWidgetData->m_bPreNull = pWidgetData->m_bIsNull;
+      pWidgetData->m_bIsNull = FALSE;
+    }
+    CFX_ByteString newValue;
+    if (!(FXJSE_Value_IsNull(hValue) || FXJSE_Value_IsUndefined(hValue))) {
+      FXJSE_Value_ToUTF8String(hValue, newValue);
+    }
+    CFX_WideString wsNewText =
+        CFX_WideString::FromUTF8(newValue, newValue.GetLength());
+    CXFA_Node* pUIChild = pWidgetData->GetUIChild();
+    if (pUIChild->GetClassID() == XFA_ELEMENT_NumericEdit) {
+      int32_t iLeadDigits = 0;
+      int32_t iFracDigits = 0;
+      pWidgetData->GetLeadDigits(iLeadDigits);
+      pWidgetData->GetFracDigits(iFracDigits);
+      wsNewText = XFA_NumericLimit(wsNewText, iLeadDigits, iFracDigits);
+    }
+    CXFA_WidgetData* pContainerWidgetData = GetContainerWidgetData();
+    CFX_WideString wsFormatText(wsNewText);
+    if (pContainerWidgetData) {
+      pContainerWidgetData->GetFormatDataValue(wsNewText, wsFormatText);
+    }
+    SetScriptContent(wsNewText, wsFormatText, TRUE, TRUE);
+  } else {
+    CFX_WideString content = GetScriptContent(TRUE);
+    if (content.IsEmpty()) {
+      FXJSE_Value_SetNull(hValue);
+    } else {
+      CXFA_Node* pUIChild = pWidgetData->GetUIChild();
+      XFA_ELEMENT eUI = pUIChild->GetClassID();
+      CXFA_Value defVal = pWidgetData->GetFormValue();
+      CXFA_Node* pNode = defVal.GetNode()->GetNodeItem(XFA_NODEITEM_FirstChild);
+      if (pNode && pNode->GetClassID() == XFA_ELEMENT_Decimal) {
+        if (eUI == XFA_ELEMENT_NumericEdit &&
+            (pNode->GetInteger(XFA_ATTRIBUTE_FracDigits) == -1)) {
+          FXJSE_Value_SetUTF8String(
+              hValue, FX_UTF8Encode(content, content.GetLength()));
+        } else {
+          CFX_Decimal decimal(content);
+          FXJSE_Value_SetFloat(hValue, (FX_FLOAT)(double)decimal);
+        }
+      } else if (pNode && pNode->GetClassID() == XFA_ELEMENT_Integer) {
+        FXJSE_Value_SetInteger(hValue, FXSYS_wtoi(content));
+      } else if (pNode && pNode->GetClassID() == XFA_ELEMENT_Boolean) {
+        FXJSE_Value_SetBoolean(hValue, FXSYS_wtoi(content) == 0 ? FALSE : TRUE);
+      } else if (pNode && pNode->GetClassID() == XFA_ELEMENT_Float) {
+        CFX_Decimal decimal(content);
+        FXJSE_Value_SetFloat(hValue, (FX_FLOAT)(double)decimal);
+      } else {
+        FXJSE_Value_SetUTF8String(hValue,
+                                  FX_UTF8Encode(content, content.GetLength()));
+      }
+    }
+  }
+}
+void CXFA_Node::Script_Field_EditValue(FXJSE_HVALUE hValue,
+                                       FX_BOOL bSetting,
+                                       XFA_ATTRIBUTE eAttribute) {
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    return;
+  }
+  CFX_WideString wsValue;
+  if (bSetting) {
+    CFX_ByteString bsValue;
+    FXJSE_Value_ToUTF8String(hValue, bsValue);
+    wsValue = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+    pWidgetData->SetValue(wsValue, XFA_VALUEPICTURE_Edit);
+  } else {
+    pWidgetData->GetValue(wsValue, XFA_VALUEPICTURE_Edit);
+    FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsValue));
+  }
+}
+void CXFA_Node::Script_Som_FontColor(FXJSE_HVALUE hValue,
+                                     FX_BOOL bSetting,
+                                     XFA_ATTRIBUTE eAttribute) {
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    return;
+  }
+  CXFA_Font font = pWidgetData->GetFont(TRUE);
+  CXFA_Node* pNode = font.GetNode();
+  if (!pNode) {
+    return;
+  }
+  CFX_WideString wsColor;
+  if (bSetting) {
+    CFX_ByteString bsValue;
+    FXJSE_Value_ToUTF8String(hValue, bsValue);
+    wsColor = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+    int32_t r, g, b;
+    XFA_STRING_TO_RGB(wsColor, r, g, b);
+    FX_ARGB color = ArgbEncode(0xff, r, g, b);
+    font.SetColor(color);
+  } else {
+    FX_ARGB color = font.GetColor();
+    int32_t a, r, g, b;
+    ArgbDecode(color, a, r, g, b);
+    wsColor.Format(L"%d,%d,%d", r, g, b);
+    FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsColor));
+  }
+}
+void CXFA_Node::Script_Field_FormatMessage(FXJSE_HVALUE hValue,
+                                           FX_BOOL bSetting,
+                                           XFA_ATTRIBUTE eAttribute) {
+  Script_Som_Message(hValue, bSetting, XFA_SOM_FormatMessage);
+}
+void CXFA_Node::Script_Field_FormattedValue(FXJSE_HVALUE hValue,
+                                            FX_BOOL bSetting,
+                                            XFA_ATTRIBUTE eAttribute) {
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    return;
+  }
+  CFX_WideString wsValue;
+  if (bSetting) {
+    CFX_ByteString bsValue;
+    FXJSE_Value_ToUTF8String(hValue, bsValue);
+    wsValue = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+    pWidgetData->SetValue(wsValue, XFA_VALUEPICTURE_Display);
+  } else {
+    pWidgetData->GetValue(wsValue, XFA_VALUEPICTURE_Display);
+    FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsValue));
+  }
+}
+void CXFA_Node::Script_Som_Mandatory(FXJSE_HVALUE hValue,
+                                     FX_BOOL bSetting,
+                                     XFA_ATTRIBUTE eAttribute) {
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    return;
+  }
+  CXFA_Validate validate = pWidgetData->GetValidate(TRUE);
+  CFX_WideString wsValue;
+  if (bSetting) {
+    CFX_ByteString bsValue;
+    FXJSE_Value_ToUTF8String(hValue, bsValue);
+    wsValue = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+    validate.SetNullTest(wsValue);
+  } else {
+    int32_t iValue = validate.GetNullTest();
+    const XFA_ATTRIBUTEENUMINFO* pInfo =
+        XFA_GetAttributeEnumByID((XFA_ATTRIBUTEENUM)iValue);
+    if (pInfo) {
+      wsValue = pInfo->pName;
+    }
+    FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsValue));
+  }
+}
+void CXFA_Node::Script_Som_MandatoryMessage(FXJSE_HVALUE hValue,
+                                            FX_BOOL bSetting,
+                                            XFA_ATTRIBUTE eAttribute) {
+  Script_Som_Message(hValue, bSetting, XFA_SOM_MandatoryMessage);
+}
+void CXFA_Node::Script_Field_ParentSubform(FXJSE_HVALUE hValue,
+                                           FX_BOOL bSetting,
+                                           XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  } else {
+    FXJSE_Value_SetNull(hValue);
+  }
+}
+void CXFA_Node::Script_Field_SelectedIndex(FXJSE_HVALUE hValue,
+                                           FX_BOOL bSetting,
+                                           XFA_ATTRIBUTE eAttribute) {
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    return;
+  }
+  if (bSetting) {
+    int32_t iIndex = FXJSE_Value_ToInteger(hValue);
+    if (iIndex == -1) {
+      pWidgetData->ClearAllSelections();
+      return;
+    }
+    pWidgetData->SetItemState(iIndex, TRUE, TRUE, TRUE);
+  } else {
+    FXJSE_Value_SetInteger(hValue, pWidgetData->GetSelectedItem());
+  }
+}
+void CXFA_Node::Script_Field_ClearItems(CFXJSE_Arguments* pArguments) {
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    return;
+  }
+  pWidgetData->DeleteItem(-1, TRUE);
+}
+void CXFA_Node::Script_Field_ExecEvent(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 1) {
+    CFX_ByteString eventString = pArguments->GetUTF8String(0);
+    int32_t iRet = execSingleEventByName(
+        CFX_WideString::FromUTF8(eventString, eventString.GetLength()),
+        XFA_ELEMENT_Field);
+    if (eventString == "validate") {
+      FXJSE_Value_SetBoolean(pArguments->GetReturnValue(),
+                             ((iRet == XFA_EVENTERROR_Error) ? FALSE : TRUE));
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"execEvent");
+  }
+}
+void CXFA_Node::Script_Field_ExecInitialize(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+    IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+    if (!pNotify) {
+      return;
+    }
+    pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Initialize, FALSE, FALSE);
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"execInitialize");
+  }
+}
+void CXFA_Node::Script_Field_DeleteItem(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"deleteItem");
+    return;
+  }
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    return;
+  }
+  int32_t iIndex = pArguments->GetInt32(0);
+  FX_BOOL bValue = pWidgetData->DeleteItem(iIndex, TRUE, TRUE);
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetBoolean(hValue, bValue);
+  }
+}
+void CXFA_Node::Script_Field_GetSaveItem(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"getSaveItem");
+    return;
+  }
+  int32_t iIndex = pArguments->GetInt32(0);
+  if (iIndex < 0) {
+    FXJSE_Value_SetNull(pArguments->GetReturnValue());
+    return;
+  }
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    FXJSE_Value_SetNull(pArguments->GetReturnValue());
+    return;
+  }
+  CFX_WideString wsValue;
+  FX_BOOL bHasItem = pWidgetData->GetChoiceListItem(wsValue, iIndex, TRUE);
+  if (bHasItem) {
+    FXJSE_Value_SetUTF8String(pArguments->GetReturnValue(),
+                              FX_UTF8Encode(wsValue, wsValue.GetLength()));
+  } else {
+    FXJSE_Value_SetNull(pArguments->GetReturnValue());
+  }
+}
+void CXFA_Node::Script_Field_BoundItem(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"boundItem");
+    return;
+  }
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    return;
+  }
+  CFX_ByteString bsValue = pArguments->GetUTF8String(0);
+  CFX_WideString wsValue =
+      CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+  CFX_WideString wsBoundValue;
+  pWidgetData->GetItemValue(wsValue, wsBoundValue);
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsBoundValue));
+  }
+}
+void CXFA_Node::Script_Field_GetItemState(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"getItemState");
+    return;
+  }
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    return;
+  }
+  int32_t iIndex = pArguments->GetInt32(0);
+  FX_BOOL bValue = pWidgetData->GetItemState(iIndex);
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetBoolean(hValue, bValue);
+  }
+}
+void CXFA_Node::Script_Field_ExecCalculate(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+    IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+    if (!pNotify) {
+      return;
+    }
+    pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate, FALSE, FALSE);
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"execCalculate");
+  }
+}
+void CXFA_Node::Script_Field_SetItems(CFXJSE_Arguments* pArguments) {}
+void CXFA_Node::Script_Field_GetDisplayItem(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"getDisplayItem");
+    return;
+  }
+  int32_t iIndex = pArguments->GetInt32(0);
+  if (iIndex < 0) {
+    FXJSE_Value_SetNull(pArguments->GetReturnValue());
+    return;
+  }
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    FXJSE_Value_SetNull(pArguments->GetReturnValue());
+    return;
+  }
+  CFX_WideString wsValue;
+  FX_BOOL bHasItem = pWidgetData->GetChoiceListItem(wsValue, iIndex, FALSE);
+  if (bHasItem) {
+    FXJSE_Value_SetUTF8String(pArguments->GetReturnValue(),
+                              FX_UTF8Encode(wsValue, wsValue.GetLength()));
+  } else {
+    FXJSE_Value_SetNull(pArguments->GetReturnValue());
+  }
+}
+void CXFA_Node::Script_Field_SetItemState(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 2) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"setItemState");
+    return;
+  }
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    return;
+  }
+  int32_t iIndex = pArguments->GetInt32(0);
+  if (pArguments->GetInt32(1) != 0) {
+    pWidgetData->SetItemState(iIndex, TRUE, TRUE, TRUE);
+  } else {
+    if (pWidgetData->GetItemState(iIndex)) {
+      pWidgetData->SetItemState(iIndex, FALSE, TRUE, TRUE);
+    }
+  }
+}
+void CXFA_Node::Script_Field_AddItem(CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength < 1 || iLength > 2) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"addItem");
+    return;
+  }
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    return;
+  }
+  CFX_WideString wsLabel;
+  CFX_WideString wsValue;
+  if (iLength >= 1) {
+    CFX_ByteString bsLable = pArguments->GetUTF8String(0);
+    wsLabel = CFX_WideString::FromUTF8(bsLable, bsLable.GetLength());
+  }
+  if (iLength >= 2) {
+    CFX_ByteString bsValue = pArguments->GetUTF8String(1);
+    wsValue = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+  }
+  pWidgetData->InsertItem(wsLabel, wsValue, -1, TRUE);
+}
+void CXFA_Node::Script_Field_ExecValidate(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+    IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+    if (!pNotify) {
+      FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), FALSE);
+    } else {
+      int32_t iRet =
+          pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate, FALSE, FALSE);
+      FXJSE_Value_SetBoolean(pArguments->GetReturnValue(),
+                             ((iRet == XFA_EVENTERROR_Error) ? FALSE : TRUE));
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"execValidate");
+  }
+}
+void CXFA_Node::Script_ExclGroup_ErrorText(FXJSE_HVALUE hValue,
+                                           FX_BOOL bSetting,
+                                           XFA_ATTRIBUTE eAttribute) {
+  if (!bSetting) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  }
+}
+void CXFA_Node::Script_ExclGroup_DefaultAndRawValue(FXJSE_HVALUE hValue,
+                                                    FX_BOOL bSetting,
+                                                    XFA_ATTRIBUTE eAttribute) {
+  CXFA_WidgetData* pWidgetData = GetWidgetData();
+  if (!pWidgetData) {
+    return;
+  }
+  if (bSetting) {
+    CFX_ByteString bsValue;
+    FXJSE_Value_ToUTF8String(hValue, bsValue);
+    pWidgetData->SetSelectedMemberByValue(
+        CFX_WideString::FromUTF8(bsValue, bsValue.GetLength()), TRUE, TRUE);
+  } else {
+    CFX_WideString wsValue = GetScriptContent(TRUE);
+    XFA_VERSION curVersion = GetDocument()->GetCurVersionMode();
+    if (wsValue.IsEmpty() && curVersion >= XFA_VERSION_300) {
+      FXJSE_Value_SetNull(hValue);
+    } else {
+      FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsValue));
+    }
+  }
+}
+void CXFA_Node::Script_ExclGroup_Transient(FXJSE_HVALUE hValue,
+                                           FX_BOOL bSetting,
+                                           XFA_ATTRIBUTE eAttribute) {}
+void CXFA_Node::Script_ExclGroup_ExecEvent(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 1) {
+    CFX_ByteString eventString = pArguments->GetUTF8String(0);
+    execSingleEventByName(
+        CFX_WideString::FromUTF8(eventString, eventString.GetLength()),
+        XFA_ELEMENT_ExclGroup);
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"execEvent");
+  }
+}
+void CXFA_Node::Script_ExclGroup_SelectedMember(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if ((argc == 0) || (argc == 1)) {
+    CXFA_WidgetData* pWidgetData = GetWidgetData();
+    if (!pWidgetData) {
+      FXJSE_Value_SetNull(pArguments->GetReturnValue());
+    } else {
+      CXFA_Node* pReturnNode = NULL;
+      if (argc == 0) {
+        pReturnNode = pWidgetData->GetSelectedMember();
+      } else {
+        CFX_ByteString szName;
+        szName = pArguments->GetUTF8String(0);
+        pReturnNode = pWidgetData->SetSelectedMember(
+            CFX_WideString::FromUTF8(szName, szName.GetLength()));
+      }
+      if (pReturnNode) {
+        FXJSE_Value_Set(
+            pArguments->GetReturnValue(),
+            m_pDocument->GetScriptContext()->GetJSValueFromMap(pReturnNode));
+      } else {
+        FXJSE_Value_SetNull(pArguments->GetReturnValue());
+      }
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"selectedMember");
+  }
+}
+void CXFA_Node::Script_ExclGroup_ExecInitialize(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+    IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+    if (!pNotify) {
+      return;
+    }
+    pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Initialize);
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"execInitialize");
+  }
+}
+void CXFA_Node::Script_ExclGroup_ExecCalculate(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+    IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+    if (!pNotify) {
+      return;
+    }
+    pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate);
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"execCalculate");
+  }
+}
+void CXFA_Node::Script_ExclGroup_ExecValidate(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+    IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+    if (!pNotify) {
+      FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), FALSE);
+    } else {
+      int32_t iRet = pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate);
+      FXJSE_Value_SetBoolean(pArguments->GetReturnValue(),
+                             ((iRet == XFA_EVENTERROR_Error) ? FALSE : TRUE));
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"execValidate");
+  }
+}
+static CXFA_Node* XFA_ScriptInstanceManager_GetItem(CXFA_Node* pInstMgrNode,
+                                                    int32_t iIndex) {
+  ASSERT(pInstMgrNode);
+  int32_t iCount = 0;
+  FX_DWORD dwNameHash = 0;
+  for (CXFA_Node* pNode = pInstMgrNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+       pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    XFA_ELEMENT eCurType = pNode->GetClassID();
+    if (eCurType == XFA_ELEMENT_InstanceManager) {
+      break;
+    }
+    if ((eCurType != XFA_ELEMENT_Subform) &&
+        (eCurType != XFA_ELEMENT_SubformSet)) {
+      continue;
+    }
+    if (iCount == 0) {
+      CFX_WideStringC wsName = pNode->GetCData(XFA_ATTRIBUTE_Name);
+      CFX_WideStringC wsInstName = pInstMgrNode->GetCData(XFA_ATTRIBUTE_Name);
+      if (wsInstName.GetLength() < 1 || wsInstName.GetAt(0) != '_' ||
+          wsInstName.Mid(1) != wsName) {
+        return NULL;
+      }
+      dwNameHash = pNode->GetNameHash();
+    }
+    if (dwNameHash != pNode->GetNameHash()) {
+      break;
+    }
+    iCount++;
+    if (iCount > iIndex) {
+      return pNode;
+    }
+  }
+  return NULL;
+}
+void CXFA_Node::Script_Som_InstanceIndex(FXJSE_HVALUE hValue,
+                                         FX_BOOL bSetting,
+                                         XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    int32_t iTo = FXJSE_Value_ToInteger(hValue);
+    int32_t iFrom = Subform_and_SubformSet_InstanceIndex();
+    CXFA_Node* pManagerNode = NULL;
+    for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_PrevSibling); pNode;
+         pNode = pNode->GetNodeItem(XFA_NODEITEM_PrevSibling)) {
+      if (pNode->GetClassID() == XFA_ELEMENT_InstanceManager) {
+        pManagerNode = pNode;
+        break;
+      }
+    }
+    if (pManagerNode) {
+      pManagerNode->InstanceManager_MoveInstance(iTo, iFrom);
+      IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+      if (!pNotify) {
+        return;
+      }
+      CXFA_Node* pToInstance =
+          XFA_ScriptInstanceManager_GetItem(pManagerNode, iTo);
+      if (pToInstance && pToInstance->GetClassID() == XFA_ELEMENT_Subform) {
+        pNotify->RunSubformIndexChange(pToInstance);
+      }
+      CXFA_Node* pFromInstance =
+          XFA_ScriptInstanceManager_GetItem(pManagerNode, iFrom);
+      if (pFromInstance && pFromInstance->GetClassID() == XFA_ELEMENT_Subform) {
+        pNotify->RunSubformIndexChange(pFromInstance);
+      }
+    }
+  } else {
+    FXJSE_Value_SetInteger(hValue, Subform_and_SubformSet_InstanceIndex());
+  }
+}
+void CXFA_Node::Script_Subform_InstanceManager(FXJSE_HVALUE hValue,
+                                               FX_BOOL bSetting,
+                                               XFA_ATTRIBUTE eAttribute) {
+  if (!bSetting) {
+    CFX_WideStringC wsName = GetCData(XFA_ATTRIBUTE_Name);
+    CXFA_Node* pInstanceMgr = NULL;
+    for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_PrevSibling); pNode;
+         pNode = pNode->GetNodeItem(XFA_NODEITEM_PrevSibling)) {
+      if (pNode->GetClassID() == XFA_ELEMENT_InstanceManager) {
+        CFX_WideStringC wsInstMgrName = pNode->GetCData(XFA_ATTRIBUTE_Name);
+        if (wsInstMgrName.GetLength() >= 1 && wsInstMgrName.GetAt(0) == '_' &&
+            wsInstMgrName.Mid(1) == wsName) {
+          pInstanceMgr = pNode;
+        }
+        break;
+      }
+    }
+    if (pInstanceMgr) {
+      FXJSE_Value_Set(
+          hValue,
+          m_pDocument->GetScriptContext()->GetJSValueFromMap(pInstanceMgr));
+    } else {
+      FXJSE_Value_SetNull(hValue);
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  }
+}
+void CXFA_Node::Script_Subform_Locale(FXJSE_HVALUE hValue,
+                                      FX_BOOL bSetting,
+                                      XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    CFX_ByteString bsLocaleName;
+    FXJSE_Value_ToUTF8String(hValue, bsLocaleName);
+    SetCData(XFA_ATTRIBUTE_Locale,
+             CFX_WideString::FromUTF8(bsLocaleName, bsLocaleName.GetLength()),
+             TRUE, TRUE);
+  } else {
+    CFX_WideString wsLocaleName;
+    GetLocaleName(wsLocaleName);
+    FXJSE_Value_SetUTF8String(
+        hValue, FX_UTF8Encode(wsLocaleName, wsLocaleName.GetLength()));
+  }
+}
+void CXFA_Node::Script_Subform_ExecEvent(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 1) {
+    CFX_ByteString eventString = pArguments->GetUTF8String(0);
+    execSingleEventByName(
+        CFX_WideString::FromUTF8(eventString, eventString.GetLength()),
+        XFA_ELEMENT_Subform);
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"execEvent");
+  }
+}
+void CXFA_Node::Script_Subform_ExecInitialize(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+    IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+    if (!pNotify) {
+      return;
+    }
+    pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Initialize);
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"execInitialize");
+  }
+}
+void CXFA_Node::Script_Subform_ExecCalculate(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+    IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+    if (!pNotify) {
+      return;
+    }
+    pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate);
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"execCalculate");
+  }
+}
+void CXFA_Node::Script_Subform_ExecValidate(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+    IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+    if (!pNotify) {
+      FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), FALSE);
+    } else {
+      int32_t iRet = pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate);
+      FXJSE_Value_SetBoolean(pArguments->GetReturnValue(),
+                             ((iRet == XFA_EVENTERROR_Error) ? FALSE : TRUE));
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"execValidate");
+  }
+}
+void CXFA_Node::Script_Subform_GetInvalidObjects(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"getInvalidObjects");
+  }
+}
+int32_t CXFA_Node::Subform_and_SubformSet_InstanceIndex() {
+  int32_t index = 0;
+  for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_PrevSibling); pNode;
+       pNode = pNode->GetNodeItem(XFA_NODEITEM_PrevSibling)) {
+    if ((pNode->GetClassID() == XFA_ELEMENT_Subform) ||
+        (pNode->GetClassID() == XFA_ELEMENT_SubformSet)) {
+      index++;
+    } else {
+      break;
+    }
+  }
+  return index;
+}
+void CXFA_Node::Script_Template_FormNodes(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 1) {
+    FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), TRUE);
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"formNodes");
+  }
+}
+void CXFA_Node::Script_Template_Remerge(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+    m_pDocument->DoDataRemerge(TRUE);
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"remerge");
+  }
+}
+void CXFA_Node::Script_Template_ExecInitialize(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+    CXFA_WidgetData* pWidgetData = GetWidgetData();
+    if (!pWidgetData) {
+      FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), FALSE);
+    } else {
+      FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), TRUE);
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"execInitialize");
+  }
+}
+void CXFA_Node::Script_Template_CreateNode(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if ((argc > 0) && (argc < 4)) {
+    CFX_WideString strTagName;
+    CFX_WideString strName;
+    CFX_WideString strNameSpace;
+    CFX_ByteString bsTagName = pArguments->GetUTF8String(0);
+    strTagName = CFX_WideString::FromUTF8(bsTagName, bsTagName.GetLength());
+    if (argc > 1) {
+      CFX_ByteString bsName = pArguments->GetUTF8String(1);
+      strName = CFX_WideString::FromUTF8(bsName, bsName.GetLength());
+      if (argc == 3) {
+        CFX_ByteString bsNameSpace = pArguments->GetUTF8String(2);
+        strNameSpace =
+            CFX_WideString::FromUTF8(bsNameSpace, bsNameSpace.GetLength());
+      }
+    }
+    const XFA_ELEMENTINFO* pElement = XFA_GetElementByName(strTagName);
+    CXFA_Node* pNewNode = CreateSamePacketNode(pElement->eName);
+    if (!pNewNode) {
+      FXJSE_Value_SetNull(pArguments->GetReturnValue());
+    } else {
+      if (!strName.IsEmpty()) {
+        if (XFA_GetAttributeOfElement(pElement->eName, XFA_ATTRIBUTE_Name,
+                                      XFA_XDPPACKET_UNKNOWN)) {
+          pNewNode->SetAttribute(XFA_ATTRIBUTE_Name, strName, TRUE);
+          if (pNewNode->GetPacketID() == XFA_XDPPACKET_Datasets) {
+            pNewNode->CreateXMLMappingNode();
+          }
+          FXJSE_Value_Set(
+              pArguments->GetReturnValue(),
+              m_pDocument->GetScriptContext()->GetJSValueFromMap(pNewNode));
+        } else {
+          ThrowScriptErrorMessage(XFA_IDS_NOT_HAVE_PROPERTY,
+                                  (const FX_WCHAR*)strTagName, L"name");
+        }
+      } else {
+        FXJSE_Value_Set(
+            pArguments->GetReturnValue(),
+            m_pDocument->GetScriptContext()->GetJSValueFromMap(pNewNode));
+      }
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"createNode");
+  }
+}
+void CXFA_Node::Script_Template_Recalculate(CFXJSE_Arguments* pArguments) {
+  if (pArguments->GetLength() == 1) {
+    FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), TRUE);
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"recalculate");
+  }
+}
+void CXFA_Node::Script_Template_ExecCalculate(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+    CXFA_WidgetData* pWidgetData = GetWidgetData();
+    if (!pWidgetData) {
+      FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), FALSE);
+    } else {
+      FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), TRUE);
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"execCalculate");
+  }
+}
+void CXFA_Node::Script_Template_ExecValidate(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+    CXFA_WidgetData* pWidgetData = GetWidgetData();
+    if (!pWidgetData) {
+      FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), FALSE);
+    } else {
+      FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), TRUE);
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"execValidate");
+  }
+}
+void CXFA_Node::Script_Manifest_Evaluate(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+    CXFA_WidgetData* pWidgetData = GetWidgetData();
+    if (!pWidgetData) {
+      FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), FALSE);
+    } else {
+      FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), TRUE);
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"evaluate");
+  }
+}
+void CXFA_Node::Script_InstanceManager_Max(FXJSE_HVALUE hValue,
+                                           FX_BOOL bSetting,
+                                           XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+    return;
+  }
+  CXFA_Occur nodeOccur(GetOccurNode());
+  FXJSE_Value_SetInteger(hValue, nodeOccur.GetMax());
+}
+void CXFA_Node::Script_InstanceManager_Min(FXJSE_HVALUE hValue,
+                                           FX_BOOL bSetting,
+                                           XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+    return;
+  }
+  CXFA_Occur nodeOccur(GetOccurNode());
+  FXJSE_Value_SetInteger(hValue, nodeOccur.GetMin());
+}
+static int32_t XFA_ScriptInstanceManager_GetCount(CXFA_Node* pInstMgrNode) {
+  ASSERT(pInstMgrNode);
+  int32_t iCount = 0;
+  FX_DWORD dwNameHash = 0;
+  for (CXFA_Node* pNode = pInstMgrNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+       pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    XFA_ELEMENT eCurType = pNode->GetClassID();
+    if (eCurType == XFA_ELEMENT_InstanceManager) {
+      break;
+    }
+    if ((eCurType != XFA_ELEMENT_Subform) &&
+        (eCurType != XFA_ELEMENT_SubformSet)) {
+      continue;
+    }
+    if (iCount == 0) {
+      CFX_WideStringC wsName = pNode->GetCData(XFA_ATTRIBUTE_Name);
+      CFX_WideStringC wsInstName = pInstMgrNode->GetCData(XFA_ATTRIBUTE_Name);
+      if (wsInstName.GetLength() < 1 || wsInstName.GetAt(0) != '_' ||
+          wsInstName.Mid(1) != wsName) {
+        return iCount;
+      }
+      dwNameHash = pNode->GetNameHash();
+    }
+    if (dwNameHash != pNode->GetNameHash()) {
+      break;
+    }
+    iCount++;
+  }
+  return iCount;
+}
+static void
+XFA_ScriptInstanceManager_ReorderDataNodes_SortNodeArrayByDocumentIdx(
+    const CXFA_NodeSet& rgNodeSet,
+    CXFA_NodeArray& rgNodeArray,
+    CFX_ArrayTemplate<int32_t>& rgIdxArray) {
+  int32_t iCount = rgNodeSet.GetCount();
+  rgNodeArray.SetSize(iCount);
+  rgIdxArray.SetSize(iCount);
+  if (iCount == 0) {
+    return;
+  }
+  int32_t iIndex = -1, iTotalIndex = -1;
+  CXFA_Node* pNode = NULL;
+  FX_POSITION pos = rgNodeSet.GetStartPosition();
+  rgNodeSet.GetNextAssoc(pos, pNode);
+  for (pNode = pNode->GetNodeItem(XFA_NODEITEM_Parent)
+                   ->GetNodeItem(XFA_NODEITEM_FirstChild);
+       pNode && iIndex < iCount;
+       pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    iTotalIndex++;
+    if (rgNodeSet.Lookup(pNode)) {
+      iIndex++;
+      rgNodeArray[iIndex] = pNode;
+      rgIdxArray[iIndex] = iTotalIndex;
+    }
+  }
+}
+struct CXFA_DualNodeArray {
+  CXFA_NodeSet firstNodeList;
+  CXFA_NodeSet secondNodeList;
+};
+static void XFA_ScriptInstanceManager_ReorderDataNodes(CXFA_NodeSet& sSet1,
+                                                       CXFA_NodeSet& sSet2,
+                                                       FX_BOOL bInsertBefore) {
+  CFX_MapPtrTemplate<CXFA_Node*,
+                     CFX_MapPtrTemplate<FX_DWORD, CXFA_DualNodeArray*>*>
+      rgNodeListMap;
+  FX_POSITION pos;
+  pos = sSet1.GetStartPosition();
+  while (pos) {
+    CXFA_Node* pNode = NULL;
+    sSet1.GetNextAssoc(pos, pNode);
+    CXFA_Node* pParentNode = pNode->GetNodeItem(XFA_NODEITEM_Parent);
+    FX_DWORD dwNameHash = pNode->GetNameHash();
+    if (!pParentNode || !dwNameHash) {
+      continue;
+    }
+    CFX_MapPtrTemplate<FX_DWORD, CXFA_DualNodeArray*>* pNodeListChildMap =
+        rgNodeListMap[pParentNode];
+    if (!pNodeListChildMap) {
+      rgNodeListMap[pParentNode] = pNodeListChildMap =
+          new CFX_MapPtrTemplate<FX_DWORD, CXFA_DualNodeArray*>;
+    }
+    CXFA_DualNodeArray* pDualNodeArray = (*pNodeListChildMap)[dwNameHash];
+    if (!pDualNodeArray) {
+      (*pNodeListChildMap)[dwNameHash] = pDualNodeArray =
+          new CXFA_DualNodeArray;
+    }
+    pDualNodeArray->firstNodeList.Add(pNode);
+  }
+  pos = sSet2.GetStartPosition();
+  while (pos) {
+    CXFA_Node* pNode = NULL;
+    sSet2.GetNextAssoc(pos, pNode);
+    CXFA_Node* pParentNode = pNode->GetNodeItem(XFA_NODEITEM_Parent);
+    FX_DWORD dwNameHash = pNode->GetNameHash();
+    if (!pParentNode || !dwNameHash) {
+      continue;
+    }
+    CFX_MapPtrTemplate<FX_DWORD, CXFA_DualNodeArray*>* pNodeListChildMap =
+        rgNodeListMap[pParentNode];
+    if (!pNodeListChildMap) {
+      rgNodeListMap[pParentNode] = pNodeListChildMap =
+          new CFX_MapPtrTemplate<FX_DWORD, CXFA_DualNodeArray*>;
+    }
+    CXFA_DualNodeArray* pDualNodeArray = (*pNodeListChildMap)[dwNameHash];
+    if (!pDualNodeArray) {
+      (*pNodeListChildMap)[dwNameHash] = pDualNodeArray =
+          new CXFA_DualNodeArray;
+    }
+    if (pDualNodeArray->firstNodeList.Lookup(pNode)) {
+      pDualNodeArray->firstNodeList.RemoveKey(pNode);
+    } else {
+      pDualNodeArray->secondNodeList.Add(pNode);
+    }
+  }
+  pos = rgNodeListMap.GetStartPosition();
+  while (pos) {
+    CXFA_Node* pParentNode = NULL;
+    CFX_MapPtrTemplate<FX_DWORD, CXFA_DualNodeArray*>* pNodeListChildMap = NULL;
+    rgNodeListMap.GetNextAssoc(pos, pParentNode, pNodeListChildMap);
+    if (!pNodeListChildMap) {
+      continue;
+    }
+    FX_POSITION childpos = pNodeListChildMap->GetStartPosition();
+    while (childpos) {
+      FX_DWORD dwNameHash = 0;
+      CXFA_DualNodeArray* pDualNodeArray = NULL;
+      pNodeListChildMap->GetNextAssoc(childpos, dwNameHash, pDualNodeArray);
+      if (!pDualNodeArray) {
+        continue;
+      }
+      if (pDualNodeArray->firstNodeList.GetCount() != 0 &&
+          pDualNodeArray->secondNodeList.GetCount() != 0) {
+        CXFA_NodeArray rgNodeArray1, rgNodeArray2;
+        CFX_ArrayTemplate<int32_t> rgIdxArray1, rgIdxArray2;
+        XFA_ScriptInstanceManager_ReorderDataNodes_SortNodeArrayByDocumentIdx(
+            pDualNodeArray->firstNodeList, rgNodeArray1, rgIdxArray1);
+        XFA_ScriptInstanceManager_ReorderDataNodes_SortNodeArrayByDocumentIdx(
+            pDualNodeArray->secondNodeList, rgNodeArray2, rgIdxArray2);
+        CXFA_Node *pParentNode = NULL, *pBeforeNode = NULL;
+        if (bInsertBefore) {
+          pBeforeNode = rgNodeArray2[0];
+          pParentNode = pBeforeNode->GetNodeItem(XFA_NODEITEM_Parent);
+        } else {
+          CXFA_Node* pLastNode = rgNodeArray2[rgIdxArray2.GetSize() - 1];
+          pParentNode = pLastNode->GetNodeItem(XFA_NODEITEM_Parent);
+          pBeforeNode = pLastNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+        }
+        for (int32_t iIdx = 0, iCount = rgIdxArray1.GetSize(); iIdx < iCount;
+             iIdx++) {
+          CXFA_Node* pCurNode = rgNodeArray1[iIdx];
+          pParentNode->RemoveChild(pCurNode);
+          pParentNode->InsertChild(pCurNode, pBeforeNode);
+        }
+      }
+      delete pDualNodeArray;
+    }
+    pNodeListChildMap->RemoveAll();
+  }
+  rgNodeListMap.RemoveAll();
+}
+static void XFA_ScriptInstanceManager_InsertItem(
+    CXFA_Node* pInstMgrNode,
+    CXFA_Node* pNewInstance,
+    int32_t iPos,
+    int32_t iCount = -1,
+    FX_BOOL bMoveDataBindingNodes = TRUE) {
+  if (iCount < 0) {
+    iCount = XFA_ScriptInstanceManager_GetCount(pInstMgrNode);
+  }
+  if (iPos < 0) {
+    iPos = iCount;
+  }
+  if (iPos == iCount) {
+    CXFA_Node* pNextSibling =
+        iCount > 0
+            ? XFA_ScriptInstanceManager_GetItem(pInstMgrNode, iCount - 1)
+                  ->GetNodeItem(XFA_NODEITEM_NextSibling)
+            : pInstMgrNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+    pInstMgrNode->GetNodeItem(XFA_NODEITEM_Parent)
+        ->InsertChild(pNewInstance, pNextSibling);
+    if (bMoveDataBindingNodes) {
+      CXFA_NodeSet sNew, sAfter;
+      CXFA_NodeIteratorTemplate<CXFA_Node,
+                                CXFA_TraverseStrategy_XFAContainerNode>
+          sIteratorNew(pNewInstance);
+      for (CXFA_Node* pNode = sIteratorNew.GetCurrent(); pNode;
+           pNode = sIteratorNew.MoveToNext()) {
+        CXFA_Node* pDataNode = pNode->GetBindData();
+        if (!pDataNode) {
+          continue;
+        }
+        sNew.Add(pDataNode);
+      }
+      CXFA_NodeIteratorTemplate<CXFA_Node,
+                                CXFA_TraverseStrategy_XFAContainerNode>
+          sIteratorAfter(pNextSibling);
+      for (CXFA_Node* pNode = sIteratorAfter.GetCurrent(); pNode;
+           pNode = sIteratorAfter.MoveToNext()) {
+        CXFA_Node* pDataNode = pNode->GetBindData();
+        if (!pDataNode) {
+          continue;
+        }
+        sAfter.Add(pDataNode);
+      }
+      XFA_ScriptInstanceManager_ReorderDataNodes(sNew, sAfter, FALSE);
+    }
+  } else {
+    CXFA_Node* pBeforeInstance =
+        XFA_ScriptInstanceManager_GetItem(pInstMgrNode, iPos);
+    pInstMgrNode->GetNodeItem(XFA_NODEITEM_Parent)
+        ->InsertChild(pNewInstance, pBeforeInstance);
+    if (bMoveDataBindingNodes) {
+      CXFA_NodeSet sNew, sBefore;
+      CXFA_NodeIteratorTemplate<CXFA_Node,
+                                CXFA_TraverseStrategy_XFAContainerNode>
+          sIteratorNew(pNewInstance);
+      for (CXFA_Node* pNode = sIteratorNew.GetCurrent(); pNode;
+           pNode = sIteratorNew.MoveToNext()) {
+        CXFA_Node* pDataNode = pNode->GetBindData();
+        if (!pDataNode) {
+          continue;
+        }
+        sNew.Add(pDataNode);
+      }
+      CXFA_NodeIteratorTemplate<CXFA_Node,
+                                CXFA_TraverseStrategy_XFAContainerNode>
+          sIteratorBefore(pBeforeInstance);
+      for (CXFA_Node* pNode = sIteratorBefore.GetCurrent(); pNode;
+           pNode = sIteratorBefore.MoveToNext()) {
+        CXFA_Node* pDataNode = pNode->GetBindData();
+        if (!pDataNode) {
+          continue;
+        }
+        sBefore.Add(pDataNode);
+      }
+      XFA_ScriptInstanceManager_ReorderDataNodes(sNew, sBefore, TRUE);
+    }
+  }
+}
+static void XFA_ScriptInstanceManager_RemoveItem(
+    CXFA_Node* pInstMgrNode,
+    CXFA_Node* pRemoveInstance,
+    FX_BOOL bRemoveDataBinding = TRUE) {
+  pInstMgrNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pRemoveInstance);
+  if (!bRemoveDataBinding) {
+    return;
+  }
+  CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode>
+      sIterator(pRemoveInstance);
+  for (CXFA_Node* pFormNode = sIterator.GetCurrent(); pFormNode;
+       pFormNode = sIterator.MoveToNext()) {
+    CXFA_Node* pDataNode = pFormNode->GetBindData();
+    if (!pDataNode) {
+      continue;
+    }
+    if (pDataNode->RemoveBindItem(pFormNode) == 0) {
+      if (CXFA_Node* pDataParent =
+              pDataNode->GetNodeItem(XFA_NODEITEM_Parent)) {
+        pDataParent->RemoveChild(pDataNode);
+      }
+    }
+    pFormNode->SetObject(XFA_ATTRIBUTE_BindingNode, NULL);
+  }
+}
+static CXFA_Node* XFA_ScriptInstanceManager_CreateInstance(
+    CXFA_Node* pInstMgrNode,
+    FX_BOOL bDataMerge) {
+  CXFA_Document* pDocument = pInstMgrNode->GetDocument();
+  CXFA_Node* pTemplateNode = pInstMgrNode->GetTemplateNode();
+  CXFA_Node* pFormParent = pInstMgrNode->GetNodeItem(XFA_NODEITEM_Parent);
+  CXFA_Node* pDataScope = NULL;
+  for (CXFA_Node* pRootBoundNode = pFormParent;
+       pRootBoundNode &&
+       pRootBoundNode->GetObjectType() == XFA_OBJECTTYPE_ContainerNode;
+       pRootBoundNode = pRootBoundNode->GetNodeItem(XFA_NODEITEM_Parent)) {
+    pDataScope = pRootBoundNode->GetBindData();
+    if (pDataScope) {
+      break;
+    }
+  }
+  if (!pDataScope) {
+    pDataScope = ToNode(pDocument->GetXFAObject(XFA_HASHCODE_Record));
+    ASSERT(pDataScope);
+  }
+  CXFA_Node* pInstance = pDocument->DataMerge_CopyContainer(
+      pTemplateNode, pFormParent, pDataScope, TRUE, bDataMerge);
+  if (pInstance) {
+    pDocument->DataMerge_UpdateBindingRelations(pInstance);
+    pFormParent->RemoveChild(pInstance);
+  }
+  return pInstance;
+}
+void CXFA_Node::Script_InstanceManager_Count(FXJSE_HVALUE hValue,
+                                             FX_BOOL bSetting,
+                                             XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    int32_t iDesired = FXJSE_Value_ToInteger(hValue);
+    InstanceManager_SetInstances(iDesired);
+  } else {
+    FXJSE_Value_SetInteger(hValue, XFA_ScriptInstanceManager_GetCount(this));
+  }
+}
+void CXFA_Node::Script_InstanceManager_MoveInstance(
+    CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc != 2) {
+    FXJSE_Value_SetUndefined(pArguments->GetReturnValue());
+    return;
+  }
+  int32_t iFrom = pArguments->GetInt32(0);
+  int32_t iTo = pArguments->GetInt32(1);
+  InstanceManager_MoveInstance(iTo, iFrom);
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  CXFA_Node* pToInstance = XFA_ScriptInstanceManager_GetItem(this, iTo);
+  if (pToInstance && pToInstance->GetClassID() == XFA_ELEMENT_Subform) {
+    pNotify->RunSubformIndexChange(pToInstance);
+  }
+  CXFA_Node* pFromInstance = XFA_ScriptInstanceManager_GetItem(this, iFrom);
+  if (pFromInstance && pFromInstance->GetClassID() == XFA_ELEMENT_Subform) {
+    pNotify->RunSubformIndexChange(pFromInstance);
+  }
+}
+void CXFA_Node::Script_InstanceManager_RemoveInstance(
+    CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc != 1) {
+    FXJSE_Value_SetUndefined(pArguments->GetReturnValue());
+    return;
+  }
+  int32_t iIndex = pArguments->GetInt32(0);
+  int32_t iCount = XFA_ScriptInstanceManager_GetCount(this);
+  if (iIndex < 0 || iIndex >= iCount) {
+    ThrowScriptErrorMessage(XFA_IDS_INDEX_OUT_OF_BOUNDS);
+    return;
+  }
+  CXFA_Occur nodeOccur(GetOccurNode());
+  int32_t iMin = nodeOccur.GetMin();
+  if (iCount - 1 < iMin) {
+    ThrowScriptErrorMessage(XFA_IDS_VIOLATE_BOUNDARY, L"min");
+    return;
+  }
+  CXFA_Node* pRemoveInstance = XFA_ScriptInstanceManager_GetItem(this, iIndex);
+  XFA_ScriptInstanceManager_RemoveItem(this, pRemoveInstance);
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (pNotify) {
+    for (int32_t i = iIndex; i < iCount - 1; i++) {
+      CXFA_Node* pSubformInstance = XFA_ScriptInstanceManager_GetItem(this, i);
+      if (pSubformInstance &&
+          pSubformInstance->GetClassID() == XFA_ELEMENT_Subform) {
+        pNotify->RunSubformIndexChange(pSubformInstance);
+      }
+    }
+  }
+  CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
+  if (!pLayoutPro) {
+    return;
+  }
+  pLayoutPro->AddChangedContainer(
+      ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form)));
+}
+void CXFA_Node::Script_InstanceManager_SetInstances(
+    CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc != 1) {
+    FXJSE_Value_SetUndefined(pArguments->GetReturnValue());
+    return;
+  }
+  int32_t iDesired = pArguments->GetInt32(0);
+  InstanceManager_SetInstances(iDesired);
+}
+void CXFA_Node::Script_InstanceManager_AddInstance(
+    CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if ((argc != 0) && (argc != 1)) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"addInstance");
+    return;
+  }
+  FX_BOOL fFlags = TRUE;
+  if (argc == 1) {
+    fFlags = pArguments->GetInt32(0) == 0 ? FALSE : TRUE;
+  }
+  int32_t iCount = XFA_ScriptInstanceManager_GetCount(this);
+  CXFA_Occur nodeOccur(GetOccurNode());
+  int32_t iMax = nodeOccur.GetMax();
+  if (iMax >= 0 && iCount >= iMax) {
+    ThrowScriptErrorMessage(XFA_IDS_VIOLATE_BOUNDARY, L"max");
+    return;
+  }
+  CXFA_Node* pNewInstance =
+      XFA_ScriptInstanceManager_CreateInstance(this, fFlags);
+  XFA_ScriptInstanceManager_InsertItem(this, pNewInstance, iCount, iCount,
+                                       FALSE);
+  FXJSE_Value_Set(
+      pArguments->GetReturnValue(),
+      m_pDocument->GetScriptContext()->GetJSValueFromMap(pNewInstance));
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  pNotify->RunNodeInitialize(pNewInstance);
+  CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
+  if (!pLayoutPro) {
+    return;
+  }
+  pLayoutPro->AddChangedContainer(
+      ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form)));
+}
+void CXFA_Node::Script_InstanceManager_InsertInstance(
+    CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if ((argc != 1) && (argc != 2)) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"insertInstance");
+    return;
+  }
+  int32_t iIndex = pArguments->GetInt32(0);
+  FX_BOOL bBind = FALSE;
+  if (argc == 2) {
+    bBind = pArguments->GetInt32(1) == 0 ? FALSE : TRUE;
+  }
+  CXFA_Occur nodeOccur(GetOccurNode());
+  int32_t iCount = XFA_ScriptInstanceManager_GetCount(this);
+  if (iIndex < 0 || iIndex > iCount) {
+    ThrowScriptErrorMessage(XFA_IDS_INDEX_OUT_OF_BOUNDS);
+    return;
+  }
+  int32_t iMax = nodeOccur.GetMax();
+  if (iMax >= 0 && iCount >= iMax) {
+    ThrowScriptErrorMessage(XFA_IDS_VIOLATE_BOUNDARY, L"max");
+    return;
+  }
+  CXFA_Node* pNewInstance =
+      XFA_ScriptInstanceManager_CreateInstance(this, bBind);
+  XFA_ScriptInstanceManager_InsertItem(this, pNewInstance, iIndex, iCount,
+                                       TRUE);
+  FXJSE_Value_Set(
+      pArguments->GetReturnValue(),
+      m_pDocument->GetScriptContext()->GetJSValueFromMap(pNewInstance));
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  pNotify->RunNodeInitialize(pNewInstance);
+  CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
+  if (!pLayoutPro) {
+    return;
+  }
+  pLayoutPro->AddChangedContainer(
+      ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form)));
+}
+int32_t CXFA_Node::InstanceManager_SetInstances(int32_t iDesired) {
+  CXFA_Occur nodeOccur(GetOccurNode());
+  int32_t iMax = nodeOccur.GetMax();
+  int32_t iMin = nodeOccur.GetMin();
+  if (iDesired < iMin) {
+    ThrowScriptErrorMessage(XFA_IDS_VIOLATE_BOUNDARY, L"min");
+    return 1;
+  }
+  if ((iMax >= 0) && (iDesired > iMax)) {
+    ThrowScriptErrorMessage(XFA_IDS_VIOLATE_BOUNDARY, L"max");
+    return 2;
+  }
+  int32_t iCount = XFA_ScriptInstanceManager_GetCount(this);
+  if (iDesired == iCount) {
+    return 0;
+  }
+  if (iDesired < iCount) {
+    CFX_WideStringC wsInstManagerName = GetCData(XFA_ATTRIBUTE_Name);
+    CFX_WideString wsInstanceName = wsInstManagerName.IsEmpty()
+                                        ? wsInstManagerName
+                                        : wsInstManagerName.Mid(1);
+    FX_DWORD dInstanceNameHash =
+        wsInstanceName.IsEmpty() ? 0 : FX_HashCode_String_GetW(
+                                           wsInstanceName,
+                                           wsInstanceName.GetLength());
+    CXFA_Node* pPrevSibling =
+        (iDesired == 0) ? this
+                        : XFA_ScriptInstanceManager_GetItem(this, iDesired - 1);
+    while (iCount > iDesired) {
+      CXFA_Node* pRemoveInstance =
+          pPrevSibling->GetNodeItem(XFA_NODEITEM_NextSibling);
+      if (pRemoveInstance->GetClassID() != XFA_ELEMENT_Subform &&
+          pRemoveInstance->GetClassID() != XFA_ELEMENT_SubformSet) {
+        continue;
+      }
+      if (pRemoveInstance->GetClassID() == XFA_ELEMENT_InstanceManager) {
+        FXSYS_assert(FALSE);
+        break;
+      }
+      if (pRemoveInstance->GetNameHash() == dInstanceNameHash) {
+        XFA_ScriptInstanceManager_RemoveItem(this, pRemoveInstance);
+        iCount--;
+      }
+    }
+  } else if (iDesired > iCount) {
+    while (iCount < iDesired) {
+      CXFA_Node* pNewInstance =
+          XFA_ScriptInstanceManager_CreateInstance(this, TRUE);
+      XFA_ScriptInstanceManager_InsertItem(this, pNewInstance, iCount, iCount,
+                                           FALSE);
+      iCount++;
+      IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+      if (!pNotify) {
+        return 0;
+      }
+      pNotify->RunNodeInitialize(pNewInstance);
+    }
+  }
+  CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
+  if (pLayoutPro) {
+    pLayoutPro->AddChangedContainer(
+        ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form)));
+  }
+  return 0;
+}
+int32_t CXFA_Node::InstanceManager_MoveInstance(int32_t iTo, int32_t iFrom) {
+  int32_t iCount = XFA_ScriptInstanceManager_GetCount(this);
+  if (iFrom > iCount || iTo > iCount - 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INDEX_OUT_OF_BOUNDS);
+    return 1;
+  }
+  if (iFrom < 0 || iTo < 0 || iFrom == iTo) {
+    return 0;
+  }
+  CXFA_Node* pMoveInstance = XFA_ScriptInstanceManager_GetItem(this, iFrom);
+  XFA_ScriptInstanceManager_RemoveItem(this, pMoveInstance, FALSE);
+  XFA_ScriptInstanceManager_InsertItem(this, pMoveInstance, iTo, iCount - 1,
+                                       TRUE);
+  CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
+  if (pLayoutPro) {
+    pLayoutPro->AddChangedContainer(
+        ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form)));
+  }
+  return 0;
+}
+void CXFA_Node::Script_Occur_Max(FXJSE_HVALUE hValue,
+                                 FX_BOOL bSetting,
+                                 XFA_ATTRIBUTE eAttribute) {
+  CXFA_Occur occur(this);
+  if (bSetting) {
+    int32_t iMax = FXJSE_Value_ToInteger(hValue);
+    occur.SetMax(iMax);
+  } else {
+    FXJSE_Value_SetInteger(hValue, occur.GetMax());
+  }
+}
+void CXFA_Node::Script_Occur_Min(FXJSE_HVALUE hValue,
+                                 FX_BOOL bSetting,
+                                 XFA_ATTRIBUTE eAttribute) {
+  CXFA_Occur occur(this);
+  if (bSetting) {
+    int32_t iMin = FXJSE_Value_ToInteger(hValue);
+    occur.SetMin(iMin);
+  } else {
+    FXJSE_Value_SetInteger(hValue, occur.GetMin());
+  }
+}
+void CXFA_Node::Script_Desc_Metadata(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if ((argc == 0) || (argc == 1)) {
+    FXJSE_Value_SetUTF8String(pArguments->GetReturnValue(), "");
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"metadata");
+  }
+}
+void CXFA_Node::Script_Form_FormNodes(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 1) {
+    CXFA_Node* pDataNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
+    if (pDataNode) {
+      CXFA_NodeArray formItems;
+      CXFA_ArrayNodeList* pFormNodes = new CXFA_ArrayNodeList(m_pDocument);
+      pFormNodes->SetArrayNodeList(formItems);
+      FXJSE_Value_SetObject(
+          pArguments->GetReturnValue(), (CXFA_Object*)pFormNodes,
+          m_pDocument->GetScriptContext()->GetJseNormalClass());
+    } else {
+      ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"formNodes");
+  }
+}
+void CXFA_Node::Script_Form_Remerge(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+    m_pDocument->DoDataRemerge(TRUE);
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"remerge");
+  }
+}
+void CXFA_Node::Script_Form_ExecInitialize(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+    IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+    if (!pNotify) {
+      return;
+    }
+    pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Initialize);
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"execInitialize");
+  }
+}
+void CXFA_Node::Script_Form_Recalculate(CFXJSE_Arguments* pArguments) {
+  CXFA_EventParam* pEventParam =
+      m_pDocument->GetScriptContext()->GetEventParam();
+  if (pEventParam->m_eType == XFA_EVENT_Calculate ||
+      pEventParam->m_eType == XFA_EVENT_InitCalculate) {
+    return;
+  }
+  int32_t argc = pArguments->GetLength();
+  if (argc == 1) {
+    const bool bScriptFlags = pArguments->GetInt32(0) != 0;
+    IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+    if (!pNotify) {
+      return;
+    }
+    if (bScriptFlags) {
+      pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate);
+      pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate);
+      pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Ready, TRUE);
+    } else {
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"recalculate");
+  }
+}
+void CXFA_Node::Script_Form_ExecCalculate(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+    IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+    if (!pNotify) {
+      return;
+    }
+    pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate);
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"execCalculate");
+  }
+}
+void CXFA_Node::Script_Form_ExecValidate(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+    IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+    if (!pNotify) {
+      FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), FALSE);
+    } else {
+      int32_t iRet = pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate);
+      FXJSE_Value_SetBoolean(pArguments->GetReturnValue(),
+                             ((iRet == XFA_EVENTERROR_Error) ? FALSE : TRUE));
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"execValidate");
+  }
+}
+void CXFA_Node::Script_Form_Checksum(FXJSE_HVALUE hValue,
+                                     FX_BOOL bSetting,
+                                     XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    CFX_ByteString bsChecksum;
+    FXJSE_Value_ToUTF8String(hValue, bsChecksum);
+    SetAttribute(XFA_ATTRIBUTE_Checksum,
+                 CFX_WideString::FromUTF8(bsChecksum, bsChecksum.GetLength()));
+  } else {
+    CFX_WideString wsChecksum;
+    GetAttribute(XFA_ATTRIBUTE_Checksum, wsChecksum, FALSE);
+    FXJSE_Value_SetUTF8String(
+        hValue, FX_UTF8Encode(wsChecksum, wsChecksum.GetLength()));
+  }
+}
+void CXFA_Node::Script_Packet_GetAttribute(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 1) {
+    CFX_ByteString bsAttributeName = pArguments->GetUTF8String(0);
+    CFX_WideString wsAttributeValue;
+    IFDE_XMLNode* pXMLNode = GetXMLMappingNode();
+    if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
+      ((IFDE_XMLElement*)pXMLNode)
+          ->GetString(CFX_WideString::FromUTF8(bsAttributeName,
+                                               bsAttributeName.GetLength()),
+                      wsAttributeValue);
+    }
+    FXJSE_Value_SetUTF8String(
+        pArguments->GetReturnValue(),
+        FX_UTF8Encode(wsAttributeValue, wsAttributeValue.GetLength()));
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"getAttribute");
+  }
+}
+void CXFA_Node::Script_Packet_SetAttribute(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 2) {
+    CFX_ByteString bsValue = pArguments->GetUTF8String(0);
+    CFX_ByteString bsName = pArguments->GetUTF8String(1);
+    IFDE_XMLNode* pXMLNode = GetXMLMappingNode();
+    if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
+      ((IFDE_XMLElement*)pXMLNode)
+          ->SetString(CFX_WideString::FromUTF8(bsName, bsName.GetLength()),
+                      CFX_WideString::FromUTF8(bsValue, bsValue.GetLength()));
+    }
+    FXJSE_Value_SetNull(pArguments->GetReturnValue());
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"setAttribute");
+  }
+}
+void CXFA_Node::Script_Packet_RemoveAttribute(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 1) {
+    CFX_ByteString bsName = pArguments->GetUTF8String(0);
+    CFX_WideString wsName =
+        CFX_WideString::FromUTF8(bsName, bsName.GetLength());
+    IFDE_XMLNode* pXMLNode = GetXMLMappingNode();
+    if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
+      IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLNode;
+      if (pXMLElement->HasAttribute(wsName)) {
+        pXMLElement->RemoveAttribute(wsName);
+      }
+    }
+    FXJSE_Value_SetNull(pArguments->GetReturnValue());
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"removeAttribute");
+  }
+}
+void CXFA_Node::Script_Packet_Content(FXJSE_HVALUE hValue,
+                                      FX_BOOL bSetting,
+                                      XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    CFX_ByteString bsNewContent;
+    FXJSE_Value_ToUTF8String(hValue, bsNewContent);
+    IFDE_XMLNode* pXMLNode = GetXMLMappingNode();
+    if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
+      IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLNode;
+      pXMLElement->SetTextData(
+          CFX_WideString::FromUTF8(bsNewContent, bsNewContent.GetLength()));
+    }
+  } else {
+    CFX_WideString wsTextData;
+    IFDE_XMLNode* pXMLNode = GetXMLMappingNode();
+    if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
+      IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLNode;
+      pXMLElement->GetTextData(wsTextData);
+    }
+    FXJSE_Value_SetUTF8String(
+        hValue, FX_UTF8Encode(wsTextData, wsTextData.GetLength()));
+  }
+}
+void CXFA_Node::Script_Source_Next(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"next");
+  }
+}
+void CXFA_Node::Script_Source_CancelBatch(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"cancelBatch");
+  }
+}
+void CXFA_Node::Script_Source_First(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"first");
+  }
+}
+void CXFA_Node::Script_Source_UpdateBatch(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"updateBatch");
+  }
+}
+void CXFA_Node::Script_Source_Previous(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"previous");
+  }
+}
+void CXFA_Node::Script_Source_IsBOF(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"isBOF");
+  }
+}
+void CXFA_Node::Script_Source_IsEOF(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"isEOF");
+  }
+}
+void CXFA_Node::Script_Source_Cancel(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"cancel");
+  }
+}
+void CXFA_Node::Script_Source_Update(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"update");
+  }
+}
+void CXFA_Node::Script_Source_Open(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"open");
+  }
+}
+void CXFA_Node::Script_Source_Delete(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"delete");
+  }
+}
+void CXFA_Node::Script_Source_AddNew(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"addNew");
+  }
+}
+void CXFA_Node::Script_Source_Requery(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"requery");
+  }
+}
+void CXFA_Node::Script_Source_Resync(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"resync");
+  }
+}
+void CXFA_Node::Script_Source_Close(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"close");
+  }
+}
+void CXFA_Node::Script_Source_Last(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"last");
+  }
+}
+void CXFA_Node::Script_Source_HasDataChanged(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 0) {
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"hasDataChanged");
+  }
+}
+void CXFA_Node::Script_Source_Db(FXJSE_HVALUE hValue,
+                                 FX_BOOL bSetting,
+                                 XFA_ATTRIBUTE eAttribute) {}
+void CXFA_Node::Script_Xfa_This(FXJSE_HVALUE hValue,
+                                FX_BOOL bSetting,
+                                XFA_ATTRIBUTE eAttribute) {
+  if (!bSetting) {
+    CXFA_Object* pThis = m_pDocument->GetScriptContext()->GetThisObject();
+    FXSYS_assert(pThis);
+    FXJSE_Value_Set(hValue,
+                    m_pDocument->GetScriptContext()->GetJSValueFromMap(pThis));
+  }
+}
+void CXFA_Node::Script_Handler_Version(FXJSE_HVALUE hValue,
+                                       FX_BOOL bSetting,
+                                       XFA_ATTRIBUTE eAttribute) {}
+void CXFA_Node::Script_SubmitFormat_Mode(FXJSE_HVALUE hValue,
+                                         FX_BOOL bSetting,
+                                         XFA_ATTRIBUTE eAttribute) {}
+void CXFA_Node::Script_Extras_Type(FXJSE_HVALUE hValue,
+                                   FX_BOOL bSetting,
+                                   XFA_ATTRIBUTE eAttribute) {}
+void CXFA_Node::Script_Script_Stateless(FXJSE_HVALUE hValue,
+                                        FX_BOOL bSetting,
+                                        XFA_ATTRIBUTE eAttribute) {
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+    return;
+  }
+  FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(FX_WSTRC(L"0")));
+}
+void CXFA_Node::Script_Encrypt_Format(FXJSE_HVALUE hValue,
+                                      FX_BOOL bSetting,
+                                      XFA_ATTRIBUTE eAttribute) {}
+enum XFA_KEYTYPE {
+  XFA_KEYTYPE_Custom,
+  XFA_KEYTYPE_Element,
+};
+void* XFA_GetMapKey_Custom(const CFX_WideStringC& wsKey) {
+  FX_DWORD dwKey = FX_HashCode_String_GetW(wsKey.GetPtr(), wsKey.GetLength());
+  return (void*)(uintptr_t)((dwKey << 1) | XFA_KEYTYPE_Custom);
+}
+void* XFA_GetMapKey_Element(XFA_ELEMENT eElement, XFA_ATTRIBUTE eAttribute) {
+  return (void*)(uintptr_t)((eElement << 16) | (eAttribute << 8) |
+                            XFA_KEYTYPE_Element);
+}
+FX_BOOL CXFA_Node::HasAttribute(XFA_ATTRIBUTE eAttr, FX_BOOL bCanInherit) {
+  void* pKey = XFA_GetMapKey_Element(GetClassID(), eAttr);
+  return HasMapModuleKey(pKey, bCanInherit);
+}
+FX_BOOL CXFA_Node::SetAttribute(XFA_ATTRIBUTE eAttr,
+                                const CFX_WideStringC& wsValue,
+                                FX_BOOL bNotify) {
+  const XFA_ATTRIBUTEINFO* pAttr = XFA_GetAttributeByID(eAttr);
+  if (pAttr == NULL) {
+    return FALSE;
+  }
+  XFA_ATTRIBUTETYPE eType = pAttr->eType;
+  if (eType == XFA_ATTRIBUTETYPE_NOTSURE) {
+    const XFA_NOTSUREATTRIBUTE* pNotsure =
+        XFA_GetNotsureAttribute(GetClassID(), pAttr->eName);
+    eType = pNotsure ? pNotsure->eType : XFA_ATTRIBUTETYPE_Cdata;
+  }
+  switch (eType) {
+    case XFA_ATTRIBUTETYPE_Enum: {
+      const XFA_ATTRIBUTEENUMINFO* pEnum = XFA_GetAttributeEnumByName(wsValue);
+      return SetEnum(pAttr->eName,
+                     pEnum ? pEnum->eName
+                           : (XFA_ATTRIBUTEENUM)(intptr_t)(pAttr->pDefValue),
+                     bNotify);
+    } break;
+    case XFA_ATTRIBUTETYPE_Cdata:
+      return SetCData(pAttr->eName, wsValue, bNotify);
+    case XFA_ATTRIBUTETYPE_Boolean:
+      return SetBoolean(pAttr->eName, wsValue != FX_WSTRC(L"0"), bNotify);
+    case XFA_ATTRIBUTETYPE_Integer:
+      return SetInteger(
+          pAttr->eName,
+          FXSYS_round(FX_wcstof(wsValue.GetPtr(), wsValue.GetLength())),
+          bNotify);
+    case XFA_ATTRIBUTETYPE_Measure:
+      return SetMeasure(pAttr->eName, CXFA_Measurement(wsValue), bNotify);
+    default:
+      break;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_Node::GetAttribute(XFA_ATTRIBUTE eAttr,
+                                CFX_WideString& wsValue,
+                                FX_BOOL bUseDefault) {
+  const XFA_ATTRIBUTEINFO* pAttr = XFA_GetAttributeByID(eAttr);
+  if (pAttr == NULL) {
+    return FALSE;
+  }
+  XFA_ATTRIBUTETYPE eType = pAttr->eType;
+  if (eType == XFA_ATTRIBUTETYPE_NOTSURE) {
+    const XFA_NOTSUREATTRIBUTE* pNotsure =
+        XFA_GetNotsureAttribute(GetClassID(), pAttr->eName);
+    eType = pNotsure ? pNotsure->eType : XFA_ATTRIBUTETYPE_Cdata;
+  }
+  switch (eType) {
+    case XFA_ATTRIBUTETYPE_Enum: {
+      XFA_ATTRIBUTEENUM eValue;
+      if (!TryEnum(pAttr->eName, eValue, bUseDefault)) {
+        return FALSE;
+      }
+      wsValue = XFA_GetAttributeEnumByID(eValue)->pName;
+      return TRUE;
+    } break;
+    case XFA_ATTRIBUTETYPE_Cdata: {
+      CFX_WideStringC wsValueC;
+      if (!TryCData(pAttr->eName, wsValueC, bUseDefault)) {
+        return FALSE;
+      }
+      wsValue = wsValueC;
+      return TRUE;
+    } break;
+    case XFA_ATTRIBUTETYPE_Boolean: {
+      FX_BOOL bValue;
+      if (!TryBoolean(pAttr->eName, bValue, bUseDefault)) {
+        return FALSE;
+      }
+      wsValue = bValue ? FX_WSTRC(L"1") : FX_WSTRC(L"0");
+      return TRUE;
+    } break;
+    case XFA_ATTRIBUTETYPE_Integer: {
+      int32_t iValue;
+      if (!TryInteger(pAttr->eName, iValue, bUseDefault)) {
+        return FALSE;
+      }
+      wsValue.Format(L"%d", iValue);
+      return TRUE;
+    } break;
+    case XFA_ATTRIBUTETYPE_Measure: {
+      CXFA_Measurement mValue;
+      if (!TryMeasure(pAttr->eName, mValue, bUseDefault)) {
+        return FALSE;
+      }
+      mValue.ToString(wsValue);
+      return TRUE;
+    } break;
+    default:
+      break;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_Node::SetAttribute(const CFX_WideStringC& wsAttr,
+                                const CFX_WideStringC& wsValue,
+                                FX_BOOL bNotify) {
+  const XFA_ATTRIBUTEINFO* pAttributeInfo = XFA_GetAttributeByName(wsValue);
+  if (pAttributeInfo) {
+    return SetAttribute(pAttributeInfo->eName, wsValue, bNotify);
+  }
+  void* pKey = XFA_GetMapKey_Custom(wsAttr);
+  SetMapModuleString(pKey, wsValue);
+  return TRUE;
+}
+FX_BOOL CXFA_Node::GetAttribute(const CFX_WideStringC& wsAttr,
+                                CFX_WideString& wsValue,
+                                FX_BOOL bUseDefault) {
+  const XFA_ATTRIBUTEINFO* pAttributeInfo = XFA_GetAttributeByName(wsAttr);
+  if (pAttributeInfo) {
+    return GetAttribute(pAttributeInfo->eName, wsValue, bUseDefault);
+  }
+  void* pKey = XFA_GetMapKey_Custom(wsAttr);
+  CFX_WideStringC wsValueC;
+  if (GetMapModuleString(pKey, wsValueC)) {
+    wsValue = wsValueC;
+  }
+  return TRUE;
+}
+FX_BOOL CXFA_Node::RemoveAttribute(const CFX_WideStringC& wsAttr) {
+  void* pKey = XFA_GetMapKey_Custom(wsAttr);
+  RemoveMapModuleKey(pKey);
+  return TRUE;
+}
+FX_BOOL CXFA_Node::TryBoolean(XFA_ATTRIBUTE eAttr,
+                              FX_BOOL& bValue,
+                              FX_BOOL bUseDefault) {
+  void* pValue = NULL;
+  if (!GetValue(eAttr, XFA_ATTRIBUTETYPE_Boolean, bUseDefault, pValue)) {
+    return FALSE;
+  }
+  bValue = (FX_BOOL)(uintptr_t)pValue;
+  return TRUE;
+}
+FX_BOOL CXFA_Node::TryInteger(XFA_ATTRIBUTE eAttr,
+                              int32_t& iValue,
+                              FX_BOOL bUseDefault) {
+  void* pValue = NULL;
+  if (!GetValue(eAttr, XFA_ATTRIBUTETYPE_Integer, bUseDefault, pValue)) {
+    return FALSE;
+  }
+  iValue = (int32_t)(uintptr_t)pValue;
+  return TRUE;
+}
+FX_BOOL CXFA_Node::TryEnum(XFA_ATTRIBUTE eAttr,
+                           XFA_ATTRIBUTEENUM& eValue,
+                           FX_BOOL bUseDefault) {
+  void* pValue = NULL;
+  if (!GetValue(eAttr, XFA_ATTRIBUTETYPE_Enum, bUseDefault, pValue)) {
+    return FALSE;
+  }
+  eValue = (XFA_ATTRIBUTEENUM)(uintptr_t)pValue;
+  return TRUE;
+}
+FX_BOOL CXFA_Node::SetMeasure(XFA_ATTRIBUTE eAttr,
+                              CXFA_Measurement mValue,
+                              FX_BOOL bNotify) {
+  void* pKey = XFA_GetMapKey_Element(GetClassID(), eAttr);
+  OnChanging(eAttr, &mValue, bNotify);
+  SetMapModuleBuffer(pKey, &mValue, sizeof(CXFA_Measurement));
+  OnChanged(eAttr, &mValue, bNotify);
+  return TRUE;
+}
+FX_BOOL CXFA_Node::TryMeasure(XFA_ATTRIBUTE eAttr,
+                              CXFA_Measurement& mValue,
+                              FX_BOOL bUseDefault) const {
+  void* pKey = XFA_GetMapKey_Element(GetClassID(), eAttr);
+  void* pValue;
+  int32_t iBytes;
+  if (GetMapModuleBuffer(pKey, pValue, iBytes) && iBytes == sizeof(mValue)) {
+    FXSYS_memcpy(&mValue, pValue, sizeof(mValue));
+    return TRUE;
+  }
+  if (bUseDefault &&
+      XFA_GetAttributeDefaultValue(pValue, GetClassID(), eAttr,
+                                   XFA_ATTRIBUTETYPE_Measure, m_ePacket)) {
+    FXSYS_memcpy(&mValue, pValue, sizeof(mValue));
+    return TRUE;
+  }
+  return FALSE;
+}
+
+CXFA_Measurement CXFA_Node::GetMeasure(XFA_ATTRIBUTE eAttr) const {
+  CXFA_Measurement mValue;
+  return TryMeasure(eAttr, mValue, TRUE) ? mValue : CXFA_Measurement();
+}
+
+FX_BOOL CXFA_Node::SetCData(XFA_ATTRIBUTE eAttr,
+                            const CFX_WideString& wsValue,
+                            FX_BOOL bNotify,
+                            FX_BOOL bScriptModify) {
+  void* pKey = XFA_GetMapKey_Element(GetClassID(), eAttr);
+  OnChanging(eAttr, (void*)(const FX_WCHAR*)wsValue, bNotify);
+  if (eAttr == XFA_ATTRIBUTE_Value) {
+    CFX_WideString* pClone = new CFX_WideString(wsValue);
+    SetUserData(pKey, pClone, &deleteWideStringCallBack);
+  } else {
+    SetMapModuleString(pKey, wsValue);
+    if (eAttr == XFA_ATTRIBUTE_Name)
+      UpdateNameHash();
+  }
+  OnChanged(eAttr, (void*)(const FX_WCHAR*)wsValue, bNotify, bScriptModify);
+  if (IsNeedSavingXMLNode() && eAttr != XFA_ATTRIBUTE_QualifiedName &&
+      eAttr != XFA_ATTRIBUTE_BindingNode) {
+    if (eAttr == XFA_ATTRIBUTE_Name &&
+        (m_eNodeClass == XFA_ELEMENT_DataValue ||
+         m_eNodeClass == XFA_ELEMENT_DataGroup)) {
+      return TRUE;
+    }
+    if (eAttr == XFA_ATTRIBUTE_Value) {
+      FDE_XMLNODETYPE eXMLType = m_pXMLNode->GetType();
+      switch (eXMLType) {
+        case FDE_XMLNODE_Element:
+          if (IsAttributeInXML()) {
+            ((IFDE_XMLElement*)m_pXMLNode)
+                ->SetString(GetCData(XFA_ATTRIBUTE_QualifiedName), wsValue);
+          } else {
+            FX_BOOL bDeleteChildren = TRUE;
+            if (GetPacketID() == XFA_XDPPACKET_Datasets) {
+              for (CXFA_Node* pChildDataNode =
+                       GetNodeItem(XFA_NODEITEM_FirstChild);
+                   pChildDataNode; pChildDataNode = pChildDataNode->GetNodeItem(
+                                       XFA_NODEITEM_NextSibling)) {
+                CXFA_NodeArray formNodes;
+                if (pChildDataNode->GetBindItems(formNodes) > 0) {
+                  bDeleteChildren = FALSE;
+                  break;
+                }
+              }
+            }
+            if (bDeleteChildren) {
+              ((IFDE_XMLElement*)m_pXMLNode)->DeleteChildren();
+            }
+            ((IFDE_XMLElement*)m_pXMLNode)->SetTextData(wsValue);
+          }
+          break;
+        case FDE_XMLNODE_Text:
+          ((IFDE_XMLText*)m_pXMLNode)->SetText(wsValue);
+          break;
+        default:
+          FXSYS_assert(0);
+      }
+      return TRUE;
+    }
+    const XFA_ATTRIBUTEINFO* pInfo = XFA_GetAttributeByID(eAttr);
+    if (pInfo) {
+      FXSYS_assert(m_pXMLNode->GetType() == FDE_XMLNODE_Element);
+      CFX_WideString wsAttrName = pInfo->pName;
+      if (pInfo->eName == XFA_ATTRIBUTE_ContentType) {
+        wsAttrName = FX_WSTRC(L"xfa:") + wsAttrName;
+      }
+      ((IFDE_XMLElement*)m_pXMLNode)->SetString(wsAttrName, wsValue);
+    }
+  }
+  return TRUE;
+}
+FX_BOOL CXFA_Node::SetAttributeValue(const CFX_WideString& wsValue,
+                                     const CFX_WideString& wsXMLValue,
+                                     FX_BOOL bNotify,
+                                     FX_BOOL bScriptModify) {
+  void* pKey = XFA_GetMapKey_Element(GetClassID(), XFA_ATTRIBUTE_Value);
+  OnChanging(XFA_ATTRIBUTE_Value, (void*)(const FX_WCHAR*)wsValue, bNotify);
+  CFX_WideString* pClone = new CFX_WideString(wsValue);
+  SetUserData(pKey, pClone, &deleteWideStringCallBack);
+  OnChanged(XFA_ATTRIBUTE_Value, (void*)(const FX_WCHAR*)wsValue, bNotify,
+            bScriptModify);
+  if (IsNeedSavingXMLNode()) {
+    FDE_XMLNODETYPE eXMLType = m_pXMLNode->GetType();
+    switch (eXMLType) {
+      case FDE_XMLNODE_Element:
+        if (IsAttributeInXML()) {
+          ((IFDE_XMLElement*)m_pXMLNode)
+              ->SetString(GetCData(XFA_ATTRIBUTE_QualifiedName), wsXMLValue);
+        } else {
+          FX_BOOL bDeleteChildren = TRUE;
+          if (GetPacketID() == XFA_XDPPACKET_Datasets) {
+            for (CXFA_Node* pChildDataNode =
+                     GetNodeItem(XFA_NODEITEM_FirstChild);
+                 pChildDataNode; pChildDataNode = pChildDataNode->GetNodeItem(
+                                     XFA_NODEITEM_NextSibling)) {
+              CXFA_NodeArray formNodes;
+              if (pChildDataNode->GetBindItems(formNodes) > 0) {
+                bDeleteChildren = FALSE;
+                break;
+              }
+            }
+          }
+          if (bDeleteChildren) {
+            ((IFDE_XMLElement*)m_pXMLNode)->DeleteChildren();
+          }
+          ((IFDE_XMLElement*)m_pXMLNode)->SetTextData(wsXMLValue);
+        }
+        break;
+      case FDE_XMLNODE_Text:
+        ((IFDE_XMLText*)m_pXMLNode)->SetText(wsXMLValue);
+        break;
+      default:
+        FXSYS_assert(0);
+    }
+  }
+  return TRUE;
+}
+FX_BOOL CXFA_Node::TryCData(XFA_ATTRIBUTE eAttr,
+                            CFX_WideString& wsValue,
+                            FX_BOOL bUseDefault,
+                            FX_BOOL bProto) {
+  void* pKey = XFA_GetMapKey_Element(GetClassID(), eAttr);
+  if (eAttr == XFA_ATTRIBUTE_Value) {
+    CFX_WideString* pStr = (CFX_WideString*)GetUserData(pKey, bProto);
+    if (pStr) {
+      wsValue = *pStr;
+      return TRUE;
+    }
+  } else {
+    CFX_WideStringC wsValueC;
+    if (GetMapModuleString(pKey, wsValueC)) {
+      wsValue = wsValueC;
+      return TRUE;
+    }
+  }
+  if (!bUseDefault) {
+    return FALSE;
+  }
+  void* pValue = NULL;
+  if (XFA_GetAttributeDefaultValue(pValue, GetClassID(), eAttr,
+                                   XFA_ATTRIBUTETYPE_Cdata, m_ePacket)) {
+    wsValue = (const FX_WCHAR*)pValue;
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_Node::TryCData(XFA_ATTRIBUTE eAttr,
+                            CFX_WideStringC& wsValue,
+                            FX_BOOL bUseDefault,
+                            FX_BOOL bProto) {
+  void* pKey = XFA_GetMapKey_Element(GetClassID(), eAttr);
+  if (eAttr == XFA_ATTRIBUTE_Value) {
+    CFX_WideString* pStr = (CFX_WideString*)GetUserData(pKey, bProto);
+    if (pStr) {
+      wsValue = *pStr;
+      return TRUE;
+    }
+  } else {
+    if (GetMapModuleString(pKey, wsValue)) {
+      return TRUE;
+    }
+  }
+  if (!bUseDefault) {
+    return FALSE;
+  }
+  void* pValue = NULL;
+  if (XFA_GetAttributeDefaultValue(pValue, GetClassID(), eAttr,
+                                   XFA_ATTRIBUTETYPE_Cdata, m_ePacket)) {
+    wsValue = (CFX_WideStringC)(const FX_WCHAR*)pValue;
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_Node::SetObject(XFA_ATTRIBUTE eAttr,
+                             void* pData,
+                             XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo) {
+  void* pKey = XFA_GetMapKey_Element(GetClassID(), eAttr);
+  return SetUserData(pKey, pData, pCallbackInfo);
+}
+FX_BOOL CXFA_Node::TryObject(XFA_ATTRIBUTE eAttr, void*& pData) {
+  void* pKey = XFA_GetMapKey_Element(GetClassID(), eAttr);
+  pData = GetUserData(pKey);
+  return pData != NULL;
+}
+FX_BOOL CXFA_Node::SetValue(XFA_ATTRIBUTE eAttr,
+                            XFA_ATTRIBUTETYPE eType,
+                            void* pValue,
+                            FX_BOOL bNotify) {
+  void* pKey = XFA_GetMapKey_Element(GetClassID(), eAttr);
+  OnChanging(eAttr, pValue, bNotify);
+  SetMapModuleValue(pKey, pValue);
+  OnChanged(eAttr, pValue, bNotify);
+  if (IsNeedSavingXMLNode()) {
+    FXSYS_assert(m_pXMLNode->GetType() == FDE_XMLNODE_Element);
+    const XFA_ATTRIBUTEINFO* pInfo = XFA_GetAttributeByID(eAttr);
+    if (pInfo) {
+      switch (eType) {
+        case XFA_ATTRIBUTETYPE_Enum:
+          ((IFDE_XMLElement*)m_pXMLNode)
+              ->SetString(
+                  pInfo->pName,
+                  XFA_GetAttributeEnumByID((XFA_ATTRIBUTEENUM)(uintptr_t)pValue)
+                      ->pName);
+          break;
+        case XFA_ATTRIBUTETYPE_Boolean:
+          ((IFDE_XMLElement*)m_pXMLNode)
+              ->SetString(pInfo->pName,
+                          pValue ? FX_WSTRC(L"1") : FX_WSTRC(L"0"));
+          break;
+        case XFA_ATTRIBUTETYPE_Integer:
+          ((IFDE_XMLElement*)m_pXMLNode)
+              ->SetInteger(pInfo->pName, (int32_t)(uintptr_t)pValue);
+          break;
+        default:
+          FXSYS_assert(0);
+      }
+    }
+  }
+  return TRUE;
+}
+FX_BOOL CXFA_Node::GetValue(XFA_ATTRIBUTE eAttr,
+                            XFA_ATTRIBUTETYPE eType,
+                            FX_BOOL bUseDefault,
+                            void*& pValue) {
+  void* pKey = XFA_GetMapKey_Element(GetClassID(), eAttr);
+  if (GetMapModuleValue(pKey, pValue)) {
+    return TRUE;
+  }
+  if (!bUseDefault) {
+    return FALSE;
+  }
+  return XFA_GetAttributeDefaultValue(pValue, GetClassID(), eAttr, eType,
+                                      m_ePacket);
+}
+static void XFA_DefaultFreeData(void* pData) {}
+static XFA_MAPDATABLOCKCALLBACKINFO gs_XFADefaultFreeData = {
+    XFA_DefaultFreeData, NULL};
+FX_BOOL CXFA_Node::SetUserData(void* pKey,
+                               void* pData,
+                               XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo) {
+  SetMapModuleBuffer(pKey, &pData, sizeof(void*),
+                     pCallbackInfo ? pCallbackInfo : &gs_XFADefaultFreeData);
+  return TRUE;
+}
+FX_BOOL CXFA_Node::TryUserData(void* pKey, void*& pData, FX_BOOL bProtoAlso) {
+  int32_t iBytes = 0;
+  if (!GetMapModuleBuffer(pKey, pData, iBytes, bProtoAlso)) {
+    return FALSE;
+  }
+  return iBytes == sizeof(void*) && FXSYS_memcpy(&pData, pData, iBytes);
+}
+FX_BOOL CXFA_Node::SetScriptContent(const CFX_WideString& wsContent,
+                                    const CFX_WideString& wsXMLValue,
+                                    FX_BOOL bNotify,
+                                    FX_BOOL bScriptModify,
+                                    FX_BOOL bSyncData) {
+  CXFA_Node* pNode = NULL;
+  CXFA_Node* pBindNode = NULL;
+  switch (GetObjectType()) {
+    case XFA_OBJECTTYPE_ContainerNode: {
+      if (XFA_FieldIsMultiListBox(this)) {
+        CXFA_Node* pValue = GetProperty(0, XFA_ELEMENT_Value);
+        CXFA_Node* pChildValue = pValue->GetNodeItem(XFA_NODEITEM_FirstChild);
+        FXSYS_assert(pChildValue);
+        pChildValue->SetCData(XFA_ATTRIBUTE_ContentType, FX_WSTRC(L"text/xml"));
+        pChildValue->SetScriptContent(wsContent, wsContent, bNotify,
+                                      bScriptModify, FALSE);
+        CXFA_Node* pBind = GetBindData();
+        if (bSyncData && pBind) {
+          CFX_WideStringArray wsSaveTextArray;
+          int32_t iSize = 0;
+          if (!wsContent.IsEmpty()) {
+            int32_t iStart = 0;
+            int32_t iLength = wsContent.GetLength();
+            int32_t iEnd = wsContent.Find(L'\n', iStart);
+            iEnd = (iEnd == -1) ? iLength : iEnd;
+            while (iEnd >= iStart) {
+              wsSaveTextArray.Add(wsContent.Mid(iStart, iEnd - iStart));
+              iStart = iEnd + 1;
+              if (iStart >= iLength) {
+                break;
+              }
+              iEnd = wsContent.Find(L'\n', iStart);
+              if (iEnd < 0) {
+                wsSaveTextArray.Add(wsContent.Mid(iStart, iLength - iStart));
+              }
+            }
+            iSize = wsSaveTextArray.GetSize();
+          }
+          if (iSize == 0) {
+            while (CXFA_Node* pChildNode =
+                       pBind->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+              pBind->RemoveChild(pChildNode);
+            }
+          } else {
+            CXFA_NodeArray valueNodes;
+            int32_t iDatas = pBind->GetNodeList(
+                valueNodes, XFA_NODEFILTER_Children, XFA_ELEMENT_DataValue);
+            if (iDatas < iSize) {
+              int32_t iAddNodes = iSize - iDatas;
+              CXFA_Node* pValueNodes = NULL;
+              while (iAddNodes-- > 0) {
+                pValueNodes =
+                    pBind->CreateSamePacketNode(XFA_ELEMENT_DataValue);
+                pValueNodes->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L"value"));
+                pValueNodes->CreateXMLMappingNode();
+                pBind->InsertChild(pValueNodes);
+              }
+              pValueNodes = NULL;
+            } else if (iDatas > iSize) {
+              int32_t iDelNodes = iDatas - iSize;
+              while (iDelNodes-- > 0) {
+                pBind->RemoveChild(pBind->GetNodeItem(XFA_NODEITEM_FirstChild));
+              }
+            }
+            int32_t i = 0;
+            for (CXFA_Node* pValueNode =
+                     pBind->GetNodeItem(XFA_NODEITEM_FirstChild);
+                 pValueNode; pValueNode = pValueNode->GetNodeItem(
+                                 XFA_NODEITEM_NextSibling)) {
+              pValueNode->SetAttributeValue(wsSaveTextArray[i],
+                                            wsSaveTextArray[i], FALSE);
+              i++;
+            }
+          }
+          CXFA_NodeArray nodeArray;
+          pBind->GetBindItems(nodeArray);
+          for (int32_t i = 0; i < nodeArray.GetSize(); i++) {
+            CXFA_Node* pNode = nodeArray[i];
+            if (pNode == this) {
+              continue;
+            }
+            pNode->SetScriptContent(wsContent, wsContent, bNotify,
+                                    bScriptModify, FALSE);
+          }
+        }
+        break;
+      } else if (GetClassID() == XFA_ELEMENT_ExclGroup) {
+        pNode = this;
+      } else {
+        CXFA_Node* pValue = GetProperty(0, XFA_ELEMENT_Value);
+        CXFA_Node* pChildValue = pValue->GetNodeItem(XFA_NODEITEM_FirstChild);
+        FXSYS_assert(pChildValue);
+        pChildValue->SetScriptContent(wsContent, wsContent, bNotify,
+                                      bScriptModify, FALSE);
+      }
+      pBindNode = GetBindData();
+      if (pBindNode && bSyncData) {
+        pBindNode->SetScriptContent(wsContent, wsXMLValue, bNotify,
+                                    bScriptModify, FALSE);
+        CXFA_NodeArray nodeArray;
+        pBindNode->GetBindItems(nodeArray);
+        for (int32_t i = 0; i < nodeArray.GetSize(); i++) {
+          CXFA_Node* pNode = nodeArray[i];
+          if (pNode == this) {
+            continue;
+          }
+          pNode->SetScriptContent(wsContent, wsContent, bNotify, TRUE, FALSE);
+        }
+      }
+      pBindNode = NULL;
+      break;
+    }
+    case XFA_OBJECTTYPE_ContentNode: {
+      CFX_WideString wsContentType;
+      if (GetClassID() == XFA_ELEMENT_ExData) {
+        GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);
+        if (wsContentType.Equal(FX_WSTRC(L"text/html"))) {
+          wsContentType = FX_WSTRC(L"");
+          SetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType);
+        }
+      }
+      CXFA_Node* pContentRawDataNode = GetNodeItem(XFA_NODEITEM_FirstChild);
+      if (!pContentRawDataNode) {
+        pContentRawDataNode =
+            CreateSamePacketNode((wsContentType.Equal(FX_WSTRC(L"text/xml")))
+                                     ? XFA_ELEMENT_Sharpxml
+                                     : XFA_ELEMENT_Sharptext);
+        InsertChild(pContentRawDataNode);
+      }
+      return pContentRawDataNode->SetScriptContent(
+          wsContent, wsXMLValue, bNotify, bScriptModify, bSyncData);
+    } break;
+    case XFA_OBJECTTYPE_NodeC:
+    case XFA_OBJECTTYPE_TextNode:
+      pNode = this;
+      break;
+    case XFA_OBJECTTYPE_NodeV:
+      pNode = this;
+      if (bSyncData && GetPacketID() == XFA_XDPPACKET_Form) {
+        CXFA_Node* pParent = GetNodeItem(XFA_NODEITEM_Parent);
+        if (pParent) {
+          pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent);
+        }
+        if (pParent && pParent->GetClassID() == XFA_ELEMENT_Value) {
+          pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent);
+          if (pParent && pParent->IsContainerNode()) {
+            pBindNode = pParent->GetBindData();
+            if (pBindNode) {
+              pBindNode->SetScriptContent(wsContent, wsXMLValue, bNotify,
+                                          bScriptModify, FALSE);
+            }
+          }
+        }
+      }
+      break;
+    default:
+      if (GetClassID() == XFA_ELEMENT_DataValue) {
+        pNode = this;
+        pBindNode = this;
+      }
+      break;
+  }
+  if (pNode) {
+    SetAttributeValue(wsContent, wsXMLValue, bNotify, bScriptModify);
+    if (pBindNode && bSyncData) {
+      CXFA_NodeArray nodeArray;
+      pBindNode->GetBindItems(nodeArray);
+      for (int32_t i = 0; i < nodeArray.GetSize(); i++) {
+        CXFA_Node* pNode = nodeArray[i];
+        pNode->SetScriptContent(wsContent, wsContent, bNotify, bScriptModify,
+                                FALSE);
+      }
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_Node::SetContent(const CFX_WideString& wsContent,
+                              const CFX_WideString& wsXMLValue,
+                              FX_BOOL bNotify,
+                              FX_BOOL bScriptModify,
+                              FX_BOOL bSyncData) {
+  return SetScriptContent(wsContent, wsXMLValue, bNotify, bScriptModify,
+                          bSyncData);
+}
+CFX_WideString CXFA_Node::GetScriptContent(FX_BOOL bScriptModify) {
+  CFX_WideString wsContent;
+  return TryContent(wsContent, bScriptModify) ? wsContent : CFX_WideString();
+}
+CFX_WideString CXFA_Node::GetContent() {
+  return GetScriptContent();
+}
+FX_BOOL CXFA_Node::TryContent(CFX_WideString& wsContent,
+                              FX_BOOL bScriptModify,
+                              FX_BOOL bProto) {
+  CXFA_Node* pNode = NULL;
+  switch (GetObjectType()) {
+    case XFA_OBJECTTYPE_ContainerNode:
+      if (GetClassID() == XFA_ELEMENT_ExclGroup) {
+        pNode = this;
+      } else {
+        CXFA_Node* pValue = GetChild(0, XFA_ELEMENT_Value);
+        if (!pValue) {
+          return FALSE;
+        }
+        CXFA_Node* pChildValue = pValue->GetNodeItem(XFA_NODEITEM_FirstChild);
+        if (pChildValue && XFA_FieldIsMultiListBox(this)) {
+          pChildValue->SetAttribute(XFA_ATTRIBUTE_ContentType,
+                                    FX_WSTRC(L"text/xml"));
+        }
+        return pChildValue
+                   ? pChildValue->TryContent(wsContent, bScriptModify, bProto)
+                   : FALSE;
+      }
+      break;
+    case XFA_OBJECTTYPE_ContentNode: {
+      CXFA_Node* pContentRawDataNode = GetNodeItem(XFA_NODEITEM_FirstChild);
+      if (!pContentRawDataNode) {
+        XFA_ELEMENT element = XFA_ELEMENT_Sharptext;
+        if (GetClassID() == XFA_ELEMENT_ExData) {
+          CFX_WideString wsContentType;
+          GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);
+          if (wsContentType.Equal(FX_WSTRC(L"text/html"))) {
+            element = XFA_ELEMENT_SharpxHTML;
+          } else if (wsContentType.Equal(FX_WSTRC(L"text/xml"))) {
+            element = XFA_ELEMENT_Sharpxml;
+          }
+        }
+        pContentRawDataNode = CreateSamePacketNode(element);
+        InsertChild(pContentRawDataNode);
+      }
+      return pContentRawDataNode->TryContent(wsContent, bScriptModify, bProto);
+    }
+    case XFA_OBJECTTYPE_NodeC:
+    case XFA_OBJECTTYPE_NodeV:
+    case XFA_OBJECTTYPE_TextNode:
+      pNode = this;
+    default:
+      if (GetClassID() == XFA_ELEMENT_DataValue) {
+        pNode = this;
+      }
+      break;
+  }
+  if (pNode) {
+    if (bScriptModify) {
+      IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+      if (pScriptContext) {
+        m_pDocument->GetScriptContext()->AddNodesOfRunScript(this);
+      }
+    }
+    return TryCData(XFA_ATTRIBUTE_Value, wsContent, FALSE, bProto);
+  }
+  return FALSE;
+}
+CXFA_Node* CXFA_Node::GetModelNode() {
+  switch (GetPacketID()) {
+    case XFA_XDPPACKET_XDP:
+      return m_pDocument->GetRoot();
+    case XFA_XDPPACKET_Config:
+      return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Config));
+    case XFA_XDPPACKET_Template:
+      return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Template));
+    case XFA_XDPPACKET_Form:
+      return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Form));
+    case XFA_XDPPACKET_Datasets:
+      return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Datasets));
+    case XFA_XDPPACKET_LocaleSet:
+      return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_LocaleSet));
+    case XFA_XDPPACKET_ConnectionSet:
+      return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_ConnectionSet));
+    case XFA_XDPPACKET_SourceSet:
+      return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_SourceSet));
+    case XFA_XDPPACKET_Xdc:
+      return ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Xdc));
+    default:
+      return this;
+  }
+}
+FX_BOOL CXFA_Node::TryNamespace(CFX_WideString& wsNamespace) {
+  wsNamespace.Empty();
+  if (GetObjectType() == XFA_OBJECTTYPE_ModelNode ||
+      GetClassID() == XFA_ELEMENT_Packet) {
+    IFDE_XMLNode* pXMLNode = GetXMLMappingNode();
+    if (!pXMLNode || pXMLNode->GetType() != FDE_XMLNODE_Element) {
+      return FALSE;
+    }
+    ((IFDE_XMLElement*)pXMLNode)->GetNamespaceURI(wsNamespace);
+    return TRUE;
+  } else if (GetPacketID() == XFA_XDPPACKET_Datasets) {
+    IFDE_XMLNode* pXMLNode = GetXMLMappingNode();
+    if (!pXMLNode) {
+      return FALSE;
+    }
+    if (pXMLNode->GetType() != FDE_XMLNODE_Element) {
+      return TRUE;
+    }
+    if (GetClassID() == XFA_ELEMENT_DataValue &&
+        GetEnum(XFA_ATTRIBUTE_Contains) == XFA_ATTRIBUTEENUM_MetaData) {
+      return XFA_FDEExtension_ResolveNamespaceQualifier(
+          (IFDE_XMLElement*)pXMLNode, GetCData(XFA_ATTRIBUTE_QualifiedName),
+          wsNamespace);
+    }
+    ((IFDE_XMLElement*)pXMLNode)->GetNamespaceURI(wsNamespace);
+    return TRUE;
+  } else {
+    CXFA_Node* pModelNode = GetModelNode();
+    return pModelNode->TryNamespace(wsNamespace);
+  }
+}
+CXFA_Node* CXFA_Node::GetProperty(int32_t index,
+                                  XFA_ELEMENT eProperty,
+                                  FX_BOOL bCreateProperty) {
+  XFA_ELEMENT eElement = GetClassID();
+  FX_DWORD dwPacket = GetPacketID();
+  const XFA_PROPERTY* pProperty =
+      XFA_GetPropertyOfElement(eElement, eProperty, dwPacket);
+  if (pProperty == NULL || index >= pProperty->uOccur) {
+    return NULL;
+  }
+  CXFA_Node* pNode = m_pChild;
+  int32_t iCount = 0;
+  for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pNode->GetClassID() == eProperty) {
+      iCount++;
+      if (iCount > index) {
+        return pNode;
+      }
+    }
+  }
+  if (!bCreateProperty) {
+    return NULL;
+  }
+  if (pProperty->uFlags & XFA_PROPERTYFLAG_OneOf) {
+    pNode = m_pChild;
+    for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+      const XFA_PROPERTY* pExistProperty =
+          XFA_GetPropertyOfElement(eElement, pNode->GetClassID(), dwPacket);
+      if (pExistProperty && (pExistProperty->uFlags & XFA_PROPERTYFLAG_OneOf)) {
+        return NULL;
+      }
+    }
+  }
+  IXFA_ObjFactory* pFactory = m_pDocument->GetParser()->GetFactory();
+  const XFA_PACKETINFO* pPacket = XFA_GetPacketByID(dwPacket);
+  CXFA_Node* pNewNode;
+  for (; iCount <= index; iCount++) {
+    pNewNode = pFactory->CreateNode(pPacket, eProperty);
+    if (!pNewNode) {
+      return NULL;
+    }
+    InsertChild(pNewNode, nullptr);
+    pNewNode->SetFlag(XFA_NODEFLAG_Initialized);
+  }
+  return pNewNode;
+}
+int32_t CXFA_Node::CountChildren(XFA_ELEMENT eElement, FX_BOOL bOnlyChild) {
+  CXFA_Node* pNode = m_pChild;
+  int32_t iCount = 0;
+  for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pNode->GetClassID() == eElement || eElement == XFA_ELEMENT_UNKNOWN) {
+      if (bOnlyChild) {
+        const XFA_PROPERTY* pProperty = XFA_GetPropertyOfElement(
+            GetClassID(), pNode->GetClassID(), XFA_XDPPACKET_UNKNOWN);
+        if (pProperty) {
+          continue;
+        }
+      }
+      iCount++;
+    }
+  }
+  return iCount;
+}
+CXFA_Node* CXFA_Node::GetChild(int32_t index,
+                               XFA_ELEMENT eElement,
+                               FX_BOOL bOnlyChild) {
+  FXSYS_assert(index > -1);
+  CXFA_Node* pNode = m_pChild;
+  int32_t iCount = 0;
+  for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pNode->GetClassID() == eElement || eElement == XFA_ELEMENT_UNKNOWN) {
+      if (bOnlyChild) {
+        const XFA_PROPERTY* pProperty = XFA_GetPropertyOfElement(
+            GetClassID(), pNode->GetClassID(), XFA_XDPPACKET_UNKNOWN);
+        if (pProperty) {
+          continue;
+        }
+      }
+      iCount++;
+      if (iCount > index) {
+        return pNode;
+      }
+    }
+  }
+  return NULL;
+}
+int32_t CXFA_Node::InsertChild(int32_t index, CXFA_Node* pNode) {
+  ASSERT(!pNode->m_pNext);
+  pNode->m_pParent = this;
+  FX_BOOL bWasPurgeNode = m_pDocument->RemovePurgeNode(pNode);
+  if (!bWasPurgeNode)
+    FXSYS_assert(false);
+
+  if (m_pChild == NULL || index == 0) {
+    if (index > 0) {
+      return -1;
+    }
+    pNode->m_pNext = m_pChild;
+    m_pChild = pNode;
+    index = 0;
+  } else if (index < 0) {
+    m_pLastChild->m_pNext = pNode;
+  } else {
+    CXFA_Node* pPrev = m_pChild;
+    int32_t iCount = 0;
+    while (++iCount != index && pPrev->m_pNext) {
+      pPrev = pPrev->m_pNext;
+    }
+    if (index > 0 && index != iCount) {
+      return -1;
+    }
+    pNode->m_pNext = pPrev->m_pNext;
+    pPrev->m_pNext = pNode;
+    index = iCount;
+  }
+  if (pNode->m_pNext == NULL) {
+    m_pLastChild = pNode;
+  }
+  ASSERT(m_pLastChild);
+  ASSERT(m_pLastChild->m_pNext == NULL);
+  pNode->SetFlag(XFA_NODEFLAG_HasRemoved, FALSE);
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (pNotify) {
+    pNotify->OnNodeEvent(this, XFA_NODEEVENT_ChildAdded, pNode);
+  }
+  if (IsNeedSavingXMLNode() && pNode->m_pXMLNode) {
+    FXSYS_assert(pNode->m_pXMLNode->GetNodeItem(IFDE_XMLNode::Parent) == NULL);
+    m_pXMLNode->InsertChildNode(pNode->m_pXMLNode, index);
+    pNode->SetFlag(XFA_NODEFLAG_OwnXMLNode, FALSE, FALSE);
+  }
+  return index;
+}
+FX_BOOL CXFA_Node::InsertChild(CXFA_Node* pNode, CXFA_Node* pBeforeNode) {
+  if (!pNode || pNode->m_pParent ||
+      (pBeforeNode && pBeforeNode->m_pParent != this)) {
+    FXSYS_assert(false);
+    return FALSE;
+  }
+  FX_BOOL bWasPurgeNode = m_pDocument->RemovePurgeNode(pNode);
+  if (!bWasPurgeNode)
+    FXSYS_assert(false);
+
+  int32_t nIndex = -1;
+  pNode->m_pParent = this;
+  if (m_pChild == NULL || pBeforeNode == m_pChild) {
+    pNode->m_pNext = m_pChild;
+    m_pChild = pNode;
+    nIndex = 0;
+  } else if (!pBeforeNode) {
+    pNode->m_pNext = m_pLastChild->m_pNext;
+    m_pLastChild->m_pNext = pNode;
+  } else {
+    nIndex = 1;
+    CXFA_Node* pPrev = m_pChild;
+    while (pPrev->m_pNext != pBeforeNode) {
+      pPrev = pPrev->m_pNext;
+      nIndex++;
+    }
+    pNode->m_pNext = pPrev->m_pNext;
+    pPrev->m_pNext = pNode;
+  }
+  if (pNode->m_pNext == NULL) {
+    m_pLastChild = pNode;
+  }
+  ASSERT(m_pLastChild);
+  ASSERT(m_pLastChild->m_pNext == NULL);
+  pNode->SetFlag(XFA_NODEFLAG_HasRemoved, FALSE);
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (pNotify) {
+    pNotify->OnNodeEvent(this, XFA_NODEEVENT_ChildAdded, pNode);
+  }
+  if (IsNeedSavingXMLNode() && pNode->m_pXMLNode) {
+    FXSYS_assert(pNode->m_pXMLNode->GetNodeItem(IFDE_XMLNode::Parent) == NULL);
+    m_pXMLNode->InsertChildNode(pNode->m_pXMLNode, nIndex);
+    pNode->SetFlag(XFA_NODEFLAG_OwnXMLNode, FALSE, FALSE);
+  }
+  return TRUE;
+}
+CXFA_Node* CXFA_Node::Deprecated_GetPrevSibling() {
+  if (!m_pParent) {
+    return NULL;
+  }
+  for (CXFA_Node* pSibling = m_pParent->m_pChild; pSibling;
+       pSibling = pSibling->m_pNext) {
+    if (pSibling->m_pNext == this) {
+      return pSibling;
+    }
+  }
+  return NULL;
+}
+FX_BOOL CXFA_Node::RemoveChild(CXFA_Node* pNode, FX_BOOL bNotify) {
+  if (pNode == NULL || pNode->m_pParent != this) {
+    FXSYS_assert(FALSE);
+    return FALSE;
+  }
+  if (m_pChild == pNode) {
+    m_pChild = pNode->m_pNext;
+    if (m_pLastChild == pNode) {
+      m_pLastChild = pNode->m_pNext;
+    }
+    pNode->m_pNext = NULL;
+    pNode->m_pParent = NULL;
+  } else {
+    CXFA_Node* pPrev = pNode->Deprecated_GetPrevSibling();
+    pPrev->m_pNext = pNode->m_pNext;
+    if (m_pLastChild == pNode) {
+      m_pLastChild = pNode->m_pNext ? pNode->m_pNext : pPrev;
+    }
+    pNode->m_pNext = NULL;
+    pNode->m_pParent = NULL;
+  }
+  ASSERT(m_pLastChild == NULL || m_pLastChild->m_pNext == NULL);
+  OnRemoved(this, pNode, bNotify);
+  pNode->SetFlag(XFA_NODEFLAG_HasRemoved);
+  m_pDocument->AddPurgeNode(pNode);
+  if (IsNeedSavingXMLNode() && pNode->m_pXMLNode) {
+    if (pNode->IsAttributeInXML()) {
+      FXSYS_assert(pNode->m_pXMLNode == m_pXMLNode &&
+                   m_pXMLNode->GetType() == FDE_XMLNODE_Element);
+      if (pNode->m_pXMLNode->GetType() == FDE_XMLNODE_Element) {
+        IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)(pNode->m_pXMLNode);
+        CFX_WideStringC wsAttributeName =
+            pNode->GetCData(XFA_ATTRIBUTE_QualifiedName);
+        pXMLElement->RemoveAttribute(wsAttributeName.GetPtr());
+      }
+      CFX_WideString wsName;
+      pNode->GetAttribute(XFA_ATTRIBUTE_Name, wsName, FALSE);
+      IFDE_XMLElement* pNewXMLElement = IFDE_XMLElement::Create(wsName);
+      CFX_WideStringC wsValue = GetCData(XFA_ATTRIBUTE_Value);
+      if (!wsValue.IsEmpty()) {
+        pNewXMLElement->SetTextData(wsValue);
+      }
+      pNode->m_pXMLNode = pNewXMLElement;
+      pNode->SetEnum(XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTEENUM_Unknown);
+    } else {
+      m_pXMLNode->RemoveChildNode(pNode->m_pXMLNode);
+    }
+    pNode->SetFlag(XFA_NODEFLAG_OwnXMLNode, TRUE, FALSE);
+  }
+  return TRUE;
+}
+CXFA_Node* CXFA_Node::GetFirstChildByName(const CFX_WideStringC& wsName) const {
+  return GetFirstChildByName(
+      wsName.IsEmpty() ? 0 : FX_HashCode_String_GetW(wsName.GetPtr(),
+                                                     wsName.GetLength()));
+}
+CXFA_Node* CXFA_Node::GetFirstChildByName(FX_DWORD dwNameHash) const {
+  for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_FirstChild); pNode;
+       pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pNode->GetNameHash() == dwNameHash) {
+      return pNode;
+    }
+  }
+  return NULL;
+}
+CXFA_Node* CXFA_Node::GetFirstChildByClass(XFA_ELEMENT eElement) const {
+  for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_FirstChild); pNode;
+       pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pNode->GetClassID() == eElement) {
+      return pNode;
+    }
+  }
+  return NULL;
+}
+CXFA_Node* CXFA_Node::GetNextSameNameSibling(FX_DWORD dwNameHash) const {
+  for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_NextSibling); pNode;
+       pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pNode->GetNameHash() == dwNameHash) {
+      return pNode;
+    }
+  }
+  return NULL;
+}
+CXFA_Node* CXFA_Node::GetNextSameNameSibling(
+    const CFX_WideStringC& wsNodeName) const {
+  return GetNextSameNameSibling(
+      wsNodeName.IsEmpty() ? 0
+                           : FX_HashCode_String_GetW(wsNodeName.GetPtr(),
+                                                     wsNodeName.GetLength()));
+}
+CXFA_Node* CXFA_Node::GetNextSameClassSibling(XFA_ELEMENT eElement) const {
+  for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_NextSibling); pNode;
+       pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pNode->GetClassID() == eElement) {
+      return pNode;
+    }
+  }
+  return NULL;
+}
+int32_t CXFA_Node::GetNodeSameNameIndex() const {
+  IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+  if (!pScriptContext) {
+    return -1;
+  }
+  return pScriptContext->GetIndexByName(const_cast<CXFA_Node*>(this));
+}
+int32_t CXFA_Node::GetNodeSameClassIndex() const {
+  IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+  if (!pScriptContext) {
+    return -1;
+  }
+  return pScriptContext->GetIndexByClassName(const_cast<CXFA_Node*>(this));
+}
+void CXFA_Node::GetSOMExpression(CFX_WideString& wsSOMExpression) {
+  IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+  if (!pScriptContext) {
+    return;
+  }
+  pScriptContext->GetSomExpression(this, wsSOMExpression);
+}
+CXFA_Node* CXFA_Node::GetInstanceMgrOfSubform() {
+  CXFA_Node* pInstanceMgr = NULL;
+  if (m_ePacket == XFA_XDPPACKET_Form) {
+    CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
+    if (!pParentNode || pParentNode->GetClassID() == XFA_ELEMENT_Area) {
+      return pInstanceMgr;
+    }
+    for (CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_PrevSibling); pNode;
+         pNode = pNode->GetNodeItem(XFA_NODEITEM_PrevSibling)) {
+      XFA_ELEMENT eType = pNode->GetClassID();
+      if ((eType == XFA_ELEMENT_Subform || eType == XFA_ELEMENT_SubformSet) &&
+          pNode->m_dwNameHash != m_dwNameHash) {
+        break;
+      }
+      if (eType == XFA_ELEMENT_InstanceManager) {
+        CFX_WideStringC wsName = GetCData(XFA_ATTRIBUTE_Name);
+        CFX_WideStringC wsInstName = pNode->GetCData(XFA_ATTRIBUTE_Name);
+        if (wsInstName.GetLength() > 0 && wsInstName.GetAt(0) == '_' &&
+            wsInstName.Mid(1) == wsName) {
+          pInstanceMgr = pNode;
+        }
+        break;
+      }
+    }
+  }
+  return pInstanceMgr;
+}
+CXFA_Node* CXFA_Node::GetOccurNode() {
+  return GetFirstChildByClass(XFA_ELEMENT_Occur);
+}
+FX_BOOL CXFA_Node::HasFlag(FX_DWORD dwFlag) const {
+  if (m_uFlags & dwFlag) {
+    return TRUE;
+  }
+  switch (dwFlag) {
+    case XFA_NODEFLAG_HasRemoved:
+      return m_pParent && m_pParent->HasFlag(dwFlag);
+    default:
+      break;
+  }
+  return FALSE;
+}
+void CXFA_Node::SetFlag(FX_DWORD dwFlag, FX_BOOL bOn, FX_BOOL bNotify) {
+  if (bOn) {
+    switch (dwFlag) {
+      case XFA_NODEFLAG_Initialized:
+        if (bNotify && !HasFlag(XFA_NODEFLAG_Initialized)) {
+          IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+          if (pNotify) {
+            pNotify->OnNodeEvent(this, XFA_NODEEVENT_Ready);
+          }
+        }
+        break;
+      default:
+        break;
+    }
+    m_uFlags |= dwFlag;
+  } else {
+    m_uFlags &= ~dwFlag;
+  }
+}
+FX_BOOL CXFA_Node::IsAttributeInXML() {
+  return GetEnum(XFA_ATTRIBUTE_Contains) == XFA_ATTRIBUTEENUM_MetaData;
+}
+void CXFA_Node::OnRemoved(CXFA_Node* pParent,
+                          CXFA_Node* pRemoved,
+                          FX_BOOL bNotify) {
+  if (bNotify && pParent) {
+    IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+    if (pNotify) {
+      pNotify->OnNodeEvent(pParent, XFA_NODEEVENT_ChildRemoved, pRemoved);
+    }
+  }
+}
+void CXFA_Node::OnChanging(XFA_ATTRIBUTE eAttr,
+                           void* pNewValue,
+                           FX_BOOL bNotify) {
+  if (bNotify && HasFlag(XFA_NODEFLAG_Initialized)) {
+    IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+    if (pNotify) {
+      pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanging,
+                           (void*)(uintptr_t)eAttr, pNewValue);
+    }
+  }
+}
+void CXFA_Node::OnChanged(XFA_ATTRIBUTE eAttr,
+                          void* pNewValue,
+                          FX_BOOL bNotify,
+                          FX_BOOL bScriptModify) {
+  if (bNotify && HasFlag(XFA_NODEFLAG_Initialized)) {
+    Script_Attribute_SendAttributeChangeMessage((void*)(uintptr_t)eAttr,
+                                                pNewValue, bScriptModify);
+  }
+}
+int32_t CXFA_Node::execSingleEventByName(const CFX_WideStringC& wsEventName,
+                                         XFA_ELEMENT eElementType) {
+  int32_t iRet = XFA_EVENTERROR_NotExist;
+  const XFA_ExecEventParaInfo* eventParaInfo =
+      GetEventParaInfoByName(wsEventName);
+  if (eventParaInfo) {
+    uint32_t validFlags = eventParaInfo->m_validFlags;
+    IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+    if (!pNotify) {
+      return iRet;
+    }
+    if (validFlags == 1) {
+      iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType);
+    } else if (validFlags == 2) {
+      iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
+                                           FALSE, FALSE);
+    } else if (validFlags == 3) {
+      if (eElementType == XFA_ELEMENT_Subform) {
+        iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
+                                             FALSE, FALSE);
+      }
+    } else if (validFlags == 4) {
+      if (eElementType == XFA_ELEMENT_ExclGroup ||
+          eElementType == XFA_ELEMENT_Field) {
+        CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
+        if (pParentNode && pParentNode->GetClassID() == XFA_ELEMENT_ExclGroup) {
+          iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
+                                               FALSE, FALSE);
+        }
+        iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
+                                             FALSE, FALSE);
+      }
+    } else if (validFlags == 5) {
+      if (eElementType == XFA_ELEMENT_Field) {
+        iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
+                                             FALSE, FALSE);
+      }
+    } else if (validFlags == 6) {
+      CXFA_WidgetData* pWidgetData = GetWidgetData();
+      if (pWidgetData) {
+        CXFA_Node* pUINode = pWidgetData->GetUIChild();
+        if (pUINode->m_eNodeClass == XFA_ELEMENT_Signature) {
+          iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
+                                               FALSE, FALSE);
+        }
+      }
+    } else if (validFlags == 7) {
+      CXFA_WidgetData* pWidgetData = GetWidgetData();
+      if (pWidgetData) {
+        CXFA_Node* pUINode = pWidgetData->GetUIChild();
+        if ((pUINode->m_eNodeClass == XFA_ELEMENT_ChoiceList) &&
+            (!pWidgetData->IsListBox())) {
+          iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType,
+                                               FALSE, FALSE);
+        }
+      }
+    }
+  }
+  return iRet;
+}
+void CXFA_Node::UpdateNameHash() {
+  const XFA_NOTSUREATTRIBUTE* pNotsure =
+      XFA_GetNotsureAttribute(GetClassID(), XFA_ATTRIBUTE_Name);
+  if (!pNotsure || pNotsure->eType == XFA_ATTRIBUTETYPE_Cdata) {
+    CFX_WideStringC wsName = GetCData(XFA_ATTRIBUTE_Name);
+    m_dwNameHash =
+        wsName.IsEmpty() ? 0 : FX_HashCode_String_GetW(wsName.GetPtr(),
+                                                       wsName.GetLength());
+  } else if (pNotsure->eType == XFA_ATTRIBUTETYPE_Enum) {
+    CFX_WideStringC wsName =
+        XFA_GetAttributeEnumByID(GetEnum(XFA_ATTRIBUTE_Name))->pName;
+    m_dwNameHash =
+        wsName.IsEmpty() ? 0 : FX_HashCode_String_GetW(wsName.GetPtr(),
+                                                       wsName.GetLength());
+  }
+}
+IFDE_XMLNode* CXFA_Node::CreateXMLMappingNode() {
+  if (!m_pXMLNode) {
+    CFX_WideStringC wsTag = GetCData(XFA_ATTRIBUTE_Name);
+    m_pXMLNode = IFDE_XMLElement::Create(wsTag);
+    SetFlag(XFA_NODEFLAG_OwnXMLNode, TRUE, FALSE);
+  }
+  return m_pXMLNode;
+}
+FX_BOOL CXFA_Node::IsNeedSavingXMLNode() {
+  return m_pXMLNode && (GetPacketID() == XFA_XDPPACKET_Datasets ||
+                        GetClassID() == XFA_ELEMENT_Xfa);
+}
+
+XFA_MAPMODULEDATA* CXFA_Node::CreateMapModuleData() {
+  if (!m_pMapModuleData)
+    m_pMapModuleData = new XFA_MAPMODULEDATA;
+  return m_pMapModuleData;
+}
+
+XFA_MAPMODULEDATA* CXFA_Node::GetMapModuleData() const {
+  return m_pMapModuleData;
+}
+
+void CXFA_Node::SetMapModuleValue(void* pKey, void* pValue) {
+  XFA_MAPMODULEDATA* pModule = CreateMapModuleData();
+  pModule->m_ValueMap.SetAt(pKey, pValue);
+}
+
+FX_BOOL CXFA_Node::GetMapModuleValue(void* pKey, void*& pValue) {
+  CXFA_Node* pNode = this;
+  while (pNode) {
+    XFA_MAPMODULEDATA* pModule = pNode->GetMapModuleData();
+    if (pModule && pModule->m_ValueMap.Lookup(pKey, pValue)) {
+      return TRUE;
+    }
+    pNode = pNode->GetPacketID() != XFA_XDPPACKET_Datasets
+                ? pNode->GetTemplateNode()
+                : NULL;
+  }
+  return FALSE;
+}
+void CXFA_Node::SetMapModuleString(void* pKey, const CFX_WideStringC& wsValue) {
+  SetMapModuleBuffer(pKey, (void*)wsValue.GetPtr(),
+                     wsValue.GetLength() * sizeof(FX_WCHAR));
+}
+FX_BOOL CXFA_Node::GetMapModuleString(void* pKey, CFX_WideStringC& wsValue) {
+  void* pValue;
+  int32_t iBytes;
+  if (!GetMapModuleBuffer(pKey, pValue, iBytes)) {
+    return FALSE;
+  }
+  wsValue = CFX_WideStringC((const FX_WCHAR*)pValue, iBytes / sizeof(FX_WCHAR));
+  return TRUE;
+}
+void CXFA_Node::SetMapModuleBuffer(
+    void* pKey,
+    void* pValue,
+    int32_t iBytes,
+    XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo) {
+  XFA_MAPMODULEDATA* pModule = CreateMapModuleData();
+  XFA_MAPDATABLOCK*& pBuffer = pModule->m_BufferMap[pKey];
+  if (pBuffer == NULL) {
+    pBuffer =
+        (XFA_MAPDATABLOCK*)FX_Alloc(uint8_t, sizeof(XFA_MAPDATABLOCK) + iBytes);
+  } else if (pBuffer->iBytes != iBytes) {
+    if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree) {
+      pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
+    }
+    pBuffer = (XFA_MAPDATABLOCK*)FX_Realloc(uint8_t, pBuffer,
+                                            sizeof(XFA_MAPDATABLOCK) + iBytes);
+  } else if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree) {
+    pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
+  }
+  if (pBuffer == NULL) {
+    return;
+  }
+  pBuffer->pCallbackInfo = pCallbackInfo;
+  pBuffer->iBytes = iBytes;
+  FXSYS_memcpy(pBuffer->GetData(), pValue, iBytes);
+}
+FX_BOOL CXFA_Node::GetMapModuleBuffer(void* pKey,
+                                      void*& pValue,
+                                      int32_t& iBytes,
+                                      FX_BOOL bProtoAlso) const {
+  XFA_MAPDATABLOCK* pBuffer = NULL;
+  const CXFA_Node* pNode = this;
+  while (pNode) {
+    XFA_MAPMODULEDATA* pModule = pNode->GetMapModuleData();
+    if (pModule && pModule->m_BufferMap.Lookup(pKey, pBuffer)) {
+      break;
+    }
+    pNode = (bProtoAlso && pNode->GetPacketID() != XFA_XDPPACKET_Datasets)
+                ? pNode->GetTemplateNode()
+                : NULL;
+  }
+  if (pBuffer == NULL) {
+    return FALSE;
+  }
+  pValue = pBuffer->GetData();
+  iBytes = pBuffer->iBytes;
+  return TRUE;
+}
+FX_BOOL CXFA_Node::HasMapModuleKey(void* pKey, FX_BOOL bProtoAlso) {
+  CXFA_Node* pNode = this;
+  while (pNode) {
+    void* pVal;
+    XFA_MAPMODULEDATA* pModule = pNode->GetMapModuleData();
+    if (pModule &&
+        (pModule->m_ValueMap.Lookup(pKey, pVal) ||
+         pModule->m_BufferMap.Lookup(pKey, (XFA_MAPDATABLOCK*&)pVal))) {
+      return TRUE;
+    }
+    pNode = (bProtoAlso && pNode->GetPacketID() != XFA_XDPPACKET_Datasets)
+                ? pNode->GetTemplateNode()
+                : NULL;
+  }
+  return FALSE;
+}
+void CXFA_Node::RemoveMapModuleKey(void* pKey) {
+  XFA_MAPMODULEDATA* pModule = GetMapModuleData();
+  if (!pModule)
+    return;
+
+  if (pKey) {
+    XFA_MAPDATABLOCK* pBuffer = NULL;
+    pModule->m_BufferMap.Lookup(pKey, pBuffer);
+    if (pBuffer) {
+      if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree) {
+        pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
+      }
+      FX_Free(pBuffer);
+    }
+    pModule->m_BufferMap.RemoveKey(pKey);
+    pModule->m_ValueMap.RemoveKey(pKey);
+  } else {
+    XFA_MAPDATABLOCK* pBuffer;
+    FX_POSITION posBuffer = pModule->m_BufferMap.GetStartPosition();
+    while (posBuffer) {
+      pModule->m_BufferMap.GetNextAssoc(posBuffer, pKey, pBuffer);
+      if (pBuffer) {
+        if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree) {
+          pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
+        }
+        FX_Free(pBuffer);
+      }
+    }
+    pModule->m_BufferMap.RemoveAll();
+    pModule->m_ValueMap.RemoveAll();
+    delete pModule;
+  }
+}
+void CXFA_Node::MergeAllData(void* pDstModule, FX_BOOL bUseSrcAttr) {
+  XFA_MAPMODULEDATA* pDstModuleData =
+      static_cast<CXFA_Node*>(pDstModule)->CreateMapModuleData();
+  XFA_MAPMODULEDATA* pSrcModuleData = GetMapModuleData();
+  if (!pSrcModuleData) {
+    return;
+  }
+  FX_POSITION psValue = pSrcModuleData->m_ValueMap.GetStartPosition();
+  while (psValue) {
+    void* pKey;
+    void* pValue;
+    pSrcModuleData->m_ValueMap.GetNextAssoc(psValue, pKey, pValue);
+    if (bUseSrcAttr || !pDstModuleData->m_ValueMap.GetValueAt(pKey)) {
+      pDstModuleData->m_ValueMap.SetAt(pKey, pValue);
+    }
+  }
+  FX_POSITION psBuffer = pSrcModuleData->m_BufferMap.GetStartPosition();
+  while (psBuffer) {
+    void* pKey;
+    XFA_MAPDATABLOCK* pSrcBuffer;
+    pSrcModuleData->m_BufferMap.GetNextAssoc(psBuffer, pKey, pSrcBuffer);
+    XFA_MAPDATABLOCK*& pBuffer = pDstModuleData->m_BufferMap[pKey];
+    if (pBuffer && !bUseSrcAttr) {
+      continue;
+    }
+    if (pSrcBuffer->pCallbackInfo && pSrcBuffer->pCallbackInfo->pFree &&
+        !pSrcBuffer->pCallbackInfo->pCopy) {
+      if (pBuffer) {
+        pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
+        pDstModuleData->m_BufferMap.RemoveKey(pKey);
+      }
+      continue;
+    }
+    if (pBuffer == NULL) {
+      pBuffer = (XFA_MAPDATABLOCK*)FX_Alloc(
+          uint8_t, sizeof(XFA_MAPDATABLOCK) + pSrcBuffer->iBytes);
+    } else if (pBuffer->iBytes != pSrcBuffer->iBytes) {
+      if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree) {
+        pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
+      }
+      pBuffer = (XFA_MAPDATABLOCK*)FX_Realloc(
+          uint8_t, pBuffer, sizeof(XFA_MAPDATABLOCK) + pSrcBuffer->iBytes);
+    } else if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree) {
+      pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
+    }
+    if (pBuffer == NULL) {
+      continue;
+    }
+    pBuffer->pCallbackInfo = pSrcBuffer->pCallbackInfo;
+    pBuffer->iBytes = pSrcBuffer->iBytes;
+    FXSYS_memcpy(pBuffer->GetData(), pSrcBuffer->GetData(), pSrcBuffer->iBytes);
+    if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pCopy) {
+      pBuffer->pCallbackInfo->pCopy(*(void**)pBuffer->GetData());
+    }
+  }
+}
+void CXFA_Node::MoveBufferMapData(CXFA_Node* pDstModule, void* pKey) {
+  if (!pDstModule) {
+    return;
+  }
+  FX_BOOL bNeedMove = TRUE;
+  if (!pKey) {
+    bNeedMove = FALSE;
+  }
+  if (pDstModule->GetClassID() != GetClassID()) {
+    bNeedMove = FALSE;
+  }
+  XFA_MAPMODULEDATA* pSrcModuleData = NULL;
+  XFA_MAPMODULEDATA* pDstModuleData = NULL;
+  if (bNeedMove) {
+    pSrcModuleData = GetMapModuleData();
+    if (!pSrcModuleData) {
+      bNeedMove = FALSE;
+    }
+    pDstModuleData = pDstModule->CreateMapModuleData();
+  }
+  if (bNeedMove) {
+    void* pBufferBlockData = pSrcModuleData->m_BufferMap.GetValueAt(pKey);
+    if (pBufferBlockData) {
+      pSrcModuleData->m_BufferMap.RemoveKey(pKey);
+      pDstModuleData->m_BufferMap.RemoveKey(pKey);
+      pDstModuleData->m_BufferMap.SetAt(pKey,
+                                        (XFA_MAPDATABLOCK*)pBufferBlockData);
+    }
+  }
+  if (pDstModule->GetObjectType() == XFA_OBJECTTYPE_NodeV) {
+    CFX_WideString wsValue = pDstModule->GetScriptContent(FALSE);
+    CFX_WideString wsFormatValue(wsValue);
+    CXFA_WidgetData* pWidgetData = pDstModule->GetContainerWidgetData();
+    if (pWidgetData) {
+      pWidgetData->GetFormatDataValue(wsValue, wsFormatValue);
+    }
+    pDstModule->SetScriptContent(wsValue, wsFormatValue, TRUE, TRUE);
+  }
+}
+void CXFA_Node::MoveBufferMapData(CXFA_Node* pSrcModule,
+                                  CXFA_Node* pDstModule,
+                                  void* pKey,
+                                  FX_BOOL bRecursive) {
+  if (!pSrcModule || !pDstModule || !pKey) {
+    return;
+  }
+  if (bRecursive) {
+    CXFA_Node* pSrcChild = pSrcModule->GetNodeItem(XFA_NODEITEM_FirstChild);
+    CXFA_Node* pDstChild = pDstModule->GetNodeItem(XFA_NODEITEM_FirstChild);
+    for (; pSrcChild && pDstChild;
+         pSrcChild = pSrcChild->GetNodeItem(XFA_NODEITEM_NextSibling),
+         pDstChild = pDstChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+      MoveBufferMapData(pSrcChild, pDstChild, pKey, TRUE);
+    }
+  }
+  pSrcModule->MoveBufferMapData(pDstModule, pKey);
+}
+CXFA_NodeList::CXFA_NodeList(CXFA_Document* pDocument)
+    : CXFA_Object(pDocument, XFA_OBJECTTYPE_NodeList) {
+  m_pDocument->GetScriptContext()->CacheList(this);
+}
+CXFA_Node* CXFA_NodeList::NamedItem(const CFX_WideStringC& wsName) {
+  int32_t iCount = GetLength();
+  FX_DWORD dwHashCode =
+      FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength());
+  for (int32_t i = 0; i < iCount; i++) {
+    CXFA_Node* ret = Item(i);
+    if (dwHashCode == ret->GetNameHash()) {
+      return ret;
+    }
+  }
+  return NULL;
+}
+void CXFA_NodeList::Script_ListClass_Append(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 1) {
+    CXFA_Node* pNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
+    if (pNode) {
+      Append(pNode);
+    } else {
+      ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"append");
+  }
+}
+void CXFA_NodeList::Script_ListClass_Insert(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 2) {
+    CXFA_Node* pNewNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
+    CXFA_Node* pBeforeNode = static_cast<CXFA_Node*>(pArguments->GetObject(1));
+    if (pNewNode) {
+      Insert(pNewNode, pBeforeNode);
+    } else {
+      ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"insert");
+  }
+}
+void CXFA_NodeList::Script_ListClass_Remove(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 1) {
+    CXFA_Node* pNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
+    if (pNode) {
+      Remove(pNode);
+    } else {
+      ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"remove");
+  }
+}
+void CXFA_NodeList::Script_ListClass_Item(CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 1) {
+    int32_t iIndex = pArguments->GetInt32(0);
+    if ((iIndex >= 0) && (iIndex + 1 <= GetLength())) {
+      FXJSE_Value_Set(
+          pArguments->GetReturnValue(),
+          m_pDocument->GetScriptContext()->GetJSValueFromMap(Item(iIndex)));
+    } else {
+      ThrowScriptErrorMessage(XFA_IDS_INDEX_OUT_OF_BOUNDS);
+    }
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"item");
+  }
+}
+void CXFA_NodeList::Script_TreelistClass_NamedItem(
+    CFXJSE_Arguments* pArguments) {
+  int32_t argc = pArguments->GetLength();
+  if (argc == 1) {
+    CFX_ByteString szName = pArguments->GetUTF8String(0);
+    CXFA_Node* pNode =
+        NamedItem(CFX_WideString::FromUTF8(szName, szName.GetLength()));
+    if (!pNode) {
+      return;
+    }
+    FXJSE_Value_Set(pArguments->GetReturnValue(),
+                    m_pDocument->GetScriptContext()->GetJSValueFromMap(pNode));
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"namedItem");
+  }
+}
+void CXFA_NodeList::Script_ListClass_Length(FXJSE_HVALUE hValue,
+                                            FX_BOOL bSetting,
+                                            XFA_ATTRIBUTE eAttribute) {
+  if (!bSetting) {
+    FXJSE_Value_SetInteger(hValue, GetLength());
+  } else {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+  }
+}
+CXFA_ArrayNodeList::CXFA_ArrayNodeList(CXFA_Document* pDocument)
+    : CXFA_NodeList(pDocument) {}
+void CXFA_ArrayNodeList::SetArrayNodeList(const CXFA_NodeArray& srcArray) {
+  if (srcArray.GetSize() > 0) {
+    m_array.Copy(srcArray);
+  }
+}
+int32_t CXFA_ArrayNodeList::GetLength() {
+  return m_array.GetSize();
+}
+FX_BOOL CXFA_ArrayNodeList::Append(CXFA_Node* pNode) {
+  m_array.Add(pNode);
+  return TRUE;
+}
+FX_BOOL CXFA_ArrayNodeList::Insert(CXFA_Node* pNewNode,
+                                   CXFA_Node* pBeforeNode) {
+  if (pBeforeNode == NULL) {
+    m_array.Add(pNewNode);
+  } else {
+    int32_t iSize = m_array.GetSize();
+    for (int32_t i = 0; i < iSize; ++i) {
+      if (m_array[i] == pBeforeNode) {
+        m_array.InsertAt(i, pNewNode);
+        break;
+      }
+    }
+  }
+  return TRUE;
+}
+FX_BOOL CXFA_ArrayNodeList::Remove(CXFA_Node* pNode) {
+  int32_t iSize = m_array.GetSize();
+  for (int32_t i = 0; i < iSize; ++i) {
+    if (m_array[i] == pNode) {
+      m_array.RemoveAt(i);
+      break;
+    }
+  }
+  return TRUE;
+}
+CXFA_Node* CXFA_ArrayNodeList::Item(int32_t iIndex) {
+  int32_t iSize = m_array.GetSize();
+  if (iIndex >= 0 && iIndex < iSize) {
+    return m_array[iIndex];
+  }
+  return NULL;
+}
+CXFA_AttachNodeList::CXFA_AttachNodeList(CXFA_Document* pDocument,
+                                         CXFA_Node* pAttachNode)
+    : CXFA_NodeList(pDocument) {
+  m_pAttachNode = pAttachNode;
+}
+int32_t CXFA_AttachNodeList::GetLength() {
+  return m_pAttachNode->CountChildren(
+      XFA_ELEMENT_UNKNOWN, m_pAttachNode->GetClassID() == XFA_ELEMENT_Subform);
+}
+FX_BOOL CXFA_AttachNodeList::Append(CXFA_Node* pNode) {
+  CXFA_Node* pParent = pNode->GetNodeItem(XFA_NODEITEM_Parent);
+  if (pParent) {
+    pParent->RemoveChild(pNode);
+  }
+  return m_pAttachNode->InsertChild(pNode);
+}
+FX_BOOL CXFA_AttachNodeList::Insert(CXFA_Node* pNewNode,
+                                    CXFA_Node* pBeforeNode) {
+  CXFA_Node* pParent = pNewNode->GetNodeItem(XFA_NODEITEM_Parent);
+  if (pParent) {
+    pParent->RemoveChild(pNewNode);
+  }
+  return m_pAttachNode->InsertChild(pNewNode, pBeforeNode);
+}
+FX_BOOL CXFA_AttachNodeList::Remove(CXFA_Node* pNode) {
+  return m_pAttachNode->RemoveChild(pNode);
+}
+CXFA_Node* CXFA_AttachNodeList::Item(int32_t iIndex) {
+  return m_pAttachNode->GetChild(
+      iIndex, XFA_ELEMENT_UNKNOWN,
+      m_pAttachNode->GetClassID() == XFA_ELEMENT_Subform);
+}
diff --git a/xfa/fxfa/parser/xfa_objectacc_imp.cpp b/xfa/fxfa/parser/xfa_objectacc_imp.cpp
new file mode 100644
index 0000000..5bf368b
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_objectacc_imp.cpp
@@ -0,0 +1,3760 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/include/fxcrt/fx_ext.h"
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_localevalue.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+#include "xfa/include/fxbarcode/BC_BarCode.h"
+
+static FX_ARGB XFA_WStringToColor(const CFX_WideStringC& wsValue) {
+  uint8_t r = 0, g = 0, b = 0;
+  if (wsValue.GetLength() == 0) {
+    return 0xff000000;
+  }
+  int cc = 0;
+  const FX_WCHAR* str = wsValue.GetPtr();
+  int len = wsValue.GetLength();
+  while (XFA_IsSpace(str[cc]) && cc < len) {
+    cc++;
+  }
+  if (cc >= len) {
+    return 0xff000000;
+  }
+  while (cc < len) {
+    if (str[cc] == ',' || !XFA_IsDigit(str[cc])) {
+      break;
+    }
+    r = r * 10 + str[cc] - '0';
+    cc++;
+  }
+  if (cc < len && str[cc] == ',') {
+    cc++;
+    while (XFA_IsSpace(str[cc]) && cc < len) {
+      cc++;
+    }
+    while (cc < len) {
+      if (str[cc] == ',' || !XFA_IsDigit(str[cc])) {
+        break;
+      }
+      g = g * 10 + str[cc] - '0';
+      cc++;
+    }
+    if (cc < len && str[cc] == ',') {
+      cc++;
+      while (XFA_IsSpace(str[cc]) && cc < len) {
+        cc++;
+      }
+      while (cc < len) {
+        if (str[cc] == ',' || !XFA_IsDigit(str[cc])) {
+          break;
+        }
+        b = b * 10 + str[cc] - '0';
+        cc++;
+      }
+    }
+  }
+  return (0xff << 24) | (r << 16) | (g << 8) | b;
+}
+XFA_ELEMENT CXFA_Data::GetClassID() const {
+  return m_pNode ? m_pNode->GetClassID() : XFA_ELEMENT_UNKNOWN;
+}
+FX_BOOL CXFA_Data::TryMeasure(XFA_ATTRIBUTE eAttr,
+                              FX_FLOAT& fValue,
+                              FX_BOOL bUseDefault) const {
+  CXFA_Measurement ms;
+  if (m_pNode->TryMeasure(eAttr, ms, bUseDefault)) {
+    fValue = ms.ToUnit(XFA_UNIT_Pt);
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_Data::SetMeasure(XFA_ATTRIBUTE eAttr, FX_FLOAT fValue) {
+  CXFA_Measurement ms(fValue, XFA_UNIT_Pt);
+  return m_pNode->SetMeasure(eAttr, ms);
+}
+CXFA_Fill::CXFA_Fill(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+CXFA_Fill::~CXFA_Fill() {}
+int32_t CXFA_Fill::GetPresence() {
+  return m_pNode->GetEnum(XFA_ATTRIBUTE_Presence);
+}
+void CXFA_Fill::SetColor(FX_ARGB color) {
+  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Color);
+  CFX_WideString wsColor;
+  int a, r, g, b;
+  ArgbDecode(color, a, r, g, b);
+  wsColor.Format(L"%d,%d,%d", r, g, b);
+  pNode->SetCData(XFA_ATTRIBUTE_Value, wsColor);
+}
+FX_ARGB CXFA_Fill::GetColor(FX_BOOL bText) {
+  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Color)) {
+    CFX_WideStringC wsColor;
+    if (pNode->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE)) {
+      return XFA_WStringToColor(wsColor);
+    }
+  }
+  if (bText) {
+    return 0xFF000000;
+  }
+  return 0xFFFFFFFF;
+}
+int32_t CXFA_Fill::GetFillType() {
+  CXFA_Node* pChild = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+  while (pChild) {
+    int32_t eType = pChild->GetClassID();
+    if (eType != XFA_ELEMENT_Color && eType != XFA_ELEMENT_Extras) {
+      return eType;
+    }
+    pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+  }
+  return XFA_ELEMENT_Solid;
+}
+int32_t CXFA_Fill::GetPattern(FX_ARGB& foreColor) {
+  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Pattern);
+  if (CXFA_Node* pColor = pNode->GetChild(0, XFA_ELEMENT_Color)) {
+    CFX_WideStringC wsColor;
+    pColor->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE);
+    foreColor = XFA_WStringToColor(wsColor);
+  } else {
+    foreColor = 0xFF000000;
+  }
+  return pNode->GetEnum(XFA_ATTRIBUTE_Type);
+}
+int32_t CXFA_Fill::GetStipple(FX_ARGB& stippleColor) {
+  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Stipple);
+  int32_t eAttr = 50;
+  pNode->TryInteger(XFA_ATTRIBUTE_Rate, eAttr);
+  if (CXFA_Node* pColor = pNode->GetChild(0, XFA_ELEMENT_Color)) {
+    CFX_WideStringC wsColor;
+    pColor->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE);
+    stippleColor = XFA_WStringToColor(wsColor);
+  } else {
+    stippleColor = 0xFF000000;
+  }
+  return eAttr;
+}
+int32_t CXFA_Fill::GetLinear(FX_ARGB& endColor) {
+  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Linear);
+  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_ToRight;
+  pNode->TryEnum(XFA_ATTRIBUTE_Type, eAttr);
+  if (CXFA_Node* pColor = pNode->GetChild(0, XFA_ELEMENT_Color)) {
+    CFX_WideStringC wsColor;
+    pColor->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE);
+    endColor = XFA_WStringToColor(wsColor);
+  } else {
+    endColor = 0xFF000000;
+  }
+  return eAttr;
+}
+int32_t CXFA_Fill::GetRadial(FX_ARGB& endColor) {
+  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Radial);
+  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_ToEdge;
+  pNode->TryEnum(XFA_ATTRIBUTE_Type, eAttr);
+  if (CXFA_Node* pColor = pNode->GetChild(0, XFA_ELEMENT_Color)) {
+    CFX_WideStringC wsColor;
+    pColor->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE);
+    endColor = XFA_WStringToColor(wsColor);
+  } else {
+    endColor = 0xFF000000;
+  }
+  return eAttr;
+}
+FX_BOOL CXFA_Fill::SetPresence(int32_t iPresence) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_Presence, (XFA_ATTRIBUTEENUM)iPresence);
+}
+FX_BOOL CXFA_Fill::SetFillType(int32_t iType) {
+  return FALSE;
+}
+FX_BOOL CXFA_Fill::SetPattern(int32_t iPattern, FX_ARGB foreColor) {
+  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Pattern);
+  CXFA_Node* pColor = pNode->GetProperty(0, XFA_ELEMENT_Color);
+  CFX_WideString wsColor;
+  int a, r, g, b;
+  ArgbDecode(foreColor, a, r, g, b);
+  wsColor.Format(L"%d,%d,%d", r, g, b);
+  pColor->SetCData(XFA_ATTRIBUTE_Value, wsColor);
+  return pNode->SetEnum(XFA_ATTRIBUTE_Type, (XFA_ATTRIBUTEENUM)iPattern);
+}
+FX_BOOL CXFA_Fill::SetStipple(int32_t iStipple, FX_ARGB stippleColor) {
+  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Stipple);
+  CXFA_Node* pColor = pNode->GetProperty(0, XFA_ELEMENT_Color);
+  CFX_WideString wsColor;
+  int a, r, g, b;
+  ArgbDecode(stippleColor, a, r, g, b);
+  wsColor.Format(L"%d,%d,%d", r, g, b);
+  pColor->SetCData(XFA_ATTRIBUTE_Value, wsColor);
+  return pNode->SetEnum(XFA_ATTRIBUTE_Rate, (XFA_ATTRIBUTEENUM)iStipple);
+}
+FX_BOOL CXFA_Fill::SetLinear(int32_t iLinear, FX_ARGB endColor) {
+  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Linear);
+  CXFA_Node* pColor = pNode->GetProperty(0, XFA_ELEMENT_Color);
+  CFX_WideString wsColor;
+  int a, r, g, b;
+  ArgbDecode(endColor, a, r, g, b);
+  wsColor.Format(L"%d,%d,%d", r, g, b);
+  pColor->SetCData(XFA_ATTRIBUTE_Value, wsColor);
+  return pNode->SetEnum(XFA_ATTRIBUTE_Type, (XFA_ATTRIBUTEENUM)iLinear);
+}
+FX_BOOL CXFA_Fill::SetRadial(int32_t iRadial, FX_ARGB endColor) {
+  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Radial);
+  CXFA_Node* pColor = pNode->GetProperty(0, XFA_ELEMENT_Color);
+  CFX_WideString wsColor;
+  int a, r, g, b;
+  ArgbDecode(endColor, a, r, g, b);
+  wsColor.Format(L"%d,%d,%d", r, g, b);
+  pColor->SetCData(XFA_ATTRIBUTE_Value, wsColor);
+  return pNode->SetEnum(XFA_ATTRIBUTE_Type, (XFA_ATTRIBUTEENUM)iRadial);
+}
+CXFA_Margin::CXFA_Margin(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+FX_BOOL CXFA_Margin::GetLeftInset(FX_FLOAT& fInset, FX_FLOAT fDefInset) const {
+  fInset = fDefInset;
+  return TryMeasure(XFA_ATTRIBUTE_LeftInset, fInset);
+}
+FX_BOOL CXFA_Margin::GetTopInset(FX_FLOAT& fInset, FX_FLOAT fDefInset) const {
+  fInset = fDefInset;
+  return TryMeasure(XFA_ATTRIBUTE_TopInset, fInset);
+}
+FX_BOOL CXFA_Margin::GetRightInset(FX_FLOAT& fInset, FX_FLOAT fDefInset) const {
+  fInset = fDefInset;
+  return TryMeasure(XFA_ATTRIBUTE_RightInset, fInset);
+}
+FX_BOOL CXFA_Margin::GetBottomInset(FX_FLOAT& fInset,
+                                    FX_FLOAT fDefInset) const {
+  fInset = fDefInset;
+  return TryMeasure(XFA_ATTRIBUTE_BottomInset, fInset);
+}
+FX_BOOL CXFA_Margin::SetLeftInset(FX_FLOAT fInset) {
+  return SetMeasure(XFA_ATTRIBUTE_LeftInset, fInset);
+}
+FX_BOOL CXFA_Margin::SetTopInset(FX_FLOAT fInset) {
+  return SetMeasure(XFA_ATTRIBUTE_TopInset, fInset);
+}
+FX_BOOL CXFA_Margin::SetRightInset(FX_FLOAT fInset) {
+  return SetMeasure(XFA_ATTRIBUTE_RightInset, fInset);
+}
+FX_BOOL CXFA_Margin::SetBottomInset(FX_FLOAT fInset) {
+  return SetMeasure(XFA_ATTRIBUTE_BottomInset, fInset);
+}
+CXFA_Font::CXFA_Font(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+FX_FLOAT CXFA_Font::GetBaselineShift() {
+  return m_pNode->GetMeasure(XFA_ATTRIBUTE_BaselineShift).ToUnit(XFA_UNIT_Pt);
+}
+FX_FLOAT CXFA_Font::GetHorizontalScale() {
+  CFX_WideString wsValue;
+  m_pNode->TryCData(XFA_ATTRIBUTE_FontHorizontalScale, wsValue);
+  int32_t iScale = FXSYS_wtoi((const FX_WCHAR*)wsValue);
+  return iScale > 0 ? (FX_FLOAT)iScale : 100.0f;
+}
+FX_FLOAT CXFA_Font::GetVerticalScale() {
+  CFX_WideString wsValue;
+  m_pNode->TryCData(XFA_ATTRIBUTE_FontVerticalScale, wsValue);
+  int32_t iScale = FXSYS_wtoi((const FX_WCHAR*)wsValue);
+  return iScale > 0 ? (FX_FLOAT)iScale : 100.0f;
+}
+FX_FLOAT CXFA_Font::GetLetterSpacing() {
+  CFX_WideStringC wsValue;
+  if (!m_pNode->TryCData(XFA_ATTRIBUTE_LetterSpacing, wsValue)) {
+    return 0;
+  }
+  CXFA_Measurement ms(wsValue);
+  if (ms.GetUnit() == XFA_UNIT_Em) {
+    return ms.GetValue() * GetFontSize();
+  }
+  return ms.ToUnit(XFA_UNIT_Pt);
+}
+int32_t CXFA_Font::GetLineThrough() {
+  int32_t iValue = 0;
+  m_pNode->TryInteger(XFA_ATTRIBUTE_LineThrough, iValue);
+  return iValue;
+}
+int32_t CXFA_Font::GetLineThroughPeriod() {
+  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_All;
+  m_pNode->TryEnum(XFA_ATTRIBUTE_LineThroughPeriod, eAttr);
+  return eAttr;
+}
+int32_t CXFA_Font::GetOverline() {
+  int32_t iValue = 0;
+  m_pNode->TryInteger(XFA_ATTRIBUTE_Overline, iValue);
+  return iValue;
+}
+int32_t CXFA_Font::GetOverlinePeriod() {
+  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_All;
+  m_pNode->TryEnum(XFA_ATTRIBUTE_OverlinePeriod, eAttr);
+  return eAttr;
+}
+int32_t CXFA_Font::GetUnderline() {
+  int32_t iValue = 0;
+  m_pNode->TryInteger(XFA_ATTRIBUTE_Underline, iValue);
+  return iValue;
+}
+int32_t CXFA_Font::GetUnderlinePeriod() {
+  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_All;
+  m_pNode->TryEnum(XFA_ATTRIBUTE_UnderlinePeriod, eAttr);
+  return eAttr;
+}
+FX_FLOAT CXFA_Font::GetFontSize() {
+  CXFA_Measurement ms;
+  m_pNode->TryMeasure(XFA_ATTRIBUTE_Size, ms);
+  return ms.ToUnit(XFA_UNIT_Pt);
+}
+void CXFA_Font::GetTypeface(CFX_WideStringC& wsTypeFace) {
+  m_pNode->TryCData(XFA_ATTRIBUTE_Typeface, wsTypeFace);
+}
+FX_BOOL CXFA_Font::IsBold() {
+  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Normal;
+  m_pNode->TryEnum(XFA_ATTRIBUTE_Weight, eAttr);
+  return eAttr == XFA_ATTRIBUTEENUM_Bold;
+}
+FX_BOOL CXFA_Font::IsItalic() {
+  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Normal;
+  m_pNode->TryEnum(XFA_ATTRIBUTE_Posture, eAttr);
+  return eAttr == XFA_ATTRIBUTEENUM_Italic;
+}
+FX_BOOL CXFA_Font::IsUseKerning() {
+  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_None;
+  m_pNode->TryEnum(XFA_ATTRIBUTE_KerningMode, eAttr);
+  return eAttr == XFA_ATTRIBUTEENUM_Pair;
+}
+void CXFA_Font::SetColor(FX_ARGB color) {
+  CXFA_Fill fill(m_pNode->GetProperty(0, XFA_ELEMENT_Fill));
+  fill.SetColor(color);
+}
+FX_ARGB CXFA_Font::GetColor() {
+  CXFA_Fill fill(m_pNode->GetChild(0, XFA_ELEMENT_Fill));
+  return fill ? fill.GetColor(TRUE) : 0xFF000000;
+}
+FX_BOOL CXFA_Font::SetBaselineShift(FX_FLOAT fBaselineShift) {
+  CXFA_Measurement ms(fBaselineShift, XFA_UNIT_Pt);
+  return m_pNode->SetMeasure(XFA_ATTRIBUTE_BaselineShift, ms);
+}
+FX_BOOL CXFA_Font::SetHorizontalScale(FX_FLOAT fHorizontalScale) {
+  CFX_WideString wsValue;
+  wsValue.Format(L"%d", (int32_t)fHorizontalScale);
+  return m_pNode->SetCData(XFA_ATTRIBUTE_FontHorizontalScale, wsValue);
+}
+FX_BOOL CXFA_Font::SetVerticalScale(FX_FLOAT fVerticalScale) {
+  CFX_WideString wsValue;
+  wsValue.Format(L"%d", (int32_t)fVerticalScale);
+  return m_pNode->SetCData(XFA_ATTRIBUTE_FontVerticalScale, wsValue);
+}
+FX_BOOL CXFA_Font::SetLetterSpacing(FX_FLOAT fLetterSpacing, XFA_UNIT eUnit) {
+  return FALSE;
+}
+FX_BOOL CXFA_Font::SetLineThrough(int32_t iLineThrough) {
+  return m_pNode->SetInteger(XFA_ATTRIBUTE_LineThrough, iLineThrough);
+}
+FX_BOOL CXFA_Font::SetLineThroughPeriod(int32_t iLineThroughPeriod) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_LineThroughPeriod,
+                          (XFA_ATTRIBUTEENUM)iLineThroughPeriod);
+}
+FX_BOOL CXFA_Font::SetOverline(int32_t iOverline) {
+  return m_pNode->SetInteger(XFA_ATTRIBUTE_Overline, iOverline);
+}
+FX_BOOL CXFA_Font::SetOverlinePeriod(int32_t iOverlinePeriod) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_OverlinePeriod,
+                          (XFA_ATTRIBUTEENUM)iOverlinePeriod);
+}
+FX_BOOL CXFA_Font::SetUnderline(int32_t iUnderline) {
+  return m_pNode->SetInteger(XFA_ATTRIBUTE_Underline, iUnderline);
+}
+FX_BOOL CXFA_Font::SetUnderlinePeriod(int32_t iUnderlinePeriod) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_UnderlinePeriod,
+                          (XFA_ATTRIBUTEENUM)iUnderlinePeriod);
+}
+CXFA_Caption::CXFA_Caption(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+int32_t CXFA_Caption::GetPresence() {
+  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Visible;
+  m_pNode->TryEnum(XFA_ATTRIBUTE_Presence, eAttr);
+  return eAttr;
+}
+int32_t CXFA_Caption::GetPlacementType() {
+  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Left;
+  m_pNode->TryEnum(XFA_ATTRIBUTE_Placement, eAttr);
+  return eAttr;
+}
+FX_FLOAT CXFA_Caption::GetReserve() {
+  CXFA_Measurement ms;
+  m_pNode->TryMeasure(XFA_ATTRIBUTE_Reserve, ms);
+  return ms.ToUnit(XFA_UNIT_Pt);
+}
+CXFA_Margin CXFA_Caption::GetMargin() {
+  return CXFA_Margin(m_pNode ? m_pNode->GetChild(0, XFA_ELEMENT_Margin) : NULL);
+}
+CXFA_Font CXFA_Caption::GetFont() {
+  return CXFA_Font(m_pNode ? m_pNode->GetChild(0, XFA_ELEMENT_Font) : NULL);
+}
+CXFA_Value CXFA_Caption::GetValue() {
+  return CXFA_Value(m_pNode ? m_pNode->GetChild(0, XFA_ELEMENT_Value) : NULL);
+}
+CXFA_Para CXFA_Caption::GetPara() {
+  return CXFA_Para(m_pNode ? m_pNode->GetChild(0, XFA_ELEMENT_Para) : NULL);
+}
+FX_BOOL CXFA_Caption::SetPresence(int32_t iPresence) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_Presence, (XFA_ATTRIBUTEENUM)iPresence);
+}
+FX_BOOL CXFA_Caption::SetPlacementType(int32_t iType) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_Placement, (XFA_ATTRIBUTEENUM)iType);
+}
+FX_BOOL CXFA_Caption::SetReserve(FX_FLOAT fReserve) {
+  CXFA_Measurement ms(fReserve, XFA_UNIT_Pt);
+  return m_pNode->SetMeasure(XFA_ATTRIBUTE_Reserve, ms);
+}
+CXFA_Para::CXFA_Para(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+int32_t CXFA_Para::GetHorizontalAlign() {
+  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Left;
+  m_pNode->TryEnum(XFA_ATTRIBUTE_HAlign, eAttr);
+  return eAttr;
+}
+int32_t CXFA_Para::GetVerticalAlign() {
+  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Top;
+  m_pNode->TryEnum(XFA_ATTRIBUTE_VAlign, eAttr);
+  return eAttr;
+}
+FX_FLOAT CXFA_Para::GetLineHeight() {
+  CXFA_Measurement ms;
+  m_pNode->TryMeasure(XFA_ATTRIBUTE_LineHeight, ms);
+  return ms.ToUnit(XFA_UNIT_Pt);
+}
+FX_FLOAT CXFA_Para::GetMarginLeft() {
+  CXFA_Measurement ms;
+  m_pNode->TryMeasure(XFA_ATTRIBUTE_MarginLeft, ms);
+  return ms.ToUnit(XFA_UNIT_Pt);
+}
+FX_FLOAT CXFA_Para::GetMarginRight() {
+  CXFA_Measurement ms;
+  m_pNode->TryMeasure(XFA_ATTRIBUTE_MarginRight, ms);
+  return ms.ToUnit(XFA_UNIT_Pt);
+}
+int32_t CXFA_Para::GetOrphans() {
+  int32_t iValue = 0;
+  m_pNode->TryInteger(XFA_ATTRIBUTE_Orphans, iValue);
+  return iValue;
+}
+FX_FLOAT CXFA_Para::GetRadixOffset() {
+  CXFA_Measurement ms;
+  m_pNode->TryMeasure(XFA_ATTRIBUTE_RadixOffset, ms);
+  return ms.ToUnit(XFA_UNIT_Pt);
+}
+FX_FLOAT CXFA_Para::GetSpaceAbove() {
+  CXFA_Measurement ms;
+  m_pNode->TryMeasure(XFA_ATTRIBUTE_SpaceAbove, ms);
+  return ms.ToUnit(XFA_UNIT_Pt);
+}
+FX_FLOAT CXFA_Para::GetSpaceBelow() {
+  CXFA_Measurement ms;
+  m_pNode->TryMeasure(XFA_ATTRIBUTE_SpaceBelow, ms);
+  return ms.ToUnit(XFA_UNIT_Pt);
+}
+FX_FLOAT CXFA_Para::GetTextIndent() {
+  CXFA_Measurement ms;
+  m_pNode->TryMeasure(XFA_ATTRIBUTE_TextIndent, ms);
+  return ms.ToUnit(XFA_UNIT_Pt);
+}
+int32_t CXFA_Para::GetWidows() {
+  int32_t iValue = 0;
+  m_pNode->TryInteger(XFA_ATTRIBUTE_Widows, iValue);
+  return iValue;
+}
+FX_BOOL CXFA_Para::SetHorizontalAlign(int32_t iHorizontalAlign) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_HAlign,
+                          (XFA_ATTRIBUTEENUM)iHorizontalAlign);
+}
+FX_BOOL CXFA_Para::SetVerticalAlign(int32_t iVerticalAlign) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_VAlign,
+                          (XFA_ATTRIBUTEENUM)iVerticalAlign);
+}
+FX_BOOL CXFA_Para::SetLineHeight(FX_FLOAT fLineHeight) {
+  CXFA_Measurement ms;
+  return m_pNode->SetMeasure(XFA_ATTRIBUTE_LineHeight, ms);
+}
+FX_BOOL CXFA_Para::SetMarginLeft(FX_FLOAT fMarginLeft) {
+  CXFA_Measurement ms(fMarginLeft, XFA_UNIT_Pt);
+  return m_pNode->SetMeasure(XFA_ATTRIBUTE_MarginLeft, ms);
+}
+FX_BOOL CXFA_Para::SetMarginRight(FX_FLOAT fMarginRight) {
+  CXFA_Measurement ms(fMarginRight, XFA_UNIT_Pt);
+  return m_pNode->SetMeasure(XFA_ATTRIBUTE_MarginRight, ms);
+}
+FX_BOOL CXFA_Para::SetOrphans(int32_t iOrphans) {
+  return m_pNode->SetInteger(XFA_ATTRIBUTE_Orphans, iOrphans);
+}
+FX_BOOL CXFA_Para::SetRadixOffset(FX_FLOAT fRadixOffset) {
+  CXFA_Measurement ms(fRadixOffset, XFA_UNIT_Pt);
+  return m_pNode->SetMeasure(XFA_ATTRIBUTE_RadixOffset, ms);
+}
+FX_BOOL CXFA_Para::SetSpaceAbove(FX_FLOAT fSpaceAbove) {
+  CXFA_Measurement ms(fSpaceAbove, XFA_UNIT_Pt);
+  return m_pNode->SetMeasure(XFA_ATTRIBUTE_SpaceAbove, ms);
+}
+FX_BOOL CXFA_Para::SetSpaceBelow(FX_FLOAT fSpaceBelow) {
+  CXFA_Measurement ms(fSpaceBelow, XFA_UNIT_Pt);
+  return m_pNode->SetMeasure(XFA_ATTRIBUTE_SpaceBelow, ms);
+}
+FX_BOOL CXFA_Para::SetTextIndent(FX_FLOAT fTextIndent) {
+  CXFA_Measurement ms(fTextIndent, XFA_UNIT_Pt);
+  return m_pNode->SetMeasure(XFA_ATTRIBUTE_TextIndent, ms);
+}
+FX_BOOL CXFA_Para::SetWidows(int32_t iWidows) {
+  return m_pNode->SetInteger(XFA_ATTRIBUTE_Widows, iWidows);
+}
+CXFA_Keep::CXFA_Keep(CXFA_Node* pNode, CXFA_Node* pParent)
+    : CXFA_Data(pNode), m_pParent(pParent) {}
+int32_t CXFA_Keep::GetIntact() {
+  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_None;
+  switch (m_pParent->GetClassID()) {
+    case XFA_ELEMENT_Subform: {
+      XFA_ATTRIBUTEENUM eAttrSubForm;
+      m_pParent->TryEnum(XFA_ATTRIBUTE_Layout, eAttrSubForm);
+      if (eAttrSubForm == XFA_ATTRIBUTEENUM_Position ||
+          eAttrSubForm == XFA_ATTRIBUTEENUM_Row) {
+        eAttr = XFA_ATTRIBUTEENUM_ContentArea;
+      }
+    } break;
+    case XFA_ELEMENT_Draw:
+      eAttr = XFA_ATTRIBUTEENUM_ContentArea;
+      break;
+    default:
+      break;
+  }
+  m_pNode->TryEnum(XFA_ATTRIBUTE_Intact, eAttr, FALSE);
+  return eAttr;
+}
+int32_t CXFA_Keep::GetNext() {
+  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_None;
+  m_pNode->TryEnum(XFA_ATTRIBUTE_Next, eAttr);
+  return eAttr;
+}
+int32_t CXFA_Keep::GetPrevious() {
+  XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_None;
+  m_pNode->TryEnum(XFA_ATTRIBUTE_Previous, eAttr);
+  return eAttr;
+}
+FX_BOOL CXFA_Keep::SetIntact(int32_t iIntact) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_Intact, (XFA_ATTRIBUTEENUM)iIntact);
+}
+FX_BOOL CXFA_Keep::SetNext(int32_t iNext) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_Next, (XFA_ATTRIBUTEENUM)iNext);
+}
+FX_BOOL CXFA_Keep::SetPrevious(int32_t iPrevious) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_Previous, (XFA_ATTRIBUTEENUM)iPrevious);
+}
+CXFA_Event::CXFA_Event(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+int32_t CXFA_Event::GetActivity() {
+  return m_pNode->GetEnum(XFA_ATTRIBUTE_Activity);
+}
+int32_t CXFA_Event::GetEventType() {
+  CXFA_Node* pChild = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+  while (pChild) {
+    int32_t eType = pChild->GetClassID();
+    if (eType != XFA_ELEMENT_Extras) {
+      return eType;
+    }
+    pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+  }
+  return XFA_ELEMENT_UNKNOWN;
+}
+void CXFA_Event::GetRef(CFX_WideStringC& wsRef) {
+  m_pNode->TryCData(XFA_ATTRIBUTE_Ref, wsRef);
+}
+int32_t CXFA_Event::GetExecuteRunAt() {
+  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Execute);
+  return pNode->GetEnum(XFA_ATTRIBUTE_RunAt);
+}
+int32_t CXFA_Event::GetExecuteType() {
+  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Execute);
+  return pNode->GetEnum(XFA_ATTRIBUTE_ExecuteType);
+}
+void CXFA_Event::GetExecuteConnection(CFX_WideString& wsConnection) {
+  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Execute);
+  CFX_WideStringC cData;
+  pNode->TryCData(XFA_ATTRIBUTE_Connection, cData);
+  wsConnection = cData;
+}
+CXFA_Script CXFA_Event::GetScript() {
+  return CXFA_Script(m_pNode->GetChild(0, XFA_ELEMENT_Script));
+}
+CXFA_Submit CXFA_Event::GetSubmit() {
+  return CXFA_Submit(m_pNode->GetChild(0, XFA_ELEMENT_Submit));
+}
+int32_t CXFA_Event::GetSignDataOperation() {
+  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_SignData);
+  return pNode->GetEnum(XFA_ATTRIBUTE_Operation);
+}
+void CXFA_Event::GetSignDataTarget(CFX_WideString& wsTarget) {
+  if (CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_SignData)) {
+    CFX_WideStringC wsCData;
+    pNode->TryCData(XFA_ATTRIBUTE_Target, wsCData);
+    wsTarget = wsCData;
+  }
+}
+FX_BOOL CXFA_Event::SetActivity(int32_t iActivity) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_Activity, (XFA_ATTRIBUTEENUM)iActivity);
+}
+FX_BOOL CXFA_Event::SetEventType(int32_t iEventType) {
+  return FALSE;
+}
+FX_BOOL CXFA_Event::SetExecuteRunAt(int32_t iExecuteRunAt) {
+  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Execute);
+  return pNode->SetEnum(XFA_ATTRIBUTE_RunAt, (XFA_ATTRIBUTEENUM)iExecuteRunAt);
+}
+FX_BOOL CXFA_Event::SetExecuteType(int32_t iExecuteType) {
+  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Execute);
+  return pNode->SetEnum(XFA_ATTRIBUTE_ExecuteType,
+                        (XFA_ATTRIBUTEENUM)iExecuteType);
+}
+FX_BOOL CXFA_Event::SetExecuteConnection(const CFX_WideString& wsConnection) {
+  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Execute);
+  return pNode->SetCData(XFA_ATTRIBUTE_Connection, wsConnection);
+}
+FX_BOOL CXFA_Event::SetSignDataOperation(int32_t iOperation) {
+  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_SignData);
+  return pNode->SetEnum(XFA_ATTRIBUTE_Operation, (XFA_ATTRIBUTEENUM)iOperation);
+}
+FX_BOOL CXFA_Event::SetSignDataTarget(const CFX_WideString& wsTarget) {
+  if (CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_SignData)) {
+    return pNode->SetCData(XFA_ATTRIBUTE_Target, wsTarget);
+  }
+  return FALSE;
+}
+CXFA_Script::CXFA_Script(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+void CXFA_Script::GetBinding(CFX_WideString& wsBinding) {
+  CFX_WideStringC cData;
+  m_pNode->TryCData(XFA_ATTRIBUTE_Binding, cData);
+  wsBinding = cData;
+}
+XFA_SCRIPTTYPE CXFA_Script::GetContentType() {
+  CFX_WideStringC cData;
+  if (m_pNode->TryCData(XFA_ATTRIBUTE_ContentType, cData, FALSE)) {
+    if (cData == FX_WSTRC(L"application/x-javascript")) {
+      return XFA_SCRIPTTYPE_Javascript;
+    } else if (cData == FX_WSTRC(L"application/x-formcalc")) {
+      return XFA_SCRIPTTYPE_Formcalc;
+    } else {
+      return XFA_SCRIPTTYPE_Unkown;
+    }
+  }
+  return XFA_SCRIPTTYPE_Formcalc;
+}
+int32_t CXFA_Script::GetRunAt() {
+  return m_pNode->GetEnum(XFA_ATTRIBUTE_RunAt);
+}
+void CXFA_Script::GetExpression(CFX_WideString& wsExpression) {
+  m_pNode->TryContent(wsExpression);
+}
+FX_BOOL CXFA_Script::SetBinding(const CFX_WideString& wsBinding) {
+  return m_pNode->SetCData(XFA_ATTRIBUTE_Binding, wsBinding);
+}
+FX_BOOL CXFA_Script::SetContentType(XFA_SCRIPTTYPE eType) {
+  CFX_WideString wsType;
+  switch (eType) {
+    case XFA_SCRIPTTYPE_Javascript:
+      wsType = L"application/x-javascript";
+      break;
+    case XFA_SCRIPTTYPE_Formcalc:
+      wsType = L"application/x-formcalc";
+      break;
+    default:
+      break;
+  }
+  return m_pNode->SetCData(XFA_ATTRIBUTE_ContentType, wsType);
+}
+FX_BOOL CXFA_Script::SetRunAt(int32_t iRunAt) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_RunAt, (XFA_ATTRIBUTEENUM)iRunAt);
+}
+FX_BOOL CXFA_Script::SetExpression(const CFX_WideString& wsExpression) {
+  return m_pNode->SetContent(wsExpression, wsExpression);
+}
+CXFA_Submit::CXFA_Submit(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+FX_BOOL CXFA_Submit::IsSubmitEmbedPDF() {
+  return m_pNode->GetBoolean(XFA_ATTRIBUTE_EmbedPDF);
+}
+int32_t CXFA_Submit::GetSubmitFormat() {
+  return m_pNode->GetEnum(XFA_ATTRIBUTE_Format);
+}
+void CXFA_Submit::GetSubmitTarget(CFX_WideStringC& wsTarget) {
+  m_pNode->TryCData(XFA_ATTRIBUTE_Target, wsTarget);
+}
+XFA_TEXTENCODING CXFA_Submit::GetSubmitTextEncoding() {
+  CFX_WideStringC wsCData;
+  if (!m_pNode->TryCData(XFA_ATTRIBUTE_TextEncoding, wsCData)) {
+    return XFA_TEXTENCODING_None;
+  }
+  CFX_WideString wsValue(wsCData);
+  if (wsValue == L"Big-Five") {
+    return XFA_TEXTENCODING_Big5;
+  } else if (wsValue == L"fontSpecific") {
+    return XFA_TEXTENCODING_FontSpecific;
+  } else if (wsValue == L"GBK") {
+    return XFA_TEXTENCODING_GBK;
+  } else if (wsValue == L"GB-18030") {
+    return XFA_TEXTENCODING_GB18030;
+  } else if (wsValue == L"GB-2312") {
+    return XFA_TEXTENCODING_GB2312;
+  } else if (wsValue == L"ISO-8859-NN") {
+    return XFA_TEXTENCODING_ISO8859NN;
+  } else if (wsValue == L"KSC-5601") {
+    return XFA_TEXTENCODING_KSC5601;
+  } else if (wsValue == L"Shift-JIS") {
+    return XFA_TEXTENCODING_ShiftJIS;
+  } else if (wsValue == L"UCS-2") {
+    return XFA_TEXTENCODING_UCS2;
+  } else if (wsValue == L"UTF-16") {
+    return XFA_TEXTENCODING_UTF16;
+  } else if (wsValue == L"UTF-8") {
+    return XFA_TEXTENCODING_UTF8;
+  }
+  return XFA_TEXTENCODING_None;
+}
+void CXFA_Submit::GetSubmitXDPContent(CFX_WideStringC& wsContent) {
+  m_pNode->TryCData(XFA_ATTRIBUTE_XdpContent, wsContent);
+}
+FX_BOOL CXFA_Submit::SetSubmitFormat(int32_t iSubmitFormat) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_Format,
+                          (XFA_ATTRIBUTEENUM)iSubmitFormat);
+}
+FX_BOOL CXFA_Submit::SetSubmitTarget(const CFX_WideString& wsTarget) {
+  return m_pNode->SetCData(XFA_ATTRIBUTE_Target, wsTarget);
+}
+FX_BOOL CXFA_Submit::SetSubmitTextEncoding(XFA_TEXTENCODING eTextEncoding) {
+  CFX_WideString wsValue;
+  switch (eTextEncoding) {
+    case XFA_TEXTENCODING_Big5:
+      wsValue = L"Big-Five";
+      break;
+    case XFA_TEXTENCODING_FontSpecific:
+      wsValue = L"fontSpecific";
+      break;
+    case XFA_TEXTENCODING_GBK:
+      wsValue = L"GBK";
+      break;
+    case XFA_TEXTENCODING_GB18030:
+      wsValue = L"GB-18030";
+      break;
+    case XFA_TEXTENCODING_GB2312:
+      wsValue = L"GB-2312";
+      break;
+    case XFA_TEXTENCODING_ISO8859NN:
+      wsValue = L"ISO-8859-NN";
+      break;
+    case XFA_TEXTENCODING_KSC5601:
+      wsValue = L"KSC-5601";
+      break;
+    case XFA_TEXTENCODING_ShiftJIS:
+      wsValue = L"Shift-JIS";
+      break;
+    case XFA_TEXTENCODING_UCS2:
+      wsValue = L"UCS-2";
+      break;
+    case XFA_TEXTENCODING_UTF16:
+      wsValue = L"UTF-16";
+      break;
+    case XFA_TEXTENCODING_UTF8:
+      wsValue = L"UTF-8";
+      break;
+    default:
+      break;
+  }
+  return m_pNode->SetCData(XFA_ATTRIBUTE_TextEncoding, wsValue);
+}
+FX_BOOL CXFA_Submit::SetSubmitXDPContent(const CFX_WideString& wsContent) {
+  return m_pNode->SetCData(XFA_ATTRIBUTE_XdpContent, wsContent);
+}
+XFA_ELEMENT CXFA_Value::GetChildValueClassID() {
+  if (!m_pNode) {
+    return XFA_ELEMENT_UNKNOWN;
+  }
+  if (CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+    return pNode->GetClassID();
+  }
+  return XFA_ELEMENT_UNKNOWN;
+}
+FX_BOOL CXFA_Value::GetChildValueContent(CFX_WideString& wsContent) {
+  if (!m_pNode) {
+    return FALSE;
+  }
+  if (CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+    return pNode->TryContent(wsContent);
+  }
+  return FALSE;
+}
+CXFA_Arc CXFA_Value::GetArc() {
+  return CXFA_Arc(m_pNode ? m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)
+                          : nullptr);
+}
+CXFA_Line CXFA_Value::GetLine() {
+  return CXFA_Line(m_pNode ? m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)
+                           : nullptr);
+}
+CXFA_Rectangle CXFA_Value::GetRectangle() {
+  return CXFA_Rectangle(m_pNode ? m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)
+                                : nullptr);
+}
+CXFA_Text CXFA_Value::GetText() {
+  return CXFA_Text(m_pNode ? m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)
+                           : nullptr);
+}
+CXFA_ExData CXFA_Value::GetExData() {
+  return CXFA_ExData(m_pNode ? m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)
+                             : nullptr);
+}
+CXFA_Image CXFA_Value::GetImage() {
+  return CXFA_Image(
+      m_pNode ? (m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) : nullptr,
+      TRUE);
+}
+FX_BOOL CXFA_Value::SetChildValueContent(const CFX_WideString& wsContent,
+                                         FX_BOOL bNotify,
+                                         XFA_ELEMENT iType) {
+  if (!m_pNode) {
+    return FALSE;
+  }
+  CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+  if (!pNode) {
+    if (iType == XFA_ELEMENT_UNKNOWN) {
+      return FALSE;
+    }
+    pNode = m_pNode->GetProperty(0, iType);
+  }
+  CFX_WideString wsFormatContent(wsContent);
+  CXFA_WidgetData* pContainerWidgetData = pNode->GetContainerWidgetData();
+  if (pContainerWidgetData) {
+    pContainerWidgetData->GetFormatDataValue(wsContent, wsFormatContent);
+  }
+  return pNode->SetContent(wsContent, wsFormatContent, bNotify);
+}
+int32_t CXFA_Line::GetHand() {
+  return m_pNode->GetEnum(XFA_ATTRIBUTE_Hand);
+}
+FX_BOOL CXFA_Line::GetSlop() {
+  XFA_ATTRIBUTEENUM eSlop = m_pNode->GetEnum(XFA_ATTRIBUTE_Slope);
+  return eSlop == XFA_ATTRIBUTEENUM_Slash;
+}
+CXFA_Edge CXFA_Line::GetEdge() {
+  return CXFA_Edge(m_pNode->GetChild(0, XFA_ELEMENT_Edge));
+}
+FX_BOOL CXFA_Line::SetHand(int32_t iHand) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_Hand, (XFA_ATTRIBUTEENUM)iHand);
+}
+FX_BOOL CXFA_Line::SetSlop(int32_t iSlop) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_Slope, (XFA_ATTRIBUTEENUM)iSlop);
+}
+CXFA_Text::CXFA_Text(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+void CXFA_Text::GetName(CFX_WideStringC& wsName) {
+  m_pNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
+}
+int32_t CXFA_Text::GetMaxChars() {
+  return m_pNode->GetInteger(XFA_ATTRIBUTE_MaxChars);
+}
+void CXFA_Text::GetRid(CFX_WideStringC& wsRid) {
+  m_pNode->TryCData(XFA_ATTRIBUTE_Rid, wsRid);
+}
+void CXFA_Text::GetContent(CFX_WideString& wsText) {
+  m_pNode->TryContent(wsText);
+}
+void CXFA_Text::SetContent(CFX_WideString wsText, FX_BOOL bNotify) {
+  CFX_WideString wsFormatValue(wsText);
+  CXFA_WidgetData* pContainerWidgetData = m_pNode->GetContainerWidgetData();
+  if (pContainerWidgetData) {
+    pContainerWidgetData->GetFormatDataValue(wsText, wsFormatValue);
+  }
+  m_pNode->SetContent(wsText, wsFormatValue, bNotify);
+}
+FX_BOOL CXFA_Text::SetName(const CFX_WideString& wsName) {
+  return m_pNode->SetCData(XFA_ATTRIBUTE_Name, wsName);
+}
+FX_BOOL CXFA_Text::SetMaxChars(int32_t iMaxChars) {
+  return m_pNode->SetInteger(XFA_ATTRIBUTE_MaxChars, iMaxChars);
+}
+FX_BOOL CXFA_Text::SetRid(const CFX_WideString& wsRid) {
+  return m_pNode->SetCData(XFA_ATTRIBUTE_Rid, wsRid);
+}
+CXFA_ExData::CXFA_ExData(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+void CXFA_ExData::GetContentType(CFX_WideStringC& wsContentType) {
+  m_pNode->TryCData(XFA_ATTRIBUTE_ContentType, wsContentType);
+}
+void CXFA_ExData::GetHref(CFX_WideStringC& wsHref) {
+  m_pNode->TryCData(XFA_ATTRIBUTE_Href, wsHref);
+}
+int32_t CXFA_ExData::GetMaxLength() {
+  return m_pNode->GetInteger(XFA_ATTRIBUTE_MaxLength);
+}
+void CXFA_ExData::GetRid(CFX_WideStringC& wsRid) {
+  m_pNode->TryCData(XFA_ATTRIBUTE_Rid, wsRid);
+}
+int32_t CXFA_ExData::GetTransferEncoding() {
+  return m_pNode->GetEnum(XFA_ATTRIBUTE_TransferEncoding);
+}
+void CXFA_ExData::GetContent(CFX_WideString& wsText) {
+  m_pNode->TryContent(wsText);
+}
+FX_BOOL CXFA_ExData::SetContentType(const CFX_WideString& wsContentType) {
+  return m_pNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
+}
+FX_BOOL CXFA_ExData::SetHref(const CFX_WideString& wsHref) {
+  return m_pNode->SetCData(XFA_ATTRIBUTE_Href, wsHref);
+}
+FX_BOOL CXFA_ExData::SetMaxLength(int32_t iMaxLength) {
+  return m_pNode->SetInteger(XFA_ATTRIBUTE_MaxLength, iMaxLength);
+}
+FX_BOOL CXFA_ExData::SetRid(const CFX_WideString& wsRid) {
+  return m_pNode->SetCData(XFA_ATTRIBUTE_Rid, wsRid);
+}
+FX_BOOL CXFA_ExData::SetTransferEncoding(int32_t iTransferEncoding) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_TransferEncoding,
+                          (XFA_ATTRIBUTEENUM)iTransferEncoding);
+}
+FX_BOOL CXFA_ExData::SetContent(const CFX_WideString& wsText,
+                                FX_BOOL bNotify,
+                                FX_BOOL bScriptModify,
+                                FX_BOOL bSyncData) {
+  CFX_WideString wsFormatValue(wsText);
+  CXFA_WidgetData* pContainerWidgetData = m_pNode->GetContainerWidgetData();
+  if (pContainerWidgetData) {
+    pContainerWidgetData->GetFormatDataValue(wsText, wsFormatValue);
+  }
+  return m_pNode->SetContent(wsText, wsFormatValue, bNotify, bScriptModify,
+                             bSyncData);
+}
+CXFA_Image::CXFA_Image(CXFA_Node* pNode, FX_BOOL bDefValue)
+    : CXFA_Data(pNode), m_bDefValue(bDefValue) {}
+int32_t CXFA_Image::GetAspect() {
+  return m_pNode->GetEnum(XFA_ATTRIBUTE_Aspect);
+}
+FX_BOOL CXFA_Image::GetContentType(CFX_WideString& wsContentType) {
+  return m_pNode->TryCData(XFA_ATTRIBUTE_ContentType, wsContentType);
+}
+FX_BOOL CXFA_Image::GetHref(CFX_WideString& wsHref) {
+  if (m_bDefValue) {
+    return m_pNode->TryCData(XFA_ATTRIBUTE_Href, wsHref);
+  }
+  return m_pNode->GetAttribute(FX_WSTRC(L"href"), wsHref);
+}
+int32_t CXFA_Image::GetTransferEncoding() {
+  if (m_bDefValue) {
+    return m_pNode->GetEnum(XFA_ATTRIBUTE_TransferEncoding);
+  }
+  return XFA_ATTRIBUTEENUM_Base64;
+}
+FX_BOOL CXFA_Image::GetContent(CFX_WideString& wsText) {
+  return m_pNode->TryContent(wsText);
+}
+FX_BOOL CXFA_Image::SetAspect(int32_t iAspect) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_Aspect, (XFA_ATTRIBUTEENUM)iAspect);
+}
+FX_BOOL CXFA_Image::SetContentType(const CFX_WideString& wsContentType) {
+  return m_pNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
+}
+FX_BOOL CXFA_Image::SetHref(const CFX_WideString& wsHref) {
+  if (m_bDefValue) {
+    return m_pNode->SetCData(XFA_ATTRIBUTE_Href, wsHref);
+  }
+  return m_pNode->SetAttribute(XFA_ATTRIBUTE_Href, wsHref);
+}
+FX_BOOL CXFA_Image::SetTransferEncoding(int32_t iTransferEncoding) {
+  if (m_bDefValue) {
+    return m_pNode->SetEnum(XFA_ATTRIBUTE_TransferEncoding,
+                            (XFA_ATTRIBUTEENUM)iTransferEncoding);
+  }
+  return TRUE;
+}
+FX_BOOL CXFA_Image::SetContent(const CFX_WideString& wsText) {
+  CFX_WideString wsFormatValue(wsText);
+  CXFA_WidgetData* pContainerWidgetData = m_pNode->GetContainerWidgetData();
+  if (pContainerWidgetData) {
+    pContainerWidgetData->GetFormatDataValue(wsText, wsFormatValue);
+  }
+  return m_pNode->SetContent(wsText, wsFormatValue);
+}
+CXFA_Calculate::CXFA_Calculate(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+int32_t CXFA_Calculate::GetOverride() {
+  XFA_ATTRIBUTEENUM eAtt = XFA_ATTRIBUTEENUM_Error;
+  m_pNode->TryEnum(XFA_ATTRIBUTE_Override, eAtt, FALSE);
+  return eAtt;
+}
+CXFA_Script CXFA_Calculate::GetScript() {
+  return CXFA_Script(m_pNode->GetChild(0, XFA_ELEMENT_Script));
+}
+void CXFA_Calculate::GetMessageText(CFX_WideString& wsMessage) {
+  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Message)) {
+    CXFA_Text text(pNode->GetChild(0, XFA_ELEMENT_Text));
+    if (text) {
+      text.GetContent(wsMessage);
+    }
+  }
+}
+FX_BOOL CXFA_Calculate::SetOverride(int32_t iOverride) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_Override, (XFA_ATTRIBUTEENUM)iOverride);
+}
+FX_BOOL CXFA_Calculate::SetMessageText(const CFX_WideString& wsMessage) {
+  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Message)) {
+    CXFA_Node* pChildNode = pNode->GetProperty(0, XFA_ELEMENT_Text);
+    return pChildNode->SetContent(wsMessage, wsMessage);
+  }
+  return FALSE;
+}
+CXFA_Validate::CXFA_Validate(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+int32_t CXFA_Validate::GetFormatTest() {
+  return m_pNode->GetEnum(XFA_ATTRIBUTE_FormatTest);
+}
+FX_BOOL CXFA_Validate::SetTestValue(int32_t iType,
+                                    CFX_WideString& wsValue,
+                                    XFA_ATTRIBUTEENUM eName) {
+  const XFA_ATTRIBUTEENUMINFO* pInfo = XFA_GetAttributeEnumByName(wsValue);
+  if (pInfo) {
+    eName = pInfo->eName;
+  }
+  m_pNode->SetEnum((XFA_ATTRIBUTE)iType, eName, FALSE);
+  return TRUE;
+}
+FX_BOOL CXFA_Validate::SetFormatTest(CFX_WideString wsValue) {
+  return SetTestValue(XFA_ATTRIBUTE_FormatTest, wsValue,
+                      XFA_ATTRIBUTEENUM_Warning);
+}
+FX_BOOL CXFA_Validate::SetNullTest(CFX_WideString wsValue) {
+  return SetTestValue(XFA_ATTRIBUTE_NullTest, wsValue,
+                      XFA_ATTRIBUTEENUM_Disabled);
+}
+int32_t CXFA_Validate::GetNullTest() {
+  return m_pNode->GetEnum(XFA_ATTRIBUTE_NullTest);
+}
+int32_t CXFA_Validate::GetScriptTest() {
+  return m_pNode->GetEnum(XFA_ATTRIBUTE_ScriptTest);
+}
+void CXFA_Validate::GetMessageText(CFX_WideString& wsMessage,
+                                   const CFX_WideStringC& wsMessageType) {
+  if (CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Message, FALSE)) {
+    CXFA_Node* pItemNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+    for (; pItemNode;
+         pItemNode = pItemNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+      if (pItemNode->GetClassID() != XFA_ELEMENT_Text) {
+        continue;
+      }
+      CFX_WideStringC wsName;
+      pItemNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
+      if (wsName.IsEmpty() || wsName == wsMessageType) {
+        pItemNode->TryContent(wsMessage);
+        return;
+      }
+    }
+  }
+}
+void CXFA_Validate::SetFormatMessageText(CFX_WideString wsMessage) {
+  SetMessageText(wsMessage, FX_WSTRC(L"formatTest"));
+}
+void CXFA_Validate::GetFormatMessageText(CFX_WideString& wsMessage) {
+  GetMessageText(wsMessage, FX_WSTRC(L"formatTest"));
+}
+void CXFA_Validate::SetNullMessageText(CFX_WideString wsMessage) {
+  SetMessageText(wsMessage, FX_WSTRC(L"nullTest"));
+}
+void CXFA_Validate::GetNullMessageText(CFX_WideString& wsMessage) {
+  GetMessageText(wsMessage, FX_WSTRC(L"nullTest"));
+}
+void CXFA_Validate::SetMessageText(CFX_WideString& wsMessage,
+                                   const CFX_WideStringC& wsMessageType) {
+  if (CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Message, TRUE)) {
+    CXFA_Node* pItemNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+    for (; pItemNode;
+         pItemNode = pItemNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+      if (pItemNode->GetClassID() != XFA_ELEMENT_Text) {
+        continue;
+      }
+      CFX_WideStringC wsName;
+      pItemNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
+      if (wsName.IsEmpty() || wsName == wsMessageType) {
+        pItemNode->SetContent(wsMessage, wsMessage, FALSE);
+        return;
+      }
+    }
+    CXFA_Node* pTextNode = pNode->CreateSamePacketNode(XFA_ELEMENT_Text);
+    pNode->InsertChild(pTextNode);
+    pTextNode->SetCData(XFA_ATTRIBUTE_Name, wsMessageType, FALSE);
+    pTextNode->SetContent(wsMessage, wsMessage, FALSE);
+  }
+}
+void CXFA_Validate::GetScriptMessageText(CFX_WideString& wsMessage) {
+  GetMessageText(wsMessage, FX_WSTRC(L"scriptTest"));
+}
+void CXFA_Validate::SetScriptMessageText(CFX_WideString wsMessage) {
+  SetMessageText(wsMessage, FX_WSTRC(L"scriptTest"));
+}
+void CXFA_Validate::GetPicture(CFX_WideString& wsPicture) {
+  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Picture)) {
+    pNode->TryContent(wsPicture);
+  }
+}
+CXFA_Script CXFA_Validate::GetScript() {
+  return CXFA_Script(m_pNode->GetChild(0, XFA_ELEMENT_Script));
+}
+CXFA_Variables::CXFA_Variables(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+int32_t CXFA_Variables::CountScripts() {
+  return m_pNode->CountChildren(XFA_ELEMENT_Script);
+}
+CXFA_Script CXFA_Variables::GetScript(int32_t nIndex) {
+  return CXFA_Script(m_pNode->GetChild(nIndex, XFA_ELEMENT_Script));
+}
+CXFA_Bind::CXFA_Bind(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+int32_t CXFA_Bind::GetMatch() {
+  return m_pNode->GetEnum(XFA_ATTRIBUTE_Match);
+}
+void CXFA_Bind::GetRef(CFX_WideStringC& wsRef) {
+  m_pNode->TryCData(XFA_ATTRIBUTE_Ref, wsRef);
+}
+void CXFA_Bind::GetPicture(CFX_WideString& wsPicture) {
+  if (CXFA_Node* pPicture = m_pNode->GetChild(0, XFA_ELEMENT_Picture)) {
+    pPicture->TryContent(wsPicture);
+  }
+}
+FX_BOOL CXFA_Bind::SetMatch(int32_t iMatch) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_Match, (XFA_ATTRIBUTEENUM)iMatch);
+}
+FX_BOOL CXFA_Bind::SetRef(const CFX_WideString& wsRef) {
+  return m_pNode->SetCData(XFA_ATTRIBUTE_Ref, wsRef);
+}
+FX_BOOL CXFA_Bind::SetPicture(const CFX_WideString& wsPicture) {
+  if (CXFA_Node* pPicture = m_pNode->GetChild(0, XFA_ELEMENT_Picture)) {
+    return pPicture->SetContent(wsPicture, wsPicture);
+  }
+  return FALSE;
+}
+CXFA_Assist::CXFA_Assist(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+CXFA_ToolTip CXFA_Assist::GetToolTip() {
+  return CXFA_ToolTip(m_pNode->GetChild(0, XFA_ELEMENT_ToolTip));
+}
+CXFA_ToolTip::CXFA_ToolTip(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+FX_BOOL CXFA_ToolTip::GetTip(CFX_WideString& wsTip) {
+  return m_pNode->TryContent(wsTip);
+}
+FX_BOOL CXFA_ToolTip::SetTip(const CFX_WideString& wsTip) {
+  return m_pNode->SetContent(wsTip, wsTip);
+}
+CXFA_BindItems::CXFA_BindItems(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+void CXFA_BindItems::GetConnection(CFX_WideStringC& wsConnection) {
+  m_pNode->TryCData(XFA_ATTRIBUTE_Connection, wsConnection);
+}
+void CXFA_BindItems::GetLabelRef(CFX_WideStringC& wsLabelRef) {
+  m_pNode->TryCData(XFA_ATTRIBUTE_LabelRef, wsLabelRef);
+}
+void CXFA_BindItems::GetValueRef(CFX_WideStringC& wsValueRef) {
+  m_pNode->TryCData(XFA_ATTRIBUTE_ValueRef, wsValueRef);
+}
+void CXFA_BindItems::GetRef(CFX_WideStringC& wsRef) {
+  m_pNode->TryCData(XFA_ATTRIBUTE_Ref, wsRef);
+}
+FX_BOOL CXFA_BindItems::SetConnection(const CFX_WideString& wsConnection) {
+  return m_pNode->SetCData(XFA_ATTRIBUTE_Connection, wsConnection);
+}
+FX_BOOL CXFA_BindItems::SetLabelRef(const CFX_WideString& wsLabelRef) {
+  return m_pNode->SetCData(XFA_ATTRIBUTE_LabelRef, wsLabelRef);
+}
+FX_BOOL CXFA_BindItems::SetValueRef(const CFX_WideString& wsValueRef) {
+  return m_pNode->SetCData(XFA_ATTRIBUTE_ValueRef, wsValueRef);
+}
+FX_BOOL CXFA_BindItems::SetRef(const CFX_WideString& wsRef) {
+  return m_pNode->SetCData(XFA_ATTRIBUTE_Ref, wsRef);
+}
+int32_t CXFA_Box::GetBreak() const {
+  if (!m_pNode) {
+    return XFA_ATTRIBUTEENUM_Close;
+  }
+  return m_pNode->GetEnum(XFA_ATTRIBUTE_Break);
+}
+int32_t CXFA_Box::GetHand() const {
+  if (!m_pNode) {
+    return XFA_ATTRIBUTEENUM_Even;
+  }
+  return m_pNode->GetEnum(XFA_ATTRIBUTE_Hand);
+}
+int32_t CXFA_Box::GetPresence() const {
+  if (!m_pNode) {
+    return XFA_ATTRIBUTEENUM_Hidden;
+  }
+  return m_pNode->GetEnum(XFA_ATTRIBUTE_Presence);
+}
+int32_t CXFA_Box::CountCorners() const {
+  if (!m_pNode) {
+    return 0;
+  }
+  return m_pNode->CountChildren(XFA_ELEMENT_Corner);
+}
+CXFA_Corner CXFA_Box::GetCorner(int32_t nIndex) const {
+  return CXFA_Corner(
+      m_pNode ? m_pNode->GetProperty(nIndex, XFA_ELEMENT_Corner, nIndex == 0)
+              : nullptr);
+}
+int32_t CXFA_Box::CountEdges() const {
+  if (!m_pNode) {
+    return 0;
+  }
+  return m_pNode->CountChildren(XFA_ELEMENT_Edge);
+}
+CXFA_Edge CXFA_Box::GetEdge(int32_t nIndex) const {
+  return CXFA_Edge(
+      m_pNode ? m_pNode->GetProperty(nIndex, XFA_ELEMENT_Edge, nIndex == 0)
+              : nullptr);
+}
+static void XFA_BOX_GetStrokes(CXFA_Node* pNode,
+                               CXFA_StrokeArray& strokes,
+                               FX_BOOL bNULL) {
+  strokes.RemoveAll();
+  if (!pNode) {
+    return;
+  }
+  strokes.SetSize(8);
+  int32_t i, j;
+  for (i = 0, j = 0; i < 4; i++) {
+    CXFA_Corner corner =
+        CXFA_Corner(pNode->GetProperty(i, XFA_ELEMENT_Corner, i == 0));
+    if (corner || i == 0) {
+      strokes.SetAt(j, corner);
+    } else if (bNULL) {
+      strokes.SetAt(j, CXFA_Stroke(nullptr));
+    } else if (i == 1) {
+      strokes.SetAt(j, strokes[0]);
+    } else if (i == 2) {
+      strokes.SetAt(j, strokes[0]);
+    } else {
+      strokes.SetAt(j, strokes[2]);
+    }
+    j++;
+    CXFA_Edge edge = CXFA_Edge(pNode->GetProperty(i, XFA_ELEMENT_Edge, i == 0));
+    if (edge || i == 0) {
+      strokes.SetAt(j, edge);
+    } else if (bNULL) {
+      strokes.SetAt(j, CXFA_Stroke(nullptr));
+    } else if (i == 1) {
+      strokes.SetAt(j, strokes[1]);
+    } else if (i == 2) {
+      strokes.SetAt(j, strokes[1]);
+    } else {
+      strokes.SetAt(j, strokes[3]);
+    }
+    j++;
+  }
+}
+void CXFA_Box::GetStrokes(CXFA_StrokeArray& strokes) const {
+  XFA_BOX_GetStrokes(m_pNode, strokes, FALSE);
+}
+FX_BOOL CXFA_Box::IsCircular() const {
+  if (!m_pNode) {
+    return FALSE;
+  }
+  return m_pNode->GetBoolean(XFA_ATTRIBUTE_Circular);
+}
+FX_BOOL CXFA_Box::GetStartAngle(FX_FLOAT& fStartAngle) const {
+  fStartAngle = 0;
+  if (!m_pNode) {
+    return FALSE;
+  }
+  CXFA_Measurement ms;
+  FX_BOOL bRet = m_pNode->TryMeasure(XFA_ATTRIBUTE_StartAngle, ms, FALSE);
+  if (bRet) {
+    fStartAngle = ms.GetValue();
+  }
+  return bRet;
+}
+FX_BOOL CXFA_Box::GetSweepAngle(FX_FLOAT& fSweepAngle) const {
+  fSweepAngle = 360;
+  if (!m_pNode) {
+    return FALSE;
+  }
+  CXFA_Measurement ms;
+  FX_BOOL bRet = m_pNode->TryMeasure(XFA_ATTRIBUTE_SweepAngle, ms, FALSE);
+  if (bRet) {
+    fSweepAngle = ms.GetValue();
+  }
+  return bRet;
+}
+CXFA_Fill CXFA_Box::GetFill(FX_BOOL bModified) const {
+  if (!m_pNode) {
+    return CXFA_Fill(nullptr);
+  }
+  CXFA_Node* pFillNode = m_pNode->GetProperty(0, XFA_ELEMENT_Fill, bModified);
+  return CXFA_Fill(pFillNode);
+}
+CXFA_Margin CXFA_Box::GetMargin() const {
+  return CXFA_Margin(m_pNode ? m_pNode->GetChild(0, XFA_ELEMENT_Margin)
+                             : nullptr);
+}
+static FX_BOOL XFA_BOX_SameStyles(const CXFA_StrokeArray& strokes) {
+  int32_t iCount = strokes.GetSize();
+  if (iCount < 1) {
+    return TRUE;
+  }
+  CXFA_Stroke stroke1 = strokes[0];
+  for (int32_t i = 1; i < iCount; i++) {
+    CXFA_Stroke stroke2 = strokes[i];
+    if (!stroke2) {
+      continue;
+    }
+    if (!stroke1) {
+      stroke1 = stroke2;
+    } else if (!stroke1.SameStyles(stroke2)) {
+      return FALSE;
+    }
+  }
+  return TRUE;
+}
+FX_BOOL CXFA_Box::SameStyles() const {
+  if (IsArc()) {
+    return TRUE;
+  }
+  CXFA_StrokeArray strokes;
+  XFA_BOX_GetStrokes(m_pNode, strokes, TRUE);
+  return XFA_BOX_SameStyles(strokes);
+}
+static int32_t XFA_BOX_3DStyle(const CXFA_StrokeArray& strokes,
+                               CXFA_Stroke& stroke) {
+  int32_t iCount = strokes.GetSize();
+  if (iCount < 1) {
+    return 0;
+  }
+  stroke = strokes[0];
+  for (int32_t i = 1; i < iCount; i++) {
+    CXFA_Stroke find = strokes[i];
+    if (!find) {
+      continue;
+    }
+    if (!stroke) {
+      stroke = find;
+    } else if (stroke.GetStrokeType() != find.GetStrokeType()) {
+      stroke = find;
+      break;
+    }
+  }
+  int32_t iType = stroke.GetStrokeType();
+  if (iType == XFA_ATTRIBUTEENUM_Lowered || iType == XFA_ATTRIBUTEENUM_Raised ||
+      iType == XFA_ATTRIBUTEENUM_Etched ||
+      iType == XFA_ATTRIBUTEENUM_Embossed) {
+    return iType;
+  }
+  return 0;
+}
+int32_t CXFA_Box::Get3DStyle(FX_BOOL& bVisible, FX_FLOAT& fThickness) const {
+  if (IsArc()) {
+    return 0;
+  }
+  CXFA_StrokeArray strokes;
+  XFA_BOX_GetStrokes(m_pNode, strokes, TRUE);
+  CXFA_Stroke stroke(NULL);
+  int32_t iType = XFA_BOX_3DStyle(strokes, stroke);
+  if (iType) {
+    bVisible = stroke.IsVisible();
+    fThickness = stroke.GetThickness();
+  }
+  return iType;
+}
+int32_t CXFA_Stroke::GetPresence() const {
+  return m_pNode ? m_pNode->GetEnum(XFA_ATTRIBUTE_Presence)
+                 : XFA_ATTRIBUTEENUM_Invisible;
+}
+int32_t CXFA_Stroke::GetCapType() const {
+  if (!m_pNode) {
+    return XFA_ATTRIBUTEENUM_Square;
+  }
+  return m_pNode->GetEnum(XFA_ATTRIBUTE_Cap);
+}
+int32_t CXFA_Stroke::GetStrokeType() const {
+  return m_pNode ? m_pNode->GetEnum(XFA_ATTRIBUTE_Stroke)
+                 : XFA_ATTRIBUTEENUM_Solid;
+}
+FX_FLOAT CXFA_Stroke::GetThickness() const {
+  return GetMSThickness().ToUnit(XFA_UNIT_Pt);
+}
+CXFA_Measurement CXFA_Stroke::GetMSThickness() const {
+  return m_pNode ? m_pNode->GetMeasure(XFA_ATTRIBUTE_Thickness)
+                 : XFA_GetAttributeDefaultValue_Measure(XFA_ELEMENT_Edge,
+                                                        XFA_ATTRIBUTE_Thickness,
+                                                        XFA_XDPPACKET_Form);
+}
+void CXFA_Stroke::SetThickness(FX_FLOAT fThickness) {
+  if (!m_pNode) {
+    return;
+  }
+  CXFA_Measurement thickness(fThickness, XFA_UNIT_Pt);
+  m_pNode->SetMeasure(XFA_ATTRIBUTE_Thickness, thickness);
+}
+void CXFA_Stroke::SetMSThickness(CXFA_Measurement msThinkness) {
+  if (!m_pNode) {
+    return;
+  }
+  m_pNode->SetMeasure(XFA_ATTRIBUTE_Thickness, msThinkness);
+}
+FX_ARGB CXFA_Stroke::GetColor() const {
+  if (!m_pNode) {
+    return 0xFF000000;
+  }
+  CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Color);
+  if (!pNode) {
+    return 0xFF000000;
+  }
+  CFX_WideStringC wsColor;
+  pNode->TryCData(XFA_ATTRIBUTE_Value, wsColor);
+  return XFA_WStringToColor(wsColor);
+}
+void CXFA_Stroke::SetColor(FX_ARGB argb) {
+  if (!m_pNode) {
+    return;
+  }
+  CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Color);
+  CFX_WideString wsColor;
+  int a, r, g, b;
+  ArgbDecode(argb, a, r, g, b);
+  wsColor.Format(L"%d,%d,%d", r, g, b);
+  pNode->SetCData(XFA_ATTRIBUTE_Value, wsColor);
+}
+int32_t CXFA_Stroke::GetJoinType() const {
+  return m_pNode ? m_pNode->GetEnum(XFA_ATTRIBUTE_Join)
+                 : XFA_ATTRIBUTEENUM_Square;
+}
+FX_BOOL CXFA_Stroke::IsInverted() const {
+  return m_pNode ? m_pNode->GetBoolean(XFA_ATTRIBUTE_Inverted) : FALSE;
+}
+FX_FLOAT CXFA_Stroke::GetRadius() const {
+  return m_pNode ? m_pNode->GetMeasure(XFA_ATTRIBUTE_Radius).ToUnit(XFA_UNIT_Pt)
+                 : 0;
+}
+FX_BOOL CXFA_Stroke::SameStyles(CXFA_Stroke stroke, FX_DWORD dwFlags) const {
+  if (m_pNode == stroke.GetNode()) {
+    return TRUE;
+  }
+  if (FXSYS_fabs(GetThickness() - stroke.GetThickness()) >= 0.01f) {
+    return FALSE;
+  }
+  if ((dwFlags & XFA_STROKE_SAMESTYLE_NoPresence) == 0 &&
+      IsVisible() != stroke.IsVisible()) {
+    return FALSE;
+  }
+  if (GetStrokeType() != stroke.GetStrokeType()) {
+    return FALSE;
+  }
+  if (GetColor() != stroke.GetColor()) {
+    return FALSE;
+  }
+  if ((dwFlags & XFA_STROKE_SAMESTYLE_Corner) != 0 &&
+      FXSYS_fabs(GetRadius() - stroke.GetRadius()) >= 0.01f) {
+    return FALSE;
+  }
+  return TRUE;
+}
+FX_FLOAT XFA_GetEdgeThickness(const CXFA_StrokeArray& strokes,
+                              FX_BOOL b3DStyle,
+                              int32_t nIndex) {
+  FX_FLOAT fThickness = 0;
+  {
+    if (strokes[nIndex * 2 + 1].GetPresence() == XFA_ATTRIBUTEENUM_Visible) {
+      if (nIndex == 0) {
+        fThickness += 2.5f;
+      }
+      fThickness += strokes[nIndex * 2 + 1].GetThickness() * (b3DStyle ? 4 : 2);
+    }
+  }
+  return fThickness;
+}
+CXFA_WidgetData::CXFA_WidgetData(CXFA_Node* pNode)
+    : CXFA_Data(pNode),
+      m_bIsNull(TRUE),
+      m_bPreNull(TRUE),
+      m_pUiChildNode(NULL),
+      m_eUIType(XFA_ELEMENT_UNKNOWN) {}
+CXFA_Node* CXFA_WidgetData::GetUIChild() {
+  if (m_eUIType == XFA_ELEMENT_UNKNOWN) {
+    m_pUiChildNode = XFA_CreateUIChild(m_pNode, m_eUIType);
+  }
+  return m_pUiChildNode;
+}
+XFA_ELEMENT CXFA_WidgetData::GetUIType() {
+  GetUIChild();
+  return m_eUIType;
+}
+CFX_WideString CXFA_WidgetData::GetRawValue() {
+  return m_pNode->GetContent();
+}
+int32_t CXFA_WidgetData::GetAccess(FX_BOOL bTemplate) {
+  if (bTemplate) {
+    CXFA_Node* pNode = m_pNode->GetTemplateNode();
+    if (pNode) {
+      return pNode->GetEnum(XFA_ATTRIBUTE_Access);
+    }
+    return XFA_ATTRIBUTEENUM_Open;
+  }
+  CXFA_Node* pNode = m_pNode;
+  while (pNode) {
+    int32_t iAcc = pNode->GetEnum(XFA_ATTRIBUTE_Access);
+    if (iAcc != XFA_ATTRIBUTEENUM_Open) {
+      return iAcc;
+    }
+    pNode =
+        pNode->GetNodeItem(XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode);
+  }
+  return XFA_ATTRIBUTEENUM_Open;
+}
+FX_BOOL CXFA_WidgetData::GetAccessKey(CFX_WideStringC& wsAccessKey) {
+  return m_pNode->TryCData(XFA_ATTRIBUTE_AccessKey, wsAccessKey);
+}
+int32_t CXFA_WidgetData::GetAnchorType() {
+  return m_pNode->GetEnum(XFA_ATTRIBUTE_AnchorType);
+}
+int32_t CXFA_WidgetData::GetColSpan() {
+  return m_pNode->GetInteger(XFA_ATTRIBUTE_ColSpan);
+}
+int32_t CXFA_WidgetData::GetPresence() {
+  return m_pNode->GetEnum(XFA_ATTRIBUTE_Presence);
+  CXFA_Node* pNode = m_pNode;
+  while (pNode && pNode->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {
+    int32_t iAcc = pNode->GetEnum(XFA_ATTRIBUTE_Presence);
+    if (iAcc != XFA_ATTRIBUTEENUM_Visible) {
+      return iAcc;
+    }
+    pNode = pNode->GetNodeItem(XFA_NODEITEM_Parent);
+  }
+  return XFA_ATTRIBUTEENUM_Visible;
+}
+int32_t CXFA_WidgetData::GetRotate() {
+  CXFA_Measurement ms;
+  if (!m_pNode->TryMeasure(XFA_ATTRIBUTE_Rotate, ms, FALSE)) {
+    return 0;
+  }
+  int32_t iRotate = FXSYS_round(ms.GetValue());
+  iRotate = XFA_MapRotation(iRotate);
+  return iRotate / 90 * 90;
+}
+CXFA_Border CXFA_WidgetData::GetBorder(FX_BOOL bModified) {
+  return CXFA_Border(m_pNode->GetProperty(0, XFA_ELEMENT_Border, bModified));
+}
+CXFA_Caption CXFA_WidgetData::GetCaption(FX_BOOL bModified) {
+  return CXFA_Caption(m_pNode->GetProperty(0, XFA_ELEMENT_Caption, bModified));
+}
+CXFA_Font CXFA_WidgetData::GetFont(FX_BOOL bModified) {
+  return CXFA_Font(m_pNode->GetProperty(0, XFA_ELEMENT_Font, bModified));
+}
+CXFA_Margin CXFA_WidgetData::GetMargin(FX_BOOL bModified) {
+  return CXFA_Margin(m_pNode->GetProperty(0, XFA_ELEMENT_Margin, bModified));
+}
+CXFA_Para CXFA_WidgetData::GetPara(FX_BOOL bModified) {
+  return CXFA_Para(m_pNode->GetProperty(0, XFA_ELEMENT_Para, bModified));
+}
+CXFA_Keep CXFA_WidgetData::GetKeep(FX_BOOL bModified) {
+  return CXFA_Keep(m_pNode->GetProperty(0, XFA_ELEMENT_Keep, bModified),
+                   m_pNode);
+}
+void CXFA_WidgetData::GetEventList(CXFA_NodeArray& events) {
+  m_pNode->GetNodeList(events, 0, XFA_ELEMENT_Event);
+}
+int32_t CXFA_WidgetData::GetEventByActivity(int32_t iActivity,
+                                            CXFA_NodeArray& events,
+                                            FX_BOOL bIsFormReady) {
+  CXFA_NodeArray allEvents;
+  GetEventList(allEvents);
+  int32_t iCount = allEvents.GetSize();
+  for (int32_t i = 0; i < iCount; i++) {
+    CXFA_Event event(allEvents[i]);
+    if (event.GetActivity() == iActivity) {
+      if (iActivity == XFA_ATTRIBUTEENUM_Ready) {
+        CFX_WideStringC wsRef;
+        event.GetRef(wsRef);
+        if (bIsFormReady) {
+          if (wsRef == CFX_WideStringC(L"$form")) {
+            events.Add(allEvents[i]);
+          }
+        } else {
+          if (wsRef == CFX_WideStringC(L"$layout")) {
+            events.Add(allEvents[i]);
+          }
+        }
+      } else {
+        events.Add(allEvents[i]);
+      }
+    }
+  }
+  return events.GetSize();
+}
+CXFA_Value CXFA_WidgetData::GetDefaultValue(FX_BOOL bModified) {
+  CXFA_Node* pTemNode = m_pNode->GetTemplateNode();
+  return CXFA_Value(pTemNode
+                        ? pTemNode->GetProperty(0, XFA_ELEMENT_Value, bModified)
+                        : nullptr);
+}
+CXFA_Value CXFA_WidgetData::GetFormValue(FX_BOOL bModified) {
+  return CXFA_Value(m_pNode->GetProperty(0, XFA_ELEMENT_Value, bModified));
+}
+CXFA_Calculate CXFA_WidgetData::GetCalculate(FX_BOOL bModified) {
+  return CXFA_Calculate(
+      m_pNode->GetProperty(0, XFA_ELEMENT_Calculate, bModified));
+}
+CXFA_Validate CXFA_WidgetData::GetValidate(FX_BOOL bModified) {
+  return CXFA_Validate(
+      m_pNode->GetProperty(0, XFA_ELEMENT_Validate, bModified));
+}
+CXFA_Variables CXFA_WidgetData::GetVariables(FX_BOOL bModified) {
+  return CXFA_Variables(
+      m_pNode->GetProperty(0, XFA_ELEMENT_Variables, bModified));
+}
+CXFA_Bind CXFA_WidgetData::GetBind(FX_BOOL bModified) {
+  return CXFA_Bind(m_pNode->GetProperty(0, XFA_ELEMENT_Bind, bModified));
+}
+CXFA_Assist CXFA_WidgetData::GetAssist(FX_BOOL bModified) {
+  return CXFA_Assist(m_pNode->GetProperty(0, XFA_ELEMENT_Assist, bModified));
+}
+void CXFA_WidgetData::GetRelevant(CFX_WideStringC& wsRelevant) {
+  m_pNode->TryCData(XFA_ATTRIBUTE_Relevant, wsRelevant);
+}
+FX_BOOL CXFA_WidgetData::GetWidth(FX_FLOAT& fWidth) {
+  return TryMeasure(XFA_ATTRIBUTE_W, fWidth);
+}
+FX_BOOL CXFA_WidgetData::GetHeight(FX_FLOAT& fHeight) {
+  return TryMeasure(XFA_ATTRIBUTE_H, fHeight);
+}
+FX_BOOL CXFA_WidgetData::GetMinWidth(FX_FLOAT& fMinWidth) {
+  return TryMeasure(XFA_ATTRIBUTE_MinW, fMinWidth);
+}
+FX_BOOL CXFA_WidgetData::GetMinHeight(FX_FLOAT& fMinHeight) {
+  return TryMeasure(XFA_ATTRIBUTE_MinH, fMinHeight);
+}
+FX_BOOL CXFA_WidgetData::GetMaxWidth(FX_FLOAT& fMaxWidth) {
+  return TryMeasure(XFA_ATTRIBUTE_MaxW, fMaxWidth);
+}
+FX_BOOL CXFA_WidgetData::GetMaxHeight(FX_FLOAT& fMaxHeight) {
+  return TryMeasure(XFA_ATTRIBUTE_MaxH, fMaxHeight);
+}
+CXFA_BindItems CXFA_WidgetData::GetBindItems() {
+  return CXFA_BindItems(m_pNode->GetChild(0, XFA_ELEMENT_BindItems));
+}
+FX_BOOL CXFA_WidgetData::SetAccess(int32_t iAccess, FX_BOOL bNotify) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_Access, (XFA_ATTRIBUTEENUM)iAccess,
+                          bNotify);
+}
+FX_BOOL CXFA_WidgetData::SetAccessKey(const CFX_WideString& wsAccessKey) {
+  return m_pNode->SetCData(XFA_ATTRIBUTE_AccessKey, wsAccessKey);
+}
+FX_BOOL CXFA_WidgetData::SetAnchorType(int32_t iType) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_AnchorType, (XFA_ATTRIBUTEENUM)iType);
+}
+FX_BOOL CXFA_WidgetData::SetColSpan(int32_t iColSpan) {
+  return m_pNode->SetInteger(XFA_ATTRIBUTE_ColSpan,
+                             (XFA_ATTRIBUTEENUM)iColSpan);
+}
+FX_BOOL CXFA_WidgetData::SetPresence(int32_t iPresence) {
+  return m_pNode->SetEnum(XFA_ATTRIBUTE_Presence, (XFA_ATTRIBUTEENUM)iPresence);
+}
+FX_BOOL CXFA_WidgetData::SetRotate(int32_t iRotate) {
+  iRotate = XFA_MapRotation(iRotate);
+  CXFA_Measurement ms((FX_FLOAT)iRotate, XFA_UNIT_Angle);
+  return m_pNode->SetMeasure(XFA_ATTRIBUTE_Rotate, ms);
+}
+FX_BOOL CXFA_WidgetData::SetRelevant(const CFX_WideString& wsRelevant) {
+  return m_pNode->SetCData(XFA_ATTRIBUTE_Relevant, wsRelevant);
+}
+FX_BOOL CXFA_WidgetData::SetStatus(FX_DWORD dwStatus) {
+  return FALSE;
+}
+FX_BOOL CXFA_WidgetData::SetWidth(FX_FLOAT fWidth) {
+  return SetMeasure(XFA_ATTRIBUTE_W, fWidth);
+}
+FX_BOOL CXFA_WidgetData::SetHeight(FX_FLOAT fHeight) {
+  return SetMeasure(XFA_ATTRIBUTE_H, fHeight);
+}
+FX_BOOL CXFA_WidgetData::SetMinWidth(FX_FLOAT fMinWidth) {
+  return SetMeasure(XFA_ATTRIBUTE_MinW, fMinWidth);
+}
+FX_BOOL CXFA_WidgetData::SetMinHeight(FX_FLOAT fMinHeight) {
+  return SetMeasure(XFA_ATTRIBUTE_MinH, fMinHeight);
+}
+FX_BOOL CXFA_WidgetData::SetMaxWidth(FX_FLOAT fMaxWidth) {
+  return SetMeasure(XFA_ATTRIBUTE_MaxW, fMaxWidth);
+}
+FX_BOOL CXFA_WidgetData::SetMaxHeight(FX_FLOAT fMaxHeight) {
+  return SetMeasure(XFA_ATTRIBUTE_MaxH, fMaxHeight);
+}
+FX_BOOL CXFA_WidgetData::SetPos(FX_FLOAT x, FX_FLOAT y) {
+  return SetMeasure(XFA_ATTRIBUTE_X, x) && SetMeasure(XFA_ATTRIBUTE_Y, y);
+}
+FX_BOOL CXFA_WidgetData::SetName(const CFX_WideString& wsName) {
+  return m_pNode->SetCData(XFA_ATTRIBUTE_Name, wsName);
+}
+FX_BOOL CXFA_WidgetData::SetButtonHighlight(int32_t iButtonHighlight) {
+  CXFA_Node* pUiChildNode = GetUIChild();
+  return pUiChildNode->SetEnum(XFA_ATTRIBUTE_Highlight,
+                               (XFA_ATTRIBUTEENUM)iButtonHighlight);
+}
+FX_BOOL CXFA_WidgetData::SetButtonRollover(const CFX_WideString& wsRollover,
+                                           FX_BOOL bRichText) {
+  return FALSE;
+}
+FX_BOOL CXFA_WidgetData::SetButtonDown(const CFX_WideString& wsDown,
+                                       FX_BOOL bRichText) {
+  return FALSE;
+}
+FX_BOOL CXFA_WidgetData::SetCheckButtonShape(int32_t iCheckButtonShape) {
+  CXFA_Node* pUiChildNode = GetUIChild();
+  return pUiChildNode->SetEnum(XFA_ATTRIBUTE_Shape,
+                               (XFA_ATTRIBUTEENUM)iCheckButtonShape);
+}
+FX_BOOL CXFA_WidgetData::SetCheckButtonMark(int32_t iCheckButtonMark) {
+  CXFA_Node* pUiChildNode = GetUIChild();
+  return pUiChildNode->SetEnum(XFA_ATTRIBUTE_Mark,
+                               (XFA_ATTRIBUTEENUM)iCheckButtonMark);
+}
+FX_BOOL CXFA_WidgetData::SetCheckButtonSize(FX_FLOAT fCheckButtonMark) {
+  CXFA_Node* pUiChildNode = GetUIChild();
+  if (pUiChildNode) {
+    CXFA_Measurement ms(fCheckButtonMark, XFA_UNIT_Pt);
+    return pUiChildNode->SetMeasure(XFA_ATTRIBUTE_Size, ms);
+  }
+  return FALSE;
+}
+CXFA_Border CXFA_WidgetData::GetUIBorder(FX_BOOL bModified) {
+  CXFA_Node* pUIChild = GetUIChild();
+  return CXFA_Border(
+      pUIChild ? pUIChild->GetProperty(0, XFA_ELEMENT_Border, bModified)
+               : nullptr);
+}
+CXFA_Margin CXFA_WidgetData::GetUIMargin(FX_BOOL bModified) {
+  CXFA_Node* pUIChild = GetUIChild();
+  return CXFA_Margin(
+      pUIChild ? pUIChild->GetProperty(0, XFA_ELEMENT_Margin, bModified)
+               : nullptr);
+}
+void CXFA_WidgetData::GetUIMargin(CFX_RectF& rtUIMargin) {
+  rtUIMargin.Reset();
+  CXFA_Margin mgUI = GetUIMargin();
+  if (!mgUI) {
+    return;
+  }
+  CXFA_Border border = GetUIBorder();
+  if (border && border.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
+    return;
+  }
+  FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
+  FX_BOOL bLeft = mgUI.GetLeftInset(fLeftInset);
+  FX_BOOL bTop = mgUI.GetTopInset(fTopInset);
+  FX_BOOL bRight = mgUI.GetRightInset(fRightInset);
+  FX_BOOL bBottom = mgUI.GetBottomInset(fBottomInset);
+  if (border) {
+    FX_BOOL bVisible = FALSE;
+    FX_FLOAT fThickness = 0;
+    border.Get3DStyle(bVisible, fThickness);
+    if (!bLeft || !bTop || !bRight || !bBottom) {
+      CXFA_StrokeArray strokes;
+      border.GetStrokes(strokes);
+      if (!bTop) {
+        fTopInset = XFA_GetEdgeThickness(strokes, bVisible, 0);
+      }
+      if (!bRight) {
+        fRightInset = XFA_GetEdgeThickness(strokes, bVisible, 1);
+      }
+      if (!bBottom) {
+        fBottomInset = XFA_GetEdgeThickness(strokes, bVisible, 2);
+      }
+      if (!bLeft) {
+        fLeftInset = XFA_GetEdgeThickness(strokes, bVisible, 3);
+      }
+    }
+  }
+  rtUIMargin.Set(fLeftInset, fTopInset, fRightInset, fBottomInset);
+}
+int32_t CXFA_WidgetData::GetButtonHighlight() {
+  CXFA_Node* pUIChild = GetUIChild();
+  if (pUIChild) {
+    return pUIChild->GetEnum(XFA_ATTRIBUTE_Highlight);
+  }
+  return XFA_GetAttributeDefaultValue_Enum(
+      XFA_ELEMENT_Button, XFA_ATTRIBUTE_Highlight, XFA_XDPPACKET_Form);
+}
+FX_BOOL CXFA_WidgetData::GetButtonRollover(CFX_WideString& wsRollover,
+                                           FX_BOOL& bRichText) {
+  if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items)) {
+    CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+    while (pText) {
+      CFX_WideStringC wsName;
+      pText->TryCData(XFA_ATTRIBUTE_Name, wsName);
+      if (wsName == FX_WSTRC(L"rollover")) {
+        pText->TryContent(wsRollover);
+        bRichText = pText->GetClassID() == XFA_ELEMENT_ExData;
+        return !wsRollover.IsEmpty();
+      }
+      pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
+    }
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetButtonDown(CFX_WideString& wsDown,
+                                       FX_BOOL& bRichText) {
+  if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items)) {
+    CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+    while (pText) {
+      CFX_WideStringC wsName;
+      pText->TryCData(XFA_ATTRIBUTE_Name, wsName);
+      if (wsName == FX_WSTRC(L"down")) {
+        pText->TryContent(wsDown);
+        bRichText = pText->GetClassID() == XFA_ELEMENT_ExData;
+        return !wsDown.IsEmpty();
+      }
+      pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
+    }
+  }
+  return FALSE;
+}
+int32_t CXFA_WidgetData::GetCheckButtonShape() {
+  CXFA_Node* pUIChild = GetUIChild();
+  if (pUIChild) {
+    return pUIChild->GetEnum(XFA_ATTRIBUTE_Shape);
+  }
+  return XFA_GetAttributeDefaultValue_Enum(
+      XFA_ELEMENT_CheckButton, XFA_ATTRIBUTE_Shape, XFA_XDPPACKET_Form);
+}
+int32_t CXFA_WidgetData::GetCheckButtonMark() {
+  CXFA_Node* pUIChild = GetUIChild();
+  if (pUIChild) {
+    return pUIChild->GetEnum(XFA_ATTRIBUTE_Mark);
+  }
+  return XFA_GetAttributeDefaultValue_Enum(
+      XFA_ELEMENT_CheckButton, XFA_ATTRIBUTE_Mark, XFA_XDPPACKET_Form);
+}
+FX_BOOL CXFA_WidgetData::IsRadioButton() {
+  if (CXFA_Node* pParent = m_pNode->GetNodeItem(XFA_NODEITEM_Parent)) {
+    return pParent->GetClassID() == XFA_ELEMENT_ExclGroup;
+  }
+  return FALSE;
+}
+FX_FLOAT CXFA_WidgetData::GetCheckButtonSize() {
+  CXFA_Node* pUIChild = GetUIChild();
+  if (pUIChild) {
+    return pUIChild->GetMeasure(XFA_ATTRIBUTE_Size).ToUnit(XFA_UNIT_Pt);
+  }
+  return XFA_GetAttributeDefaultValue_Measure(
+             XFA_ELEMENT_CheckButton, XFA_ATTRIBUTE_Size, XFA_XDPPACKET_Form)
+      .ToUnit(XFA_UNIT_Pt);
+}
+FX_BOOL CXFA_WidgetData::IsAllowNeutral() {
+  CXFA_Node* pUIChild = GetUIChild();
+  if (pUIChild) {
+    return pUIChild->GetBoolean(XFA_ATTRIBUTE_AllowNeutral);
+  }
+  return XFA_GetAttributeDefaultValue_Boolean(
+      XFA_ELEMENT_CheckButton, XFA_ATTRIBUTE_AllowNeutral, XFA_XDPPACKET_Form);
+}
+XFA_CHECKSTATE CXFA_WidgetData::GetCheckState() {
+  CFX_WideString wsValue = GetRawValue();
+  if (wsValue.IsEmpty()) {
+    return XFA_CHECKSTATE_Off;
+  }
+  if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items)) {
+    CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+    int32_t i = 0;
+    while (pText) {
+      CFX_WideString wsContent;
+      if (pText->TryContent(wsContent) && (wsContent == wsValue)) {
+        return (XFA_CHECKSTATE)i;
+      }
+      i++;
+      pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
+    }
+  }
+  return XFA_CHECKSTATE_Off;
+}
+void CXFA_WidgetData::SetCheckState(XFA_CHECKSTATE eCheckState,
+                                    FX_BOOL bNotify) {
+  CXFA_WidgetData exclGroup(GetExclGroupNode());
+  if (exclGroup) {
+    CFX_WideString wsValue;
+    if (eCheckState != XFA_CHECKSTATE_Off) {
+      if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items)) {
+        CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+        if (pText) {
+          pText->TryContent(wsValue);
+        }
+      }
+    }
+    CXFA_Node* pChild =
+        exclGroup.GetNode()->GetNodeItem(XFA_NODEITEM_FirstChild);
+    for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+      if (pChild->GetClassID() != XFA_ELEMENT_Field) {
+        continue;
+      }
+      CXFA_Node* pItem = pChild->GetChild(0, XFA_ELEMENT_Items);
+      if (!pItem) {
+        continue;
+      }
+      CXFA_Node* pItemchild = pItem->GetNodeItem(XFA_NODEITEM_FirstChild);
+      if (!pItemchild) {
+        continue;
+      }
+      CFX_WideString text = pItemchild->GetContent();
+      CFX_WideString wsChildValue = text;
+      if (wsValue != text) {
+        pItemchild = pItemchild->GetNodeItem(XFA_NODEITEM_NextSibling);
+        if (pItemchild) {
+          wsChildValue = pItemchild->GetContent();
+        } else {
+          wsChildValue.Empty();
+        }
+      }
+      CXFA_WidgetData ch(pChild);
+      ch.SyncValue(wsChildValue, bNotify);
+    }
+    exclGroup.SyncValue(wsValue, bNotify);
+  } else {
+    CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items);
+    if (!pItems) {
+      return;
+    }
+    int32_t i = -1;
+    CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+    CFX_WideString wsContent;
+    while (pText) {
+      i++;
+      if (i == eCheckState) {
+        pText->TryContent(wsContent);
+        break;
+      }
+      pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
+    }
+    SyncValue(wsContent, bNotify);
+  }
+}
+CXFA_Node* CXFA_WidgetData::GetExclGroupNode() {
+  CXFA_Node* pExcl = ToNode(m_pNode->GetNodeItem(XFA_NODEITEM_Parent));
+  if (!pExcl || pExcl->GetClassID() != XFA_ELEMENT_ExclGroup) {
+    return NULL;
+  }
+  return pExcl;
+}
+CXFA_Node* CXFA_WidgetData::GetSelectedMember() {
+  CXFA_Node* pSelectedMember = NULL;
+  CFX_WideString wsState = GetRawValue();
+  if (wsState.IsEmpty()) {
+    return pSelectedMember;
+  }
+  for (CXFA_Node* pNode = ToNode(m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild));
+       pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    CXFA_WidgetData widgetData(pNode);
+    if (widgetData.GetCheckState() == XFA_CHECKSTATE_On) {
+      pSelectedMember = pNode;
+      break;
+    }
+  }
+  return pSelectedMember;
+}
+CXFA_Node* CXFA_WidgetData::SetSelectedMember(const CFX_WideStringC& wsName,
+                                              FX_BOOL bNotify) {
+  CXFA_Node* pSelectedMember = NULL;
+  FX_DWORD nameHash =
+      FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength());
+  for (CXFA_Node* pNode = ToNode(m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild));
+       pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pNode->GetNameHash() == nameHash) {
+      CXFA_WidgetData widgetData(pNode);
+      widgetData.SetCheckState(XFA_CHECKSTATE_On, bNotify);
+      pSelectedMember = pNode;
+      break;
+    }
+  }
+  return pSelectedMember;
+}
+void CXFA_WidgetData::SetSelectedMemberByValue(const CFX_WideStringC& wsValue,
+                                               FX_BOOL bNotify,
+                                               FX_BOOL bScriptModify,
+                                               FX_BOOL bSyncData) {
+  CFX_WideString wsExclGroup;
+  for (CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild); pNode;
+       pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pNode->GetClassID() != XFA_ELEMENT_Field) {
+      continue;
+    }
+    CXFA_Node* pItem = pNode->GetChild(0, XFA_ELEMENT_Items);
+    if (!pItem) {
+      continue;
+    }
+    CXFA_Node* pItemchild = pItem->GetNodeItem(XFA_NODEITEM_FirstChild);
+    if (!pItemchild) {
+      continue;
+    }
+    CFX_WideString wsChildValue = pItemchild->GetContent();
+    if (wsValue != wsChildValue) {
+      pItemchild = pItemchild->GetNodeItem(XFA_NODEITEM_NextSibling);
+      if (pItemchild) {
+        wsChildValue = pItemchild->GetContent();
+      } else {
+        wsChildValue.Empty();
+      }
+    } else {
+      wsExclGroup = wsValue;
+    }
+    pNode->SetContent(wsChildValue, wsChildValue, bNotify, bScriptModify,
+                      FALSE);
+  }
+  if (m_pNode) {
+    m_pNode->SetContent(wsExclGroup, wsExclGroup, bNotify, bScriptModify,
+                        bSyncData);
+  }
+}
+CXFA_Node* CXFA_WidgetData::GetExclGroupFirstMember() {
+  CXFA_Node* pExcl = GetNode();
+  if (!pExcl) {
+    return NULL;
+  }
+  CXFA_Node* pNode = pExcl->GetNodeItem(XFA_NODEITEM_FirstChild);
+  while (pNode) {
+    if (pNode->GetClassID() == XFA_ELEMENT_Field) {
+      return pNode;
+    }
+    pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+  }
+  return NULL;
+}
+CXFA_Node* CXFA_WidgetData::GetExclGroupNextMember(CXFA_Node* pNode) {
+  if (!pNode) {
+    return NULL;
+  }
+  CXFA_Node* pNodeField = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+  while (pNodeField) {
+    if (pNodeField->GetClassID() == XFA_ELEMENT_Field) {
+      return pNodeField;
+    }
+    pNodeField = pNodeField->GetNodeItem(XFA_NODEITEM_NextSibling);
+  }
+  return NULL;
+}
+int32_t CXFA_WidgetData::GetChoiceListCommitOn() {
+  CXFA_Node* pUIChild = GetUIChild();
+  if (pUIChild) {
+    return pUIChild->GetEnum(XFA_ATTRIBUTE_CommitOn);
+  }
+  return XFA_GetAttributeDefaultValue_Enum(
+      XFA_ELEMENT_ChoiceList, XFA_ATTRIBUTE_CommitOn, XFA_XDPPACKET_Form);
+}
+FX_BOOL CXFA_WidgetData::IsChoiceListAllowTextEntry() {
+  CXFA_Node* pUIChild = GetUIChild();
+  if (pUIChild) {
+    return pUIChild->GetBoolean(XFA_ATTRIBUTE_TextEntry);
+  }
+  return XFA_GetAttributeDefaultValue_Boolean(
+      XFA_ELEMENT_ChoiceList, XFA_ATTRIBUTE_TextEntry, XFA_XDPPACKET_Form);
+}
+int32_t CXFA_WidgetData::GetChoiceListOpen() {
+  CXFA_Node* pUIChild = GetUIChild();
+  if (pUIChild) {
+    return pUIChild->GetEnum(XFA_ATTRIBUTE_Open);
+  }
+  return XFA_GetAttributeDefaultValue_Enum(
+      XFA_ELEMENT_ChoiceList, XFA_ATTRIBUTE_Open, XFA_XDPPACKET_Form);
+}
+FX_BOOL CXFA_WidgetData::IsListBox() {
+  int32_t iOpenMode = GetChoiceListOpen();
+  return (iOpenMode == XFA_ATTRIBUTEENUM_Always ||
+          iOpenMode == XFA_ATTRIBUTEENUM_MultiSelect);
+}
+int32_t CXFA_WidgetData::CountChoiceListItems(FX_BOOL bSaveValue) {
+  CXFA_NodeArray pItems;
+  CXFA_Node* pItem = NULL;
+  int32_t iCount = 0;
+  CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+  for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pNode->GetClassID() != XFA_ELEMENT_Items) {
+      continue;
+    }
+    iCount++;
+    pItems.Add(pNode);
+    if (iCount == 2) {
+      break;
+    }
+  }
+  if (iCount == 0) {
+    return 0;
+  }
+  pItem = pItems[0];
+  if (iCount > 1) {
+    FX_BOOL bItemOneHasSave = pItems[0]->GetBoolean(XFA_ATTRIBUTE_Save);
+    FX_BOOL bItemTwoHasSave = pItems[1]->GetBoolean(XFA_ATTRIBUTE_Save);
+    if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave) {
+      pItem = pItems[1];
+    }
+  }
+  pItems.RemoveAll();
+  return pItem->CountChildren(XFA_ELEMENT_UNKNOWN);
+}
+FX_BOOL CXFA_WidgetData::GetChoiceListItem(CFX_WideString& wsText,
+                                           int32_t nIndex,
+                                           FX_BOOL bSaveValue) {
+  wsText.Empty();
+  CXFA_NodeArray pItemsArray;
+  CXFA_Node* pItems = NULL;
+  int32_t iCount = 0;
+  CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+  for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pNode->GetClassID() != XFA_ELEMENT_Items) {
+      continue;
+    }
+    iCount++;
+    pItemsArray.Add(pNode);
+    if (iCount == 2) {
+      break;
+    }
+  }
+  if (iCount == 0) {
+    return FALSE;
+  }
+  pItems = pItemsArray[0];
+  if (iCount > 1) {
+    FX_BOOL bItemOneHasSave = pItemsArray[0]->GetBoolean(XFA_ATTRIBUTE_Save);
+    FX_BOOL bItemTwoHasSave = pItemsArray[1]->GetBoolean(XFA_ATTRIBUTE_Save);
+    if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave) {
+      pItems = pItemsArray[1];
+    }
+  }
+  if (pItems) {
+    CXFA_Node* pItem = pItems->GetChild(nIndex, XFA_ELEMENT_UNKNOWN);
+    if (pItem) {
+      pItem->TryContent(wsText);
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+void CXFA_WidgetData::GetChoiceListItems(CFX_WideStringArray& wsTextArray,
+                                         FX_BOOL bSaveValue) {
+  CXFA_NodeArray pItems;
+  CXFA_Node* pItem = NULL;
+  int32_t iCount = 0;
+  CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+  for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pNode->GetClassID() != XFA_ELEMENT_Items) {
+      continue;
+    }
+    iCount++;
+    pItems.Add(pNode);
+    if (iCount == 2) {
+      break;
+    }
+  }
+  if (iCount == 0) {
+    return;
+  }
+  pItem = pItems[0];
+  if (iCount > 1) {
+    FX_BOOL bItemOneHasSave = pItems[0]->GetBoolean(XFA_ATTRIBUTE_Save);
+    FX_BOOL bItemTwoHasSave = pItems[1]->GetBoolean(XFA_ATTRIBUTE_Save);
+    if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave) {
+      pItem = pItems[1];
+    }
+  }
+  pItems.RemoveAll();
+  pNode = pItem->GetNodeItem(XFA_NODEITEM_FirstChild);
+  for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    pNode->TryContent(wsTextArray.Add());
+  }
+}
+int32_t CXFA_WidgetData::CountSelectedItems() {
+  CFX_WideStringArray wsValueArray;
+  GetSelectedItemsValue(wsValueArray);
+  if (IsListBox() || !IsChoiceListAllowTextEntry()) {
+    return wsValueArray.GetSize();
+  }
+  int32_t iSelected = 0;
+  CFX_WideStringArray wsSaveTextArray;
+  GetChoiceListItems(wsSaveTextArray, TRUE);
+  int32_t iValues = wsValueArray.GetSize();
+  for (int32_t i = 0; i < iValues; i++) {
+    int32_t iSaves = wsSaveTextArray.GetSize();
+    for (int32_t j = 0; j < iSaves; j++) {
+      if (wsValueArray[i] == wsSaveTextArray[j]) {
+        iSelected++;
+        break;
+      }
+    }
+  }
+  return iSelected;
+}
+int32_t CXFA_WidgetData::GetSelectedItem(int32_t nIndex) {
+  CFX_WideStringArray wsValueArray;
+  GetSelectedItemsValue(wsValueArray);
+  CFX_WideStringArray wsSaveTextArray;
+  GetChoiceListItems(wsSaveTextArray, TRUE);
+  int32_t iSaves = wsSaveTextArray.GetSize();
+  for (int32_t j = 0; j < iSaves; j++) {
+    if (wsValueArray[nIndex] == wsSaveTextArray[j]) {
+      return j;
+    }
+  }
+  return -1;
+}
+void CXFA_WidgetData::GetSelectedItems(CFX_Int32Array& iSelArray) {
+  CFX_WideStringArray wsValueArray;
+  GetSelectedItemsValue(wsValueArray);
+  int32_t iValues = wsValueArray.GetSize();
+  if (iValues < 1) {
+    return;
+  }
+  CFX_WideStringArray wsSaveTextArray;
+  GetChoiceListItems(wsSaveTextArray, TRUE);
+  int32_t iSaves = wsSaveTextArray.GetSize();
+  for (int32_t i = 0; i < iValues; i++) {
+    for (int32_t j = 0; j < iSaves; j++) {
+      if (wsValueArray[i] == wsSaveTextArray[j]) {
+        iSelArray.Add(j);
+        break;
+      }
+    }
+  }
+}
+void CXFA_WidgetData::GetSelectedItemsValue(
+    CFX_WideStringArray& wsSelTextArray) {
+  CFX_WideString wsValue = GetRawValue();
+  if (GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
+    if (!wsValue.IsEmpty()) {
+      int32_t iStart = 0;
+      int32_t iLength = wsValue.GetLength();
+      int32_t iEnd = wsValue.Find(L'\n', iStart);
+      iEnd = (iEnd == -1) ? iLength : iEnd;
+      while (iEnd >= iStart) {
+        wsSelTextArray.Add(wsValue.Mid(iStart, iEnd - iStart));
+        iStart = iEnd + 1;
+        if (iStart >= iLength) {
+          break;
+        }
+        iEnd = wsValue.Find(L'\n', iStart);
+        if (iEnd < 0) {
+          wsSelTextArray.Add(wsValue.Mid(iStart, iLength - iStart));
+        }
+      }
+    }
+  } else {
+    wsSelTextArray.Add(wsValue);
+  }
+}
+FX_BOOL CXFA_WidgetData::GetItemState(int32_t nIndex) {
+  if (nIndex < 0) {
+    return FALSE;
+  }
+  CFX_WideStringArray wsSaveTextArray;
+  GetChoiceListItems(wsSaveTextArray, TRUE);
+  if (wsSaveTextArray.GetSize() <= nIndex) {
+    return FALSE;
+  }
+  CFX_WideStringArray wsValueArray;
+  GetSelectedItemsValue(wsValueArray);
+  int32_t iValues = wsValueArray.GetSize();
+  for (int32_t j = 0; j < iValues; j++) {
+    if (wsValueArray[j] == wsSaveTextArray[nIndex]) {
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+void CXFA_WidgetData::SetItemState(int32_t nIndex,
+                                   FX_BOOL bSelected,
+                                   FX_BOOL bNotify,
+                                   FX_BOOL bScriptModify,
+                                   FX_BOOL bSyncData) {
+  if (nIndex < 0) {
+    return;
+  }
+  CFX_WideStringArray wsSaveTextArray;
+  GetChoiceListItems(wsSaveTextArray, TRUE);
+  if (wsSaveTextArray.GetSize() <= nIndex) {
+    return;
+  }
+  int32_t iSel = -1;
+  CFX_WideStringArray wsValueArray;
+  GetSelectedItemsValue(wsValueArray);
+  int32_t iValues = wsValueArray.GetSize();
+  for (int32_t j = 0; j < iValues; j++) {
+    if (wsValueArray[j] == wsSaveTextArray[nIndex]) {
+      iSel = j;
+      break;
+    }
+  }
+  if (GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
+    if (bSelected) {
+      if (iSel < 0) {
+        CFX_WideString wsValue = GetRawValue();
+        if (!wsValue.IsEmpty()) {
+          wsValue += L"\n";
+        }
+        wsValue += wsSaveTextArray[nIndex];
+        m_pNode->SetContent(wsValue, wsValue, bNotify, bScriptModify,
+                            bSyncData);
+      }
+    } else if (iSel >= 0) {
+      CFX_Int32Array iSelArray;
+      GetSelectedItems(iSelArray);
+      for (int32_t i = 0; i < iSelArray.GetSize(); i++) {
+        if (iSelArray[i] == nIndex) {
+          iSelArray.RemoveAt(i);
+          break;
+        }
+      }
+      SetSelectdItems(iSelArray, bNotify, bScriptModify, bSyncData);
+    }
+  } else {
+    if (bSelected) {
+      if (iSel < 0) {
+        CFX_WideString wsSaveText = wsSaveTextArray[nIndex];
+        CFX_WideString wsFormatText(wsSaveText);
+        GetFormatDataValue(wsSaveText, wsFormatText);
+        m_pNode->SetContent(wsSaveText, wsFormatText, bNotify, bScriptModify,
+                            bSyncData);
+      }
+    } else if (iSel >= 0) {
+      m_pNode->SetContent(CFX_WideString(), CFX_WideString(), bNotify,
+                          bScriptModify, bSyncData);
+    }
+  }
+}
+void CXFA_WidgetData::SetSelectdItems(CFX_Int32Array& iSelArray,
+                                      FX_BOOL bNotify,
+                                      FX_BOOL bScriptModify,
+                                      FX_BOOL bSyncData) {
+  CFX_WideString wsValue;
+  int32_t iSize = iSelArray.GetSize();
+  if (iSize >= 1) {
+    CFX_WideStringArray wsSaveTextArray;
+    GetChoiceListItems(wsSaveTextArray, TRUE);
+    CFX_WideString wsItemValue;
+    for (int32_t i = 0; i < iSize; i++) {
+      wsItemValue = (iSize == 1)
+                        ? wsSaveTextArray[iSelArray[i]]
+                        : wsSaveTextArray[iSelArray[i]] + FX_WSTRC(L"\n");
+      wsValue += wsItemValue;
+    }
+  }
+  CFX_WideString wsFormat(wsValue);
+  if (GetChoiceListOpen() != XFA_ATTRIBUTEENUM_MultiSelect) {
+    GetFormatDataValue(wsValue, wsFormat);
+  }
+  m_pNode->SetContent(wsValue, wsFormat, bNotify, bScriptModify, bSyncData);
+}
+void CXFA_WidgetData::ClearAllSelections() {
+  CXFA_Node* pBind = m_pNode->GetBindData();
+  if (pBind && GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
+    while (CXFA_Node* pChildNode =
+               pBind->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+      pBind->RemoveChild(pChildNode);
+    }
+  } else {
+    SyncValue(CFX_WideString(), FALSE);
+  }
+}
+void CXFA_WidgetData::InsertItem(const CFX_WideString& wsLabel,
+                                 const CFX_WideString& wsValue,
+                                 int32_t nIndex,
+                                 FX_BOOL bNotify) {
+  CFX_WideString wsNewValue(wsValue);
+  if (wsNewValue.IsEmpty()) {
+    wsNewValue = wsLabel;
+  }
+  CXFA_NodeArray listitems;
+  int32_t iCount = 0;
+  CXFA_Node* pItemNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+  for (; pItemNode;
+       pItemNode = pItemNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pItemNode->GetClassID() != XFA_ELEMENT_Items) {
+      continue;
+    }
+    listitems.Add(pItemNode);
+    iCount++;
+  }
+  if (iCount < 1) {
+    CXFA_Node* pItems = m_pNode->CreateSamePacketNode(XFA_ELEMENT_Items);
+    m_pNode->InsertChild(-1, pItems);
+    InsertListTextItem(pItems, wsLabel, nIndex);
+    CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_ELEMENT_Items);
+    m_pNode->InsertChild(-1, pSaveItems);
+    pSaveItems->SetBoolean(XFA_ATTRIBUTE_Save, TRUE);
+    InsertListTextItem(pSaveItems, wsNewValue, nIndex);
+  } else if (iCount > 1) {
+    for (int32_t i = 0; i < 2; i++) {
+      CXFA_Node* pNode = listitems[i];
+      FX_BOOL bHasSave = pNode->GetBoolean(XFA_ATTRIBUTE_Save);
+      if (bHasSave) {
+        InsertListTextItem(pNode, wsNewValue, nIndex);
+      } else {
+        InsertListTextItem(pNode, wsLabel, nIndex);
+      }
+    }
+  } else {
+    CXFA_Node* pNode = listitems[0];
+    pNode->SetBoolean(XFA_ATTRIBUTE_Save, FALSE);
+    pNode->SetEnum(XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTEENUM_Visible);
+    CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_ELEMENT_Items);
+    m_pNode->InsertChild(-1, pSaveItems);
+    pSaveItems->SetBoolean(XFA_ATTRIBUTE_Save, TRUE);
+    pSaveItems->SetEnum(XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTEENUM_Hidden);
+    listitems.RemoveAll();
+    CXFA_Node* pListNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+    int32_t i = 0;
+    while (pListNode) {
+      CFX_WideString wsOldValue;
+      pListNode->TryContent(wsOldValue);
+      InsertListTextItem(pSaveItems, wsOldValue, i);
+      i++;
+      pListNode = pListNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+    }
+    InsertListTextItem(pNode, wsLabel, nIndex);
+    InsertListTextItem(pSaveItems, wsNewValue, nIndex);
+  }
+  if (!bNotify) {
+    return;
+  }
+  m_pNode->GetDocument()->GetNotify()->OnWidgetDataEvent(
+      this, XFA_WIDGETEVENT_ListItemAdded, (void*)(const FX_WCHAR*)wsLabel,
+      (void*)(const FX_WCHAR*)wsValue, (void*)(uintptr_t)nIndex);
+}
+void CXFA_WidgetData::GetItemLabel(const CFX_WideStringC& wsValue,
+                                   CFX_WideString& wsLabel) {
+  int32_t iCount = 0;
+  CXFA_NodeArray listitems;
+  CXFA_Node* pItems = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+  for (; pItems; pItems = pItems->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pItems->GetClassID() != XFA_ELEMENT_Items) {
+      continue;
+    }
+    iCount++;
+    listitems.Add(pItems);
+  }
+  if (iCount <= 1) {
+    wsLabel = wsValue;
+  } else {
+    CXFA_Node* pLabelItems = listitems[0];
+    FX_BOOL bSave = pLabelItems->GetBoolean(XFA_ATTRIBUTE_Save);
+    CXFA_Node* pSaveItems = NULL;
+    if (bSave) {
+      pSaveItems = pLabelItems;
+      pLabelItems = listitems[1];
+    } else {
+      pSaveItems = listitems[1];
+    }
+    iCount = 0;
+    int32_t iSearch = -1;
+    CFX_WideString wsContent;
+    CXFA_Node* pChildItem = pSaveItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+    for (; pChildItem;
+         pChildItem = pChildItem->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+      pChildItem->TryContent(wsContent);
+      if (wsContent == wsValue) {
+        iSearch = iCount;
+        break;
+      }
+      iCount++;
+    }
+    if (iSearch < 0) {
+      return;
+    }
+    if (CXFA_Node* pText =
+            pLabelItems->GetChild(iSearch, XFA_ELEMENT_UNKNOWN)) {
+      pText->TryContent(wsLabel);
+    }
+  }
+}
+void CXFA_WidgetData::GetItemValue(const CFX_WideStringC& wsLabel,
+                                   CFX_WideString& wsValue) {
+  int32_t iCount = 0;
+  CXFA_NodeArray listitems;
+  CXFA_Node* pItems = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+  for (; pItems; pItems = pItems->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pItems->GetClassID() != XFA_ELEMENT_Items) {
+      continue;
+    }
+    iCount++;
+    listitems.Add(pItems);
+  }
+  if (iCount <= 1) {
+    wsValue = wsLabel;
+  } else {
+    CXFA_Node* pLabelItems = listitems[0];
+    FX_BOOL bSave = pLabelItems->GetBoolean(XFA_ATTRIBUTE_Save);
+    CXFA_Node* pSaveItems = NULL;
+    if (bSave) {
+      pSaveItems = pLabelItems;
+      pLabelItems = listitems[1];
+    } else {
+      pSaveItems = listitems[1];
+    }
+    iCount = 0;
+    int32_t iSearch = -1;
+    CFX_WideString wsContent;
+    CXFA_Node* pChildItem = pLabelItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+    for (; pChildItem;
+         pChildItem = pChildItem->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+      pChildItem->TryContent(wsContent);
+      if (wsContent == wsLabel) {
+        iSearch = iCount;
+        break;
+      }
+      iCount++;
+    }
+    if (iSearch < 0) {
+      return;
+    }
+    if (CXFA_Node* pText = pSaveItems->GetChild(iSearch, XFA_ELEMENT_UNKNOWN)) {
+      pText->TryContent(wsValue);
+    }
+  }
+}
+FX_BOOL CXFA_WidgetData::DeleteItem(int32_t nIndex,
+                                    FX_BOOL bNotify,
+                                    FX_BOOL bScriptModify,
+                                    FX_BOOL bSyncData) {
+  FX_BOOL bSetValue = FALSE;
+  CXFA_Node* pItems = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+  for (; pItems; pItems = pItems->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    if (pItems->GetClassID() != XFA_ELEMENT_Items) {
+      continue;
+    }
+    if (nIndex < 0) {
+      while (CXFA_Node* pNode = pItems->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+        pItems->RemoveChild(pNode);
+      }
+    } else {
+      if (!bSetValue && pItems->GetBoolean(XFA_ATTRIBUTE_Save)) {
+        SetItemState(nIndex, FALSE, TRUE, bScriptModify, bSyncData);
+        bSetValue = TRUE;
+      }
+      int32_t i = 0;
+      CXFA_Node* pNode = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+      while (pNode) {
+        if (i == nIndex) {
+          pItems->RemoveChild(pNode);
+          break;
+        }
+        i++;
+        pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+      }
+    }
+  }
+  if (!bNotify) {
+    return TRUE;
+  }
+  m_pNode->GetDocument()->GetNotify()->OnWidgetDataEvent(
+      this, XFA_WIDGETEVENT_ListItemRemoved, (void*)(uintptr_t)nIndex);
+  return TRUE;
+}
+int32_t CXFA_WidgetData::GetHorizontalScrollPolicy() {
+  CXFA_Node* pUIChild = GetUIChild();
+  if (pUIChild) {
+    return pUIChild->GetEnum(XFA_ATTRIBUTE_HScrollPolicy);
+  }
+  return XFA_ATTRIBUTEENUM_Auto;
+}
+int32_t CXFA_WidgetData::GetNumberOfCells() {
+  CXFA_Node* pUIChild = GetUIChild();
+  if (!pUIChild) {
+    return -1;
+  }
+  if (CXFA_Node* pNode = pUIChild->GetChild(0, XFA_ELEMENT_Comb)) {
+    return pNode->GetInteger(XFA_ATTRIBUTE_NumberOfCells);
+  }
+  return -1;
+}
+FX_BOOL CXFA_WidgetData::IsDateTimeEditUsePicker() {
+  return TRUE;
+}
+CFX_WideString CXFA_WidgetData::GetBarcodeType() {
+  CXFA_Node* pUIChild = GetUIChild();
+  return pUIChild ? pUIChild->GetCData(XFA_ATTRIBUTE_Type) : NULL;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_CharEncoding(int32_t& val) {
+  CXFA_Node* pUIChild = GetUIChild();
+  CFX_WideString wsCharEncoding;
+  if (pUIChild->TryCData(XFA_ATTRIBUTE_CharEncoding, wsCharEncoding)) {
+    if (wsCharEncoding.CompareNoCase(L"UTF-16")) {
+      val = CHAR_ENCODING_UNICODE;
+      return TRUE;
+    } else if (wsCharEncoding.CompareNoCase(L"UTF-8")) {
+      val = CHAR_ENCODING_UTF8;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_Checksum(int32_t& val) {
+  CXFA_Node* pUIChild = GetUIChild();
+  XFA_ATTRIBUTEENUM eChecksum;
+  if (pUIChild->TryEnum(XFA_ATTRIBUTE_Checksum, eChecksum)) {
+    switch (eChecksum) {
+      case XFA_ATTRIBUTEENUM_None:
+        val = 0;
+        return TRUE;
+      case XFA_ATTRIBUTEENUM_Auto:
+        val = 1;
+        return TRUE;
+      case XFA_ATTRIBUTEENUM_1mod10:
+        break;
+      case XFA_ATTRIBUTEENUM_1mod10_1mod11:
+        break;
+      case XFA_ATTRIBUTEENUM_2mod10:
+        break;
+      default:
+        break;
+    }
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_DataLength(int32_t& val) {
+  CXFA_Node* pUIChild = GetUIChild();
+  CFX_WideString wsDataLength;
+  if (pUIChild->TryCData(XFA_ATTRIBUTE_DataLength, wsDataLength)) {
+    val = FXSYS_wtoi(wsDataLength);
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_StartChar(FX_CHAR& val) {
+  CXFA_Node* pUIChild = GetUIChild();
+  CFX_WideStringC wsStartEndChar;
+  if (pUIChild->TryCData(XFA_ATTRIBUTE_StartChar, wsStartEndChar)) {
+    if (wsStartEndChar.GetLength()) {
+      val = (FX_CHAR)wsStartEndChar.GetAt(0);
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_EndChar(FX_CHAR& val) {
+  CXFA_Node* pUIChild = GetUIChild();
+  CFX_WideStringC wsStartEndChar;
+  if (pUIChild->TryCData(XFA_ATTRIBUTE_EndChar, wsStartEndChar)) {
+    if (wsStartEndChar.GetLength()) {
+      val = (FX_CHAR)wsStartEndChar.GetAt(0);
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_ECLevel(int32_t& val) {
+  CXFA_Node* pUIChild = GetUIChild();
+  CFX_WideString wsECLevel;
+  if (pUIChild->TryCData(XFA_ATTRIBUTE_ErrorCorrectionLevel, wsECLevel)) {
+    val = FXSYS_wtoi(wsECLevel);
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_ModuleWidth(int32_t& val) {
+  CXFA_Node* pUIChild = GetUIChild();
+  CXFA_Measurement mModuleWidthHeight;
+  if (pUIChild->TryMeasure(XFA_ATTRIBUTE_ModuleWidth, mModuleWidthHeight)) {
+    val = (int32_t)mModuleWidthHeight.ToUnit(XFA_UNIT_Pt);
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_ModuleHeight(int32_t& val) {
+  CXFA_Node* pUIChild = GetUIChild();
+  CXFA_Measurement mModuleWidthHeight;
+  if (pUIChild->TryMeasure(XFA_ATTRIBUTE_ModuleHeight, mModuleWidthHeight)) {
+    val = (int32_t)mModuleWidthHeight.ToUnit(XFA_UNIT_Pt);
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_PrintChecksum(FX_BOOL& val) {
+  CXFA_Node* pUIChild = GetUIChild();
+  FX_BOOL bPrintCheckDigit;
+  if (pUIChild->TryBoolean(XFA_ATTRIBUTE_PrintCheckDigit, bPrintCheckDigit)) {
+    val = bPrintCheckDigit;
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_TextLocation(int32_t& val) {
+  CXFA_Node* pUIChild = GetUIChild();
+  XFA_ATTRIBUTEENUM eTextLocation;
+  if (pUIChild->TryEnum(XFA_ATTRIBUTE_TextLocation, eTextLocation)) {
+    switch (eTextLocation) {
+      case XFA_ATTRIBUTEENUM_None:
+        val = BC_TEXT_LOC_NONE;
+        return TRUE;
+      case XFA_ATTRIBUTEENUM_Above:
+        val = BC_TEXT_LOC_ABOVE;
+        return TRUE;
+      case XFA_ATTRIBUTEENUM_Below:
+        val = BC_TEXT_LOC_BELOW;
+        return TRUE;
+      case XFA_ATTRIBUTEENUM_AboveEmbedded:
+        val = BC_TEXT_LOC_ABOVEEMBED;
+        return TRUE;
+      case XFA_ATTRIBUTEENUM_BelowEmbedded:
+        val = BC_TEXT_LOC_BELOWEMBED;
+        return TRUE;
+      default:
+        break;
+    }
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_Truncate(FX_BOOL& val) {
+  CXFA_Node* pUIChild = GetUIChild();
+  FX_BOOL bTruncate;
+  if (pUIChild->TryBoolean(XFA_ATTRIBUTE_Truncate, bTruncate)) {
+    val = bTruncate;
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_WideNarrowRatio(FX_FLOAT& val) {
+  CXFA_Node* pUIChild = GetUIChild();
+  CFX_WideString wsWideNarrowRatio;
+  if (pUIChild->TryCData(XFA_ATTRIBUTE_WideNarrowRatio, wsWideNarrowRatio)) {
+    FX_STRSIZE ptPos = wsWideNarrowRatio.Find(':');
+    FX_FLOAT fRatio = 0;
+    if (ptPos >= 0) {
+      fRatio = (FX_FLOAT)FXSYS_wtoi(wsWideNarrowRatio);
+    } else {
+      int32_t fA, fB;
+      fA = FXSYS_wtoi(wsWideNarrowRatio.Left(ptPos));
+      fB = FXSYS_wtoi(wsWideNarrowRatio.Mid(ptPos + 1));
+      if (fB) {
+        fRatio = (FX_FLOAT)fA / fB;
+      }
+    }
+    val = fRatio;
+    return TRUE;
+  }
+  return FALSE;
+}
+void CXFA_WidgetData::GetPasswordChar(CFX_WideString& wsPassWord) {
+  CXFA_Node* pUIChild = GetUIChild();
+  if (pUIChild) {
+    pUIChild->TryCData(XFA_ATTRIBUTE_PasswordChar, wsPassWord);
+  } else {
+    wsPassWord = XFA_GetAttributeDefaultValue_Cdata(XFA_ELEMENT_PasswordEdit,
+                                                    XFA_ATTRIBUTE_PasswordChar,
+                                                    XFA_XDPPACKET_Form);
+  }
+}
+FX_BOOL CXFA_WidgetData::IsAllowRichText() {
+  CXFA_Node* pUIChild = GetUIChild();
+  FX_BOOL bValue = FALSE;
+  if (pUIChild &&
+      pUIChild->TryBoolean(XFA_ATTRIBUTE_AllowRichText, bValue, FALSE)) {
+    return bValue;
+  }
+  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Value)) {
+    if (CXFA_Node* pChild = pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+      return pChild->GetClassID() == XFA_ELEMENT_ExData;
+    }
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_WidgetData::IsMultiLine() {
+  CXFA_Node* pUIChild = GetUIChild();
+  if (pUIChild) {
+    return pUIChild->GetBoolean(XFA_ATTRIBUTE_MultiLine);
+  }
+  return XFA_GetAttributeDefaultValue_Boolean(
+      XFA_ELEMENT_TextEdit, XFA_ATTRIBUTE_MultiLine, XFA_XDPPACKET_Form);
+}
+int32_t CXFA_WidgetData::GetVerticalScrollPolicy() {
+  CXFA_Node* pUIChild = GetUIChild();
+  if (pUIChild) {
+    return pUIChild->GetEnum(XFA_ATTRIBUTE_VScrollPolicy);
+  }
+  return XFA_GetAttributeDefaultValue_Enum(
+      XFA_ELEMENT_TextEdit, XFA_ATTRIBUTE_VScrollPolicy, XFA_XDPPACKET_Form);
+}
+int32_t CXFA_WidgetData::GetMaxChars(XFA_ELEMENT& eType) {
+  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Value)) {
+    if (CXFA_Node* pChild = pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+      switch (pChild->GetClassID()) {
+        case XFA_ELEMENT_Text:
+          eType = XFA_ELEMENT_Text;
+          return pChild->GetInteger(XFA_ATTRIBUTE_MaxChars);
+        case XFA_ELEMENT_ExData: {
+          eType = XFA_ELEMENT_ExData;
+          int32_t iMax = pChild->GetInteger(XFA_ATTRIBUTE_MaxLength);
+          return iMax < 0 ? 0 : iMax;
+        }
+        default:
+          break;
+      }
+    }
+  }
+  return 0;
+}
+FX_BOOL CXFA_WidgetData::GetFracDigits(int32_t& iFracDigits) {
+  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Value)) {
+    if (CXFA_Node* pChild = pNode->GetChild(0, XFA_ELEMENT_Decimal)) {
+      return pChild->TryInteger(XFA_ATTRIBUTE_FracDigits, iFracDigits);
+    }
+  }
+  iFracDigits = -1;
+  return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetLeadDigits(int32_t& iLeadDigits) {
+  if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Value)) {
+    if (CXFA_Node* pChild = pNode->GetChild(0, XFA_ELEMENT_Decimal)) {
+      return pChild->TryInteger(XFA_ATTRIBUTE_LeadDigits, iLeadDigits);
+    }
+  }
+  iLeadDigits = -1;
+  return FALSE;
+}
+CFX_WideString XFA_NumericLimit(const CFX_WideString& wsValue,
+                                int32_t iLead,
+                                int32_t iTread) {
+  if ((iLead == -1) && (iTread == -1)) {
+    return wsValue;
+  }
+  CFX_WideString wsRet;
+  int32_t iLead_ = 0, iTread_ = -1;
+  int32_t iCount = wsValue.GetLength();
+  if (iCount == 0) {
+    return wsValue;
+  }
+  int32_t i = 0;
+  if (wsValue[i] == L'-') {
+    wsRet += L'-';
+    i++;
+  }
+  for (; i < iCount; i++) {
+    FX_WCHAR wc = wsValue[i];
+    if (XFA_IsDigit(wc)) {
+      if (iLead >= 0) {
+        iLead_++;
+        if (iLead_ > iLead) {
+          return L"0";
+        }
+      } else if (iTread_ >= 0) {
+        iTread_++;
+        if (iTread_ > iTread) {
+          if (iTread != -1) {
+            CFX_Decimal wsDeci = CFX_Decimal(wsValue);
+            wsDeci.SetScale(iTread);
+            wsRet = wsDeci;
+          }
+          return wsRet;
+        }
+      }
+    } else if (wc == L'.') {
+      iTread_ = 0;
+      iLead = -1;
+    }
+    wsRet += wc;
+  }
+  return wsRet;
+}
+FX_BOOL CXFA_WidgetData::SetValue(const CFX_WideString& wsValue,
+                                  XFA_VALUEPICTURE eValueType) {
+  if (wsValue.IsEmpty()) {
+    SyncValue(wsValue, TRUE);
+    return TRUE;
+  }
+  m_bPreNull = m_bIsNull;
+  m_bIsNull = FALSE;
+  CFX_WideString wsNewText(wsValue);
+  CFX_WideString wsPicture;
+  GetPictureContent(wsPicture, eValueType);
+  FX_BOOL bValidate = TRUE;
+  FX_BOOL bSyncData = FALSE;
+  CXFA_Node* pNode = GetUIChild();
+  if (!pNode) {
+    return TRUE;
+  }
+  XFA_ELEMENT uiType = pNode->GetClassID();
+  if (!wsPicture.IsEmpty()) {
+    CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
+    IFX_Locale* pLocale = GetLocal();
+    CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
+    bValidate =
+        widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture);
+    if (bValidate) {
+      widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsNewText,
+                                     wsPicture, pLocale, pLocalMgr);
+      wsNewText = widgetValue.GetValue();
+      if (uiType == XFA_ELEMENT_NumericEdit) {
+        int32_t iLeadDigits = 0;
+        int32_t iFracDigits = 0;
+        GetLeadDigits(iLeadDigits);
+        GetFracDigits(iFracDigits);
+        wsNewText = XFA_NumericLimit(wsNewText, iLeadDigits, iFracDigits);
+      }
+      bSyncData = TRUE;
+    }
+  } else {
+    if (uiType == XFA_ELEMENT_NumericEdit) {
+      if (wsNewText != FX_WSTRC(L"0")) {
+        int32_t iLeadDigits = 0;
+        int32_t iFracDigits = 0;
+        GetLeadDigits(iLeadDigits);
+        GetFracDigits(iFracDigits);
+        wsNewText = XFA_NumericLimit(wsNewText, iLeadDigits, iFracDigits);
+      }
+      bSyncData = TRUE;
+    }
+  }
+  if (uiType != XFA_ELEMENT_NumericEdit || bSyncData) {
+    SyncValue(wsNewText, TRUE);
+  }
+  return bValidate;
+}
+FX_BOOL CXFA_WidgetData::GetPictureContent(CFX_WideString& wsPicture,
+                                           XFA_VALUEPICTURE ePicture) {
+  if (ePicture == XFA_VALUEPICTURE_Raw) {
+    return FALSE;
+  }
+  CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
+  switch (ePicture) {
+    case XFA_VALUEPICTURE_Display: {
+      if (CXFA_Node* pFormat = m_pNode->GetChild(0, XFA_ELEMENT_Format)) {
+        if (CXFA_Node* pPicture = pFormat->GetChild(0, XFA_ELEMENT_Picture)) {
+          if (pPicture->TryContent(wsPicture)) {
+            return TRUE;
+          }
+        }
+      }
+      CFX_WideString wsDataPicture, wsTimePicture;
+      IFX_Locale* pLocale = GetLocal();
+      if (!pLocale) {
+        return FALSE;
+      }
+      FX_DWORD dwType = widgetValue.GetType();
+      switch (dwType) {
+        case XFA_VT_DATE:
+          pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium,
+                                  wsPicture);
+          break;
+        case XFA_VT_TIME:
+          pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium,
+                                  wsPicture);
+          break;
+        case XFA_VT_DATETIME:
+          pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium,
+                                  wsDataPicture);
+          pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium,
+                                  wsTimePicture);
+          wsPicture = wsDataPicture + FX_WSTRC(L"T") + wsTimePicture;
+          break;
+        case XFA_VT_DECIMAL:
+        case XFA_VT_FLOAT:
+          break;
+        default:
+          break;
+      }
+    }
+      return TRUE;
+    case XFA_VALUEPICTURE_Edit: {
+      CXFA_Node* pUI = m_pNode->GetChild(0, XFA_ELEMENT_Ui);
+      if (pUI) {
+        if (CXFA_Node* pPicture = pUI->GetChild(0, XFA_ELEMENT_Picture)) {
+          if (pPicture->TryContent(wsPicture)) {
+            return TRUE;
+          }
+        }
+      }
+      {
+        CFX_WideString wsDataPicture, wsTimePicture;
+        IFX_Locale* pLocale = GetLocal();
+        if (!pLocale) {
+          return FALSE;
+        }
+        FX_DWORD dwType = widgetValue.GetType();
+        switch (dwType) {
+          case XFA_VT_DATE:
+            pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short,
+                                    wsPicture);
+            break;
+          case XFA_VT_TIME:
+            pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short,
+                                    wsPicture);
+            break;
+          case XFA_VT_DATETIME:
+            pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short,
+                                    wsDataPicture);
+            pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short,
+                                    wsTimePicture);
+            wsPicture = wsDataPicture + L"T" + wsTimePicture;
+            break;
+          default:
+            break;
+        }
+      }
+    }
+      return TRUE;
+    case XFA_VALUEPICTURE_DataBind: {
+      if (CXFA_Bind bind = GetBind()) {
+        bind.GetPicture(wsPicture);
+        return TRUE;
+      }
+    } break;
+    default:
+      break;
+  }
+  return FALSE;
+}
+IFX_Locale* CXFA_WidgetData::GetLocal() {
+  IFX_Locale* pLocale = NULL;
+  if (!m_pNode) {
+    return pLocale;
+  }
+  FX_BOOL bLocale = FALSE;
+  CFX_WideString wsLocaleName;
+  bLocale = m_pNode->GetLocaleName(wsLocaleName);
+  if (bLocale) {
+    if (wsLocaleName.Equal(FX_WSTRC(L"ambient"))) {
+      pLocale = m_pNode->GetDocument()->GetLocalMgr()->GetDefLocale();
+    } else {
+      pLocale =
+          m_pNode->GetDocument()->GetLocalMgr()->GetLocaleByName(wsLocaleName);
+    }
+  }
+  return pLocale;
+}
+static FX_BOOL XFA_SplitDateTime(const CFX_WideString& wsDateTime,
+                                 CFX_WideString& wsDate,
+                                 CFX_WideString& wsTime) {
+  wsDate = L"";
+  wsTime = L"";
+  if (wsDateTime.IsEmpty()) {
+    return FALSE;
+  }
+  int nSplitIndex = -1;
+  nSplitIndex = wsDateTime.Find('T');
+  if (nSplitIndex < 0) {
+    nSplitIndex = wsDateTime.Find(' ');
+  }
+  if (nSplitIndex < 0) {
+    return FALSE;
+  }
+  wsDate = wsDateTime.Left(nSplitIndex);
+  if (!wsDate.IsEmpty()) {
+    int32_t iCount = wsDate.GetLength();
+    int32_t i = 0;
+    for (i = 0; i < iCount; i++) {
+      if (wsDate[i] >= '0' && wsDate[i] <= '9') {
+        break;
+      }
+    }
+    if (i == iCount) {
+      return FALSE;
+    }
+  }
+  wsTime = wsDateTime.Right(wsDateTime.GetLength() - nSplitIndex - 1);
+  if (!wsTime.IsEmpty()) {
+    int32_t iCount = wsTime.GetLength();
+    int32_t i = 0;
+    for (i = 0; i < iCount; i++) {
+      if (wsTime[i] >= '0' && wsTime[i] <= '9') {
+        break;
+      }
+    }
+    if (i == iCount) {
+      return FALSE;
+    }
+  }
+  return TRUE;
+}
+
+FX_BOOL CXFA_WidgetData::GetValue(CFX_WideString& wsValue,
+                                  XFA_VALUEPICTURE eValueType) {
+  wsValue = m_pNode->GetContent();
+
+  if (eValueType == XFA_VALUEPICTURE_Display)
+    GetItemLabel(wsValue, wsValue);
+
+  CFX_WideString wsPicture;
+  GetPictureContent(wsPicture, eValueType);
+  CXFA_Node* pNode = GetUIChild();
+  if (!pNode)
+    return TRUE;
+
+  XFA_ELEMENT uiType = GetUIChild()->GetClassID();
+  switch (uiType) {
+    case XFA_ELEMENT_ChoiceList: {
+      if (eValueType == XFA_VALUEPICTURE_Display) {
+        int32_t iSelItemIndex = GetSelectedItem(0);
+        if (iSelItemIndex >= 0) {
+          GetChoiceListItem(wsValue, iSelItemIndex);
+          wsPicture.Empty();
+        }
+      }
+    } break;
+    case XFA_ELEMENT_NumericEdit:
+      if (eValueType != XFA_VALUEPICTURE_Raw && wsPicture.IsEmpty()) {
+        IFX_Locale* pLocale = GetLocal();
+        if (eValueType == XFA_VALUEPICTURE_Display && pLocale) {
+          CFX_WideString wsOutput;
+          NormalizeNumStr(wsValue, wsOutput);
+          FormatNumStr(wsOutput, pLocale, wsOutput);
+          wsValue = wsOutput;
+        }
+      }
+      break;
+    default:
+      break;
+  }
+  if (wsPicture.IsEmpty())
+    return TRUE;
+
+  if (IFX_Locale* pLocale = GetLocal()) {
+    CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
+    CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
+    switch (widgetValue.GetType()) {
+      case XFA_VT_DATE: {
+        CFX_WideString wsDate, wsTime;
+        if (XFA_SplitDateTime(wsValue, wsDate, wsTime)) {
+          CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
+          if (date.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
+            return TRUE;
+        }
+        break;
+      }
+      case XFA_VT_TIME: {
+        CFX_WideString wsDate, wsTime;
+        if (XFA_SplitDateTime(wsValue, wsDate, wsTime)) {
+          CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
+          if (time.FormatPatterns(wsValue, wsPicture, pLocale, eValueType))
+            return TRUE;
+        }
+        break;
+      }
+      default:
+        break;
+    }
+    widgetValue.FormatPatterns(wsValue, wsPicture, pLocale, eValueType);
+  }
+  return TRUE;
+}
+
+FX_BOOL CXFA_WidgetData::GetNormalizeDataValue(
+    const CFX_WideStringC& wsValue,
+    CFX_WideString& wsNormalizeValue) {
+  wsNormalizeValue = wsValue;
+  if (wsValue.IsEmpty()) {
+    return TRUE;
+  }
+  CFX_WideString wsPicture;
+  GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind);
+  if (wsPicture.IsEmpty()) {
+    return TRUE;
+  }
+  FXSYS_assert(GetNode());
+  CXFA_LocaleMgr* pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
+  IFX_Locale* pLocale = GetLocal();
+  CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
+  if (widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture)) {
+    widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsNormalizeValue,
+                                   wsPicture, pLocale, pLocalMgr);
+    wsNormalizeValue = widgetValue.GetValue();
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetFormatDataValue(const CFX_WideStringC& wsValue,
+                                            CFX_WideString& wsFormatedValue) {
+  wsFormatedValue = wsValue;
+  if (wsValue.IsEmpty()) {
+    return TRUE;
+  }
+  CFX_WideString wsPicture;
+  GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind);
+  if (wsPicture.IsEmpty()) {
+    return TRUE;
+  }
+  if (IFX_Locale* pLocale = GetLocal()) {
+    FXSYS_assert(GetNode());
+    CXFA_Node* pNodeValue = GetNode()->GetChild(0, XFA_ELEMENT_Value);
+    if (!pNodeValue) {
+      return FALSE;
+    }
+    CXFA_Node* pValueChild = pNodeValue->GetNodeItem(XFA_NODEITEM_FirstChild);
+    if (!pValueChild) {
+      return FALSE;
+    }
+    int32_t iVTType = XFA_VT_NULL;
+    XFA_ELEMENT eType = pValueChild->GetClassID();
+    switch (eType) {
+      case XFA_ELEMENT_Decimal:
+        iVTType = XFA_VT_DECIMAL;
+        break;
+      case XFA_ELEMENT_Float:
+        iVTType = XFA_VT_FLOAT;
+        break;
+      case XFA_ELEMENT_Date:
+        iVTType = XFA_VT_DATE;
+        break;
+      case XFA_ELEMENT_Time:
+        iVTType = XFA_VT_TIME;
+        break;
+      case XFA_ELEMENT_DateTime:
+        iVTType = XFA_VT_DATETIME;
+        break;
+      case XFA_ELEMENT_Boolean:
+        iVTType = XFA_VT_BOOLEAN;
+        break;
+      case XFA_ELEMENT_Integer:
+        iVTType = XFA_VT_INTEGER;
+        break;
+      case XFA_ELEMENT_Text:
+        iVTType = XFA_VT_TEXT;
+        break;
+      default:
+        iVTType = XFA_VT_NULL;
+        break;
+    }
+    CXFA_LocaleMgr* pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
+    CXFA_LocaleValue widgetValue(iVTType, wsValue, pLocalMgr);
+    switch (widgetValue.GetType()) {
+      case XFA_VT_DATE: {
+        CFX_WideString wsDate, wsTime;
+        if (XFA_SplitDateTime(wsValue, wsDate, wsTime)) {
+          CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
+          if (date.FormatPatterns(wsFormatedValue, wsPicture, pLocale,
+                                  XFA_VALUEPICTURE_DataBind)) {
+            return TRUE;
+          }
+        }
+        break;
+      }
+      case XFA_VT_TIME: {
+        CFX_WideString wsDate, wsTime;
+        if (XFA_SplitDateTime(wsValue, wsDate, wsTime)) {
+          CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
+          if (time.FormatPatterns(wsFormatedValue, wsPicture, pLocale,
+                                  XFA_VALUEPICTURE_DataBind)) {
+            return TRUE;
+          }
+        }
+        break;
+      }
+      default:
+        break;
+    }
+    widgetValue.FormatPatterns(wsFormatedValue, wsPicture, pLocale,
+                               XFA_VALUEPICTURE_DataBind);
+  }
+  return FALSE;
+}
+void CXFA_WidgetData::NormalizeNumStr(const CFX_WideString& wsValue,
+                                      CFX_WideString& wsOutput) {
+  if (wsValue.IsEmpty()) {
+    return;
+  }
+  wsOutput = wsValue;
+  wsOutput.TrimLeft('0');
+  int32_t dot_index = wsOutput.Find('.');
+  int32_t iFracDigits = 0;
+  if (!wsOutput.IsEmpty() && dot_index >= 0 &&
+      (!GetFracDigits(iFracDigits) || iFracDigits != -1)) {
+    wsOutput.TrimRight(L"0");
+    wsOutput.TrimRight(L".");
+  }
+  if (wsOutput.IsEmpty() || wsOutput[0] == '.') {
+    wsOutput.Insert(0, '0');
+  }
+}
+void CXFA_WidgetData::FormatNumStr(const CFX_WideString& wsValue,
+                                   IFX_Locale* pLocale,
+                                   CFX_WideString& wsOutput) {
+  if (wsValue.IsEmpty()) {
+    return;
+  }
+  CFX_WideString wsSrcNum = wsValue;
+  CFX_WideString wsGroupSymbol;
+  pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol);
+  FX_BOOL bNeg = FALSE;
+  if (wsSrcNum[0] == '-') {
+    bNeg = TRUE;
+    wsSrcNum.Delete(0, 1);
+  }
+  int32_t len = wsSrcNum.GetLength();
+  int32_t dot_index = wsSrcNum.Find('.');
+  if (dot_index == -1) {
+    dot_index = len;
+  }
+  int32_t cc = dot_index - 1;
+  if (cc >= 0) {
+    int nPos = dot_index % 3;
+    wsOutput.Empty();
+    for (int32_t i = 0; i < dot_index; i++) {
+      if (i % 3 == nPos && i != 0) {
+        wsOutput += wsGroupSymbol;
+      }
+      wsOutput += wsSrcNum[i];
+    }
+    if (dot_index < len) {
+      CFX_WideString wsSymbol;
+      pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsSymbol);
+      wsOutput += wsSymbol;
+      wsOutput += wsSrcNum.Right(len - dot_index - 1);
+    }
+    if (bNeg) {
+      CFX_WideString wsMinusymbol;
+      pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
+      wsOutput = wsMinusymbol + wsOutput;
+    }
+  }
+}
+void CXFA_WidgetData::SyncValue(const CFX_WideString& wsValue,
+                                FX_BOOL bNotify) {
+  if (!m_pNode) {
+    return;
+  }
+  CFX_WideString wsFormatValue(wsValue);
+  CXFA_WidgetData* pContainerWidgetData = m_pNode->GetContainerWidgetData();
+  if (pContainerWidgetData) {
+    pContainerWidgetData->GetFormatDataValue(wsValue, wsFormatValue);
+  }
+  m_pNode->SetContent(wsValue, wsFormatValue, bNotify);
+}
+void CXFA_WidgetData::InsertListTextItem(CXFA_Node* pItems,
+                                         const CFX_WideStringC& wsText,
+                                         int32_t nIndex) {
+  CXFA_Node* pText = pItems->CreateSamePacketNode(XFA_ELEMENT_Text);
+  pItems->InsertChild(nIndex, pText);
+  pText->SetContent(wsText, wsText, FALSE, FALSE, FALSE);
+}
+CXFA_Filter CXFA_WidgetData::GetFilter(FX_BOOL bModified) {
+  if (!m_pUiChildNode) {
+    return CXFA_Filter(nullptr);
+  }
+  return CXFA_Filter(
+      m_pUiChildNode->GetProperty(0, XFA_ELEMENT_Filter, bModified));
+}
+CXFA_Manifest CXFA_WidgetData::GetManifest(FX_BOOL bModified) {
+  if (!m_pUiChildNode) {
+    return CXFA_Manifest(nullptr);
+  }
+  return CXFA_Manifest(
+      m_pUiChildNode->GetProperty(0, XFA_ELEMENT_Manifest, bModified));
+}
+CXFA_Occur::CXFA_Occur(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+int32_t CXFA_Occur::GetMax() {
+  int32_t iMax = 1;
+  if (m_pNode) {
+    if (!m_pNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, TRUE)) {
+      iMax = GetMin();
+    }
+  }
+  return iMax;
+}
+int32_t CXFA_Occur::GetMin() {
+  int32_t iMin = 1;
+  if (m_pNode) {
+    if (!m_pNode->TryInteger(XFA_ATTRIBUTE_Min, iMin, TRUE) || iMin < 0) {
+      iMin = 1;
+    }
+  }
+  return iMin;
+}
+int32_t CXFA_Occur::GetInitial() {
+  int32_t iInit = 1;
+  if (m_pNode) {
+    int32_t iMin = GetMin();
+    if (!m_pNode->TryInteger(XFA_ATTRIBUTE_Initial, iInit, TRUE) ||
+        iInit < iMin) {
+      iInit = iMin;
+    }
+  }
+  return iInit;
+}
+FX_BOOL CXFA_Occur::GetOccurInfo(int32_t& iMin, int32_t& iMax, int32_t& iInit) {
+  if (!m_pNode) {
+    return FALSE;
+  }
+  if (!m_pNode->TryInteger(XFA_ATTRIBUTE_Min, iMin, FALSE) || iMin < 0) {
+    iMin = 1;
+  }
+  if (!m_pNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, FALSE)) {
+    if (iMin == 0) {
+      iMax = 1;
+    } else {
+      iMax = iMin;
+    }
+  }
+  if (!m_pNode->TryInteger(XFA_ATTRIBUTE_Initial, iInit, FALSE) ||
+      iInit < iMin) {
+    iInit = iMin;
+  }
+  return TRUE;
+}
+void CXFA_Occur::SetMax(int32_t iMax) {
+  iMax = (iMax != -1 && iMax < 1) ? 1 : iMax;
+  m_pNode->SetInteger(XFA_ATTRIBUTE_Max, iMax, FALSE);
+  int32_t iMin = GetMin();
+  if (iMax != -1 && iMax < iMin) {
+    iMin = iMax;
+    m_pNode->SetInteger(XFA_ATTRIBUTE_Min, iMin, FALSE);
+  }
+}
+void CXFA_Occur::SetMin(int32_t iMin) {
+  iMin = (iMin < 0) ? 1 : iMin;
+  m_pNode->SetInteger(XFA_ATTRIBUTE_Min, iMin, FALSE);
+  int32_t iMax = GetMax();
+  if (iMax > 0 && iMax < iMin) {
+    iMax = iMin;
+    m_pNode->SetInteger(XFA_ATTRIBUTE_Max, iMax, FALSE);
+  }
+}
+XFA_ATTRIBUTEENUM XFA_GetEnumTypeAttribute(
+    CXFA_Node* pNode,
+    XFA_ATTRIBUTE attributeValue = XFA_ATTRIBUTE_Type,
+    XFA_ATTRIBUTEENUM eDefaultValue = XFA_ATTRIBUTEENUM_Optional) {
+  XFA_ATTRIBUTEENUM eType = eDefaultValue;
+  if (pNode) {
+    if (!pNode->TryEnum(attributeValue, eType, TRUE)) {
+      eType = eDefaultValue;
+    }
+  }
+  return eType;
+}
+CFX_WideString CXFA_Filter::GetFilterString(XFA_ATTRIBUTE eAttribute) {
+  CFX_WideString wsStringValue;
+  if (m_pNode) {
+    m_pNode->GetAttribute(eAttribute, wsStringValue, FALSE);
+  }
+  return wsStringValue;
+}
+XFA_ATTRIBUTEENUM CXFA_Filter::GetAppearanceFilterType() {
+  if (!m_pNode) {
+    return XFA_ATTRIBUTEENUM_Optional;
+  }
+  CXFA_Node* pAppearanceFilterNode =
+      m_pNode->GetProperty(0, XFA_ELEMENT_AppearanceFilter);
+  return XFA_GetEnumTypeAttribute(pAppearanceFilterNode);
+}
+CFX_WideString CXFA_Filter::GetAppearanceFilterContent() {
+  CFX_WideString wsContent;
+  if (m_pNode) {
+    CXFA_Node* pAppearanceFilterNode =
+        m_pNode->GetProperty(0, XFA_ELEMENT_AppearanceFilter);
+    pAppearanceFilterNode->TryContent(wsContent);
+  }
+  return wsContent;
+}
+XFA_ATTRIBUTEENUM CXFA_Filter::GetCertificatesCredentialServerPolicy() {
+  if (!m_pNode) {
+    return XFA_ATTRIBUTEENUM_Optional;
+  }
+  CXFA_Node* pCertsNode = m_pNode->GetProperty(0, XFA_ELEMENT_Certificates);
+  return XFA_GetEnumTypeAttribute(pCertsNode,
+                                  XFA_ATTRIBUTE_CredentialServerPolicy);
+}
+CFX_WideString CXFA_Filter::GetCertificatesURL() {
+  CFX_WideString wsURL;
+  if (m_pNode) {
+    CXFA_Node* pCertsNode = m_pNode->GetProperty(0, XFA_ELEMENT_Certificates);
+    pCertsNode->GetAttribute(XFA_ATTRIBUTE_Url, wsURL, FALSE);
+  }
+  return wsURL;
+}
+CFX_WideString CXFA_Filter::GetCertificatesURLPolicy() {
+  CFX_WideString wsURLPolicy;
+  if (m_pNode) {
+    CXFA_Node* pCertsNode = m_pNode->GetProperty(0, XFA_ELEMENT_Certificates);
+    pCertsNode->GetAttribute(XFA_ATTRIBUTE_UrlPolicy, wsURLPolicy, FALSE);
+  }
+  return wsURLPolicy;
+}
+CXFA_WrapCertificate CXFA_Filter::GetCertificatesEncryption(FX_BOOL bModified) {
+  if (!m_pNode) {
+    return CXFA_WrapCertificate(NULL);
+  }
+  CXFA_Node* pCertsNode =
+      m_pNode->GetProperty(0, XFA_ELEMENT_Certificates, bModified);
+  return CXFA_WrapCertificate(
+      pCertsNode ? pCertsNode->GetProperty(0, XFA_ELEMENT_Encryption, bModified)
+                 : NULL);
+}
+CXFA_WrapCertificate CXFA_Filter::GetCertificatesIssuers(FX_BOOL bModified) {
+  if (!m_pNode) {
+    return CXFA_WrapCertificate(NULL);
+  }
+  CXFA_Node* pCertsNode =
+      m_pNode->GetProperty(0, XFA_ELEMENT_Certificates, bModified);
+  return CXFA_WrapCertificate(
+      pCertsNode ? pCertsNode->GetProperty(0, XFA_ELEMENT_Issuers, bModified)
+                 : NULL);
+}
+CFX_WideString CXFA_Filter::GetCertificatesKeyUsageString(
+    XFA_ATTRIBUTE eAttribute) {
+  if (!m_pNode) {
+    return FX_WSTRC(L"");
+  }
+  CXFA_Node* pCertsNode = m_pNode->GetProperty(0, XFA_ELEMENT_Certificates);
+  CXFA_Node* pKeyUsageNode = pCertsNode->GetProperty(0, XFA_ELEMENT_KeyUsage);
+  CFX_WideString wsAttributeValue;
+  pKeyUsageNode->GetAttribute(eAttribute, wsAttributeValue, FALSE);
+  return wsAttributeValue;
+}
+CXFA_Oids CXFA_Filter::GetCertificatesOids() {
+  if (!m_pNode) {
+    return CXFA_Oids(NULL);
+  }
+  CXFA_Node* pCertsNode = m_pNode->GetProperty(0, XFA_ELEMENT_Certificates);
+  return CXFA_Oids(pCertsNode ? pCertsNode->GetProperty(0, XFA_ELEMENT_Oids)
+                              : NULL);
+}
+CXFA_WrapCertificate CXFA_Filter::GetCertificatesSigning(FX_BOOL bModified) {
+  if (!m_pNode) {
+    return CXFA_WrapCertificate(NULL);
+  }
+  CXFA_Node* pCertsNode =
+      m_pNode->GetProperty(0, XFA_ELEMENT_Certificates, bModified);
+  return CXFA_WrapCertificate(
+      pCertsNode ? pCertsNode->GetProperty(0, XFA_ELEMENT_Signing, bModified)
+                 : NULL);
+}
+CXFA_DigestMethods CXFA_Filter::GetDigestMethods(FX_BOOL bModified) {
+  return CXFA_DigestMethods(
+      m_pNode ? m_pNode->GetProperty(0, XFA_ELEMENT_DigestMethods, bModified)
+              : NULL);
+}
+CXFA_Encodings CXFA_Filter::GetEncodings(FX_BOOL bModified) {
+  return CXFA_Encodings(
+      m_pNode ? m_pNode->GetProperty(0, XFA_ELEMENT_Encodings, bModified)
+              : NULL);
+}
+CXFA_EncryptionMethods CXFA_Filter::GetEncryptionMethods(FX_BOOL bModified) {
+  return CXFA_EncryptionMethods(
+      m_pNode
+          ? m_pNode->GetProperty(0, XFA_ELEMENT_EncryptionMethods, bModified)
+          : NULL);
+}
+XFA_ATTRIBUTEENUM CXFA_Filter::GetHandlerType() {
+  if (!m_pNode) {
+    return XFA_ATTRIBUTEENUM_Optional;
+  }
+  CXFA_Node* pHandlerNode = m_pNode->GetProperty(0, XFA_ELEMENT_Handler);
+  return XFA_GetEnumTypeAttribute(pHandlerNode);
+}
+CFX_WideString CXFA_Filter::GetHandlerContent() {
+  CFX_WideString wsContent;
+  if (m_pNode) {
+    CXFA_Node* pHandlerNode = m_pNode->GetProperty(0, XFA_ELEMENT_Handler);
+    pHandlerNode->TryContent(wsContent);
+  }
+  return wsContent;
+}
+XFA_ATTRIBUTEENUM CXFA_Filter::GetlockDocumentType() {
+  if (!m_pNode) {
+    return XFA_ATTRIBUTEENUM_Optional;
+  }
+  CXFA_Node* pLockDocNode = m_pNode->GetProperty(0, XFA_ELEMENT_LockDocument);
+  return XFA_GetEnumTypeAttribute(pLockDocNode);
+}
+CFX_WideString CXFA_Filter::GetlockDocumentContent() {
+  CFX_WideString wsContent = FX_WSTRC(L"auto");
+  if (m_pNode) {
+    CXFA_Node* pLockDocNode = m_pNode->GetProperty(0, XFA_ELEMENT_LockDocument);
+    pLockDocNode->TryContent(wsContent);
+  }
+  return wsContent;
+}
+int32_t CXFA_Filter::GetMDPPermissions() {
+  int32_t iPermissions = 2;
+  if (m_pNode) {
+    CXFA_Node* pMDPNode = m_pNode->GetProperty(0, XFA_ELEMENT_Mdp);
+    if (!pMDPNode->TryInteger(XFA_ATTRIBUTE_Permissions, iPermissions, TRUE)) {
+      iPermissions = 2;
+    }
+  }
+  return iPermissions;
+}
+XFA_ATTRIBUTEENUM CXFA_Filter::GetMDPSignatureType() {
+  if (!m_pNode) {
+    return XFA_ATTRIBUTEENUM_Filter;
+  }
+  CXFA_Node* pMDPNode = m_pNode->GetProperty(0, XFA_ELEMENT_Mdp);
+  return XFA_GetEnumTypeAttribute(pMDPNode, XFA_ATTRIBUTE_SignatureType,
+                                  XFA_ATTRIBUTEENUM_Filter);
+}
+CXFA_Reasons CXFA_Filter::GetReasons(FX_BOOL bModified) {
+  return CXFA_Reasons(m_pNode ? m_pNode->GetProperty(0, XFA_ELEMENT_Reasons)
+                              : NULL);
+}
+CFX_WideString CXFA_Filter::GetTimeStampServer() {
+  CFX_WideString wsServerURI;
+  if (m_pNode) {
+    CXFA_Node* pTimeStampNode = m_pNode->GetProperty(0, XFA_ELEMENT_TimeStamp);
+    pTimeStampNode->GetAttribute(XFA_ATTRIBUTE_Server, wsServerURI, FALSE);
+  }
+  return wsServerURI;
+}
+XFA_ATTRIBUTEENUM CXFA_Filter::GetTimeStampType() {
+  if (!m_pNode) {
+    return XFA_ATTRIBUTEENUM_Optional;
+  }
+  CXFA_Node* pTimeStampNode = m_pNode->GetProperty(0, XFA_ELEMENT_TimeStamp);
+  return XFA_GetEnumTypeAttribute(pTimeStampNode);
+}
+CFX_WideString CXFA_Certificate::GetCertificateName() {
+  CFX_WideString wsName;
+  if (m_pNode) {
+    m_pNode->GetAttribute(XFA_ATTRIBUTE_Name, wsName, FALSE);
+  }
+  return wsName;
+}
+CFX_WideString CXFA_Certificate::GetCertificateContent() {
+  CFX_WideString wsContent;
+  if (m_pNode) {
+    m_pNode->TryContent(wsContent);
+  }
+  return wsContent;
+}
+XFA_ATTRIBUTEENUM CXFA_WrapCertificate::GetType() {
+  return XFA_GetEnumTypeAttribute(m_pNode);
+}
+int32_t CXFA_WrapCertificate::CountCertificates() {
+  return m_pNode ? m_pNode->CountChildren(XFA_ELEMENT_Certificate) : 0;
+}
+CXFA_Certificate CXFA_WrapCertificate::GetCertificate(int32_t nIndex) {
+  return CXFA_Certificate(
+      (nIndex > -1 && m_pNode)
+          ? m_pNode->GetChild(nIndex, XFA_ELEMENT_Certificate)
+          : NULL);
+}
+XFA_ATTRIBUTEENUM CXFA_Oids::GetOidsType() {
+  return XFA_GetEnumTypeAttribute(m_pNode);
+}
+int32_t CXFA_Oids::CountOids() {
+  return m_pNode ? m_pNode->CountChildren(XFA_ELEMENT_Oid) : 0;
+}
+CFX_WideString CXFA_Oids::GetOidContent(int32_t nIndex) {
+  if (nIndex <= -1 || !m_pNode) {
+    return FX_WSTRC(L"");
+  }
+  CXFA_Node* pOidNode = m_pNode->GetChild(nIndex, XFA_ELEMENT_Oid);
+  if (!pOidNode) {
+    return FX_WSTRC(L"");
+  }
+  CFX_WideString wsContent;
+  pOidNode->TryContent(wsContent);
+  return wsContent;
+}
+XFA_ATTRIBUTEENUM CXFA_SubjectDNs::GetSubjectDNsType() {
+  return XFA_GetEnumTypeAttribute(m_pNode);
+}
+int32_t CXFA_SubjectDNs::CountSubjectDNs() {
+  return m_pNode ? m_pNode->CountChildren(XFA_ELEMENT_SubjectDN) : 0;
+}
+CFX_WideString CXFA_SubjectDNs::GetSubjectDNString(int32_t nIndex,
+                                                   XFA_ATTRIBUTE eAttribute) {
+  if (nIndex <= -1 || !m_pNode) {
+    return FX_WSTRC(L"");
+  }
+  CXFA_Node* pSubjectDNNode = m_pNode->GetChild(nIndex, XFA_ELEMENT_SubjectDN);
+  if (!pSubjectDNNode) {
+    return FX_WSTRC(L"");
+  }
+  CFX_WideString wsAttributeValue;
+  pSubjectDNNode->GetAttribute(eAttribute, wsAttributeValue, FALSE);
+  return wsAttributeValue;
+}
+CFX_WideString CXFA_SubjectDNs::GetSubjectDNContent(int32_t nIndex) {
+  if (nIndex <= -1 || !m_pNode) {
+    return FX_WSTRC(L"");
+  }
+  CXFA_Node* pSubjectDNNode = m_pNode->GetChild(nIndex, XFA_ELEMENT_SubjectDN);
+  if (!pSubjectDNNode) {
+    return FX_WSTRC(L"");
+  }
+  CFX_WideString wsContent;
+  pSubjectDNNode->TryContent(wsContent);
+  return wsContent;
+}
+XFA_ATTRIBUTEENUM CXFA_DigestMethods::GetDigestMethodsType() {
+  return XFA_GetEnumTypeAttribute(m_pNode);
+}
+int32_t CXFA_DigestMethods::CountDigestMethods() {
+  return m_pNode ? m_pNode->CountChildren(XFA_ELEMENT_DigestMethod) : 0;
+}
+CFX_WideString CXFA_DigestMethods::GetDigestMethodContent(int32_t nIndex) {
+  if (nIndex <= -1 || !m_pNode) {
+    return FX_WSTRC(L"");
+  }
+  CXFA_Node* pDigestMethodNode =
+      m_pNode->GetChild(nIndex, XFA_ELEMENT_DigestMethod);
+  if (!pDigestMethodNode) {
+    return FX_WSTRC(L"");
+  }
+  CFX_WideString wsContent;
+  pDigestMethodNode->TryContent(wsContent);
+  return wsContent;
+}
+XFA_ATTRIBUTEENUM CXFA_Encodings::GetEncodingsType() {
+  return XFA_GetEnumTypeAttribute(m_pNode);
+}
+int32_t CXFA_Encodings::CountEncodings() {
+  return m_pNode ? m_pNode->CountChildren(XFA_ELEMENT_Encoding) : 0;
+}
+CFX_WideString CXFA_Encodings::GetEncodingContent(int32_t nIndex) {
+  if (nIndex <= -1 || !m_pNode) {
+    return FX_WSTRC(L"");
+  }
+  CXFA_Node* pEncodingNode = m_pNode->GetChild(nIndex, XFA_ELEMENT_Encoding);
+  if (!pEncodingNode) {
+    return FX_WSTRC(L"");
+  }
+  CFX_WideString wsContent;
+  pEncodingNode->TryContent(wsContent);
+  return wsContent;
+}
+XFA_ATTRIBUTEENUM CXFA_EncryptionMethods::GetEncryptionMethodsType() {
+  return XFA_GetEnumTypeAttribute(m_pNode);
+}
+int32_t CXFA_EncryptionMethods::CountEncryptionMethods() {
+  return m_pNode ? m_pNode->CountChildren(XFA_ELEMENT_EncryptionMethod) : 0;
+}
+CFX_WideString CXFA_EncryptionMethods::GetEncryptionMethodContent(
+    int32_t nIndex) {
+  if (nIndex <= -1 || !m_pNode) {
+    return FX_WSTRC(L"");
+  }
+  CXFA_Node* pEncryMethodNode =
+      m_pNode->GetChild(nIndex, XFA_ELEMENT_EncryptionMethod);
+  if (!pEncryMethodNode) {
+    return FX_WSTRC(L"");
+  }
+  CFX_WideString wsContent;
+  pEncryMethodNode->TryContent(wsContent);
+  return wsContent;
+}
+XFA_ATTRIBUTEENUM CXFA_Reasons::GetReasonsType() {
+  return XFA_GetEnumTypeAttribute(m_pNode);
+}
+int32_t CXFA_Reasons::CountReasons() {
+  return m_pNode ? m_pNode->CountChildren(XFA_ELEMENT_Reason) : 0;
+}
+CFX_WideString CXFA_Reasons::GetReasonContent(int32_t nIndex) {
+  if (nIndex <= -1 || !m_pNode) {
+    return FX_WSTRC(L"");
+  }
+  CXFA_Node* pReasonNode = m_pNode->GetChild(nIndex, XFA_ELEMENT_Reason);
+  if (!pReasonNode) {
+    return FX_WSTRC(L"");
+  }
+  CFX_WideString wsContent;
+  pReasonNode->TryContent(wsContent);
+  return wsContent;
+}
+XFA_ATTRIBUTEENUM CXFA_Manifest::GetAction() {
+  return XFA_GetEnumTypeAttribute(m_pNode, XFA_ATTRIBUTE_Action,
+                                  XFA_ATTRIBUTEENUM_Include);
+}
+int32_t CXFA_Manifest::CountReives() {
+  return m_pNode ? m_pNode->CountChildren(XFA_ELEMENT_Ref) : 0;
+}
+CFX_WideString CXFA_Manifest::GetRefContent(int32_t nIndex) {
+  if (nIndex <= -1 || !m_pNode) {
+    return FX_WSTRC(L"");
+  }
+  CXFA_Node* pRefNode = m_pNode->GetChild(nIndex, XFA_ELEMENT_Ref);
+  if (!pRefNode) {
+    return FX_WSTRC(L"");
+  }
+  CFX_WideString wsContent;
+  pRefNode->TryContent(wsContent);
+  return wsContent;
+}
diff --git a/xfa/fxfa/parser/xfa_parser.h b/xfa/fxfa/parser/xfa_parser.h
new file mode 100644
index 0000000..2d45e5f
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_parser.h
@@ -0,0 +1,38 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_PARSER_H_
+#define XFA_FXFA_PARSER_XFA_PARSER_H_
+
+#include "xfa/fxfa/parser/xfa_document.h"
+
+class IXFA_Parser {
+ public:
+  static IXFA_Parser* Create(IXFA_ObjFactory* pFactory,
+                             FX_BOOL bDocumentParser = FALSE);
+  virtual ~IXFA_Parser() {}
+  virtual void Release() = 0;
+  virtual int32_t StartParse(IFX_FileRead* pStream,
+                             XFA_XDPPACKET ePacketID = XFA_XDPPACKET_XDP) = 0;
+  virtual int32_t DoParse(IFX_Pause* pPause = NULL) = 0;
+  virtual int32_t ParseXMLData(const CFX_WideString& wsXML,
+                               IFDE_XMLNode*& pXMLNode,
+                               IFX_Pause* pPause = NULL) = 0;
+  virtual void ConstructXFANode(CXFA_Node* pXFANode,
+                                IFDE_XMLNode* pXMLNode) = 0;
+  virtual IXFA_ObjFactory* GetFactory() const = 0;
+  virtual CXFA_Node* GetRootNode() const = 0;
+  virtual IFDE_XMLDoc* GetXMLDoc() const = 0;
+  virtual void CloseParser() = 0;
+};
+class IXFA_DocParser : public IXFA_Parser {
+ public:
+  static IXFA_DocParser* Create(IXFA_Notify* pNotify);
+  virtual CXFA_Document* GetDocument() const = 0;
+  virtual IXFA_Notify* GetNotify() const = 0;
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_PARSER_H_
diff --git a/xfa/fxfa/parser/xfa_parser_imp.cpp b/xfa/fxfa/parser/xfa_parser_imp.cpp
new file mode 100644
index 0000000..f27e3a6
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_parser_imp.cpp
@@ -0,0 +1,1568 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_parser_imp.h"
+
+#include "xfa/fgas/crt/fgas_codepage.h"
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_basic_imp.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+IXFA_Parser* IXFA_Parser::Create(IXFA_ObjFactory* pFactory,
+                                 FX_BOOL bDocumentParser) {
+  return new CXFA_SimpleParser(pFactory, bDocumentParser);
+}
+CXFA_SimpleParser::CXFA_SimpleParser(IXFA_ObjFactory* pFactory,
+                                     FX_BOOL bDocumentParser)
+    : m_pXMLParser(nullptr),
+      m_pXMLDoc(nullptr),
+      m_pStream(nullptr),
+      m_pFileRead(nullptr),
+      m_pFactory(pFactory),
+      m_pRootNode(nullptr),
+      m_ePacketID(XFA_XDPPACKET_UNKNOWN),
+      m_bDocumentParser(bDocumentParser) {}
+CXFA_SimpleParser::~CXFA_SimpleParser() {
+  CloseParser();
+}
+void CXFA_SimpleParser::SetFactory(IXFA_ObjFactory* pFactory) {
+  m_pFactory = pFactory;
+}
+static IFDE_XMLNode* XFA_FDEExtension_GetDocumentNode(
+    IFDE_XMLDoc* pXMLDoc,
+    FX_BOOL bVerifyWellFormness = FALSE) {
+  if (!pXMLDoc) {
+    return NULL;
+  }
+  IFDE_XMLNode* pXMLFakeRoot = pXMLDoc->GetRoot();
+  for (IFDE_XMLNode* pXMLNode =
+           pXMLFakeRoot->GetNodeItem(IFDE_XMLNode::FirstChild);
+       pXMLNode; pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+    if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
+      if (bVerifyWellFormness) {
+        for (IFDE_XMLNode* pNextNode =
+                 pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling);
+             pNextNode;
+             pNextNode = pNextNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+          if (pNextNode->GetType() == FDE_XMLNODE_Element) {
+            return FALSE;
+          }
+        }
+      }
+      return pXMLNode;
+    }
+  }
+  return NULL;
+}
+int32_t CXFA_SimpleParser::StartParse(IFX_FileRead* pStream,
+                                      XFA_XDPPACKET ePacketID) {
+  CloseParser();
+  m_pFileRead = pStream;
+  m_pStream = IFX_Stream::CreateStream(
+      pStream, FX_STREAMACCESS_Read | FX_STREAMACCESS_Text);
+  if (m_pStream == NULL) {
+    return XFA_PARSESTATUS_StreamErr;
+  }
+  FX_WORD wCodePage = m_pStream->GetCodePage();
+  if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE &&
+      wCodePage != FX_CODEPAGE_UTF8) {
+    m_pStream->SetCodePage(FX_CODEPAGE_UTF8);
+  }
+  m_pXMLDoc = IFDE_XMLDoc::Create();
+  if (m_pXMLDoc == NULL) {
+    return XFA_PARSESTATUS_StatusErr;
+  }
+  m_pXMLParser = new CXFA_XMLParser(m_pXMLDoc->GetRoot(), m_pStream);
+  if (m_pXMLParser == NULL) {
+    return XFA_PARSESTATUS_StatusErr;
+  }
+  if (!m_pXMLDoc->LoadXML(m_pXMLParser)) {
+    return XFA_PARSESTATUS_StatusErr;
+  }
+  m_ePacketID = ePacketID;
+  return XFA_PARSESTATUS_Ready;
+}
+int32_t CXFA_SimpleParser::DoParse(IFX_Pause* pPause) {
+  if (m_pXMLDoc == NULL || m_ePacketID == XFA_XDPPACKET_UNKNOWN) {
+    return XFA_PARSESTATUS_StatusErr;
+  }
+  int32_t iRet = m_pXMLDoc->DoLoad(pPause);
+  if (iRet < 0) {
+    return XFA_PARSESTATUS_SyntaxErr;
+  }
+  if (iRet < 100) {
+    return iRet / 2;
+  }
+  m_pRootNode = ParseAsXDPPacket(XFA_FDEExtension_GetDocumentNode(m_pXMLDoc),
+                                 m_ePacketID);
+  m_pXMLDoc->CloseXML();
+  if (m_pStream) {
+    m_pStream->Release();
+    m_pStream = NULL;
+  }
+  if (!m_pRootNode) {
+    return XFA_PARSESTATUS_StatusErr;
+  }
+  return XFA_PARSESTATUS_Done;
+}
+int32_t CXFA_SimpleParser::ParseXMLData(const CFX_WideString& wsXML,
+                                        IFDE_XMLNode*& pXMLNode,
+                                        IFX_Pause* pPause) {
+  CloseParser();
+  pXMLNode = NULL;
+  IFX_Stream* pStream = XFA_CreateWideTextRead(wsXML);
+  if (!pStream) {
+    return XFA_PARSESTATUS_StreamErr;
+  }
+  m_pStream = pStream;
+  m_pXMLDoc = IFDE_XMLDoc::Create();
+  if (m_pXMLDoc == NULL) {
+    return XFA_PARSESTATUS_StatusErr;
+  }
+  CXFA_XMLParser* pParser = new CXFA_XMLParser(m_pXMLDoc->GetRoot(), m_pStream);
+  if (pParser == NULL) {
+    return XFA_PARSESTATUS_StatusErr;
+  }
+
+  pParser->m_dwCheckStatus = 0x03;
+  if (!m_pXMLDoc->LoadXML(pParser)) {
+    return XFA_PARSESTATUS_StatusErr;
+  }
+  int32_t iRet = m_pXMLDoc->DoLoad(pPause);
+  if (iRet < 0 || iRet >= 100) {
+    m_pXMLDoc->CloseXML();
+  }
+  if (iRet < 0) {
+    return XFA_PARSESTATUS_SyntaxErr;
+  }
+  if (iRet < 100) {
+    return iRet / 2;
+  }
+  if (m_pStream) {
+    m_pStream->Release();
+    m_pStream = NULL;
+  }
+  pXMLNode = XFA_FDEExtension_GetDocumentNode(m_pXMLDoc);
+  return XFA_PARSESTATUS_Done;
+}
+
+void CXFA_SimpleParser::ConstructXFANode(CXFA_Node* pXFANode,
+                                         IFDE_XMLNode* pXMLNode) {
+  XFA_XDPPACKET ePacketID = (XFA_XDPPACKET)pXFANode->GetPacketID();
+  if (ePacketID == XFA_XDPPACKET_Datasets) {
+    if (pXFANode->GetClassID() == XFA_ELEMENT_DataValue) {
+      for (IFDE_XMLNode* pXMLChild =
+               pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild);
+           pXMLChild;
+           pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+        FDE_XMLNODETYPE eNodeType = pXMLChild->GetType();
+        if (eNodeType == FDE_XMLNODE_Instruction)
+          continue;
+
+        if (eNodeType == FDE_XMLNODE_Element) {
+          CXFA_Node* pXFAChild = m_pFactory->CreateNode(XFA_XDPPACKET_Datasets,
+                                                        XFA_ELEMENT_DataValue);
+          if (!pXFAChild)
+            return;
+
+          CFX_WideString wsNodeStr;
+          ((IFDE_XMLElement*)pXMLChild)->GetLocalTagName(wsNodeStr);
+          pXFAChild->SetCData(XFA_ATTRIBUTE_Name, wsNodeStr);
+          CFX_WideString wsChildValue;
+          XFA_GetPlainTextFromRichText((IFDE_XMLElement*)pXMLChild,
+                                       wsChildValue);
+          if (!wsChildValue.IsEmpty())
+            pXFAChild->SetCData(XFA_ATTRIBUTE_Value, wsChildValue);
+
+          pXFANode->InsertChild(pXFAChild);
+          pXFAChild->SetXMLMappingNode(pXMLChild);
+          pXFAChild->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+          break;
+        }
+      }
+      m_pRootNode = pXFANode;
+    } else {
+      m_pRootNode = DataLoader(pXFANode, pXMLNode, TRUE);
+    }
+  } else if (pXFANode->GetObjectType() == XFA_OBJECTTYPE_ContentNode) {
+    ParseContentNode(pXFANode, pXMLNode, ePacketID);
+    m_pRootNode = pXFANode;
+  } else {
+    m_pRootNode = NormalLoader(pXFANode, pXMLNode, ePacketID);
+  }
+}
+
+FX_BOOL XFA_FDEExtension_ResolveNamespaceQualifier(
+    IFDE_XMLElement* pNode,
+    const CFX_WideStringC& wsQualifier,
+    CFX_WideString& wsNamespaceURI) {
+  if (!pNode) {
+    return FALSE;
+  }
+  IFDE_XMLNode* pFakeRoot = pNode->GetNodeItem(IFDE_XMLNode::Root);
+  CFX_WideString wsNSAttribute;
+  FX_BOOL bRet = FALSE;
+  if (wsQualifier.IsEmpty()) {
+    wsNSAttribute = FX_WSTRC(L"xmlns");
+    bRet = TRUE;
+  } else {
+    wsNSAttribute = FX_WSTRC(L"xmlns:") + wsQualifier;
+  }
+  for (; pNode != pFakeRoot;
+       pNode = (IFDE_XMLElement*)pNode->GetNodeItem(IFDE_XMLNode::Parent)) {
+    if (pNode->GetType() != FDE_XMLNODE_Element) {
+      continue;
+    }
+    if (pNode->HasAttribute(wsNSAttribute)) {
+      pNode->GetString(wsNSAttribute, wsNamespaceURI);
+      return TRUE;
+    }
+  }
+  wsNamespaceURI.Empty();
+  return bRet;
+}
+static inline void XFA_FDEExtension_GetElementTagNamespaceURI(
+    IFDE_XMLElement* pElement,
+    CFX_WideString& wsNamespaceURI) {
+  CFX_WideString wsNodeStr;
+  pElement->GetNamespacePrefix(wsNodeStr);
+  if (!XFA_FDEExtension_ResolveNamespaceQualifier(pElement, wsNodeStr,
+                                                  wsNamespaceURI)) {
+    wsNamespaceURI.Empty();
+  }
+}
+static FX_BOOL XFA_FDEExtension_MatchNodeName(
+    IFDE_XMLNode* pNode,
+    const CFX_WideStringC& wsLocalTagName,
+    const CFX_WideStringC& wsNamespaceURIPrefix,
+    FX_DWORD eMatchFlags = XFA_XDPPACKET_FLAGS_NOMATCH) {
+  if (!pNode || pNode->GetType() != FDE_XMLNODE_Element) {
+    return FALSE;
+  }
+  IFDE_XMLElement* pElement = reinterpret_cast<IFDE_XMLElement*>(pNode);
+  CFX_WideString wsNodeStr;
+  pElement->GetLocalTagName(wsNodeStr);
+  if (wsNodeStr != wsLocalTagName) {
+    return FALSE;
+  }
+  XFA_FDEExtension_GetElementTagNamespaceURI(pElement, wsNodeStr);
+  if (eMatchFlags & XFA_XDPPACKET_FLAGS_NOMATCH) {
+    return TRUE;
+  }
+  if (eMatchFlags & XFA_XDPPACKET_FLAGS_PREFIXMATCH) {
+    return wsNodeStr.Left(wsNamespaceURIPrefix.GetLength()) ==
+           wsNamespaceURIPrefix;
+  }
+  return wsNodeStr == wsNamespaceURIPrefix;
+}
+static FX_BOOL XFA_FDEExtension_GetAttributeLocalName(
+    const CFX_WideStringC& wsAttributeName,
+    CFX_WideString& wsLocalAttrName) {
+  CFX_WideString wsAttrName(wsAttributeName);
+  FX_STRSIZE iFind = wsAttrName.Find(L':', 0);
+  if (iFind < 0) {
+    wsLocalAttrName = wsAttrName;
+    return FALSE;
+  } else {
+    wsLocalAttrName = wsAttrName.Right(wsAttrName.GetLength() - iFind - 1);
+    return TRUE;
+  }
+}
+static FX_BOOL XFA_FDEExtension_ResolveAttribute(
+    IFDE_XMLElement* pElement,
+    const CFX_WideStringC& wsAttributeName,
+    CFX_WideString& wsLocalAttrName,
+    CFX_WideString& wsNamespaceURI) {
+  CFX_WideString wsAttrName(wsAttributeName);
+  CFX_WideString wsNSPrefix;
+  if (XFA_FDEExtension_GetAttributeLocalName(wsAttributeName,
+                                             wsLocalAttrName)) {
+    wsNSPrefix = wsAttrName.Left(wsAttributeName.GetLength() -
+                                 wsLocalAttrName.GetLength() - 1);
+  }
+  if (wsLocalAttrName == FX_WSTRC(L"xmlns") ||
+      wsNSPrefix == FX_WSTRC(L"xmlns") || wsNSPrefix == FX_WSTRC(L"xml")) {
+    return FALSE;
+  }
+  if (!XFA_FDEExtension_ResolveNamespaceQualifier(pElement, wsNSPrefix,
+                                                  wsNamespaceURI)) {
+    wsNamespaceURI.Empty();
+    return FALSE;
+  }
+  return TRUE;
+}
+static FX_BOOL XFA_FDEExtension_FindAttributeWithNS(
+    IFDE_XMLElement* pElement,
+    const CFX_WideStringC& wsLocalAttributeName,
+    const CFX_WideStringC& wsNamespaceURIPrefix,
+    CFX_WideString& wsValue,
+    FX_BOOL bMatchNSAsPrefix = FALSE) {
+  if (!pElement) {
+    return FALSE;
+  }
+  CFX_WideString wsAttrName;
+  CFX_WideString wsAttrValue;
+  CFX_WideString wsAttrNS;
+  for (int32_t iAttrCount = pElement->CountAttributes(), i = 0; i < iAttrCount;
+       i++) {
+    pElement->GetAttribute(i, wsAttrName, wsAttrValue);
+    FX_STRSIZE iFind = wsAttrName.Find(L':', 0);
+    CFX_WideString wsNSPrefix;
+    if (iFind < 0) {
+      if (wsLocalAttributeName != wsAttrName) {
+        continue;
+      }
+    } else {
+      if (wsLocalAttributeName !=
+          wsAttrName.Right(wsAttrName.GetLength() - iFind - 1)) {
+        continue;
+      }
+      wsNSPrefix = wsAttrName.Left(iFind);
+    }
+    if (!XFA_FDEExtension_ResolveNamespaceQualifier(pElement, wsNSPrefix,
+                                                    wsAttrNS)) {
+      continue;
+    }
+    if (bMatchNSAsPrefix) {
+      if (wsAttrNS.Left(wsNamespaceURIPrefix.GetLength()) !=
+          wsNamespaceURIPrefix) {
+        continue;
+      }
+    } else {
+      if (wsAttrNS != wsNamespaceURIPrefix) {
+        continue;
+      }
+    }
+    wsValue = wsAttrValue;
+    return TRUE;
+  }
+  return FALSE;
+}
+CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket(IFDE_XMLNode* pXMLDocumentNode,
+                                               XFA_XDPPACKET ePacketID) {
+  switch (ePacketID) {
+    case XFA_XDPPACKET_UNKNOWN:
+      return NULL;
+    case XFA_XDPPACKET_XDP:
+      return ParseAsXDPPacket_XDP(pXMLDocumentNode, ePacketID);
+    case XFA_XDPPACKET_Config:
+      return ParseAsXDPPacket_Config(pXMLDocumentNode, ePacketID);
+    case XFA_XDPPACKET_Template:
+    case XFA_XDPPACKET_Form:
+      return ParseAsXDPPacket_TemplateForm(pXMLDocumentNode, ePacketID);
+    case XFA_XDPPACKET_Datasets:
+      return ParseAsXDPPacket_Data(pXMLDocumentNode, ePacketID);
+    case XFA_XDPPACKET_Xdc:
+      return ParseAsXDPPacket_Xdc(pXMLDocumentNode, ePacketID);
+    case XFA_XDPPACKET_LocaleSet:
+    case XFA_XDPPACKET_ConnectionSet:
+    case XFA_XDPPACKET_SourceSet:
+      return ParseAsXDPPacket_LocaleConnectionSourceSet(pXMLDocumentNode,
+                                                        ePacketID);
+    default:
+      return ParseAsXDPPacket_User(pXMLDocumentNode, ePacketID);
+  }
+  return NULL;
+}
+CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_XDP(
+    IFDE_XMLNode* pXMLDocumentNode,
+    XFA_XDPPACKET ePacketID) {
+  if (!XFA_FDEExtension_MatchNodeName(
+          pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_XDP)->pName,
+          XFA_GetPacketByIndex(XFA_PACKET_XDP)->pURI,
+          XFA_GetPacketByIndex(XFA_PACKET_XDP)->eFlags)) {
+    return nullptr;
+  }
+  CXFA_Node* pXFARootNode =
+      m_pFactory->CreateNode(XFA_XDPPACKET_XDP, XFA_ELEMENT_Xfa);
+  if (!pXFARootNode) {
+    return nullptr;
+  }
+  m_pRootNode = pXFARootNode;
+  pXFARootNode->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L"xfa"));
+  {
+    IFDE_XMLElement* pElement = (IFDE_XMLElement*)pXMLDocumentNode;
+    int32_t iAttributeCount = pElement->CountAttributes();
+    for (int32_t i = 0; i < iAttributeCount; i++) {
+      CFX_WideString wsAttriName, wsAttriValue;
+      pElement->GetAttribute(i, wsAttriName, wsAttriValue);
+      if (wsAttriName == FX_WSTRC(L"uuid")) {
+        pXFARootNode->SetCData(XFA_ATTRIBUTE_Uuid, wsAttriValue);
+      } else if (wsAttriName == FX_WSTRC(L"timeStamp")) {
+        pXFARootNode->SetCData(XFA_ATTRIBUTE_TimeStamp, wsAttriValue);
+      }
+    }
+  }
+  IFDE_XMLNode* pXMLConfigDOMRoot = nullptr;
+  CXFA_Node* pXFAConfigDOMRoot = nullptr;
+  {
+    for (IFDE_XMLNode* pChildItem =
+             pXMLDocumentNode->GetNodeItem(IFDE_XMLNode::FirstChild);
+         pChildItem;
+         pChildItem = pChildItem->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+      const XFA_PACKETINFO* pPacketInfo =
+          XFA_GetPacketByIndex(XFA_PACKET_Config);
+      if (!XFA_FDEExtension_MatchNodeName(pChildItem, pPacketInfo->pName,
+                                          pPacketInfo->pURI,
+                                          pPacketInfo->eFlags)) {
+        continue;
+      }
+      if (pXFARootNode->GetFirstChildByName(pPacketInfo->uHash)) {
+        return nullptr;
+      }
+      pXMLConfigDOMRoot = pChildItem;
+      pXFAConfigDOMRoot =
+          ParseAsXDPPacket_Config(pXMLConfigDOMRoot, XFA_XDPPACKET_Config);
+      pXFARootNode->InsertChild(pXFAConfigDOMRoot, NULL);
+    }
+  }
+  IFDE_XMLNode* pXMLDatasetsDOMRoot = nullptr;
+  IFDE_XMLNode* pXMLFormDOMRoot = nullptr;
+  IFDE_XMLNode* pXMLTemplateDOMRoot = nullptr;
+  {
+    for (IFDE_XMLNode* pChildItem =
+             pXMLDocumentNode->GetNodeItem(IFDE_XMLNode::FirstChild);
+         pChildItem;
+         pChildItem = pChildItem->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+      if (!pChildItem || pChildItem->GetType() != FDE_XMLNODE_Element) {
+        continue;
+      }
+      if (pChildItem == pXMLConfigDOMRoot) {
+        continue;
+      }
+      IFDE_XMLElement* pElement =
+          reinterpret_cast<IFDE_XMLElement*>(pChildItem);
+      CFX_WideString wsPacketName;
+      pElement->GetLocalTagName(wsPacketName);
+      const XFA_PACKETINFO* pPacketInfo = XFA_GetPacketByName(wsPacketName);
+      if (pPacketInfo && pPacketInfo->pURI) {
+        if (!XFA_FDEExtension_MatchNodeName(pElement, pPacketInfo->pName,
+                                            pPacketInfo->pURI,
+                                            pPacketInfo->eFlags)) {
+          pPacketInfo = nullptr;
+        }
+      }
+      XFA_XDPPACKET ePacket =
+          pPacketInfo ? pPacketInfo->eName : XFA_XDPPACKET_USER;
+      if (ePacket == XFA_XDPPACKET_XDP) {
+        continue;
+      }
+      if (ePacket == XFA_XDPPACKET_Datasets) {
+        if (pXMLDatasetsDOMRoot) {
+          return nullptr;
+        }
+        pXMLDatasetsDOMRoot = pElement;
+      } else if (ePacket == XFA_XDPPACKET_Form) {
+        if (pXMLFormDOMRoot) {
+          return nullptr;
+        }
+        pXMLFormDOMRoot = pElement;
+      } else if (ePacket == XFA_XDPPACKET_Template) {
+        if (pXMLTemplateDOMRoot) {
+          // Found a duplicate template packet.
+          return nullptr;
+        }
+        CXFA_Node* pPacketNode = ParseAsXDPPacket(pElement, ePacket);
+        if (pPacketNode) {
+          pXMLTemplateDOMRoot = pElement;
+          pXFARootNode->InsertChild(pPacketNode);
+        }
+      } else {
+        CXFA_Node* pPacketNode = ParseAsXDPPacket(pElement, ePacket);
+        if (pPacketNode) {
+          if (pPacketInfo &&
+              (pPacketInfo->eFlags & XFA_XDPPACKET_FLAGS_SUPPORTONE) &&
+              pXFARootNode->GetFirstChildByName(pPacketInfo->uHash)) {
+            return nullptr;
+          }
+          pXFARootNode->InsertChild(pPacketNode);
+        }
+      }
+    }
+  }
+  if (!pXMLTemplateDOMRoot) {
+    // No template is found.
+    return nullptr;
+  }
+  if (pXMLDatasetsDOMRoot) {
+    CXFA_Node* pPacketNode =
+        ParseAsXDPPacket(pXMLDatasetsDOMRoot, XFA_XDPPACKET_Datasets);
+    if (pPacketNode) {
+      pXFARootNode->InsertChild(pPacketNode);
+    }
+  }
+  if (pXMLFormDOMRoot) {
+    CXFA_Node* pPacketNode =
+        ParseAsXDPPacket(pXMLFormDOMRoot, XFA_XDPPACKET_Form);
+    if (pPacketNode) {
+      pXFARootNode->InsertChild(pPacketNode);
+    }
+  }
+  pXFARootNode->SetXMLMappingNode(pXMLDocumentNode);
+  return pXFARootNode;
+}
+CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_Config(
+    IFDE_XMLNode* pXMLDocumentNode,
+    XFA_XDPPACKET ePacketID) {
+  if (!XFA_FDEExtension_MatchNodeName(
+          pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_Config)->pName,
+          XFA_GetPacketByIndex(XFA_PACKET_Config)->pURI,
+          XFA_GetPacketByIndex(XFA_PACKET_Config)->eFlags)) {
+    return NULL;
+  }
+  CXFA_Node* pNode =
+      m_pFactory->CreateNode(XFA_XDPPACKET_Config, XFA_ELEMENT_Config);
+  if (!pNode) {
+    return NULL;
+  }
+  pNode->SetCData(XFA_ATTRIBUTE_Name,
+                  XFA_GetPacketByIndex(XFA_PACKET_Config)->pName);
+  if (!NormalLoader(pNode, pXMLDocumentNode, ePacketID)) {
+    return NULL;
+  }
+  pNode->SetXMLMappingNode(pXMLDocumentNode);
+  return pNode;
+}
+CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_TemplateForm(
+    IFDE_XMLNode* pXMLDocumentNode,
+    XFA_XDPPACKET ePacketID) {
+  CXFA_Node* pNode = NULL;
+  if (ePacketID == XFA_XDPPACKET_Template) {
+    if (XFA_FDEExtension_MatchNodeName(
+            pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_Template)->pName,
+            XFA_GetPacketByIndex(XFA_PACKET_Template)->pURI,
+            XFA_GetPacketByIndex(XFA_PACKET_Template)->eFlags)) {
+      pNode =
+          m_pFactory->CreateNode(XFA_XDPPACKET_Template, XFA_ELEMENT_Template);
+      if (!pNode) {
+        return NULL;
+      }
+      pNode->SetCData(XFA_ATTRIBUTE_Name,
+                      XFA_GetPacketByIndex(XFA_PACKET_Template)->pName);
+      if (m_bDocumentParser) {
+        CFX_WideString wsNamespaceURI;
+        IFDE_XMLElement* pXMLDocumentElement =
+            (IFDE_XMLElement*)pXMLDocumentNode;
+        pXMLDocumentElement->GetNamespaceURI(wsNamespaceURI);
+        if (wsNamespaceURI.IsEmpty()) {
+          pXMLDocumentElement->GetString(L"xmlns:xfa", wsNamespaceURI);
+        }
+        pNode->GetDocument()->RecognizeXFAVersionNumber(wsNamespaceURI);
+      }
+      if (!NormalLoader(pNode, pXMLDocumentNode, ePacketID)) {
+        return NULL;
+      }
+    }
+  } else if (ePacketID == XFA_XDPPACKET_Form) {
+    if (XFA_FDEExtension_MatchNodeName(
+            pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_Form)->pName,
+            XFA_GetPacketByIndex(XFA_PACKET_Form)->pURI,
+            XFA_GetPacketByIndex(XFA_PACKET_Form)->eFlags)) {
+      IFDE_XMLElement* pXMLDocumentElement = (IFDE_XMLElement*)pXMLDocumentNode;
+      CFX_WideString wsChecksum;
+      pXMLDocumentElement->GetString(L"checksum", wsChecksum);
+      if (wsChecksum.GetLength() != 28 ||
+          m_pXMLParser->m_dwCheckStatus != 0x03) {
+        return NULL;
+      }
+      IXFA_ChecksumContext* pChecksum = XFA_Checksum_Create();
+      pChecksum->StartChecksum();
+      pChecksum->UpdateChecksum(m_pFileRead, m_pXMLParser->m_nStart[0],
+                                m_pXMLParser->m_nSize[0]);
+      pChecksum->UpdateChecksum(m_pFileRead, m_pXMLParser->m_nStart[1],
+                                m_pXMLParser->m_nSize[1]);
+      pChecksum->FinishChecksum();
+      CFX_ByteString bsCheck;
+      pChecksum->GetChecksum(bsCheck);
+      pChecksum->Release();
+      if (bsCheck != wsChecksum.UTF8Encode()) {
+        return NULL;
+      }
+
+      pNode = m_pFactory->CreateNode(XFA_XDPPACKET_Form, XFA_ELEMENT_Form);
+      if (!pNode) {
+        return NULL;
+      }
+      pNode->SetCData(XFA_ATTRIBUTE_Name,
+                      XFA_GetPacketByIndex(XFA_PACKET_Form)->pName);
+      pNode->SetAttribute(XFA_ATTRIBUTE_Checksum, wsChecksum);
+      CXFA_Node* pTemplateRoot =
+          m_pRootNode->GetFirstChildByClass(XFA_ELEMENT_Template);
+      CXFA_Node* pTemplateChosen =
+          pTemplateRoot
+              ? pTemplateRoot->GetFirstChildByClass(XFA_ELEMENT_Subform)
+              : NULL;
+      FX_BOOL bUseAttribute = TRUE;
+      if (pTemplateChosen &&
+          pTemplateChosen->GetEnum(XFA_ATTRIBUTE_RestoreState) !=
+              XFA_ATTRIBUTEENUM_Auto) {
+        bUseAttribute = FALSE;
+      }
+      if (!NormalLoader(pNode, pXMLDocumentNode, ePacketID, bUseAttribute)) {
+        return NULL;
+      }
+    }
+  }
+  if (pNode) {
+    pNode->SetXMLMappingNode(pXMLDocumentNode);
+  }
+  return pNode;
+}
+static IFDE_XMLNode* XFA_GetDataSetsFromXDP(IFDE_XMLNode* pXMLDocumentNode) {
+  if (XFA_FDEExtension_MatchNodeName(
+          pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pName,
+          XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pURI,
+          XFA_GetPacketByIndex(XFA_PACKET_Datasets)->eFlags)) {
+    return pXMLDocumentNode;
+  }
+  if (!XFA_FDEExtension_MatchNodeName(
+          pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_XDP)->pName,
+          XFA_GetPacketByIndex(XFA_PACKET_XDP)->pURI,
+          XFA_GetPacketByIndex(XFA_PACKET_XDP)->eFlags)) {
+    return NULL;
+  }
+  for (IFDE_XMLNode* pDatasetsNode =
+           pXMLDocumentNode->GetNodeItem(IFDE_XMLNode::FirstChild);
+       pDatasetsNode;
+       pDatasetsNode = pDatasetsNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+    if (!XFA_FDEExtension_MatchNodeName(
+            pDatasetsNode, XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pName,
+            XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pURI,
+            XFA_GetPacketByIndex(XFA_PACKET_Datasets)->eFlags)) {
+      continue;
+    }
+    return pDatasetsNode;
+  }
+  return NULL;
+}
+CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_Data(
+    IFDE_XMLNode* pXMLDocumentNode,
+    XFA_XDPPACKET ePacketID) {
+  IFDE_XMLNode* pDatasetsXMLNode = XFA_GetDataSetsFromXDP(pXMLDocumentNode);
+  if (pDatasetsXMLNode) {
+    CXFA_Node* pNode =
+        m_pFactory->CreateNode(XFA_XDPPACKET_Datasets, XFA_ELEMENT_DataModel);
+    if (!pNode) {
+      return NULL;
+    }
+    pNode->SetCData(XFA_ATTRIBUTE_Name,
+                    XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pName);
+    if (!DataLoader(pNode, pDatasetsXMLNode, FALSE)) {
+      return NULL;
+    }
+    pNode->SetXMLMappingNode(pDatasetsXMLNode);
+    return pNode;
+  }
+  IFDE_XMLNode* pDataXMLNode = NULL;
+  if (XFA_FDEExtension_MatchNodeName(
+          pXMLDocumentNode, FX_WSTRC(L"data"),
+          XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pURI,
+          XFA_GetPacketByIndex(XFA_PACKET_Datasets)->eFlags)) {
+    ((IFDE_XMLElement*)pXMLDocumentNode)->RemoveAttribute(L"xmlns:xfa");
+    pDataXMLNode = pXMLDocumentNode;
+  } else {
+    IFDE_XMLElement* pDataElement =
+        IFDE_XMLElement::Create(FX_WSTRC(L"xfa:data"));
+    IFDE_XMLNode* pParentXMLNode =
+        pXMLDocumentNode->GetNodeItem(IFDE_XMLNode::Parent);
+    if (pParentXMLNode) {
+      pParentXMLNode->RemoveChildNode(pXMLDocumentNode);
+    }
+    FXSYS_assert(pXMLDocumentNode->GetType() == FDE_XMLNODE_Element);
+    if (pXMLDocumentNode->GetType() == FDE_XMLNODE_Element) {
+      ((IFDE_XMLElement*)pXMLDocumentNode)->RemoveAttribute(L"xmlns:xfa");
+    }
+    pDataElement->InsertChildNode(pXMLDocumentNode);
+    pDataXMLNode = pDataElement;
+  }
+  if (pDataXMLNode) {
+    CXFA_Node* pNode =
+        m_pFactory->CreateNode(XFA_XDPPACKET_Datasets, XFA_ELEMENT_DataGroup);
+    if (!pNode) {
+      if (pDataXMLNode != pXMLDocumentNode) {
+        pDataXMLNode->Release();
+      }
+      return NULL;
+    }
+    CFX_WideString wsLocalName;
+    ((IFDE_XMLElement*)pDataXMLNode)->GetLocalTagName(wsLocalName);
+    pNode->SetCData(XFA_ATTRIBUTE_Name, wsLocalName);
+    if (!DataLoader(pNode, pDataXMLNode, TRUE)) {
+      return NULL;
+    }
+    pNode->SetXMLMappingNode(pDataXMLNode);
+    if (pDataXMLNode != pXMLDocumentNode) {
+      pNode->SetFlag(XFA_NODEFLAG_OwnXMLNode, TRUE, FALSE);
+    }
+    return pNode;
+  }
+  return NULL;
+}
+CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_LocaleConnectionSourceSet(
+    IFDE_XMLNode* pXMLDocumentNode,
+    XFA_XDPPACKET ePacketID) {
+  CXFA_Node* pNode = NULL;
+  if (ePacketID == XFA_XDPPACKET_LocaleSet) {
+    if (XFA_FDEExtension_MatchNodeName(
+            pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_LocaleSet)->pName,
+            XFA_GetPacketByIndex(XFA_PACKET_LocaleSet)->pURI,
+            XFA_GetPacketByIndex(XFA_PACKET_LocaleSet)->eFlags)) {
+      pNode = m_pFactory->CreateNode(XFA_XDPPACKET_LocaleSet,
+                                     XFA_ELEMENT_LocaleSet);
+      if (!pNode) {
+        return NULL;
+      }
+      pNode->SetCData(XFA_ATTRIBUTE_Name,
+                      XFA_GetPacketByIndex(XFA_PACKET_LocaleSet)->pName);
+      if (!NormalLoader(pNode, pXMLDocumentNode, ePacketID)) {
+        return NULL;
+      }
+    }
+  } else if (ePacketID == XFA_XDPPACKET_ConnectionSet) {
+    if (XFA_FDEExtension_MatchNodeName(
+            pXMLDocumentNode,
+            XFA_GetPacketByIndex(XFA_PACKET_ConnectionSet)->pName,
+            XFA_GetPacketByIndex(XFA_PACKET_ConnectionSet)->pURI,
+            XFA_GetPacketByIndex(XFA_PACKET_ConnectionSet)->eFlags)) {
+      pNode = m_pFactory->CreateNode(XFA_XDPPACKET_ConnectionSet,
+                                     XFA_ELEMENT_ConnectionSet);
+      if (!pNode) {
+        return NULL;
+      }
+      pNode->SetCData(XFA_ATTRIBUTE_Name,
+                      XFA_GetPacketByIndex(XFA_PACKET_ConnectionSet)->pName);
+      if (!NormalLoader(pNode, pXMLDocumentNode, ePacketID)) {
+        return NULL;
+      }
+    }
+  } else if (ePacketID == XFA_XDPPACKET_SourceSet) {
+    if (XFA_FDEExtension_MatchNodeName(
+            pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_SourceSet)->pName,
+            XFA_GetPacketByIndex(XFA_PACKET_SourceSet)->pURI,
+            XFA_GetPacketByIndex(XFA_PACKET_SourceSet)->eFlags)) {
+      pNode = m_pFactory->CreateNode(XFA_XDPPACKET_SourceSet,
+                                     XFA_ELEMENT_SourceSet);
+      if (!pNode) {
+        return NULL;
+      }
+      pNode->SetCData(XFA_ATTRIBUTE_Name,
+                      XFA_GetPacketByIndex(XFA_PACKET_SourceSet)->pName);
+      if (!NormalLoader(pNode, pXMLDocumentNode, ePacketID)) {
+        return NULL;
+      }
+    }
+  }
+  if (pNode) {
+    pNode->SetXMLMappingNode(pXMLDocumentNode);
+  }
+  return pNode;
+}
+CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_Xdc(
+    IFDE_XMLNode* pXMLDocumentNode,
+    XFA_XDPPACKET ePacketID) {
+  if (XFA_FDEExtension_MatchNodeName(
+          pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_Xdc)->pName,
+          XFA_GetPacketByIndex(XFA_PACKET_Xdc)->pURI,
+          XFA_GetPacketByIndex(XFA_PACKET_Xdc)->eFlags)) {
+    CXFA_Node* pNode =
+        m_pFactory->CreateNode(XFA_XDPPACKET_Xdc, XFA_ELEMENT_Xdc);
+    if (!pNode) {
+      return NULL;
+    }
+    pNode->SetCData(XFA_ATTRIBUTE_Name,
+                    XFA_GetPacketByIndex(XFA_PACKET_Xdc)->pName);
+    pNode->SetXMLMappingNode(pXMLDocumentNode);
+    return pNode;
+  }
+  return NULL;
+}
+CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_User(
+    IFDE_XMLNode* pXMLDocumentNode,
+    XFA_XDPPACKET ePacketID) {
+  CXFA_Node* pNode =
+      m_pFactory->CreateNode(XFA_XDPPACKET_XDP, XFA_ELEMENT_Packet);
+  if (!pNode) {
+    return NULL;
+  }
+  CFX_WideString wsName;
+  ((IFDE_XMLElement*)pXMLDocumentNode)->GetLocalTagName(wsName);
+  pNode->SetCData(XFA_ATTRIBUTE_Name, wsName);
+  if (!UserPacketLoader(pNode, pXMLDocumentNode)) {
+    return NULL;
+  }
+  pNode->SetXMLMappingNode(pXMLDocumentNode);
+  return pNode;
+}
+CXFA_Node* CXFA_SimpleParser::UserPacketLoader(CXFA_Node* pXFANode,
+                                               IFDE_XMLNode* pXMLDoc) {
+  return pXFANode;
+}
+static FX_BOOL XFA_FDEExtension_IsStringAllWhitespace(CFX_WideString wsText) {
+  wsText.TrimRight(L"\x20\x9\xD\xA");
+  return wsText.IsEmpty();
+}
+CXFA_Node* CXFA_SimpleParser::DataLoader(CXFA_Node* pXFANode,
+                                         IFDE_XMLNode* pXMLDoc,
+                                         FX_BOOL bDoTransform) {
+  ParseDataGroup(pXFANode, pXMLDoc, XFA_XDPPACKET_Datasets);
+  return pXFANode;
+}
+CXFA_Node* CXFA_SimpleParser::NormalLoader(CXFA_Node* pXFANode,
+                                           IFDE_XMLNode* pXMLDoc,
+                                           XFA_XDPPACKET ePacketID,
+                                           FX_BOOL bUseAttribute) {
+  FX_BOOL bOneOfPropertyFound = FALSE;
+  for (IFDE_XMLNode* pXMLChild = pXMLDoc->GetNodeItem(IFDE_XMLNode::FirstChild);
+       pXMLChild;
+       pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+    switch (pXMLChild->GetType()) {
+      case FDE_XMLNODE_Element: {
+        IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLChild;
+        CFX_WideString wsTagName;
+        pXMLElement->GetLocalTagName(wsTagName);
+        const XFA_ELEMENTINFO* pElemInfo = XFA_GetElementByName(wsTagName);
+        if (!pElemInfo) {
+          continue;
+        }
+        const XFA_PROPERTY* pPropertyInfo = XFA_GetPropertyOfElement(
+            pXFANode->GetClassID(), pElemInfo->eName, ePacketID);
+        if (pPropertyInfo &&
+            ((pPropertyInfo->uFlags &
+              (XFA_PROPERTYFLAG_OneOf | XFA_PROPERTYFLAG_DefaultOneOf)) != 0)) {
+          if (bOneOfPropertyFound) {
+            break;
+          }
+          bOneOfPropertyFound = TRUE;
+        }
+        CXFA_Node* pXFAChild =
+            m_pFactory->CreateNode(ePacketID, pElemInfo->eName);
+        if (pXFAChild == NULL) {
+          return NULL;
+        }
+        if (ePacketID == XFA_XDPPACKET_Config) {
+          pXFAChild->SetAttribute(XFA_ATTRIBUTE_Name, wsTagName);
+        }
+        FX_BOOL IsNeedValue = TRUE;
+        for (int32_t i = 0, count = pXMLElement->CountAttributes(); i < count;
+             i++) {
+          CFX_WideString wsAttrQualifiedName;
+          CFX_WideString wsAttrName;
+          CFX_WideString wsAttrValue;
+          pXMLElement->GetAttribute(i, wsAttrQualifiedName, wsAttrValue);
+          XFA_FDEExtension_GetAttributeLocalName(wsAttrQualifiedName,
+                                                 wsAttrName);
+          if (wsAttrName == FX_WSTRC(L"nil") &&
+              wsAttrValue == FX_WSTRC(L"true")) {
+            IsNeedValue = FALSE;
+          }
+          const XFA_ATTRIBUTEINFO* lpAttrInfo =
+              XFA_GetAttributeByName(wsAttrName);
+          if (!lpAttrInfo) {
+            continue;
+          }
+          if (!bUseAttribute && lpAttrInfo->eName != XFA_ATTRIBUTE_Name &&
+              lpAttrInfo->eName != XFA_ATTRIBUTE_Save) {
+            continue;
+          }
+          pXFAChild->SetAttribute(lpAttrInfo->eName, wsAttrValue);
+        }
+        pXFANode->InsertChild(pXFAChild);
+        if (pElemInfo->eName == XFA_ELEMENT_Validate ||
+            pElemInfo->eName == XFA_ELEMENT_Locale) {
+          if (ePacketID == XFA_XDPPACKET_Config) {
+            ParseContentNode(pXFAChild, pXMLElement, ePacketID);
+          } else {
+            NormalLoader(pXFAChild, pXMLElement, ePacketID, bUseAttribute);
+          }
+          break;
+        }
+        switch (pXFAChild->GetObjectType()) {
+          case XFA_OBJECTTYPE_ContentNode:
+          case XFA_OBJECTTYPE_TextNode:
+          case XFA_OBJECTTYPE_NodeC:
+          case XFA_OBJECTTYPE_NodeV:
+            if (IsNeedValue) {
+              ParseContentNode(pXFAChild, pXMLElement, ePacketID);
+            }
+            break;
+          default:
+            NormalLoader(pXFAChild, pXMLElement, ePacketID, bUseAttribute);
+            break;
+        }
+      } break;
+      case FDE_XMLNODE_Instruction:
+        ParseInstruction(pXFANode, (IFDE_XMLInstruction*)pXMLChild, ePacketID);
+        break;
+      default:
+        break;
+    }
+  }
+  return pXFANode;
+}
+FX_BOOL XFA_RecognizeRichText(IFDE_XMLElement* pRichTextXMLNode) {
+  if (pRichTextXMLNode) {
+    CFX_WideString wsNamespaceURI;
+    XFA_FDEExtension_GetElementTagNamespaceURI(pRichTextXMLNode,
+                                               wsNamespaceURI);
+    if (wsNamespaceURI == FX_WSTRC(L"http://www.w3.org/1999/xhtml")) {
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+class RichTextNodeVisitor {
+ public:
+  static inline IFDE_XMLNode* GetFirstChild(IFDE_XMLNode* pNode) {
+    return pNode->GetNodeItem(IFDE_XMLNode::FirstChild);
+  }
+  static inline IFDE_XMLNode* GetNextSibling(IFDE_XMLNode* pNode) {
+    return pNode->GetNodeItem(IFDE_XMLNode::NextSibling);
+  }
+  static inline IFDE_XMLNode* GetParent(IFDE_XMLNode* pNode) {
+    return pNode->GetNodeItem(IFDE_XMLNode::Parent);
+  }
+};
+
+void XFA_ConvertXMLToPlainText(IFDE_XMLElement* pRootXMLNode,
+                               CFX_WideString& wsOutput) {
+  for (IFDE_XMLNode* pXMLChild =
+           pRootXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild);
+       pXMLChild;
+       pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+    switch (pXMLChild->GetType()) {
+      case FDE_XMLNODE_Element: {
+        CFX_WideString wsTextData;
+        ((IFDE_XMLElement*)pXMLChild)->GetTextData(wsTextData);
+        wsTextData += FX_WSTRC(L"\n");
+        wsOutput += wsTextData;
+      } break;
+      case FDE_XMLNODE_Text: {
+        CFX_WideString wsText;
+        ((IFDE_XMLText*)pXMLChild)->GetText(wsText);
+        if (XFA_FDEExtension_IsStringAllWhitespace(wsText)) {
+          continue;
+        } else {
+          wsOutput = wsText;
+        }
+      } break;
+      case FDE_XMLNODE_CharData: {
+        CFX_WideString wsCharData;
+        ((IFDE_XMLCharData*)pXMLChild)->GetCharData(wsCharData);
+        if (XFA_FDEExtension_IsStringAllWhitespace(wsCharData)) {
+          continue;
+        } else {
+          wsOutput = wsCharData;
+        }
+      } break;
+      default:
+        FXSYS_assert(FALSE);
+        break;
+    }
+  }
+}
+
+void CXFA_SimpleParser::ParseContentNode(CXFA_Node* pXFANode,
+                                         IFDE_XMLNode* pXMLNode,
+                                         XFA_XDPPACKET ePacketID) {
+  XFA_ELEMENT element = XFA_ELEMENT_Sharptext;
+  if (pXFANode->GetClassID() == XFA_ELEMENT_ExData) {
+    CFX_WideStringC wsContentType =
+        pXFANode->GetCData(XFA_ATTRIBUTE_ContentType);
+    if (wsContentType == FX_WSTRC(L"text/html"))
+      element = XFA_ELEMENT_SharpxHTML;
+    else if (wsContentType == FX_WSTRC(L"text/xml"))
+      element = XFA_ELEMENT_Sharpxml;
+  }
+  if (element == XFA_ELEMENT_SharpxHTML)
+    pXFANode->SetXMLMappingNode(pXMLNode);
+
+  CFX_WideString wsValue;
+  for (IFDE_XMLNode* pXMLChild =
+           pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild);
+       pXMLChild;
+       pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+    FDE_XMLNODETYPE eNodeType = pXMLChild->GetType();
+    if (eNodeType == FDE_XMLNODE_Instruction)
+      continue;
+
+    if (element == XFA_ELEMENT_SharpxHTML) {
+      if (eNodeType != FDE_XMLNODE_Element)
+        break;
+
+      if (XFA_RecognizeRichText((IFDE_XMLElement*)pXMLChild))
+        XFA_GetPlainTextFromRichText((IFDE_XMLElement*)pXMLChild, wsValue);
+    } else if (element == XFA_ELEMENT_Sharpxml) {
+      if (eNodeType != FDE_XMLNODE_Element)
+        break;
+      XFA_ConvertXMLToPlainText((IFDE_XMLElement*)pXMLChild, wsValue);
+    } else {
+      if (eNodeType == FDE_XMLNODE_Element)
+        break;
+      if (eNodeType == FDE_XMLNODE_Text)
+        ((IFDE_XMLText*)pXMLChild)->GetText(wsValue);
+      else if (eNodeType == FDE_XMLNODE_CharData)
+        ((IFDE_XMLCharData*)pXMLChild)->GetCharData(wsValue);
+    }
+    break;
+  }
+  if (!wsValue.IsEmpty()) {
+    if (pXFANode->GetObjectType() == XFA_OBJECTTYPE_ContentNode) {
+      CXFA_Node* pContentRawDataNode =
+          m_pFactory->CreateNode(ePacketID, element);
+      FXSYS_assert(pContentRawDataNode);
+      pContentRawDataNode->SetCData(XFA_ATTRIBUTE_Value, wsValue);
+      pXFANode->InsertChild(pContentRawDataNode);
+    } else {
+      pXFANode->SetCData(XFA_ATTRIBUTE_Value, wsValue);
+    }
+  }
+}
+
+void CXFA_SimpleParser::ParseDataGroup(CXFA_Node* pXFANode,
+                                       IFDE_XMLNode* pXMLNode,
+                                       XFA_XDPPACKET ePacketID) {
+  for (IFDE_XMLNode* pXMLChild =
+           pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild);
+       pXMLChild;
+       pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+    switch (pXMLChild->GetType()) {
+      case FDE_XMLNODE_Element: {
+        IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLChild;
+        {
+          CFX_WideString wsNamespaceURI;
+          XFA_FDEExtension_GetElementTagNamespaceURI(pXMLElement,
+                                                     wsNamespaceURI);
+          if (wsNamespaceURI ==
+                  FX_WSTRC(L"http://www.xfa.com/schema/xfa-package/") ||
+              wsNamespaceURI ==
+                  FX_WSTRC(L"http://www.xfa.org/schema/xfa-package/") ||
+              wsNamespaceURI ==
+                  FX_WSTRC(L"http://www.w3.org/2001/XMLSchema-instance")) {
+            continue;
+          }
+          if (0) {
+            continue;
+          }
+        }
+        XFA_ELEMENT eNodeType = XFA_ELEMENT_DataModel;
+        if (eNodeType == XFA_ELEMENT_DataModel) {
+          CFX_WideString wsDataNodeAttr;
+          if (XFA_FDEExtension_FindAttributeWithNS(
+                  pXMLElement, FX_WSTRC(L"dataNode"),
+                  FX_WSTRC(L"http://www.xfa.org/schema/xfa-data/1.0/"),
+                  wsDataNodeAttr)) {
+            if (wsDataNodeAttr == FX_WSTRC(L"dataGroup")) {
+              eNodeType = XFA_ELEMENT_DataGroup;
+            } else if (wsDataNodeAttr == FX_WSTRC(L"dataValue")) {
+              eNodeType = XFA_ELEMENT_DataValue;
+            }
+          }
+        }
+        CFX_WideString wsContentType;
+        if (eNodeType == XFA_ELEMENT_DataModel) {
+          if (XFA_FDEExtension_FindAttributeWithNS(
+                  pXMLElement, FX_WSTRC(L"contentType"),
+                  FX_WSTRC(L"http://www.xfa.org/schema/xfa-data/1.0/"),
+                  wsContentType)) {
+            if (!wsContentType.IsEmpty()) {
+              eNodeType = XFA_ELEMENT_DataValue;
+            }
+          }
+        }
+        if (eNodeType == XFA_ELEMENT_DataModel) {
+          for (IFDE_XMLNode* pXMLDataChild =
+                   pXMLElement->GetNodeItem(IFDE_XMLNode::FirstChild);
+               pXMLDataChild; pXMLDataChild = pXMLDataChild->GetNodeItem(
+                                  IFDE_XMLNode::NextSibling)) {
+            if (pXMLDataChild->GetType() == FDE_XMLNODE_Element) {
+              if (!XFA_RecognizeRichText((IFDE_XMLElement*)pXMLDataChild)) {
+                eNodeType = XFA_ELEMENT_DataGroup;
+                break;
+              }
+            }
+          }
+        }
+        if (eNodeType == XFA_ELEMENT_DataModel) {
+          eNodeType = XFA_ELEMENT_DataValue;
+        }
+        CXFA_Node* pXFAChild =
+            m_pFactory->CreateNode(XFA_XDPPACKET_Datasets, eNodeType);
+        if (pXFAChild == NULL) {
+          return;
+        }
+        CFX_WideString wsNodeName;
+        pXMLElement->GetLocalTagName(wsNodeName);
+        pXFAChild->SetCData(XFA_ATTRIBUTE_Name, wsNodeName);
+        FX_BOOL bNeedValue = TRUE;
+        if (1) {
+          for (int32_t i = 0, count = pXMLElement->CountAttributes(); i < count;
+               i++) {
+            CFX_WideString wsAttrQualifiedName;
+            CFX_WideString wsAttrValue;
+            CFX_WideString wsAttrName;
+            CFX_WideString wsAttrNamespaceURI;
+            pXMLElement->GetAttribute(i, wsAttrQualifiedName, wsAttrValue);
+            if (!XFA_FDEExtension_ResolveAttribute(
+                    pXMLElement, wsAttrQualifiedName, wsAttrName,
+                    wsAttrNamespaceURI)) {
+              continue;
+            }
+            if (wsAttrName == FX_WSTRC(L"nil") &&
+                wsAttrValue == FX_WSTRC(L"true")) {
+              bNeedValue = FALSE;
+              continue;
+            }
+            if (wsAttrNamespaceURI ==
+                    FX_WSTRC(L"http://www.xfa.com/schema/xfa-package/") ||
+                wsAttrNamespaceURI ==
+                    FX_WSTRC(L"http://www.xfa.org/schema/xfa-package/") ||
+                wsAttrNamespaceURI ==
+                    FX_WSTRC(L"http://www.w3.org/2001/XMLSchema-instance") ||
+                wsAttrNamespaceURI ==
+                    FX_WSTRC(L"http://www.xfa.org/schema/xfa-data/1.0/")) {
+              continue;
+            }
+            if (0) {
+              continue;
+            }
+            CXFA_Node* pXFAMetaData = m_pFactory->CreateNode(
+                XFA_XDPPACKET_Datasets, XFA_ELEMENT_DataValue);
+            if (pXFAMetaData == NULL) {
+              return;
+            }
+            pXFAMetaData->SetCData(XFA_ATTRIBUTE_Name, wsAttrName);
+            pXFAMetaData->SetCData(XFA_ATTRIBUTE_QualifiedName,
+                                   wsAttrQualifiedName);
+            pXFAMetaData->SetCData(XFA_ATTRIBUTE_Value, wsAttrValue);
+            pXFAMetaData->SetEnum(XFA_ATTRIBUTE_Contains,
+                                  XFA_ATTRIBUTEENUM_MetaData);
+            pXFAChild->InsertChild(pXFAMetaData);
+            pXFAMetaData->SetXMLMappingNode(pXMLElement);
+            pXFAMetaData->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+          }
+          if (!bNeedValue) {
+            CFX_WideString wsNilName = FX_WSTRC(L"xsi:nil");
+            pXMLElement->RemoveAttribute(wsNilName);
+          }
+        }
+        pXFANode->InsertChild(pXFAChild);
+        if (eNodeType == XFA_ELEMENT_DataGroup) {
+          ParseDataGroup(pXFAChild, pXMLElement, ePacketID);
+        } else {
+          if (bNeedValue) {
+            ParseDataValue(pXFAChild, pXMLChild, XFA_XDPPACKET_Datasets);
+          }
+        }
+        pXFAChild->SetXMLMappingNode(pXMLElement);
+        pXFAChild->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+      }
+        continue;
+      case FDE_XMLNODE_CharData: {
+        IFDE_XMLCharData* pXMLCharData = (IFDE_XMLCharData*)pXMLChild;
+        CFX_WideString wsCharData;
+        pXMLCharData->GetCharData(wsCharData);
+        if (XFA_FDEExtension_IsStringAllWhitespace(wsCharData)) {
+          continue;
+        }
+        CXFA_Node* pXFAChild = m_pFactory->CreateNode(XFA_XDPPACKET_Datasets,
+                                                      XFA_ELEMENT_DataValue);
+        if (pXFAChild == NULL) {
+          return;
+        }
+        pXFAChild->SetCData(XFA_ATTRIBUTE_Value, wsCharData);
+        pXFANode->InsertChild(pXFAChild);
+        pXFAChild->SetXMLMappingNode(pXMLCharData);
+        pXFAChild->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+      }
+        continue;
+      case FDE_XMLNODE_Text: {
+        IFDE_XMLText* pXMLText = (IFDE_XMLText*)pXMLChild;
+        CFX_WideString wsText;
+        pXMLText->GetText(wsText);
+        if (XFA_FDEExtension_IsStringAllWhitespace(wsText)) {
+          continue;
+        }
+        CXFA_Node* pXFAChild = m_pFactory->CreateNode(XFA_XDPPACKET_Datasets,
+                                                      XFA_ELEMENT_DataValue);
+        if (pXFAChild == NULL) {
+          return;
+        }
+        pXFAChild->SetCData(XFA_ATTRIBUTE_Value, wsText);
+        pXFANode->InsertChild(pXFAChild);
+        pXFAChild->SetXMLMappingNode(pXMLText);
+        pXFAChild->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+      }
+        continue;
+      case FDE_XMLNODE_Instruction:
+        continue;
+      default:
+        continue;
+    }
+  }
+}
+
+void CXFA_SimpleParser::ParseDataValue(CXFA_Node* pXFANode,
+                                       IFDE_XMLNode* pXMLNode,
+                                       XFA_XDPPACKET ePacketID) {
+  CFX_WideTextBuf wsValueTextBuf;
+  CFX_WideTextBuf wsCurValueTextBuf;
+  FX_BOOL bMarkAsCompound = FALSE;
+  IFDE_XMLNode* pXMLCurValueNode = nullptr;
+  for (IFDE_XMLNode* pXMLChild =
+           pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild);
+       pXMLChild;
+       pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+    FDE_XMLNODETYPE eNodeType = pXMLChild->GetType();
+    if (eNodeType == FDE_XMLNODE_Instruction)
+      continue;
+
+    CFX_WideString wsText;
+    if (eNodeType == FDE_XMLNODE_Text) {
+      ((IFDE_XMLText*)pXMLChild)->GetText(wsText);
+      if (!pXMLCurValueNode)
+        pXMLCurValueNode = pXMLChild;
+
+      wsCurValueTextBuf << wsText;
+    } else if (eNodeType == FDE_XMLNODE_CharData) {
+      ((IFDE_XMLCharData*)pXMLChild)->GetCharData(wsText);
+      if (!pXMLCurValueNode)
+        pXMLCurValueNode = pXMLChild;
+
+      wsCurValueTextBuf << wsText;
+    } else if (XFA_RecognizeRichText((IFDE_XMLElement*)pXMLChild)) {
+      XFA_GetPlainTextFromRichText((IFDE_XMLElement*)pXMLChild, wsText);
+      if (!pXMLCurValueNode)
+        pXMLCurValueNode = pXMLChild;
+
+      wsCurValueTextBuf << wsText;
+    } else {
+      bMarkAsCompound = TRUE;
+      if (pXMLCurValueNode) {
+        CFX_WideStringC wsCurValue = wsCurValueTextBuf.GetWideString();
+        if (!wsCurValue.IsEmpty()) {
+          CXFA_Node* pXFAChild =
+              m_pFactory->CreateNode(ePacketID, XFA_ELEMENT_DataValue);
+          if (!pXFAChild)
+            return;
+
+          pXFAChild->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L""));
+          pXFAChild->SetCData(XFA_ATTRIBUTE_Value, wsCurValue);
+          pXFANode->InsertChild(pXFAChild);
+          pXFAChild->SetXMLMappingNode(pXMLCurValueNode);
+          pXFAChild->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+          wsValueTextBuf << wsCurValue;
+          wsCurValueTextBuf.Clear();
+        }
+        pXMLCurValueNode = nullptr;
+      }
+      CXFA_Node* pXFAChild =
+          m_pFactory->CreateNode(ePacketID, XFA_ELEMENT_DataValue);
+      if (!pXFAChild)
+        return;
+
+      CFX_WideString wsNodeStr;
+      ((IFDE_XMLElement*)pXMLChild)->GetLocalTagName(wsNodeStr);
+      pXFAChild->SetCData(XFA_ATTRIBUTE_Name, wsNodeStr);
+      ParseDataValue(pXFAChild, pXMLChild, ePacketID);
+      pXFANode->InsertChild(pXFAChild);
+      pXFAChild->SetXMLMappingNode(pXMLChild);
+      pXFAChild->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+      CFX_WideStringC wsCurValue = pXFAChild->GetCData(XFA_ATTRIBUTE_Value);
+      wsValueTextBuf << wsCurValue;
+    }
+  }
+  if (pXMLCurValueNode) {
+    CFX_WideStringC wsCurValue = wsCurValueTextBuf.GetWideString();
+    if (!wsCurValue.IsEmpty()) {
+      if (bMarkAsCompound) {
+        CXFA_Node* pXFAChild =
+            m_pFactory->CreateNode(ePacketID, XFA_ELEMENT_DataValue);
+        if (!pXFAChild)
+          return;
+
+        pXFAChild->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L""));
+        pXFAChild->SetCData(XFA_ATTRIBUTE_Value, wsCurValue);
+        pXFANode->InsertChild(pXFAChild);
+        pXFAChild->SetXMLMappingNode(pXMLCurValueNode);
+        pXFAChild->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+      }
+      wsValueTextBuf << wsCurValue;
+      wsCurValueTextBuf.Clear();
+    }
+    pXMLCurValueNode = nullptr;
+  }
+  CFX_WideStringC wsNodeValue = wsValueTextBuf.GetWideString();
+  pXFANode->SetCData(XFA_ATTRIBUTE_Value, wsNodeValue);
+}
+
+void CXFA_SimpleParser::ParseInstruction(CXFA_Node* pXFANode,
+                                         IFDE_XMLInstruction* pXMLInstruction,
+                                         XFA_XDPPACKET ePacketID) {
+  if (!m_bDocumentParser) {
+    return;
+  }
+  CFX_WideString wsTargetName;
+  pXMLInstruction->GetTargetName(wsTargetName);
+  if (wsTargetName == FX_WSTRC(L"originalXFAVersion")) {
+    CFX_WideString wsData;
+    if (pXMLInstruction->GetData(0, wsData) &&
+        (pXFANode->GetDocument()->RecognizeXFAVersionNumber(wsData) !=
+         XFA_VERSION_UNKNOWN)) {
+      wsData.Empty();
+      if (pXMLInstruction->GetData(1, wsData) &&
+          wsData == FX_WSTRC(L"v2.7-scripting:1")) {
+        pXFANode->GetDocument()->SetFlag(XFA_DOCFLAG_Scripting, TRUE);
+      }
+    }
+  } else if (wsTargetName == FX_WSTRC(L"acrobat")) {
+    CFX_WideString wsData;
+    if (pXMLInstruction->GetData(0, wsData) &&
+        wsData == FX_WSTRC(L"JavaScript")) {
+      if (pXMLInstruction->GetData(1, wsData) &&
+          wsData == FX_WSTRC(L"strictScoping")) {
+        pXFANode->GetDocument()->SetFlag(XFA_DOCFLAG_StrictScoping, TRUE);
+      }
+    }
+  }
+}
+void CXFA_SimpleParser::CloseParser() {
+  if (m_pXMLDoc) {
+    m_pXMLDoc->Release();
+    m_pXMLDoc = NULL;
+  }
+  if (m_pStream) {
+    m_pStream->Release();
+    m_pStream = NULL;
+  }
+}
+IXFA_DocParser* IXFA_DocParser::Create(IXFA_Notify* pNotify) {
+  return new CXFA_DocumentParser(pNotify);
+}
+CXFA_DocumentParser::CXFA_DocumentParser(IXFA_Notify* pNotify)
+    : m_nodeParser(NULL, TRUE), m_pNotify(pNotify), m_pDocument(NULL) {}
+CXFA_DocumentParser::~CXFA_DocumentParser() {
+  CloseParser();
+}
+int32_t CXFA_DocumentParser::StartParse(IFX_FileRead* pStream,
+                                        XFA_XDPPACKET ePacketID) {
+  CloseParser();
+  int32_t nRetStatus = m_nodeParser.StartParse(pStream, ePacketID);
+  if (nRetStatus == XFA_PARSESTATUS_Ready) {
+    m_pDocument = new CXFA_Document(this);
+    m_nodeParser.SetFactory(m_pDocument);
+  }
+  return nRetStatus;
+}
+int32_t CXFA_DocumentParser::DoParse(IFX_Pause* pPause) {
+  int32_t nRetStatus = m_nodeParser.DoParse(pPause);
+  if (nRetStatus >= XFA_PARSESTATUS_Done) {
+    FXSYS_assert(m_pDocument);
+    m_pDocument->SetRoot(m_nodeParser.GetRootNode());
+  }
+  return nRetStatus;
+}
+int32_t CXFA_DocumentParser::ParseXMLData(const CFX_WideString& wsXML,
+                                          IFDE_XMLNode*& pXMLNode,
+                                          IFX_Pause* pPause) {
+  CloseParser();
+  int32_t nRetStatus = m_nodeParser.ParseXMLData(wsXML, pXMLNode, NULL);
+  if (nRetStatus == XFA_PARSESTATUS_Done && pXMLNode) {
+    m_pDocument = new CXFA_Document(this);
+    m_nodeParser.SetFactory(m_pDocument);
+  }
+  return nRetStatus;
+}
+void CXFA_DocumentParser::ConstructXFANode(CXFA_Node* pXFANode,
+                                           IFDE_XMLNode* pXMLNode) {
+  if (!pXFANode || !pXMLNode) {
+    return;
+  }
+  m_nodeParser.ConstructXFANode(pXFANode, pXMLNode);
+  CXFA_Node* pRootNode = m_nodeParser.GetRootNode();
+  if (m_pDocument && pRootNode) {
+    m_pDocument->SetRoot(pRootNode);
+  }
+}
+void CXFA_DocumentParser::CloseParser() {
+  if (m_pDocument) {
+    delete m_pDocument;
+    m_pDocument = NULL;
+  }
+  m_nodeParser.CloseParser();
+}
+CXFA_XMLParser::CXFA_XMLParser(IFDE_XMLNode* pRoot, IFX_Stream* pStream)
+    : m_nElementStart(0),
+      m_dwCheckStatus(0),
+      m_dwCurrentCheckStatus(0),
+      m_pRoot(pRoot),
+      m_pStream(pStream),
+      m_pParser(nullptr),
+      m_pParent(pRoot),
+      m_pChild(nullptr),
+      m_NodeStack(16),
+      m_dwStatus(FDE_XMLSYNTAXSTATUS_None) {
+  ASSERT(m_pParent && m_pStream);
+  m_NodeStack.Push(m_pParent);
+  m_pParser = IFDE_XMLSyntaxParser::Create();
+  m_pParser->Init(m_pStream, 32 * 1024, 1024 * 1024);
+}
+CXFA_XMLParser::~CXFA_XMLParser() {
+  if (m_pParser) {
+    m_pParser->Release();
+  }
+  m_NodeStack.RemoveAll();
+  m_ws1.Empty();
+  m_ws2.Empty();
+}
+int32_t CXFA_XMLParser::DoParser(IFX_Pause* pPause) {
+  if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error) {
+    return -1;
+  }
+  if (m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) {
+    return 100;
+  }
+  int32_t iCount = 0;
+  while (TRUE) {
+    m_dwStatus = m_pParser->DoSyntaxParse();
+    switch (m_dwStatus) {
+      case FDE_XMLSYNTAXSTATUS_InstructionOpen:
+        break;
+      case FDE_XMLSYNTAXSTATUS_InstructionClose:
+        if (m_pChild) {
+          if (m_pChild->GetType() != FDE_XMLNODE_Instruction) {
+            m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+            break;
+          }
+        }
+        m_pChild = m_pParent;
+        break;
+      case FDE_XMLSYNTAXSTATUS_ElementOpen:
+        if (m_dwCheckStatus != 0x03 && m_NodeStack.GetSize() == 2) {
+          m_nElementStart = m_pParser->GetCurrentPos() - 1;
+        }
+        break;
+      case FDE_XMLSYNTAXSTATUS_ElementBreak:
+        break;
+      case FDE_XMLSYNTAXSTATUS_ElementClose:
+        if (m_pChild->GetType() != FDE_XMLNODE_Element) {
+          m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+          break;
+        }
+        m_pParser->GetTagName(m_ws1);
+        ((IFDE_XMLElement*)m_pChild)->GetTagName(m_ws2);
+        if (m_ws1.GetLength() > 0 && !m_ws1.Equal(m_ws2)) {
+          m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+          break;
+        }
+        m_NodeStack.Pop();
+        if (m_NodeStack.GetSize() < 1) {
+          m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+          break;
+        } else if (m_dwCurrentCheckStatus != 0 && m_NodeStack.GetSize() == 2) {
+          m_nSize[m_dwCurrentCheckStatus - 1] =
+              m_pParser->GetCurrentBinaryPos() -
+              m_nStart[m_dwCurrentCheckStatus - 1];
+          m_dwCurrentCheckStatus = 0;
+        }
+
+        m_pParent = (IFDE_XMLNode*)*m_NodeStack.GetTopElement();
+        m_pChild = m_pParent;
+        iCount++;
+        break;
+      case FDE_XMLSYNTAXSTATUS_TargetName:
+        m_pParser->GetTargetName(m_ws1);
+        if (m_ws1 == FX_WSTRC(L"originalXFAVersion") ||
+            m_ws1 == FX_WSTRC(L"acrobat")) {
+          m_pChild = IFDE_XMLInstruction::Create(m_ws1);
+          m_pParent->InsertChildNode(m_pChild);
+        } else {
+          m_pChild = NULL;
+        }
+        m_ws1.Empty();
+        break;
+      case FDE_XMLSYNTAXSTATUS_TagName:
+        m_pParser->GetTagName(m_ws1);
+        m_pChild = IFDE_XMLElement::Create(m_ws1);
+        m_pParent->InsertChildNode(m_pChild);
+        m_NodeStack.Push(m_pChild);
+        m_pParent = m_pChild;
+
+        if (m_dwCheckStatus != 0x03 && m_NodeStack.GetSize() == 3) {
+          CFX_WideString wsTag;
+          ((IFDE_XMLElement*)m_pChild)->GetLocalTagName(wsTag);
+          if (wsTag == FX_WSTRC(L"template")) {
+            m_dwCheckStatus |= 0x01;
+            m_dwCurrentCheckStatus = 0x01;
+            m_nStart[0] = m_pParser->GetCurrentBinaryPos() -
+                          (m_pParser->GetCurrentPos() - m_nElementStart);
+          } else if (wsTag == FX_WSTRC(L"datasets")) {
+            m_dwCheckStatus |= 0x02;
+            m_dwCurrentCheckStatus = 0x02;
+            m_nStart[1] = m_pParser->GetCurrentBinaryPos() -
+                          (m_pParser->GetCurrentPos() - m_nElementStart);
+          }
+        }
+        break;
+      case FDE_XMLSYNTAXSTATUS_AttriName:
+        m_pParser->GetAttributeName(m_ws1);
+        break;
+      case FDE_XMLSYNTAXSTATUS_AttriValue:
+        if (m_pChild) {
+          m_pParser->GetAttributeName(m_ws2);
+          if (m_pChild->GetType() == FDE_XMLNODE_Element) {
+            ((IFDE_XMLElement*)m_pChild)->SetString(m_ws1, m_ws2);
+          }
+        }
+        m_ws1.Empty();
+        break;
+      case FDE_XMLSYNTAXSTATUS_Text:
+        m_pParser->GetTextData(m_ws1);
+        m_pChild = IFDE_XMLText::Create(m_ws1);
+        m_pParent->InsertChildNode(m_pChild);
+        m_pChild = m_pParent;
+        break;
+      case FDE_XMLSYNTAXSTATUS_CData:
+        m_pParser->GetTextData(m_ws1);
+        m_pChild = IFDE_XMLCharData::Create(m_ws1);
+        m_pParent->InsertChildNode(m_pChild);
+        m_pChild = m_pParent;
+        break;
+      case FDE_XMLSYNTAXSTATUS_TargetData:
+        if (m_pChild) {
+          if (m_pChild->GetType() != FDE_XMLNODE_Instruction) {
+            m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+            break;
+          }
+          if (!m_ws1.IsEmpty()) {
+            ((IFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1);
+          }
+          m_pParser->GetTargetData(m_ws1);
+          ((IFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1);
+        }
+        m_ws1.Empty();
+        break;
+      default:
+        break;
+    }
+    if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error ||
+        m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) {
+      break;
+    }
+    if (pPause && iCount > 500 && pPause->NeedToPauseNow()) {
+      break;
+    }
+  }
+  return (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || m_NodeStack.GetSize() != 1)
+             ? -1
+             : m_pParser->GetStatus();
+}
diff --git a/xfa/fxfa/parser/xfa_parser_imp.h b/xfa/fxfa/parser/xfa_parser_imp.h
new file mode 100644
index 0000000..136cae6
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_parser_imp.h
@@ -0,0 +1,138 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_PARSER_IMP_H_
+#define XFA_FXFA_PARSER_XFA_PARSER_IMP_H_
+
+#include "xfa/fxfa/parser/xfa_parser.h"
+
+class CXFA_XMLParser;
+
+class CXFA_SimpleParser : public IXFA_Parser {
+ public:
+  CXFA_SimpleParser(IXFA_ObjFactory* pFactory, FX_BOOL bDocumentParser = FALSE);
+  ~CXFA_SimpleParser();
+  virtual void Release() { delete this; }
+
+  virtual int32_t StartParse(IFX_FileRead* pStream,
+                             XFA_XDPPACKET ePacketID = XFA_XDPPACKET_XDP);
+  virtual int32_t DoParse(IFX_Pause* pPause = NULL);
+  virtual int32_t ParseXMLData(const CFX_WideString& wsXML,
+                               IFDE_XMLNode*& pXMLNode,
+                               IFX_Pause* pPause = NULL);
+  virtual void ConstructXFANode(CXFA_Node* pXFANode, IFDE_XMLNode* pXMLNode);
+  virtual IXFA_ObjFactory* GetFactory() const { return m_pFactory; }
+  virtual CXFA_Node* GetRootNode() const { return m_pRootNode; }
+  virtual IFDE_XMLDoc* GetXMLDoc() const { return m_pXMLDoc; }
+  virtual void CloseParser();
+
+ protected:
+  CXFA_Node* ParseAsXDPPacket(IFDE_XMLNode* pXMLDocumentNode,
+                              XFA_XDPPACKET ePacketID);
+  CXFA_Node* ParseAsXDPPacket_XDP(IFDE_XMLNode* pXMLDocumentNode,
+                                  XFA_XDPPACKET ePacketID);
+  CXFA_Node* ParseAsXDPPacket_Config(IFDE_XMLNode* pXMLDocumentNode,
+                                     XFA_XDPPACKET ePacketID);
+  CXFA_Node* ParseAsXDPPacket_TemplateForm(IFDE_XMLNode* pXMLDocumentNode,
+                                           XFA_XDPPACKET ePacketID);
+  CXFA_Node* ParseAsXDPPacket_Data(IFDE_XMLNode* pXMLDocumentNode,
+                                   XFA_XDPPACKET ePacketID);
+  CXFA_Node* ParseAsXDPPacket_LocaleConnectionSourceSet(
+      IFDE_XMLNode* pXMLDocumentNode,
+      XFA_XDPPACKET ePacketID);
+  CXFA_Node* ParseAsXDPPacket_Xdc(IFDE_XMLNode* pXMLDocumentNode,
+                                  XFA_XDPPACKET ePacketID);
+  CXFA_Node* ParseAsXDPPacket_User(IFDE_XMLNode* pXMLDocumentNode,
+                                   XFA_XDPPACKET ePacketID);
+  CXFA_Node* NormalLoader(CXFA_Node* pXFANode,
+                          IFDE_XMLNode* pXMLDoc,
+                          XFA_XDPPACKET ePacketID,
+                          FX_BOOL bUseAttribute = TRUE);
+  CXFA_Node* DataLoader(CXFA_Node* pXFANode,
+                        IFDE_XMLNode* pXMLDoc,
+                        FX_BOOL bDoTransform);
+  CXFA_Node* UserPacketLoader(CXFA_Node* pXFANode, IFDE_XMLNode* pXMLDoc);
+  void ParseContentNode(CXFA_Node* pXFANode,
+                        IFDE_XMLNode* pXMLNode,
+                        XFA_XDPPACKET ePacketID);
+  void ParseDataValue(CXFA_Node* pXFANode,
+                      IFDE_XMLNode* pXMLNode,
+                      XFA_XDPPACKET ePacketID);
+  void ParseDataGroup(CXFA_Node* pXFANode,
+                      IFDE_XMLNode* pXMLNode,
+                      XFA_XDPPACKET ePacketID);
+  void ParseInstruction(CXFA_Node* pXFANode,
+                        IFDE_XMLInstruction* pXMLInstruction,
+                        XFA_XDPPACKET ePacketID);
+  void SetFactory(IXFA_ObjFactory* pFactory);
+
+  CXFA_XMLParser* m_pXMLParser;
+  IFDE_XMLDoc* m_pXMLDoc;
+  IFX_Stream* m_pStream;
+  IFX_FileRead* m_pFileRead;
+  IXFA_ObjFactory* m_pFactory;
+  CXFA_Node* m_pRootNode;
+  XFA_XDPPACKET m_ePacketID;
+  FX_BOOL m_bDocumentParser;
+  friend class CXFA_DocumentParser;
+};
+
+class CXFA_DocumentParser : public IXFA_DocParser {
+ public:
+  CXFA_DocumentParser(IXFA_Notify* pNotify);
+  ~CXFA_DocumentParser();
+  virtual void Release() { delete this; }
+  virtual int32_t StartParse(IFX_FileRead* pStream,
+                             XFA_XDPPACKET ePacketID = XFA_XDPPACKET_XDP);
+  virtual int32_t DoParse(IFX_Pause* pPause = NULL);
+  virtual int32_t ParseXMLData(const CFX_WideString& wsXML,
+                               IFDE_XMLNode*& pXMLNode,
+                               IFX_Pause* pPause = NULL);
+  virtual void ConstructXFANode(CXFA_Node* pXFANode, IFDE_XMLNode* pXMLNode);
+  virtual IXFA_ObjFactory* GetFactory() const {
+    return m_nodeParser.GetFactory();
+  }
+  virtual CXFA_Node* GetRootNode() const { return m_nodeParser.GetRootNode(); }
+  virtual IFDE_XMLDoc* GetXMLDoc() const { return m_nodeParser.GetXMLDoc(); }
+  virtual IXFA_Notify* GetNotify() const { return m_pNotify; }
+  virtual CXFA_Document* GetDocument() const { return m_pDocument; }
+  virtual void CloseParser();
+
+ protected:
+  CXFA_SimpleParser m_nodeParser;
+  IXFA_Notify* m_pNotify;
+  CXFA_Document* m_pDocument;
+};
+typedef CFX_StackTemplate<IFDE_XMLNode*> CXFA_XMLNodeStack;
+
+class CXFA_XMLParser : public IFDE_XMLParser {
+ public:
+  CXFA_XMLParser(IFDE_XMLNode* pRoot, IFX_Stream* pStream);
+  ~CXFA_XMLParser();
+
+  virtual void Release() { delete this; }
+  virtual int32_t DoParser(IFX_Pause* pPause);
+
+  FX_FILESIZE m_nStart[2];
+  size_t m_nSize[2];
+  FX_FILESIZE m_nElementStart;
+  FX_WORD m_dwCheckStatus;
+  FX_WORD m_dwCurrentCheckStatus;
+
+ protected:
+  IFDE_XMLNode* m_pRoot;
+  IFX_Stream* m_pStream;
+  IFDE_XMLSyntaxParser* m_pParser;
+
+  IFDE_XMLNode* m_pParent;
+  IFDE_XMLNode* m_pChild;
+  CXFA_XMLNodeStack m_NodeStack;
+  CFX_WideString m_ws1;
+  CFX_WideString m_ws2;
+  FX_DWORD m_dwStatus;
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_PARSER_IMP_H_
diff --git a/xfa/fxfa/parser/xfa_parser_imp_embeddertest.cpp b/xfa/fxfa/parser/xfa_parser_imp_embeddertest.cpp
new file mode 100644
index 0000000..63fe272
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_parser_imp_embeddertest.cpp
@@ -0,0 +1,15 @@
+// Copyright 2015 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "testing/embedder_test.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class XFAParserImpEmbeddertest : public EmbedderTest {};
+
+TEST_F(XFAParserImpEmbeddertest, Bug_216) {
+  EXPECT_TRUE(OpenDocument("bug_216.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  EXPECT_NE(nullptr, page);
+  UnloadPage(page);
+}
diff --git a/xfa/fxfa/parser/xfa_script.h b/xfa/fxfa/parser/xfa_script.h
new file mode 100644
index 0000000..6d8f3a0
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script.h
@@ -0,0 +1,121 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_SCRIPT_H_
+#define XFA_FXFA_PARSER_XFA_SCRIPT_H_
+
+#include "xfa/include/fxfa/fxfa.h"
+#include "xfa/include/fxfa/fxfa_objectacc.h"
+
+#define XFA_RESOLVENODE_Children 0x0001
+#define XFA_RESOLVENODE_Attributes 0x0004
+#define XFA_RESOLVENODE_Properties 0x0008
+#define XFA_RESOLVENODE_Siblings 0x0020
+#define XFA_RESOLVENODE_Parent 0x0040
+#define XFA_RESOLVENODE_AnyChild 0x0080
+#define XFA_RESOLVENODE_ALL 0x0100
+#define XFA_RESOLVENODE_CreateNode 0x0400
+#define XFA_RESOLVENODE_Bind 0x0800
+#define XFA_RESOLVENODE_BindNew 0x1000
+
+enum XFA_SCRIPTLANGTYPE {
+  XFA_SCRIPTLANGTYPE_Formcalc = XFA_SCRIPTTYPE_Formcalc,
+  XFA_SCRIPTLANGTYPE_Javascript = XFA_SCRIPTTYPE_Javascript,
+  XFA_SCRIPTLANGTYPE_Unkown = XFA_SCRIPTTYPE_Unkown,
+};
+
+enum XFA_RESOVENODE_RSTYPE {
+  XFA_RESOVENODE_RSTYPE_Nodes,
+  XFA_RESOVENODE_RSTYPE_Attribute,
+  XFA_RESOLVENODE_RSTYPE_CreateNodeOne,
+  XFA_RESOLVENODE_RSTYPE_CreateNodeAll,
+  XFA_RESOLVENODE_RSTYPE_CreateNodeMidAll,
+  XFA_RESOVENODE_RSTYPE_ExistNodes,
+};
+
+class CXFA_HVALUEArray : public CFX_ArrayTemplate<FXJSE_HVALUE> {
+ public:
+  CXFA_HVALUEArray(FXJSE_HRUNTIME hRunTime) : m_hRunTime(hRunTime) {}
+  ~CXFA_HVALUEArray() {
+    for (int32_t i = 0; i < GetSize(); i++) {
+      FXJSE_Value_Release(GetAt(i));
+    }
+  }
+  void GetAttributeObject(CXFA_ObjArray& objArray) {
+    for (int32_t i = 0; i < GetSize(); i++) {
+      CXFA_Object* pObject = (CXFA_Object*)FXJSE_Value_ToObject(GetAt(i), NULL);
+      objArray.Add(pObject);
+    }
+  }
+  FXJSE_HRUNTIME m_hRunTime;
+};
+
+struct XFA_RESOLVENODE_RS {
+  XFA_RESOLVENODE_RS()
+      : dwFlags(XFA_RESOVENODE_RSTYPE_Nodes), pScriptAttribute(NULL) {}
+  ~XFA_RESOLVENODE_RS() { nodes.RemoveAll(); }
+  int32_t GetAttributeResult(CXFA_HVALUEArray& hValueArray) const {
+    if (pScriptAttribute && pScriptAttribute->eValueType == XFA_SCRIPT_Object) {
+      FXJSE_HRUNTIME hRunTime = hValueArray.m_hRunTime;
+      for (int32_t i = 0; i < nodes.GetSize(); i++) {
+        FXJSE_HVALUE hValue = FXJSE_Value_Create(hRunTime);
+        (nodes[i]->*(pScriptAttribute->lpfnCallback))(
+            hValue, FALSE, (XFA_ATTRIBUTE)pScriptAttribute->eAttribute);
+        hValueArray.Add(hValue);
+      }
+    }
+    return hValueArray.GetSize();
+  }
+
+  CXFA_ObjArray nodes;
+  XFA_RESOVENODE_RSTYPE dwFlags;
+  const XFA_SCRIPTATTRIBUTEINFO* pScriptAttribute;
+};
+
+struct XFA_JSBUILTININFO {
+  uint32_t uUnicodeHash;
+  const FX_CHAR* pName;
+};
+
+const XFA_JSBUILTININFO* XFA_GetJSBuiltinByHash(uint32_t uHashCode);
+
+class IXFA_ScriptContext {
+ public:
+  virtual ~IXFA_ScriptContext() {}
+  virtual void Release() = 0;
+  virtual void Initialize(FXJSE_HRUNTIME hRuntime) = 0;
+
+  virtual void SetEventParam(CXFA_EventParam param) = 0;
+  virtual CXFA_EventParam* GetEventParam() = 0;
+  virtual FX_BOOL RunScript(XFA_SCRIPTLANGTYPE eScriptType,
+                            const CFX_WideStringC& wsScript,
+                            FXJSE_HVALUE hRetValue,
+                            CXFA_Object* pThisObject = NULL) = 0;
+  virtual int32_t ResolveObjects(CXFA_Object* refNode,
+                                 const CFX_WideStringC& wsExpression,
+                                 XFA_RESOLVENODE_RS& resolveNodeRS,
+                                 FX_DWORD dwStyles = XFA_RESOLVENODE_Children,
+                                 CXFA_Node* bindNode = NULL) = 0;
+  virtual FXJSE_HVALUE GetJSValueFromMap(CXFA_Object* pObject) = 0;
+  virtual void CacheList(CXFA_NodeList* pList) = 0;
+  virtual CXFA_Object* GetThisObject() const = 0;
+  virtual FXJSE_HRUNTIME GetRuntime() const = 0;
+  virtual int32_t GetIndexByName(CXFA_Node* refNode) = 0;
+  virtual int32_t GetIndexByClassName(CXFA_Node* refNode) = 0;
+  virtual void GetSomExpression(CXFA_Node* refNode,
+                                CFX_WideString& wsExpression) = 0;
+
+  virtual void SetNodesOfRunScript(CXFA_NodeArray* pArray) = 0;
+  virtual void AddNodesOfRunScript(const CXFA_NodeArray& nodes) = 0;
+  virtual void AddNodesOfRunScript(CXFA_Node* pNode) = 0;
+  virtual FXJSE_HCLASS GetJseNormalClass() = 0;
+  virtual XFA_SCRIPTLANGTYPE GetType() = 0;
+  virtual void SetRunAtType(XFA_ATTRIBUTEENUM eRunAt) = 0;
+  virtual FX_BOOL IsRunAtClient() = 0;
+};
+IXFA_ScriptContext* XFA_ScriptContext_Create(CXFA_Document* pDocument);
+
+#endif  // XFA_FXFA_PARSER_XFA_SCRIPT_H_
diff --git a/xfa/fxfa/parser/xfa_script_datawindow.cpp b/xfa/fxfa/parser/xfa_script_datawindow.cpp
new file mode 100644
index 0000000..9c771e6
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script_datawindow.cpp
@@ -0,0 +1,47 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_script_datawindow.h"
+
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+CScript_DataWindow::CScript_DataWindow(CXFA_Document* pDocument)
+    : CXFA_OrdinaryObject(pDocument, XFA_ELEMENT_DataWindow) {
+  m_uScriptHash = XFA_HASHCODE_DataWindow;
+}
+CScript_DataWindow::~CScript_DataWindow() {}
+void CScript_DataWindow::Script_DataWindow_MoveCurrentRecord(
+    CFXJSE_Arguments* pArguments) {}
+void CScript_DataWindow::Script_DataWindow_Record(
+    CFXJSE_Arguments* pArguments) {}
+void CScript_DataWindow::Script_DataWindow_GotoRecord(
+    CFXJSE_Arguments* pArguments) {}
+void CScript_DataWindow::Script_DataWindow_IsRecordGroup(
+    CFXJSE_Arguments* pArguments) {}
+void CScript_DataWindow::Script_DataWindow_RecordsBefore(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {}
+void CScript_DataWindow::Script_DataWindow_CurrentRecordNumber(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {}
+void CScript_DataWindow::Script_DataWindow_RecordsAfter(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {}
+void CScript_DataWindow::Script_DataWindow_IsDefined(FXJSE_HVALUE hValue,
+                                                     FX_BOOL bSetting,
+                                                     XFA_ATTRIBUTE eAttribute) {
+}
diff --git a/xfa/fxfa/parser/xfa_script_datawindow.h b/xfa/fxfa/parser/xfa_script_datawindow.h
new file mode 100644
index 0000000..9974e11
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script_datawindow.h
@@ -0,0 +1,34 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_SCRIPT_DATAWINDOW_H_
+#define XFA_FXFA_PARSER_XFA_SCRIPT_DATAWINDOW_H_
+
+#include "xfa/fxfa/parser/xfa_object.h"
+
+class CScript_DataWindow : public CXFA_OrdinaryObject {
+ public:
+  CScript_DataWindow(CXFA_Document* pDocument);
+  virtual ~CScript_DataWindow();
+  void Script_DataWindow_MoveCurrentRecord(CFXJSE_Arguments* pArguments);
+  void Script_DataWindow_Record(CFXJSE_Arguments* pArguments);
+  void Script_DataWindow_GotoRecord(CFXJSE_Arguments* pArguments);
+  void Script_DataWindow_IsRecordGroup(CFXJSE_Arguments* pArguments);
+  void Script_DataWindow_RecordsBefore(FXJSE_HVALUE hValue,
+                                       FX_BOOL bSetting,
+                                       XFA_ATTRIBUTE eAttribute);
+  void Script_DataWindow_CurrentRecordNumber(FXJSE_HVALUE hValue,
+                                             FX_BOOL bSetting,
+                                             XFA_ATTRIBUTE eAttribute);
+  void Script_DataWindow_RecordsAfter(FXJSE_HVALUE hValue,
+                                      FX_BOOL bSetting,
+                                      XFA_ATTRIBUTE eAttribute);
+  void Script_DataWindow_IsDefined(FXJSE_HVALUE hValue,
+                                   FX_BOOL bSetting,
+                                   XFA_ATTRIBUTE eAttribute);
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_SCRIPT_DATAWINDOW_H_
diff --git a/xfa/fxfa/parser/xfa_script_eventpseudomodel.cpp b/xfa/fxfa/parser/xfa_script_eventpseudomodel.cpp
new file mode 100644
index 0000000..4e1cb22
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script_eventpseudomodel.cpp
@@ -0,0 +1,269 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_script_eventpseudomodel.h"
+
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+CScript_EventPseudoModel::CScript_EventPseudoModel(CXFA_Document* pDocument)
+    : CXFA_OrdinaryObject(pDocument, XFA_ELEMENT_EventPseudoModel) {
+  m_uScriptHash = XFA_HASHCODE_Event;
+}
+CScript_EventPseudoModel::~CScript_EventPseudoModel() {}
+void Script_EventPseudoModel_StringProperty(FXJSE_HVALUE hValue,
+                                            CFX_WideString& wsValue,
+                                            FX_BOOL bSetting) {
+  if (bSetting) {
+    CFX_ByteString bsValue;
+    FXJSE_Value_ToUTF8String(hValue, bsValue);
+    wsValue = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+  } else {
+    FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsValue));
+  }
+}
+void Script_EventPseudoModel_InterProperty(FXJSE_HVALUE hValue,
+                                           int32_t& iValue,
+                                           FX_BOOL bSetting) {
+  if (bSetting) {
+    iValue = FXJSE_Value_ToInteger(hValue);
+  } else {
+    FXJSE_Value_SetInteger(hValue, iValue);
+  }
+}
+void Script_EventPseudoModel_BooleanProperty(FXJSE_HVALUE hValue,
+                                             FX_BOOL& bValue,
+                                             FX_BOOL bSetting) {
+  if (bSetting) {
+    bValue = FXJSE_Value_ToBoolean(hValue);
+  } else {
+    FXJSE_Value_SetBoolean(hValue, bValue);
+  }
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_Property(
+    FXJSE_HVALUE hValue,
+    FX_DWORD dwFlag,
+    FX_BOOL bSetting) {
+  IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+  if (!pScriptContext) {
+    return;
+  }
+  CXFA_EventParam* pEventParam = pScriptContext->GetEventParam();
+  if (!pEventParam) {
+    return;
+  }
+  switch (dwFlag) {
+    case XFA_EVENT_CANCELACTION:
+      Script_EventPseudoModel_BooleanProperty(
+          hValue, pEventParam->m_bCancelAction, bSetting);
+      break;
+    case XFA_EVENT_CHANGE:
+      Script_EventPseudoModel_StringProperty(hValue, pEventParam->m_wsChange,
+                                             bSetting);
+      break;
+    case XFA_EVENT_COMMITKEY:
+      Script_EventPseudoModel_InterProperty(hValue, pEventParam->m_iCommitKey,
+                                            bSetting);
+      break;
+    case XFA_EVENT_FULLTEXT:
+      Script_EventPseudoModel_StringProperty(hValue, pEventParam->m_wsFullText,
+                                             bSetting);
+      break;
+    case XFA_EVENT_KEYDOWN:
+      Script_EventPseudoModel_BooleanProperty(hValue, pEventParam->m_bKeyDown,
+                                              bSetting);
+      break;
+    case XFA_EVENT_MODIFIER:
+      Script_EventPseudoModel_BooleanProperty(hValue, pEventParam->m_bModifier,
+                                              bSetting);
+      break;
+    case XFA_EVENT_NEWCONTENTTYPE:
+      Script_EventPseudoModel_StringProperty(
+          hValue, pEventParam->m_wsNewContentType, bSetting);
+      break;
+    case XFA_EVENT_NEWTEXT:
+      Script_EventPseudoModel_StringProperty(hValue, pEventParam->m_wsNewText,
+                                             bSetting);
+      break;
+    case XFA_EVENT_PREVCONTENTTYPE:
+      Script_EventPseudoModel_StringProperty(
+          hValue, pEventParam->m_wsPrevContentType, bSetting);
+      break;
+    case XFA_EVENT_PREVTEXT:
+      Script_EventPseudoModel_StringProperty(hValue, pEventParam->m_wsPrevText,
+                                             bSetting);
+      break;
+    case XFA_EVENT_REENTER:
+      Script_EventPseudoModel_BooleanProperty(hValue, pEventParam->m_bReenter,
+                                              bSetting);
+      break;
+    case XFA_EVENT_SELEND:
+      Script_EventPseudoModel_InterProperty(hValue, pEventParam->m_iSelEnd,
+                                            bSetting);
+      break;
+    case XFA_EVENT_SELSTART:
+      Script_EventPseudoModel_InterProperty(hValue, pEventParam->m_iSelStart,
+                                            bSetting);
+      break;
+    case XFA_EVENT_SHIFT:
+      Script_EventPseudoModel_BooleanProperty(hValue, pEventParam->m_bShift,
+                                              bSetting);
+      break;
+    case XFA_EVENT_SOAPFAULTCODE:
+      Script_EventPseudoModel_StringProperty(
+          hValue, pEventParam->m_wsSoapFaultCode, bSetting);
+      break;
+    case XFA_EVENT_SOAPFAULTSTRING:
+      Script_EventPseudoModel_StringProperty(
+          hValue, pEventParam->m_wsSoapFaultString, bSetting);
+      break;
+    case XFA_EVENT_TARGET:
+      break;
+    default:
+      break;
+  }
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_CancelAction(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  Script_EventPseudoModel_Property(hValue, XFA_EVENT_CANCELACTION, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_Change(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  Script_EventPseudoModel_Property(hValue, XFA_EVENT_CHANGE, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_CommitKey(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  Script_EventPseudoModel_Property(hValue, XFA_EVENT_COMMITKEY, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_FullText(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  Script_EventPseudoModel_Property(hValue, XFA_EVENT_FULLTEXT, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_KeyDown(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  Script_EventPseudoModel_Property(hValue, XFA_EVENT_KEYDOWN, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_Modifier(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  Script_EventPseudoModel_Property(hValue, XFA_EVENT_MODIFIER, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_NewContentType(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  Script_EventPseudoModel_Property(hValue, XFA_EVENT_NEWCONTENTTYPE, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_NewText(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  Script_EventPseudoModel_Property(hValue, XFA_EVENT_NEWTEXT, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_PrevContentType(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  Script_EventPseudoModel_Property(hValue, XFA_EVENT_PREVCONTENTTYPE, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_PrevText(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  Script_EventPseudoModel_Property(hValue, XFA_EVENT_PREVTEXT, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_Reenter(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  Script_EventPseudoModel_Property(hValue, XFA_EVENT_REENTER, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_SelEnd(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  Script_EventPseudoModel_Property(hValue, XFA_EVENT_SELEND, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_SelStart(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  Script_EventPseudoModel_Property(hValue, XFA_EVENT_SELSTART, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_Shift(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  Script_EventPseudoModel_Property(hValue, XFA_EVENT_SHIFT, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_SoapFaultCode(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  Script_EventPseudoModel_Property(hValue, XFA_EVENT_SOAPFAULTCODE, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_SoapFaultString(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  Script_EventPseudoModel_Property(hValue, XFA_EVENT_SOAPFAULTSTRING, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_Target(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  Script_EventPseudoModel_Property(hValue, XFA_EVENT_TARGET, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_Emit(
+    CFXJSE_Arguments* pArguments) {
+  IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+  if (!pScriptContext) {
+    return;
+  }
+  CXFA_EventParam* pEventParam = pScriptContext->GetEventParam();
+  if (!pEventParam) {
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_WidgetHandler* pWidgetHandler = pNotify->GetWidgetHandler();
+  if (!pWidgetHandler) {
+    return;
+  }
+  pWidgetHandler->ProcessEvent(pEventParam->m_pTarget, pEventParam);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_Reset(
+    CFXJSE_Arguments* pArguments) {
+  IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+  if (!pScriptContext) {
+    return;
+  }
+  CXFA_EventParam* pEventParam = pScriptContext->GetEventParam();
+  if (!pEventParam) {
+    return;
+  }
+  pEventParam->Reset();
+}
diff --git a/xfa/fxfa/parser/xfa_script_eventpseudomodel.h b/xfa/fxfa/parser/xfa_script_eventpseudomodel.h
new file mode 100644
index 0000000..e1db83a
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script_eventpseudomodel.h
@@ -0,0 +1,96 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_SCRIPT_EVENTPSEUDOMODEL_H_
+#define XFA_FXFA_PARSER_XFA_SCRIPT_EVENTPSEUDOMODEL_H_
+
+#include "xfa/fxfa/parser/xfa_object.h"
+
+#define XFA_EVENT_CHANGE 0
+#define XFA_EVENT_COMMITKEY 1
+#define XFA_EVENT_FULLTEXT 2
+#define XFA_EVENT_KEYDOWN 3
+#define XFA_EVENT_MODIFIER 4
+#define XFA_EVENT_NEWCONTENTTYPE 5
+#define XFA_EVENT_NEWTEXT 6
+#define XFA_EVENT_PREVCONTENTTYPE 7
+#define XFA_EVENT_PREVTEXT 8
+#define XFA_EVENT_REENTER 9
+#define XFA_EVENT_SELEND 10
+#define XFA_EVENT_SELSTART 11
+#define XFA_EVENT_SHIFT 12
+#define XFA_EVENT_SOAPFAULTCODE 13
+#define XFA_EVENT_SOAPFAULTSTRING 14
+#define XFA_EVENT_TARGET 15
+#define XFA_EVENT_CANCELACTION 16
+
+class CScript_EventPseudoModel : public CXFA_OrdinaryObject {
+ public:
+  explicit CScript_EventPseudoModel(CXFA_Document* pDocument);
+  virtual ~CScript_EventPseudoModel();
+
+  void Script_EventPseudoModel_CancelAction(FXJSE_HVALUE hValue,
+                                            FX_BOOL bSetting,
+                                            XFA_ATTRIBUTE eAttribute);
+  void Script_EventPseudoModel_Change(FXJSE_HVALUE hValue,
+                                      FX_BOOL bSetting,
+                                      XFA_ATTRIBUTE eAttribute);
+  void Script_EventPseudoModel_CommitKey(FXJSE_HVALUE hValue,
+                                         FX_BOOL bSetting,
+                                         XFA_ATTRIBUTE eAttribute);
+  void Script_EventPseudoModel_FullText(FXJSE_HVALUE hValue,
+                                        FX_BOOL bSetting,
+                                        XFA_ATTRIBUTE eAttribute);
+  void Script_EventPseudoModel_KeyDown(FXJSE_HVALUE hValue,
+                                       FX_BOOL bSetting,
+                                       XFA_ATTRIBUTE eAttribute);
+  void Script_EventPseudoModel_Modifier(FXJSE_HVALUE hValue,
+                                        FX_BOOL bSetting,
+                                        XFA_ATTRIBUTE eAttribute);
+  void Script_EventPseudoModel_NewContentType(FXJSE_HVALUE hValue,
+                                              FX_BOOL bSetting,
+                                              XFA_ATTRIBUTE eAttribute);
+  void Script_EventPseudoModel_NewText(FXJSE_HVALUE hValue,
+                                       FX_BOOL bSetting,
+                                       XFA_ATTRIBUTE eAttribute);
+  void Script_EventPseudoModel_PrevContentType(FXJSE_HVALUE hValue,
+                                               FX_BOOL bSetting,
+                                               XFA_ATTRIBUTE eAttribute);
+  void Script_EventPseudoModel_PrevText(FXJSE_HVALUE hValue,
+                                        FX_BOOL bSetting,
+                                        XFA_ATTRIBUTE eAttribute);
+  void Script_EventPseudoModel_Reenter(FXJSE_HVALUE hValue,
+                                       FX_BOOL bSetting,
+                                       XFA_ATTRIBUTE eAttribute);
+  void Script_EventPseudoModel_SelEnd(FXJSE_HVALUE hValue,
+                                      FX_BOOL bSetting,
+                                      XFA_ATTRIBUTE eAttribute);
+  void Script_EventPseudoModel_SelStart(FXJSE_HVALUE hValue,
+                                        FX_BOOL bSetting,
+                                        XFA_ATTRIBUTE eAttribute);
+  void Script_EventPseudoModel_Shift(FXJSE_HVALUE hValue,
+                                     FX_BOOL bSetting,
+                                     XFA_ATTRIBUTE eAttribute);
+  void Script_EventPseudoModel_SoapFaultCode(FXJSE_HVALUE hValue,
+                                             FX_BOOL bSetting,
+                                             XFA_ATTRIBUTE eAttribute);
+  void Script_EventPseudoModel_SoapFaultString(FXJSE_HVALUE hValue,
+                                               FX_BOOL bSetting,
+                                               XFA_ATTRIBUTE eAttribute);
+  void Script_EventPseudoModel_Target(FXJSE_HVALUE hValue,
+                                      FX_BOOL bSetting,
+                                      XFA_ATTRIBUTE eAttribute);
+
+  void Script_EventPseudoModel_Emit(CFXJSE_Arguments* pArguments);
+  void Script_EventPseudoModel_Reset(CFXJSE_Arguments* pArguments);
+
+ protected:
+  void Script_EventPseudoModel_Property(FXJSE_HVALUE hValue,
+                                        FX_DWORD dwFlag,
+                                        FX_BOOL bSetting);
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_SCRIPT_EVENTPSEUDOMODEL_H_
diff --git a/xfa/fxfa/parser/xfa_script_hostpseudomodel.cpp b/xfa/fxfa/parser/xfa_script_hostpseudomodel.cpp
new file mode 100644
index 0000000..1f5886b
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script_hostpseudomodel.cpp
@@ -0,0 +1,800 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_script_hostpseudomodel.h"
+
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+CScript_HostPseudoModel::CScript_HostPseudoModel(CXFA_Document* pDocument)
+    : CXFA_OrdinaryObject(pDocument, XFA_ELEMENT_HostPseudoModel) {
+  m_uScriptHash = XFA_HASHCODE_Host;
+}
+CScript_HostPseudoModel::~CScript_HostPseudoModel() {}
+void CScript_HostPseudoModel::Script_HostPseudoModel_LoadString(
+    FXJSE_HVALUE hValue,
+    IXFA_Notify* pNotify,
+    FX_DWORD dwFlag) {
+  CFX_WideString wsValue;
+  pNotify->GetAppProvider()->LoadString(dwFlag, wsValue);
+  FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsValue));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_AppType(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+    return;
+  }
+  CFX_WideString wsAppType;
+  pNotify->GetAppProvider()->GetAppType(wsAppType);
+  FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsAppType));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_FoxitAppType(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+    return;
+  }
+  CFX_WideString wsAppType;
+  pNotify->GetAppProvider()->GetFoxitAppType(wsAppType);
+  FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsAppType));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_CalculationsEnabled(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  if (bSetting) {
+    pNotify->GetDocProvider()->SetCalculationsEnabled(
+        hDoc, FXJSE_Value_ToBoolean(hValue));
+    return;
+  }
+  FX_BOOL bEnabled = pNotify->GetDocProvider()->IsCalculationsEnabled(hDoc);
+  FXJSE_Value_SetBoolean(hValue, bEnabled);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_CurrentPage(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  if (bSetting) {
+    pNotify->GetDocProvider()->SetCurrentPage(hDoc,
+                                              FXJSE_Value_ToInteger(hValue));
+    return;
+  }
+  int32_t iCurrentPage = pNotify->GetDocProvider()->GetCurrentPage(hDoc);
+  FXJSE_Value_SetInteger(hValue, iCurrentPage);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_Language(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_UNABLE_SET_LANGUAGE);
+    return;
+  }
+  CFX_WideString wsLanguage;
+  pNotify->GetAppProvider()->GetLanguage(wsLanguage);
+  FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsLanguage));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_NumPages(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_UNABLE_SET_NUMPAGES);
+    return;
+  }
+  int32_t iNumPages = pNotify->GetDocProvider()->CountPages(hDoc);
+  FXJSE_Value_SetInteger(hValue, iNumPages);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_Platform(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_UNABLE_SET_PLATFORM);
+    return;
+  }
+  CFX_WideString wsPlatform;
+  pNotify->GetAppProvider()->GetPlatform(wsPlatform);
+  FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsPlatform));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_Title(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  if (!m_pDocument->GetScriptContext()->IsRunAtClient()) {
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  if (bSetting) {
+    CFX_ByteString bsValue;
+    FXJSE_Value_ToUTF8String(hValue, bsValue);
+    pNotify->GetDocProvider()->SetTitle(
+        hDoc, CFX_WideString::FromUTF8(bsValue, bsValue.GetLength()));
+    return;
+  }
+  CFX_WideString wsTitle;
+  pNotify->GetDocProvider()->GetTitle(hDoc, wsTitle);
+  FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsTitle));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_ValidationsEnabled(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  if (bSetting) {
+    pNotify->GetDocProvider()->SetValidationsEnabled(
+        hDoc, FXJSE_Value_ToBoolean(hValue));
+    return;
+  }
+  FX_BOOL bEnabled = pNotify->GetDocProvider()->IsValidationsEnabled(hDoc);
+  FXJSE_Value_SetBoolean(hValue, bEnabled);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_Variation(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  if (!m_pDocument->GetScriptContext()->IsRunAtClient()) {
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_UNABLE_SET_VARIATION);
+    return;
+  }
+  CFX_WideString wsVariation;
+  pNotify->GetAppProvider()->GetVariation(wsVariation);
+  FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsVariation));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_Version(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_UNABLE_SET_VERSION);
+    return;
+  }
+  CFX_WideString wsVersion;
+  pNotify->GetAppProvider()->GetVersion(wsVersion);
+  FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsVersion));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_FoxitVersion(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_UNABLE_SET_VERSION);
+    return;
+  }
+  CFX_WideString wsVersion;
+  pNotify->GetAppProvider()->GetFoxitVersion(wsVersion);
+  FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsVersion));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_Name(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+    return;
+  }
+  CFX_WideString wsAppName;
+  pNotify->GetAppProvider()->GetAppName(wsAppName);
+  FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsAppName));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_FoxitName(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+    return;
+  }
+  CFX_WideString wsFoxitAppName;
+  pNotify->GetAppProvider()->GetFoxitAppName(wsFoxitAppName);
+  FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsFoxitAppName));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_GotoURL(
+    CFXJSE_Arguments* pArguments) {
+  if (!m_pDocument->GetScriptContext()->IsRunAtClient()) {
+    return;
+  }
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"gotoURL");
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  CFX_WideString wsURL;
+  if (iLength >= 1) {
+    CFX_ByteString bsURL = pArguments->GetUTF8String(0);
+    wsURL = CFX_WideString::FromUTF8(bsURL, bsURL.GetLength());
+  }
+  pNotify->GetDocProvider()->GotoURL(hDoc, wsURL);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_OpenList(
+    CFXJSE_Arguments* pArguments) {
+  if (!m_pDocument->GetScriptContext()->IsRunAtClient()) {
+    return;
+  }
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"openList");
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  CXFA_Node* pNode = NULL;
+  if (iLength >= 1) {
+    FXJSE_HVALUE hValue = pArguments->GetValue(0);
+    if (FXJSE_Value_IsObject(hValue)) {
+      pNode = static_cast<CXFA_Node*>(FXJSE_Value_ToObject(hValue, nullptr));
+    } else if (FXJSE_Value_IsUTF8String(hValue)) {
+      CFX_ByteString bsString;
+      FXJSE_Value_ToUTF8String(hValue, bsString);
+      CFX_WideString wsExpression =
+          CFX_WideString::FromUTF8(bsString, bsString.GetLength());
+      IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+      if (!pScriptContext) {
+        FXJSE_Value_Release(hValue);
+        return;
+      }
+      CXFA_Object* pObject = pScriptContext->GetThisObject();
+      if (!pObject) {
+        FXJSE_Value_Release(hValue);
+        return;
+      }
+      FX_DWORD dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Parent |
+                        XFA_RESOLVENODE_Siblings;
+      XFA_RESOLVENODE_RS resoveNodeRS;
+      int32_t iRet = pScriptContext->ResolveObjects(pObject, wsExpression,
+                                                    resoveNodeRS, dwFlag);
+      if (iRet < 1 || !resoveNodeRS.nodes[0]->IsNode()) {
+        FXJSE_Value_Release(hValue);
+        return;
+      }
+      pNode = resoveNodeRS.nodes[0]->AsNode();
+    }
+    FXJSE_Value_Release(hValue);
+  }
+  IXFA_DocLayout* pDocLayout = m_pDocument->GetDocLayout();
+  if (!pDocLayout) {
+    return;
+  }
+  IXFA_Widget* hWidget = pNotify->GetHWidget(pDocLayout->GetLayoutItem(pNode));
+  if (!hWidget) {
+    return;
+  }
+  pNotify->GetDocProvider()->SetFocusWidget(pNotify->GetHDOC(), hWidget);
+  pNotify->OpenDropDownList(hWidget);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_Response(
+    CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength < 1 || iLength > 4) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"response");
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  CFX_WideString wsQuestion;
+  CFX_WideString wsTitle;
+  CFX_WideString wsDefaultAnswer;
+  FX_BOOL bMark = FALSE;
+  if (iLength >= 1) {
+    CFX_ByteString bsQuestion = pArguments->GetUTF8String(0);
+    wsQuestion = CFX_WideString::FromUTF8(bsQuestion, bsQuestion.GetLength());
+  }
+  if (iLength >= 2) {
+    CFX_ByteString bsTitle = pArguments->GetUTF8String(1);
+    wsTitle = CFX_WideString::FromUTF8(bsTitle, bsTitle.GetLength());
+  }
+  if (iLength >= 3) {
+    CFX_ByteString bsDefaultAnswer = pArguments->GetUTF8String(2);
+    wsDefaultAnswer =
+        CFX_WideString::FromUTF8(bsDefaultAnswer, bsDefaultAnswer.GetLength());
+  }
+  if (iLength >= 4) {
+    bMark = pArguments->GetInt32(3) == 0 ? FALSE : TRUE;
+  }
+  CFX_WideString wsAnswer;
+  pNotify->GetAppProvider()->Response(wsAnswer, wsQuestion, wsTitle,
+                                      wsDefaultAnswer, bMark);
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsAnswer));
+  }
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_DocumentInBatch(
+    CFXJSE_Arguments* pArguments) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  int32_t iCur = pNotify->GetAppProvider()->GetCurDocumentInBatch();
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetInteger(hValue, iCur);
+  }
+}
+static int32_t XFA_FilterName(const CFX_WideStringC& wsExpression,
+                              int32_t nStart,
+                              CFX_WideString& wsFilter) {
+  FXSYS_assert(nStart > -1);
+  int32_t iLength = wsExpression.GetLength();
+  if (nStart >= iLength) {
+    return iLength;
+  }
+  FX_WCHAR* pBuf = wsFilter.GetBuffer(iLength - nStart);
+  int32_t nCount = 0;
+  const FX_WCHAR* pSrc = wsExpression.GetPtr();
+  FX_WCHAR wCur;
+  while (nStart < iLength) {
+    wCur = pSrc[nStart++];
+    if (wCur == ',') {
+      break;
+    }
+    pBuf[nCount++] = wCur;
+  }
+  wsFilter.ReleaseBuffer(nCount);
+  wsFilter.TrimLeft();
+  wsFilter.TrimRight();
+  return nStart;
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_ResetData(
+    CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength < 0 || iLength > 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"resetData");
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  CFX_WideString wsExpression;
+  if (iLength >= 1) {
+    CFX_ByteString bsExpression = pArguments->GetUTF8String(0);
+    wsExpression =
+        CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+  }
+  if (wsExpression.IsEmpty()) {
+    pNotify->ResetData();
+    return;
+  }
+  int32_t iStart = 0;
+  CFX_WideString wsName;
+  CXFA_Node* pNode = NULL;
+  int32_t iExpLength = wsExpression.GetLength();
+  while (iStart < iExpLength) {
+    iStart = XFA_FilterName(wsExpression, iStart, wsName);
+    IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+    if (!pScriptContext) {
+      return;
+    }
+    CXFA_Object* pObject = pScriptContext->GetThisObject();
+    if (!pObject) {
+      return;
+    }
+    FX_DWORD dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Parent |
+                      XFA_RESOLVENODE_Siblings;
+    XFA_RESOLVENODE_RS resoveNodeRS;
+    int32_t iRet =
+        pScriptContext->ResolveObjects(pObject, wsName, resoveNodeRS, dwFlag);
+    if (iRet < 1 || !resoveNodeRS.nodes[0]->IsNode()) {
+      continue;
+    }
+    pNode = resoveNodeRS.nodes[0]->AsNode();
+    pNotify->ResetData(pNode->GetWidgetData());
+  }
+  if (!pNode) {
+    pNotify->ResetData();
+  }
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_Beep(
+    CFXJSE_Arguments* pArguments) {
+  if (!m_pDocument->GetScriptContext()->IsRunAtClient()) {
+    return;
+  }
+  int32_t iLength = pArguments->GetLength();
+  if (iLength < 0 || iLength > 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"beep");
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  FX_DWORD dwType = 4;
+  if (iLength >= 1) {
+    dwType = pArguments->GetInt32(0);
+  }
+  pNotify->GetAppProvider()->Beep(dwType);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_SetFocus(
+    CFXJSE_Arguments* pArguments) {
+  if (!m_pDocument->GetScriptContext()->IsRunAtClient()) {
+    return;
+  }
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"setFocus");
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  CXFA_Node* pNode = NULL;
+  if (iLength >= 1) {
+    FXJSE_HVALUE hValue = pArguments->GetValue(0);
+    if (FXJSE_Value_IsObject(hValue)) {
+      pNode = static_cast<CXFA_Node*>(FXJSE_Value_ToObject(hValue, NULL));
+    } else if (FXJSE_Value_IsUTF8String(hValue)) {
+      CFX_ByteString bsString;
+      FXJSE_Value_ToUTF8String(hValue, bsString);
+      CFX_WideString wsExpression =
+          CFX_WideString::FromUTF8(bsString, bsString.GetLength());
+      IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+      if (!pScriptContext) {
+        FXJSE_Value_Release(hValue);
+        return;
+      }
+      CXFA_Object* pObject = pScriptContext->GetThisObject();
+      if (!pObject) {
+        FXJSE_Value_Release(hValue);
+        return;
+      }
+      FX_DWORD dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Parent |
+                        XFA_RESOLVENODE_Siblings;
+      XFA_RESOLVENODE_RS resoveNodeRS;
+      int32_t iRet = pScriptContext->ResolveObjects(pObject, wsExpression,
+                                                    resoveNodeRS, dwFlag);
+      if (iRet < 1 || !resoveNodeRS.nodes[0]->IsNode()) {
+        FXJSE_Value_Release(hValue);
+        return;
+      }
+      pNode = resoveNodeRS.nodes[0]->AsNode();
+    }
+    FXJSE_Value_Release(hValue);
+  }
+  pNotify->SetFocusWidgetNode(pNode);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_GetFocus(
+    CFXJSE_Arguments* pArguments) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  CXFA_Node* pNode = pNotify->GetFocusWidgetNode();
+  if (!pNode) {
+    return;
+  }
+  FXJSE_Value_Set(pArguments->GetReturnValue(),
+                  m_pDocument->GetScriptContext()->GetJSValueFromMap(pNode));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_MessageBox(
+    CFXJSE_Arguments* pArguments) {
+  if (!m_pDocument->GetScriptContext()->IsRunAtClient()) {
+    return;
+  }
+  int32_t iLength = pArguments->GetLength();
+  if (iLength < 1 || iLength > 4) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"messageBox");
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  CFX_WideString wsMessage;
+  CFX_WideString bsTitle;
+  FX_DWORD dwMessageType = XFA_MBICON_Error;
+  FX_DWORD dwButtonType = XFA_MB_OK;
+  if (iLength >= 1) {
+    if (!Script_HostPseudoModel_ValidateArgsForMsg(pArguments, 0, wsMessage)) {
+      return;
+    }
+  }
+  if (iLength >= 2) {
+    if (!Script_HostPseudoModel_ValidateArgsForMsg(pArguments, 1, bsTitle)) {
+      return;
+    }
+  }
+  if (iLength >= 3) {
+    dwMessageType = pArguments->GetInt32(2);
+    if (dwMessageType > XFA_MBICON_Status) {
+      dwMessageType = XFA_MBICON_Error;
+    }
+  }
+  if (iLength >= 4) {
+    dwButtonType = pArguments->GetInt32(3);
+    if (dwButtonType > XFA_MB_YesNoCancel) {
+      dwButtonType = XFA_MB_OK;
+    }
+  }
+  int32_t iValue = pNotify->GetAppProvider()->MsgBox(
+      wsMessage, bsTitle, dwMessageType, dwButtonType);
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetInteger(hValue, iValue);
+  }
+}
+FX_BOOL CScript_HostPseudoModel::Script_HostPseudoModel_ValidateArgsForMsg(
+    CFXJSE_Arguments* pArguments,
+    int32_t iArgIndex,
+    CFX_WideString& wsValue) {
+  if (pArguments == NULL || iArgIndex < 0) {
+    return FALSE;
+  }
+  FX_BOOL bIsJsType = FALSE;
+  if (m_pDocument->GetScriptContext()->GetType() ==
+      XFA_SCRIPTLANGTYPE_Javascript) {
+    bIsJsType = TRUE;
+  }
+  FXJSE_HVALUE hValueArg = pArguments->GetValue(iArgIndex);
+  if (!FXJSE_Value_IsUTF8String(hValueArg) && bIsJsType) {
+    ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+    FXJSE_Value_Release(hValueArg);
+    return FALSE;
+  }
+  if (FXJSE_Value_IsNull(hValueArg)) {
+    wsValue = FX_WSTRC(L"");
+  } else {
+    CFX_ByteString byMessage;
+    FXJSE_Value_ToUTF8String(hValueArg, byMessage);
+    wsValue = CFX_WideString::FromUTF8(byMessage, byMessage.GetLength());
+  }
+  FXJSE_Value_Release(hValueArg);
+  return TRUE;
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_DocumentCountInBatch(
+    CFXJSE_Arguments* pArguments) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  int32_t iValue = pNotify->GetAppProvider()->GetDocumentCountInBatch();
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetInteger(hValue, iValue);
+  }
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_Print(
+    CFXJSE_Arguments* pArguments) {
+  if (!m_pDocument->GetScriptContext()->IsRunAtClient()) {
+    return;
+  }
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 8) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"print");
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  FX_DWORD dwOptions = 0;
+  FX_BOOL bShowDialog = TRUE;
+  if (iLength >= 1) {
+    bShowDialog = pArguments->GetInt32(0) == 0 ? FALSE : TRUE;
+  }
+  if (bShowDialog) {
+    dwOptions |= XFA_PRINTOPT_ShowDialog;
+  }
+  int32_t nStartPage = 0;
+  if (iLength >= 2) {
+    nStartPage = pArguments->GetInt32(1);
+  }
+  int32_t nEndPage = 0;
+  if (iLength >= 3) {
+    nEndPage = pArguments->GetInt32(2);
+  }
+  FX_BOOL bCanCancel = TRUE;
+  if (iLength >= 4) {
+    bCanCancel = pArguments->GetInt32(3) == 0 ? FALSE : TRUE;
+  }
+  if (bCanCancel) {
+    dwOptions |= XFA_PRINTOPT_CanCancel;
+  }
+  FX_BOOL bShrinkPage = TRUE;
+  if (iLength >= 5) {
+    bShrinkPage = pArguments->GetInt32(4) == 0 ? FALSE : TRUE;
+  }
+  if (bShrinkPage) {
+    dwOptions |= XFA_PRINTOPT_ShrinkPage;
+  }
+  FX_BOOL bAsImage = TRUE;
+  if (iLength >= 6) {
+    bAsImage = pArguments->GetInt32(5) == 0 ? FALSE : TRUE;
+  }
+  if (bAsImage) {
+    dwOptions |= XFA_PRINTOPT_AsImage;
+  }
+  FX_BOOL bReverseOrder = TRUE;
+  if (iLength >= 7) {
+    bAsImage = pArguments->GetInt32(5) == 0 ? FALSE : TRUE;
+  }
+  bReverseOrder = pArguments->GetInt32(6) == 0 ? FALSE : TRUE;
+  if (bReverseOrder) {
+    dwOptions |= XFA_PRINTOPT_ReverseOrder;
+  }
+  FX_BOOL bPrintAnnot = TRUE;
+  if (iLength >= 8) {
+    bPrintAnnot = pArguments->GetInt32(7) == 0 ? FALSE : TRUE;
+  }
+  if (bPrintAnnot) {
+    dwOptions |= XFA_PRINTOPT_PrintAnnot;
+  }
+  pNotify->GetDocProvider()->Print(hDoc, nStartPage, nEndPage, dwOptions);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_ImportData(
+    CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength < 0 || iLength > 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"importData");
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  CFX_WideString wsFilePath;
+  if (iLength > 0) {
+    CFX_ByteString bsFilePath = pArguments->GetUTF8String(0);
+    wsFilePath = CFX_WideString::FromUTF8(bsFilePath, bsFilePath.GetLength());
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  pNotify->GetDocProvider()->ImportData(hDoc, wsFilePath);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_ExportData(
+    CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength < 0 || iLength > 2) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"exportData");
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  CFX_WideString wsFilePath;
+  FX_BOOL bXDP = TRUE;
+  if (iLength >= 1) {
+    CFX_ByteString bsFilePath = pArguments->GetUTF8String(0);
+    wsFilePath = CFX_WideString::FromUTF8(bsFilePath, bsFilePath.GetLength());
+  }
+  if (iLength >= 2) {
+    bXDP = pArguments->GetInt32(1) == 0 ? FALSE : TRUE;
+  }
+  pNotify->GetDocProvider()->ExportData(hDoc, wsFilePath, bXDP);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_PageUp(
+    CFXJSE_Arguments* pArguments) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  int32_t nCurPage = pNotify->GetDocProvider()->GetCurrentPage(hDoc);
+  int32_t nNewPage = 0;
+  if (nCurPage <= 1) {
+    return;
+  }
+  nNewPage = nCurPage - 1;
+  pNotify->GetDocProvider()->SetCurrentPage(hDoc, nNewPage);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_PageDown(
+    CFXJSE_Arguments* pArguments) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  int32_t nCurPage = pNotify->GetDocProvider()->GetCurrentPage(hDoc);
+  int32_t nPageCount = pNotify->GetDocProvider()->CountPages(hDoc);
+  if (!nPageCount || nCurPage == nPageCount) {
+    return;
+  }
+  int32_t nNewPage = 0;
+  if (nCurPage >= nPageCount) {
+    nNewPage = nPageCount - 1;
+  } else {
+    nNewPage = nCurPage + 1;
+  }
+  pNotify->GetDocProvider()->SetCurrentPage(hDoc, nNewPage);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_CurrentDateTime(
+    CFXJSE_Arguments* pArguments) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  CFX_WideString wsDataTime = pNotify->GetCurrentDateTime();
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsDataTime));
+  }
+}
diff --git a/xfa/fxfa/parser/xfa_script_hostpseudomodel.h b/xfa/fxfa/parser/xfa_script_hostpseudomodel.h
new file mode 100644
index 0000000..dcc2a9b
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script_hostpseudomodel.h
@@ -0,0 +1,89 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_SCRIPT_HOSTPSEUDOMODEL_H_
+#define XFA_FXFA_PARSER_XFA_SCRIPT_HOSTPSEUDOMODEL_H_
+
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+
+class CScript_HostPseudoModel : public CXFA_OrdinaryObject {
+ public:
+  CScript_HostPseudoModel(CXFA_Document* pDocument);
+  virtual ~CScript_HostPseudoModel();
+
+  void Script_HostPseudoModel_AppType(FXJSE_HVALUE hValue,
+                                      FX_BOOL bSetting,
+                                      XFA_ATTRIBUTE eAttribute);
+  void Script_HostPseudoModel_FoxitAppType(FXJSE_HVALUE hValue,
+                                           FX_BOOL bSetting,
+                                           XFA_ATTRIBUTE eAttribute);
+  void Script_HostPseudoModel_CalculationsEnabled(FXJSE_HVALUE hValue,
+                                                  FX_BOOL bSetting,
+                                                  XFA_ATTRIBUTE eAttribute);
+  void Script_HostPseudoModel_CurrentPage(FXJSE_HVALUE hValue,
+                                          FX_BOOL bSetting,
+                                          XFA_ATTRIBUTE eAttribute);
+  void Script_HostPseudoModel_Language(FXJSE_HVALUE hValue,
+                                       FX_BOOL bSetting,
+                                       XFA_ATTRIBUTE eAttribute);
+  void Script_HostPseudoModel_NumPages(FXJSE_HVALUE hValue,
+                                       FX_BOOL bSetting,
+                                       XFA_ATTRIBUTE eAttribute);
+  void Script_HostPseudoModel_Platform(FXJSE_HVALUE hValue,
+                                       FX_BOOL bSetting,
+                                       XFA_ATTRIBUTE eAttribute);
+  void Script_HostPseudoModel_Title(FXJSE_HVALUE hValue,
+                                    FX_BOOL bSetting,
+                                    XFA_ATTRIBUTE eAttribute);
+  void Script_HostPseudoModel_ValidationsEnabled(FXJSE_HVALUE hValue,
+                                                 FX_BOOL bSetting,
+                                                 XFA_ATTRIBUTE eAttribute);
+  void Script_HostPseudoModel_Variation(FXJSE_HVALUE hValue,
+                                        FX_BOOL bSetting,
+                                        XFA_ATTRIBUTE eAttribute);
+  void Script_HostPseudoModel_Version(FXJSE_HVALUE hValue,
+                                      FX_BOOL bSetting,
+                                      XFA_ATTRIBUTE eAttribute);
+  void Script_HostPseudoModel_FoxitVersion(FXJSE_HVALUE hValue,
+                                           FX_BOOL bSetting,
+                                           XFA_ATTRIBUTE eAttribute);
+  void Script_HostPseudoModel_Name(FXJSE_HVALUE hValue,
+                                   FX_BOOL bSetting,
+                                   XFA_ATTRIBUTE eAttribute);
+  void Script_HostPseudoModel_FoxitName(FXJSE_HVALUE hValue,
+                                        FX_BOOL bSetting,
+                                        XFA_ATTRIBUTE eAttribute);
+
+  void Script_HostPseudoModel_GotoURL(CFXJSE_Arguments* pArguments);
+  void Script_HostPseudoModel_OpenList(CFXJSE_Arguments* pArguments);
+  void Script_HostPseudoModel_Response(CFXJSE_Arguments* pArguments);
+  void Script_HostPseudoModel_DocumentInBatch(CFXJSE_Arguments* pArguments);
+  void Script_HostPseudoModel_ResetData(CFXJSE_Arguments* pArguments);
+  void Script_HostPseudoModel_Beep(CFXJSE_Arguments* pArguments);
+  void Script_HostPseudoModel_SetFocus(CFXJSE_Arguments* pArguments);
+  void Script_HostPseudoModel_GetFocus(CFXJSE_Arguments* pArguments);
+  void Script_HostPseudoModel_MessageBox(CFXJSE_Arguments* pArguments);
+  void Script_HostPseudoModel_DocumentCountInBatch(
+      CFXJSE_Arguments* pArguments);
+  void Script_HostPseudoModel_Print(CFXJSE_Arguments* pArguments);
+  void Script_HostPseudoModel_ImportData(CFXJSE_Arguments* pArguments);
+  void Script_HostPseudoModel_ExportData(CFXJSE_Arguments* pArguments);
+  void Script_HostPseudoModel_PageUp(CFXJSE_Arguments* pArguments);
+  void Script_HostPseudoModel_PageDown(CFXJSE_Arguments* pArguments);
+  void Script_HostPseudoModel_CurrentDateTime(CFXJSE_Arguments* pArguments);
+
+ protected:
+  void Script_HostPseudoModel_LoadString(FXJSE_HVALUE hValue,
+                                         IXFA_Notify* pNotify,
+                                         FX_DWORD dwFlag);
+  FX_BOOL Script_HostPseudoModel_ValidateArgsForMsg(
+      CFXJSE_Arguments* pArguments,
+      int32_t iArgIndex,
+      CFX_WideString& wsValue);
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_SCRIPT_HOSTPSEUDOMODEL_H_
diff --git a/xfa/fxfa/parser/xfa_script_imp.cpp b/xfa/fxfa/parser/xfa_script_imp.cpp
new file mode 100644
index 0000000..275f494
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script_imp.cpp
@@ -0,0 +1,781 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_script_imp.h"
+
+#include "core/include/fxcrt/fx_ext.h"
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_script_nodehelper.h"
+#include "xfa/fxfa/parser/xfa_script_resolveprocessor.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+CXFA_ScriptContext::CXFA_ScriptContext(CXFA_Document* pDocument)
+    : m_pDocument(pDocument),
+      m_hJsContext(nullptr),
+      m_hJsRuntime(nullptr),
+      m_hJsClass(nullptr),
+      m_eScriptType(XFA_SCRIPTLANGTYPE_Unkown),
+      m_pScriptNodeArray(nullptr),
+      m_pResolveProcessor(nullptr),
+      m_hFM2JSContext(nullptr),
+      m_pThisObject(nullptr),
+      m_dwBuiltInInFlags(0),
+      m_eRunAtType(XFA_ATTRIBUTEENUM_Client) {
+  FXSYS_memset(&m_JsGlobalClass, 0, sizeof(FXJSE_CLASS));
+  FXSYS_memset(&m_JsNormalClass, 0, sizeof(FXJSE_CLASS));
+}
+CXFA_ScriptContext::~CXFA_ScriptContext() {
+  FX_POSITION ps = m_mapXFAToHValue.GetStartPosition();
+  while (ps) {
+    CXFA_Object* pXFAObj;
+    FXJSE_HVALUE pValue;
+    m_mapXFAToHValue.GetNextAssoc(ps, pXFAObj, pValue);
+    FXJSE_Value_Release(pValue);
+  }
+  m_mapXFAToHValue.RemoveAll();
+  ReleaseVariablesMap();
+  if (m_hFM2JSContext) {
+    XFA_FM2JS_ContextRelease(m_hFM2JSContext);
+    m_hFM2JSContext = NULL;
+  }
+  if (m_hJsContext) {
+    FXJSE_Context_Release(m_hJsContext);
+    m_hJsContext = NULL;
+  }
+  if (m_pResolveProcessor) {
+    delete m_pResolveProcessor;
+    m_pResolveProcessor = NULL;
+  }
+  m_upObjectArray.RemoveAll();
+  for (int32_t i = 0; i < m_CacheListArray.GetSize(); i++) {
+    delete ((CXFA_NodeList*)m_CacheListArray[i]);
+  }
+  m_CacheListArray.RemoveAll();
+}
+void CXFA_ScriptContext::Initialize(FXJSE_HRUNTIME hRuntime) {
+  m_hJsRuntime = hRuntime;
+  DefineJsContext();
+  DefineJsClass();
+  m_pResolveProcessor = new CXFA_ResolveProcessor;
+}
+void CXFA_ScriptContext::Release() {
+  delete this;
+}
+FX_BOOL CXFA_ScriptContext::RunScript(XFA_SCRIPTLANGTYPE eScriptType,
+                                      const CFX_WideStringC& wsScript,
+                                      FXJSE_HVALUE hRetValue,
+                                      CXFA_Object* pThisObject) {
+  CFX_ByteString btScript;
+  XFA_SCRIPTLANGTYPE eSaveType = m_eScriptType;
+  m_eScriptType = eScriptType;
+  if (eScriptType == XFA_SCRIPTLANGTYPE_Formcalc) {
+    if (!m_hFM2JSContext) {
+      m_hFM2JSContext = XFA_FM2JS_ContextCreate();
+      XFA_FM2JS_ContextInitialize(m_hFM2JSContext, m_hJsRuntime, m_hJsContext,
+                                  m_pDocument);
+    }
+    CFX_WideTextBuf wsJavaScript;
+    CFX_WideString wsErrorInfo;
+    int32_t iFlags = XFA_FM2JS_Translate(wsScript, wsJavaScript, wsErrorInfo);
+    if (iFlags) {
+      FXJSE_Value_SetUndefined(hRetValue);
+      return FALSE;
+    }
+    btScript =
+        FX_UTF8Encode(wsJavaScript.GetBuffer(), wsJavaScript.GetLength());
+  } else {
+    btScript = FX_UTF8Encode(wsScript.GetPtr(), wsScript.GetLength());
+  }
+  CXFA_Object* pOriginalObject = m_pThisObject;
+  m_pThisObject = pThisObject;
+  FXJSE_HVALUE pValue = pThisObject ? GetJSValueFromMap(pThisObject) : NULL;
+  FX_BOOL bRet = FXJSE_ExecuteScript(m_hJsContext, btScript, hRetValue, pValue);
+  m_pThisObject = pOriginalObject;
+  m_eScriptType = eSaveType;
+  return bRet;
+}
+void CXFA_ScriptContext::GlobalPropertySetter(FXJSE_HOBJECT hObject,
+                                              const CFX_ByteStringC& szPropName,
+                                              FXJSE_HVALUE hValue) {
+  CXFA_Object* lpOrginalNode =
+      (CXFA_Object*)FXJSE_Value_ToObject(hObject, NULL);
+  CXFA_Document* pDoc = lpOrginalNode->GetDocument();
+  CXFA_ScriptContext* lpScriptContext =
+      (CXFA_ScriptContext*)pDoc->GetScriptContext();
+  CXFA_Object* lpCurNode = lpScriptContext->GetVariablesThis(lpOrginalNode);
+  CFX_WideString wsPropName = CFX_WideString::FromUTF8(
+      (const FX_CHAR*)szPropName.GetPtr(), szPropName.GetLength());
+  FX_DWORD dwFlag = XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings |
+                    XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
+                    XFA_RESOLVENODE_Attributes;
+  CXFA_Node* pRefNode = ToNode(lpScriptContext->GetThisObject());
+  if (lpOrginalNode->GetObjectType() == XFA_OBJECTTYPE_VariablesThis) {
+    pRefNode = ToNode(lpCurNode);
+  }
+  if (lpScriptContext->QueryNodeByFlag(pRefNode, wsPropName, hValue, dwFlag,
+                                       TRUE)) {
+    return;
+  }
+  if (lpOrginalNode->GetObjectType() == XFA_OBJECTTYPE_VariablesThis) {
+    if (FXJSE_Value_IsUndefined(hValue)) {
+      FXJSE_Value_SetObjectOwnProp(hObject, szPropName, hValue);
+      return;
+    }
+  }
+  IXFA_Notify* pNotify = pDoc->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  pNotify->GetDocProvider()->SetGlobalProperty(pNotify->GetHDOC(), szPropName,
+                                               hValue);
+}
+FX_BOOL CXFA_ScriptContext::QueryNodeByFlag(CXFA_Node* refNode,
+                                            const CFX_WideStringC& propname,
+                                            FXJSE_HVALUE hValue,
+                                            FX_DWORD dwFlag,
+                                            FX_BOOL bSetting) {
+  if (!refNode)
+    return false;
+  XFA_RESOLVENODE_RS resolveRs;
+  if (ResolveObjects(refNode, propname, resolveRs, dwFlag) <= 0)
+    return false;
+  if (resolveRs.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
+    FXJSE_HVALUE pValue = GetJSValueFromMap(resolveRs.nodes[0]);
+    FXJSE_Value_Set(hValue, pValue);
+    return true;
+  }
+  if (resolveRs.dwFlags == XFA_RESOVENODE_RSTYPE_Attribute) {
+    const XFA_SCRIPTATTRIBUTEINFO* lpAttributeInfo = resolveRs.pScriptAttribute;
+    if (lpAttributeInfo) {
+      (resolveRs.nodes[0]->*(lpAttributeInfo->lpfnCallback))(
+          hValue, bSetting, (XFA_ATTRIBUTE)lpAttributeInfo->eAttribute);
+    }
+  }
+  return true;
+}
+void CXFA_ScriptContext::GlobalPropertyGetter(FXJSE_HOBJECT hObject,
+                                              const CFX_ByteStringC& szPropName,
+                                              FXJSE_HVALUE hValue) {
+  CXFA_Object* pOrginalObject =
+      (CXFA_Object*)FXJSE_Value_ToObject(hObject, NULL);
+  CXFA_Document* pDoc = pOrginalObject->GetDocument();
+  CXFA_ScriptContext* lpScriptContext =
+      (CXFA_ScriptContext*)pDoc->GetScriptContext();
+  CXFA_Object* lpCurNode = lpScriptContext->GetVariablesThis(pOrginalObject);
+  CFX_WideString wsPropName = CFX_WideString::FromUTF8(
+      (const FX_CHAR*)szPropName.GetPtr(), szPropName.GetLength());
+  if (lpScriptContext->GetType() == XFA_SCRIPTLANGTYPE_Formcalc) {
+    if (szPropName == FOXIT_XFA_FM2JS_FORMCALC_RUNTIME) {
+      XFA_FM2JS_GlobalPropertyGetter(lpScriptContext->m_hFM2JSContext, hValue);
+      return;
+    }
+    uint32_t uHashCode =
+        FX_HashCode_String_GetW(wsPropName, wsPropName.GetLength());
+    if (uHashCode != XFA_HASHCODE_Layout) {
+      CXFA_Object* pObject =
+          lpScriptContext->GetDocument()->GetXFAObject(uHashCode);
+      if (pObject) {
+        FXJSE_Value_Set(hValue, lpScriptContext->GetJSValueFromMap(pObject));
+        return;
+      }
+    }
+  }
+  FX_DWORD dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
+                    XFA_RESOLVENODE_Attributes;
+  CXFA_Node* pRefNode = ToNode(lpScriptContext->GetThisObject());
+  if (pOrginalObject->GetObjectType() == XFA_OBJECTTYPE_VariablesThis) {
+    pRefNode = ToNode(lpCurNode);
+  }
+  if (lpScriptContext->QueryNodeByFlag(pRefNode, wsPropName, hValue, dwFlag,
+                                       FALSE)) {
+    return;
+  }
+  dwFlag = XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings;
+  if (lpScriptContext->QueryNodeByFlag(pRefNode, wsPropName, hValue, dwFlag,
+                                       FALSE)) {
+    return;
+  }
+  CXFA_Object* pScriptObject =
+      lpScriptContext->GetVariablesThis(pOrginalObject, TRUE);
+  if (pScriptObject &&
+      lpScriptContext->QueryVariableHValue(pScriptObject->AsNode(), szPropName,
+                                           hValue, TRUE)) {
+    return;
+  }
+  IXFA_Notify* pNotify = pDoc->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  pNotify->GetDocProvider()->GetGlobalProperty(pNotify->GetHDOC(), szPropName,
+                                               hValue);
+}
+void CXFA_ScriptContext::NormalPropertyGetter(FXJSE_HOBJECT hObject,
+                                              const CFX_ByteStringC& szPropName,
+                                              FXJSE_HVALUE hValue) {
+  CXFA_Object* pOrginalObject =
+      (CXFA_Object*)FXJSE_Value_ToObject(hObject, NULL);
+  if (pOrginalObject == NULL) {
+    FXJSE_Value_SetUndefined(hValue);
+    return;
+  }
+  CFX_WideString wsPropName = CFX_WideString::FromUTF8(
+      (const FX_CHAR*)szPropName.GetPtr(), szPropName.GetLength());
+  CXFA_ScriptContext* lpScriptContext =
+      (CXFA_ScriptContext*)pOrginalObject->GetDocument()->GetScriptContext();
+  CXFA_Object* pObject = lpScriptContext->GetVariablesThis(pOrginalObject);
+  if (wsPropName == FX_WSTRC(L"xfa")) {
+    FXJSE_HVALUE pValue = lpScriptContext->GetJSValueFromMap(
+        lpScriptContext->GetDocument()->GetRoot());
+    FXJSE_Value_Set(hValue, pValue);
+    return;
+  }
+  FX_DWORD dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
+                    XFA_RESOLVENODE_Attributes;
+  FX_BOOL bRet = lpScriptContext->QueryNodeByFlag(ToNode(pObject), wsPropName,
+                                                  hValue, dwFlag, FALSE);
+  if (bRet) {
+    return;
+  }
+  if (pObject == lpScriptContext->GetThisObject() ||
+      (lpScriptContext->GetType() == XFA_SCRIPTLANGTYPE_Javascript &&
+       !lpScriptContext->IsStrictScopeInJavaScript())) {
+    dwFlag = XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings;
+    bRet = lpScriptContext->QueryNodeByFlag(ToNode(pObject), wsPropName, hValue,
+                                            dwFlag, FALSE);
+  }
+  if (bRet) {
+    return;
+  }
+  CXFA_Object* pScriptObject =
+      lpScriptContext->GetVariablesThis(pOrginalObject, TRUE);
+  if (pScriptObject) {
+    bRet = lpScriptContext->QueryVariableHValue(ToNode(pScriptObject),
+                                                szPropName, hValue, TRUE);
+  }
+  if (!bRet) {
+    FXJSE_Value_SetUndefined(hValue);
+  }
+}
+void CXFA_ScriptContext::NormalPropertySetter(FXJSE_HOBJECT hObject,
+                                              const CFX_ByteStringC& szPropName,
+                                              FXJSE_HVALUE hValue) {
+  CXFA_Object* pOrginalObject =
+      (CXFA_Object*)FXJSE_Value_ToObject(hObject, NULL);
+  if (pOrginalObject == NULL) {
+    return;
+  }
+  CXFA_ScriptContext* lpScriptContext =
+      (CXFA_ScriptContext*)pOrginalObject->GetDocument()->GetScriptContext();
+  CXFA_Object* pObject = lpScriptContext->GetVariablesThis(pOrginalObject);
+  CFX_WideString wsPropName = CFX_WideString::FromUTF8(
+      (const FX_CHAR*)szPropName.GetPtr(), szPropName.GetLength());
+  const XFA_SCRIPTATTRIBUTEINFO* lpAttributeInfo =
+      XFA_GetScriptAttributeByName(pObject->GetClassID(), wsPropName);
+  if (lpAttributeInfo) {
+    (pObject->*(lpAttributeInfo->lpfnCallback))(
+        hValue, TRUE, (XFA_ATTRIBUTE)lpAttributeInfo->eAttribute);
+  } else {
+    if (pObject->IsNode()) {
+      if (wsPropName.GetAt(0) == '#') {
+        wsPropName = wsPropName.Right(wsPropName.GetLength() - 1);
+      }
+      CXFA_Node* pNode = ToNode(pObject);
+      CXFA_Node* pPropOrChild = NULL;
+      const XFA_ELEMENTINFO* lpElementInfo = XFA_GetElementByName(wsPropName);
+      if (lpElementInfo) {
+        pPropOrChild = pNode->GetProperty(0, lpElementInfo->eName);
+      } else {
+        pPropOrChild = pNode->GetFirstChildByName(wsPropName);
+      }
+      if (pPropOrChild) {
+        CFX_WideString wsDefaultName = FX_WSTRC(L"{default}");
+        const XFA_SCRIPTATTRIBUTEINFO* lpAttributeInfo =
+            XFA_GetScriptAttributeByName(pPropOrChild->GetClassID(),
+                                         wsDefaultName);
+        if (lpAttributeInfo) {
+          (pPropOrChild->*(lpAttributeInfo->lpfnCallback))(
+              hValue, TRUE, (XFA_ATTRIBUTE)lpAttributeInfo->eAttribute);
+          return;
+        }
+      }
+    }
+    CXFA_Object* pScriptObject =
+        lpScriptContext->GetVariablesThis(pOrginalObject, TRUE);
+    if (pScriptObject) {
+      lpScriptContext->QueryVariableHValue(ToNode(pScriptObject), szPropName,
+                                           hValue, FALSE);
+    }
+  }
+}
+int32_t CXFA_ScriptContext::NormalPropTypeGetter(
+    FXJSE_HOBJECT hObject,
+    const CFX_ByteStringC& szPropName,
+    FX_BOOL bQueryIn) {
+  CXFA_Object* pObject = (CXFA_Object*)FXJSE_Value_ToObject(hObject, NULL);
+  if (pObject == NULL) {
+    return FXJSE_ClassPropType_None;
+  }
+  CXFA_ScriptContext* lpScriptContext =
+      (CXFA_ScriptContext*)pObject->GetDocument()->GetScriptContext();
+  pObject = lpScriptContext->GetVariablesThis(pObject);
+  XFA_ELEMENT objElement = pObject->GetClassID();
+  CFX_WideString wsPropName = CFX_WideString::FromUTF8(
+      (const FX_CHAR*)szPropName.GetPtr(), szPropName.GetLength());
+  if (XFA_GetMethodByName(objElement, wsPropName)) {
+    return FXJSE_ClassPropType_Method;
+  }
+  if (bQueryIn && !XFA_GetScriptAttributeByName(objElement, wsPropName)) {
+    return FXJSE_ClassPropType_None;
+  }
+  return FXJSE_ClassPropType_Property;
+}
+int32_t CXFA_ScriptContext::GlobalPropTypeGetter(
+    FXJSE_HOBJECT hObject,
+    const CFX_ByteStringC& szPropName,
+    FX_BOOL bQueryIn) {
+  CXFA_Object* pObject = (CXFA_Object*)FXJSE_Value_ToObject(hObject, NULL);
+  if (pObject == NULL) {
+    return FXJSE_ClassPropType_None;
+  }
+  CXFA_ScriptContext* lpScriptContext =
+      (CXFA_ScriptContext*)pObject->GetDocument()->GetScriptContext();
+  pObject = lpScriptContext->GetVariablesThis(pObject);
+  XFA_ELEMENT objElement = pObject->GetClassID();
+  CFX_WideString wsPropName = CFX_WideString::FromUTF8(
+      (const FX_CHAR*)szPropName.GetPtr(), szPropName.GetLength());
+  if (XFA_GetMethodByName(objElement, wsPropName)) {
+    return FXJSE_ClassPropType_Method;
+  }
+  return FXJSE_ClassPropType_Property;
+}
+void CXFA_ScriptContext::NormalMethodCall(FXJSE_HOBJECT hThis,
+                                          const CFX_ByteStringC& szFuncName,
+                                          CFXJSE_Arguments& args) {
+  CXFA_Object* pObject = (CXFA_Object*)FXJSE_Value_ToObject(hThis, NULL);
+  if (pObject == NULL) {
+    return;
+  }
+  CXFA_ScriptContext* lpScriptContext =
+      (CXFA_ScriptContext*)pObject->GetDocument()->GetScriptContext();
+  pObject = lpScriptContext->GetVariablesThis(pObject);
+  CFX_WideString wsFunName = CFX_WideString::FromUTF8(
+      (const FX_CHAR*)szFuncName.GetPtr(), szFuncName.GetLength());
+  const XFA_METHODINFO* lpMethodInfo =
+      XFA_GetMethodByName(pObject->GetClassID(), wsFunName);
+  if (NULL == lpMethodInfo) {
+    return;
+  }
+  (pObject->*(lpMethodInfo->lpfnCallback))(&args);
+}
+FX_BOOL CXFA_ScriptContext::IsStrictScopeInJavaScript() {
+  return m_pDocument->HasFlag(XFA_DOCFLAG_StrictScoping);
+}
+XFA_SCRIPTLANGTYPE CXFA_ScriptContext::GetType() {
+  return m_eScriptType;
+}
+void CXFA_ScriptContext::DefineJsContext() {
+  m_JsGlobalClass.constructor = NULL;
+  m_JsGlobalClass.name = "Root";
+  m_JsGlobalClass.propNum = 0;
+  m_JsGlobalClass.properties = NULL;
+  m_JsGlobalClass.methNum = 0;
+  m_JsGlobalClass.methods = NULL;
+  m_JsGlobalClass.dynPropGetter = CXFA_ScriptContext::GlobalPropertyGetter;
+  m_JsGlobalClass.dynPropSetter = CXFA_ScriptContext::GlobalPropertySetter;
+  m_JsGlobalClass.dynPropTypeGetter = CXFA_ScriptContext::GlobalPropTypeGetter;
+  m_JsGlobalClass.dynPropDeleter = NULL;
+  m_JsGlobalClass.dynMethodCall = CXFA_ScriptContext::NormalMethodCall;
+  m_hJsContext = FXJSE_Context_Create(m_hJsRuntime, &m_JsGlobalClass,
+                                      m_pDocument->GetRoot());
+  RemoveBuiltInObjs(m_hJsContext);
+  FXJSE_Context_EnableCompatibleMode(
+      m_hJsContext, FXJSE_COMPATIBLEMODEFLAG_CONSTRUCTOREXTRAMETHODS);
+}
+FXJSE_HCONTEXT CXFA_ScriptContext::CreateVariablesContext(
+    CXFA_Node* pScriptNode,
+    CXFA_Node* pSubform) {
+  if (pScriptNode == NULL || pSubform == NULL) {
+    return NULL;
+  }
+  if (m_mapVariableToHValue.GetCount() == 0) {
+    m_JsGlobalVariablesClass.constructor = NULL;
+    m_JsGlobalVariablesClass.name = "XFAScriptObject";
+    m_JsGlobalVariablesClass.propNum = 0;
+    m_JsGlobalVariablesClass.properties = NULL;
+    m_JsGlobalVariablesClass.methNum = 0;
+    m_JsGlobalVariablesClass.methods = NULL;
+    m_JsGlobalVariablesClass.dynPropGetter =
+        CXFA_ScriptContext::GlobalPropertyGetter;
+    m_JsGlobalVariablesClass.dynPropSetter =
+        CXFA_ScriptContext::GlobalPropertySetter;
+    m_JsGlobalVariablesClass.dynPropTypeGetter =
+        CXFA_ScriptContext::NormalPropTypeGetter;
+    m_JsGlobalVariablesClass.dynPropDeleter = NULL;
+    m_JsGlobalVariablesClass.dynMethodCall =
+        CXFA_ScriptContext::NormalMethodCall;
+  }
+  CXFA_ThisProxy* lpVariableNode = new CXFA_ThisProxy(pSubform, pScriptNode);
+  FXJSE_HCONTEXT hVariablesContext = FXJSE_Context_Create(
+      m_hJsRuntime, &m_JsGlobalVariablesClass, (CXFA_Object*)lpVariableNode);
+  RemoveBuiltInObjs(hVariablesContext);
+  FXJSE_Context_EnableCompatibleMode(
+      hVariablesContext, FXJSE_COMPATIBLEMODEFLAG_CONSTRUCTOREXTRAMETHODS);
+  m_mapVariableToHValue.SetAt(pScriptNode, hVariablesContext);
+  return hVariablesContext;
+}
+CXFA_Object* CXFA_ScriptContext::GetVariablesThis(CXFA_Object* pObject,
+                                                  FX_BOOL bScriptNode) {
+  if (pObject->GetObjectType() == XFA_OBJECTTYPE_VariablesThis) {
+    return bScriptNode ? ((CXFA_ThisProxy*)pObject)->GetScriptNode()
+                       : ((CXFA_ThisProxy*)pObject)->GetThisNode();
+  }
+  return pObject;
+}
+FX_BOOL CXFA_ScriptContext::RunVariablesScript(CXFA_Node* pScriptNode) {
+  if (pScriptNode == NULL) {
+    return FALSE;
+  }
+  if (pScriptNode->GetClassID() == XFA_ELEMENT_Script) {
+    CXFA_Node* pParent = pScriptNode->GetNodeItem(XFA_NODEITEM_Parent);
+    if (!pParent || pParent->GetClassID() != XFA_ELEMENT_Variables) {
+      return FALSE;
+    }
+    if (m_mapVariableToHValue.GetValueAt(pScriptNode)) {
+      return TRUE;
+    }
+    CXFA_Node* pTextNode = pScriptNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+    if (!pTextNode) {
+      return FALSE;
+    }
+    CFX_WideStringC wsScript;
+    if (!pTextNode->TryCData(XFA_ATTRIBUTE_Value, wsScript)) {
+      return FALSE;
+    }
+    CFX_ByteString btScript =
+        FX_UTF8Encode(wsScript.GetPtr(), wsScript.GetLength());
+    FXJSE_HVALUE hRetValue = FXJSE_Value_Create(m_hJsRuntime);
+    CXFA_Node* pThisObject = pParent->GetNodeItem(XFA_NODEITEM_Parent);
+    FXJSE_HCONTEXT hVariablesContext =
+        CreateVariablesContext(pScriptNode, pThisObject);
+    CXFA_Object* pOriginalObject = m_pThisObject;
+    m_pThisObject = pThisObject;
+    FX_BOOL bRet = FXJSE_ExecuteScript(hVariablesContext, btScript, hRetValue);
+    m_pThisObject = pOriginalObject;
+    FXJSE_Value_Release(hRetValue);
+    return bRet;
+  }
+  return TRUE;
+}
+FX_BOOL CXFA_ScriptContext::QueryVariableHValue(
+    CXFA_Node* pScriptNode,
+    const CFX_ByteStringC& szPropName,
+    FXJSE_HVALUE hValue,
+    FX_BOOL bGetter) {
+  if (!pScriptNode || pScriptNode->GetClassID() != XFA_ELEMENT_Script) {
+    return FALSE;
+  }
+  CXFA_Node* variablesNode = pScriptNode->GetNodeItem(XFA_NODEITEM_Parent);
+  if (!variablesNode || variablesNode->GetClassID() != XFA_ELEMENT_Variables) {
+    return FALSE;
+  }
+  FX_BOOL bRes = FALSE;
+  void* lpVariables = m_mapVariableToHValue.GetValueAt(pScriptNode);
+  if (lpVariables) {
+    FXJSE_HCONTEXT hVariableContext = (FXJSE_HCONTEXT)lpVariables;
+    FXJSE_HVALUE hObject = FXJSE_Context_GetGlobalObject(hVariableContext);
+    FXJSE_HVALUE hVariableValue = FXJSE_Value_Create(m_hJsRuntime);
+    if (!bGetter) {
+      FXJSE_Value_SetObjectOwnProp(hObject, szPropName, hValue);
+      bRes = TRUE;
+    } else if (FXJSE_Value_ObjectHasOwnProp(hObject, szPropName, FALSE)) {
+      FXJSE_Value_GetObjectProp(hObject, szPropName, hVariableValue);
+      if (FXJSE_Value_IsFunction(hVariableValue)) {
+        FXJSE_Value_SetFunctionBind(hValue, hVariableValue, hObject);
+      } else if (bGetter) {
+        FXJSE_Value_Set(hValue, hVariableValue);
+      } else {
+        FXJSE_Value_Set(hVariableValue, hValue);
+      }
+      bRes = TRUE;
+    }
+    FXJSE_Value_Release(hVariableValue);
+    FXJSE_Value_Release(hObject);
+  }
+  return bRes;
+}
+void CXFA_ScriptContext::ReleaseVariablesMap() {
+  FX_POSITION ps = m_mapVariableToHValue.GetStartPosition();
+  while (ps) {
+    CXFA_Object* pScriptNode;
+    FXJSE_HCONTEXT hVariableContext;
+    m_mapVariableToHValue.GetNextAssoc(ps, pScriptNode, hVariableContext);
+    FXJSE_HVALUE hObject = FXJSE_Context_GetGlobalObject(hVariableContext);
+    CXFA_Object* lpCurNode = (CXFA_Object*)FXJSE_Value_ToObject(hObject, NULL);
+    if (lpCurNode) {
+      delete (CXFA_ThisProxy*)lpCurNode;
+      lpCurNode = NULL;
+    }
+    FXJSE_Value_Release(hObject);
+    FXJSE_Context_Release(hVariableContext);
+    hVariableContext = NULL;
+  }
+  m_mapVariableToHValue.RemoveAll();
+}
+void CXFA_ScriptContext::DefineJsClass() {
+  m_JsNormalClass.constructor = NULL;
+  m_JsNormalClass.name = "XFAObject";
+  m_JsNormalClass.propNum = 0;
+  m_JsNormalClass.properties = NULL;
+  m_JsNormalClass.methNum = 0;
+  m_JsNormalClass.methods = NULL;
+  m_JsNormalClass.dynPropGetter = CXFA_ScriptContext::NormalPropertyGetter;
+  m_JsNormalClass.dynPropSetter = CXFA_ScriptContext::NormalPropertySetter;
+  m_JsNormalClass.dynPropTypeGetter = CXFA_ScriptContext::NormalPropTypeGetter;
+  m_JsNormalClass.dynPropDeleter = NULL;
+  m_JsNormalClass.dynMethodCall = CXFA_ScriptContext::NormalMethodCall;
+  m_hJsClass = FXJSE_DefineClass(m_hJsContext, &m_JsNormalClass);
+}
+void CXFA_ScriptContext::RemoveBuiltInObjs(FXJSE_HCONTEXT jsContext) const {
+  static const CFX_ByteStringC OBJ_NAME[2] = {"Number", "Date"};
+  FXJSE_HVALUE hObject = FXJSE_Context_GetGlobalObject(jsContext);
+  FXJSE_HVALUE hProp = FXJSE_Value_Create(m_hJsRuntime);
+  for (int i = 0; i < 2; ++i) {
+    if (FXJSE_Value_GetObjectProp(hObject, OBJ_NAME[i], hProp))
+      FXJSE_Value_DeleteObjectProp(hObject, OBJ_NAME[i]);
+  }
+  FXJSE_Value_Release(hProp);
+  FXJSE_Value_Release(hObject);
+}
+FXJSE_HCLASS CXFA_ScriptContext::GetJseNormalClass() {
+  return m_hJsClass;
+}
+int32_t CXFA_ScriptContext::ResolveObjects(CXFA_Object* refNode,
+                                           const CFX_WideStringC& wsExpression,
+                                           XFA_RESOLVENODE_RS& resolveNodeRS,
+                                           FX_DWORD dwStyles,
+                                           CXFA_Node* bindNode) {
+  if (wsExpression.IsEmpty()) {
+    return 0;
+  }
+  if (m_eScriptType != XFA_SCRIPTLANGTYPE_Formcalc ||
+      (dwStyles & (XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings))) {
+    m_upObjectArray.RemoveAll();
+  }
+  if (refNode && refNode->IsNode() &&
+      (dwStyles & (XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings))) {
+    m_upObjectArray.Add(refNode->AsNode());
+  }
+  FX_BOOL bNextCreate = FALSE;
+  if (dwStyles & XFA_RESOLVENODE_CreateNode) {
+    m_pResolveProcessor->GetNodeHelper()->XFA_SetCreateNodeType(bindNode);
+  }
+  m_pResolveProcessor->GetNodeHelper()->m_pCreateParent = NULL;
+  m_pResolveProcessor->GetNodeHelper()->m_iCurAllStart = -1;
+  CXFA_ResolveNodesData rndFind;
+  int32_t nStart = 0;
+  int32_t nLevel = 0;
+  int32_t nRet = -1;
+  rndFind.m_pSC = this;
+  CXFA_ObjArray findNodes;
+  findNodes.Add(refNode ? refNode : m_pDocument->GetRoot());
+  int32_t nNodes = 0;
+  while (TRUE) {
+    nNodes = findNodes.GetSize();
+    int32_t i = 0;
+    rndFind.m_dwStyles = dwStyles;
+    m_pResolveProcessor->m_iCurStart = nStart;
+    nStart = m_pResolveProcessor->XFA_ResolveNodes_GetFilter(wsExpression,
+                                                             nStart, rndFind);
+    if (nStart < 1) {
+      if ((dwStyles & XFA_RESOLVENODE_CreateNode) && !bNextCreate) {
+        CXFA_Node* pDataNode = NULL;
+        nStart = m_pResolveProcessor->GetNodeHelper()->m_iCurAllStart;
+        if (nStart != -1) {
+          pDataNode = m_pDocument->GetNotBindNode(findNodes);
+          if (pDataNode) {
+            findNodes.RemoveAll();
+            findNodes.Add(pDataNode);
+            break;
+          }
+        } else {
+          pDataNode = findNodes[0]->AsNode();
+          findNodes.RemoveAll();
+          findNodes.Add(pDataNode);
+          break;
+        }
+        dwStyles |= XFA_RESOLVENODE_Bind;
+        findNodes.RemoveAll();
+        findNodes.Add(m_pResolveProcessor->GetNodeHelper()->m_pAllStartParent);
+        continue;
+      } else {
+        break;
+      }
+    }
+    if (bNextCreate) {
+      FX_BOOL bCreate =
+          m_pResolveProcessor->GetNodeHelper()->XFA_ResolveNodes_CreateNode(
+              rndFind.m_wsName, rndFind.m_wsCondition,
+              nStart == wsExpression.GetLength(), this);
+      if (bCreate) {
+        continue;
+      } else {
+        break;
+      }
+    }
+    CXFA_ObjArray retNodes;
+    while (i < nNodes) {
+      FX_BOOL bDataBind = FALSE;
+      if (((dwStyles & XFA_RESOLVENODE_Bind) ||
+           (dwStyles & XFA_RESOLVENODE_CreateNode)) &&
+          nNodes > 1) {
+        CXFA_ResolveNodesData rndBind;
+        m_pResolveProcessor->XFA_ResolveNodes_GetFilter(wsExpression, nStart,
+                                                        rndBind);
+        m_pResolveProcessor->XFA_ResolveNode_SetIndexDataBind(
+            rndBind.m_wsCondition, i, nNodes);
+        bDataBind = TRUE;
+      }
+      rndFind.m_CurNode = findNodes[i++];
+      rndFind.m_nLevel = nLevel;
+      rndFind.m_dwFlag = XFA_RESOVENODE_RSTYPE_Nodes;
+      nRet = m_pResolveProcessor->XFA_ResolveNodes(rndFind);
+      if (nRet < 1) {
+        continue;
+      }
+      if (rndFind.m_dwFlag == XFA_RESOVENODE_RSTYPE_Attribute &&
+          rndFind.m_pScriptAttribute && nStart < wsExpression.GetLength()) {
+        FXJSE_HVALUE hValue = FXJSE_Value_Create(m_hJsRuntime);
+        (rndFind.m_Nodes[0]->*(rndFind.m_pScriptAttribute->lpfnCallback))(
+            hValue, FALSE,
+            (XFA_ATTRIBUTE)rndFind.m_pScriptAttribute->eAttribute);
+        rndFind.m_Nodes.SetAt(0,
+                              (CXFA_Object*)FXJSE_Value_ToObject(hValue, NULL));
+        FXJSE_Value_Release(hValue);
+      }
+      int32_t iSize = m_upObjectArray.GetSize();
+      if (iSize) {
+        m_upObjectArray.RemoveAt(iSize - 1);
+      }
+      retNodes.Append(rndFind.m_Nodes);
+      rndFind.m_Nodes.RemoveAll();
+      if (bDataBind) {
+        break;
+      }
+    }
+    findNodes.RemoveAll();
+    nNodes = retNodes.GetSize();
+    if (nNodes < 1) {
+      if (dwStyles & XFA_RESOLVENODE_CreateNode) {
+        bNextCreate = TRUE;
+        if (m_pResolveProcessor->GetNodeHelper()->m_pCreateParent == NULL) {
+          m_pResolveProcessor->GetNodeHelper()->m_pCreateParent =
+              ToNode(rndFind.m_CurNode);
+          m_pResolveProcessor->GetNodeHelper()->m_iCreateCount = 1;
+        }
+        FX_BOOL bCreate =
+            m_pResolveProcessor->GetNodeHelper()->XFA_ResolveNodes_CreateNode(
+                rndFind.m_wsName, rndFind.m_wsCondition,
+                nStart == wsExpression.GetLength(), this);
+        if (bCreate) {
+          continue;
+        } else {
+          break;
+        }
+      } else {
+        break;
+      }
+    }
+    findNodes.Copy(retNodes);
+    rndFind.m_Nodes.RemoveAll();
+    if (nLevel == 0) {
+      dwStyles &= ~(XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings);
+    }
+    nLevel++;
+  }
+  if (!bNextCreate) {
+    resolveNodeRS.dwFlags = rndFind.m_dwFlag;
+    if (nNodes > 0) {
+      resolveNodeRS.nodes.Append(findNodes);
+    }
+    if (rndFind.m_dwFlag == XFA_RESOVENODE_RSTYPE_Attribute) {
+      resolveNodeRS.pScriptAttribute = rndFind.m_pScriptAttribute;
+      return 1;
+    }
+  }
+  if (dwStyles & (XFA_RESOLVENODE_CreateNode | XFA_RESOLVENODE_Bind |
+                  XFA_RESOLVENODE_BindNew)) {
+    m_pResolveProcessor->XFA_ResolveNode_SetResultCreateNode(
+        resolveNodeRS, rndFind.m_wsCondition);
+    if (!bNextCreate && (dwStyles & XFA_RESOLVENODE_CreateNode)) {
+      resolveNodeRS.dwFlags = XFA_RESOVENODE_RSTYPE_ExistNodes;
+    }
+    return resolveNodeRS.nodes.GetSize();
+  }
+  return nNodes;
+}
+FXJSE_HVALUE CXFA_ScriptContext::GetJSValueFromMap(CXFA_Object* pObject) {
+  if (!pObject) {
+    return NULL;
+  }
+  if (pObject->IsNode()) {
+    RunVariablesScript(pObject->AsNode());
+  }
+  void* pValue = m_mapXFAToHValue.GetValueAt(pObject);
+  if (pValue == NULL) {
+    FXJSE_HVALUE jsHvalue = FXJSE_Value_Create(m_hJsRuntime);
+    FXJSE_Value_SetObject(jsHvalue, pObject, m_hJsClass);
+    m_mapXFAToHValue.SetAt(pObject, jsHvalue);
+    pValue = jsHvalue;
+  }
+  return (FXJSE_HVALUE)pValue;
+}
+int32_t CXFA_ScriptContext::GetIndexByName(CXFA_Node* refNode) {
+  CXFA_NodeHelper* lpNodeHelper = m_pResolveProcessor->GetNodeHelper();
+  return lpNodeHelper->XFA_GetIndex(refNode, XFA_LOGIC_Transparent,
+                                    lpNodeHelper->XFA_NodeIsProperty(refNode),
+                                    FALSE);
+}
+int32_t CXFA_ScriptContext::GetIndexByClassName(CXFA_Node* refNode) {
+  CXFA_NodeHelper* lpNodeHelper = m_pResolveProcessor->GetNodeHelper();
+  return lpNodeHelper->XFA_GetIndex(refNode, XFA_LOGIC_Transparent,
+                                    lpNodeHelper->XFA_NodeIsProperty(refNode),
+                                    TRUE);
+}
+void CXFA_ScriptContext::GetSomExpression(CXFA_Node* refNode,
+                                          CFX_WideString& wsExpression) {
+  CXFA_NodeHelper* lpNodeHelper = m_pResolveProcessor->GetNodeHelper();
+  lpNodeHelper->XFA_GetNameExpression(refNode, wsExpression, TRUE,
+                                      XFA_LOGIC_Transparent);
+}
+void CXFA_ScriptContext::SetNodesOfRunScript(CXFA_NodeArray* pArray) {
+  m_pScriptNodeArray = pArray;
+}
+void CXFA_ScriptContext::AddNodesOfRunScript(const CXFA_NodeArray& nodes) {
+  if (!m_pScriptNodeArray) {
+    return;
+  }
+  if (nodes.GetSize() > 0) {
+    m_pScriptNodeArray->Copy(nodes);
+  }
+}
+void CXFA_ScriptContext::AddNodesOfRunScript(CXFA_Node* pNode) {
+  if (!m_pScriptNodeArray) {
+    return;
+  }
+  if (m_pScriptNodeArray->Find(pNode) == -1) {
+    m_pScriptNodeArray->Add(pNode);
+  }
+}
+IXFA_ScriptContext* XFA_ScriptContext_Create(CXFA_Document* pDocument) {
+  return new CXFA_ScriptContext(pDocument);
+}
diff --git a/xfa/fxfa/parser/xfa_script_imp.h b/xfa/fxfa/parser/xfa_script_imp.h
new file mode 100644
index 0000000..e4b5501
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script_imp.h
@@ -0,0 +1,127 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_SCRIPT_IMP_H_
+#define XFA_FXFA_PARSER_XFA_SCRIPT_IMP_H_
+
+#include <map>
+
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+
+#define XFA_RESOLVENODE_TagName 0x0002
+
+class CXFA_ResolveProcessor;
+
+class CXFA_ScriptContext : public IXFA_ScriptContext {
+ public:
+  explicit CXFA_ScriptContext(CXFA_Document* pDocument);
+  ~CXFA_ScriptContext();
+
+  virtual void Release();
+  virtual void Initialize(FXJSE_HRUNTIME hRuntime);
+  virtual void SetEventParam(CXFA_EventParam param) { m_eventParam = param; }
+  virtual CXFA_EventParam* GetEventParam() { return &m_eventParam; }
+  virtual FX_BOOL RunScript(XFA_SCRIPTLANGTYPE eScriptType,
+                            const CFX_WideStringC& wsScript,
+                            FXJSE_HVALUE hRetValue,
+                            CXFA_Object* pThisObject = NULL);
+
+  virtual int32_t ResolveObjects(CXFA_Object* refNode,
+                                 const CFX_WideStringC& wsExpression,
+                                 XFA_RESOLVENODE_RS& resolveNodeRS,
+                                 FX_DWORD dwStyles = XFA_RESOLVENODE_Children,
+                                 CXFA_Node* bindNode = NULL);
+  virtual FXJSE_HVALUE GetJSValueFromMap(CXFA_Object* pObject);
+  virtual void CacheList(CXFA_NodeList* pList) { m_CacheListArray.Add(pList); }
+  virtual CXFA_Object* GetThisObject() const { return m_pThisObject; }
+  virtual FXJSE_HRUNTIME GetRuntime() const { return m_hJsRuntime; }
+
+  virtual int32_t GetIndexByName(CXFA_Node* refNode);
+  virtual int32_t GetIndexByClassName(CXFA_Node* refNode);
+  virtual void GetSomExpression(CXFA_Node* refNode,
+                                CFX_WideString& wsExpression);
+
+  virtual void SetNodesOfRunScript(CXFA_NodeArray* pArray);
+  virtual void AddNodesOfRunScript(const CXFA_NodeArray& nodes);
+  virtual void AddNodesOfRunScript(CXFA_Node* pNode);
+  virtual FXJSE_HCLASS GetJseNormalClass();
+
+  virtual void SetRunAtType(XFA_ATTRIBUTEENUM eRunAt) { m_eRunAtType = eRunAt; }
+  virtual FX_BOOL IsRunAtClient() {
+    return m_eRunAtType != XFA_ATTRIBUTEENUM_Server;
+  }
+  FX_BOOL QueryNodeByFlag(CXFA_Node* refNode,
+                          const CFX_WideStringC& propname,
+                          FXJSE_HVALUE hValue,
+                          FX_DWORD dwFlag,
+                          FX_BOOL bSetting);
+  FX_BOOL QueryVariableHValue(CXFA_Node* pScriptNode,
+                              const CFX_ByteStringC& szPropName,
+                              FXJSE_HVALUE hValue,
+                              FX_BOOL bGetter);
+  FX_BOOL QueryBuiltinHValue(const CFX_ByteStringC& szPropName,
+                             FXJSE_HVALUE hValue);
+  static void GlobalPropertyGetter(FXJSE_HOBJECT hObject,
+                                   const CFX_ByteStringC& szPropName,
+                                   FXJSE_HVALUE hValue);
+  static void GlobalPropertySetter(FXJSE_HOBJECT hObject,
+                                   const CFX_ByteStringC& szPropName,
+                                   FXJSE_HVALUE hValue);
+  static void NormalPropertyGetter(FXJSE_HOBJECT hObject,
+                                   const CFX_ByteStringC& szPropName,
+                                   FXJSE_HVALUE hValue);
+  static void NormalPropertySetter(FXJSE_HOBJECT hObject,
+                                   const CFX_ByteStringC& szPropName,
+                                   FXJSE_HVALUE hValue);
+  static void NormalMethodCall(FXJSE_HOBJECT hThis,
+                               const CFX_ByteStringC& szFuncName,
+                               CFXJSE_Arguments& args);
+  static int32_t NormalPropTypeGetter(FXJSE_HOBJECT hObject,
+                                      const CFX_ByteStringC& szPropName,
+                                      FX_BOOL bQueryIn);
+  static int32_t GlobalPropTypeGetter(FXJSE_HOBJECT hObject,
+                                      const CFX_ByteStringC& szPropName,
+                                      FX_BOOL bQueryIn);
+  FX_BOOL RunVariablesScript(CXFA_Node* pScriptNode);
+  CXFA_Object* GetVariablesThis(CXFA_Object* pObject,
+                                FX_BOOL bScriptNode = FALSE);
+  void ReleaseVariablesMap();
+  FX_BOOL IsStrictScopeInJavaScript();
+  XFA_SCRIPTLANGTYPE GetType();
+  CXFA_NodeArray& GetUpObjectArray() { return m_upObjectArray; }
+  CXFA_Document* GetDocument() const { return m_pDocument; }
+
+ protected:
+  void DefineJsContext();
+  FXJSE_HCONTEXT CreateVariablesContext(CXFA_Node* pScriptNode,
+                                        CXFA_Node* pSubform);
+  void DefineJsClass();
+  void RemoveBuiltInObjs(FXJSE_HCONTEXT jsContext) const;
+
+  CXFA_Document* m_pDocument;
+  FXJSE_HCONTEXT m_hJsContext;
+  FXJSE_HRUNTIME m_hJsRuntime;
+  FXJSE_HCLASS m_hJsClass;
+  XFA_SCRIPTLANGTYPE m_eScriptType;
+  FXJSE_CLASS m_JsGlobalClass;
+  FXJSE_CLASS m_JsNormalClass;
+  CFX_MapPtrTemplate<CXFA_Object*, FXJSE_HVALUE> m_mapXFAToHValue;
+  FXJSE_CLASS m_JsGlobalVariablesClass;
+  CFX_MapPtrTemplate<CXFA_Object*, FXJSE_HCONTEXT> m_mapVariableToHValue;
+  CXFA_EventParam m_eventParam;
+  CXFA_NodeArray m_upObjectArray;
+  CFX_PtrArray m_CacheListArray;
+  CXFA_NodeArray* m_pScriptNodeArray;
+  CXFA_ResolveProcessor* m_pResolveProcessor;
+  XFA_HFM2JSCONTEXT m_hFM2JSContext;
+  CXFA_Object* m_pThisObject;
+  FX_DWORD m_dwBuiltInInFlags;
+  XFA_ATTRIBUTEENUM m_eRunAtType;
+};
+
+#endif  //  XFA_FXFA_PARSER_XFA_SCRIPT_IMP_H_
diff --git a/xfa/fxfa/parser/xfa_script_layoutpseudomodel.cpp b/xfa/fxfa/parser/xfa_script_layoutpseudomodel.cpp
new file mode 100644
index 0000000..d4a4ea8
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script_layoutpseudomodel.cpp
@@ -0,0 +1,552 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_script_layoutpseudomodel.h"
+
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_document_layout_imp.h"
+#include "xfa/fxfa/parser/xfa_layout_appadapter.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+CScript_LayoutPseudoModel::CScript_LayoutPseudoModel(CXFA_Document* pDocument)
+    : CXFA_OrdinaryObject(pDocument, XFA_ELEMENT_LayoutPseudoModel) {
+  m_uScriptHash = XFA_HASHCODE_Layout;
+}
+CScript_LayoutPseudoModel::~CScript_LayoutPseudoModel() {}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Ready(
+    FXJSE_HVALUE hValue,
+    FX_BOOL bSetting,
+    XFA_ATTRIBUTE eAttribute) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  if (bSetting) {
+    ThrowScriptErrorMessage(XFA_IDS_UNABLE_SET_READY);
+    return;
+  }
+  int32_t iStatus = pNotify->GetLayoutStatus();
+  FXJSE_Value_SetBoolean(hValue, iStatus >= 2);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_HWXY(
+    CFXJSE_Arguments* pArguments,
+    XFA_LAYOUTMODEL_HWXY layoutModel) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength < 1 || iLength > 3) {
+    const FX_WCHAR* methodName = NULL;
+    switch (layoutModel) {
+      case XFA_LAYOUTMODEL_H:
+        methodName = L"h";
+        break;
+      case XFA_LAYOUTMODEL_W:
+        methodName = L"w";
+        break;
+      case XFA_LAYOUTMODEL_X:
+        methodName = L"x";
+        break;
+      case XFA_LAYOUTMODEL_Y:
+        methodName = L"y";
+        break;
+    }
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, methodName);
+    return;
+  }
+  CXFA_Node* pNode = NULL;
+  CFX_WideString wsUnit = FX_WSTRC(L"pt");
+  int32_t iIndex = 0;
+  if (iLength >= 1) {
+    pNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
+  }
+  if (iLength >= 2) {
+    CFX_ByteString bsUnit = pArguments->GetUTF8String(1);
+    if (!bsUnit.IsEmpty()) {
+      wsUnit = CFX_WideString::FromUTF8(bsUnit, bsUnit.GetLength());
+    }
+  }
+  if (iLength >= 3) {
+    iIndex = pArguments->GetInt32(2);
+  }
+  if (!pNode) {
+    return;
+  }
+  IXFA_DocLayout* pDocLayout = m_pDocument->GetDocLayout();
+  if (!pDocLayout) {
+    return;
+  }
+  CFX_RectF rtRect;
+  CXFA_Measurement measure;
+  CXFA_LayoutItem* pLayoutItem = pDocLayout->GetLayoutItem(pNode);
+  if (!pLayoutItem) {
+    return;
+  }
+  while (iIndex > 0 && pLayoutItem) {
+    pLayoutItem = pLayoutItem->GetNext();
+    iIndex--;
+  }
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (!pLayoutItem) {
+    FXJSE_Value_SetFloat(hValue, 0);
+    return;
+  }
+  pLayoutItem->GetRect(rtRect, TRUE);
+  switch (layoutModel) {
+    case XFA_LAYOUTMODEL_H:
+      measure.Set(rtRect.height, XFA_UNIT_Pt);
+      break;
+    case XFA_LAYOUTMODEL_W:
+      measure.Set(rtRect.width, XFA_UNIT_Pt);
+      break;
+    case XFA_LAYOUTMODEL_X:
+      measure.Set(rtRect.left, XFA_UNIT_Pt);
+      break;
+    case XFA_LAYOUTMODEL_Y:
+      measure.Set(rtRect.top, XFA_UNIT_Pt);
+      break;
+  }
+  XFA_UNIT unit = measure.GetUnit(wsUnit);
+  FX_FLOAT fValue = measure.ToUnit(unit);
+  fValue = FXSYS_round(fValue * 1000) / 1000.0f;
+  if (hValue) {
+    FXJSE_Value_SetFloat(hValue, fValue);
+  }
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_H(
+    CFXJSE_Arguments* pArguments) {
+  Script_LayoutPseudoModel_HWXY(pArguments, XFA_LAYOUTMODEL_H);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_W(
+    CFXJSE_Arguments* pArguments) {
+  Script_LayoutPseudoModel_HWXY(pArguments, XFA_LAYOUTMODEL_W);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_X(
+    CFXJSE_Arguments* pArguments) {
+  Script_LayoutPseudoModel_HWXY(pArguments, XFA_LAYOUTMODEL_X);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Y(
+    CFXJSE_Arguments* pArguments) {
+  Script_LayoutPseudoModel_HWXY(pArguments, XFA_LAYOUTMODEL_Y);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_NumberedPageCount(
+    CFXJSE_Arguments* pArguments,
+    FX_BOOL bNumbered) {
+  IXFA_DocLayout* pDocLayout = m_pDocument->GetDocLayout();
+  if (!pDocLayout) {
+    return;
+  }
+  int32_t iPageCount = 0;
+  int32_t iPageNum = pDocLayout->CountPages();
+  if (bNumbered) {
+    for (int32_t i = 0; i < iPageNum; i++) {
+      IXFA_LayoutPage* pLayoutPage = pDocLayout->GetPage(i);
+      if (!pLayoutPage) {
+        continue;
+      }
+      CXFA_Node* pMasterPage = pLayoutPage->GetMasterPage();
+      if (pMasterPage->GetInteger(XFA_ATTRIBUTE_Numbered)) {
+        iPageCount++;
+      }
+    }
+  } else {
+    iPageCount = iPageNum;
+  }
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetInteger(hValue, iPageCount);
+  }
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_PageCount(
+    CFXJSE_Arguments* pArguments) {
+  Script_LayoutPseudoModel_NumberedPageCount(pArguments, TRUE);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_PageSpan(
+    CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"pageSpan");
+    return;
+  }
+  CXFA_Node* pNode = NULL;
+  if (iLength >= 1) {
+    pNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
+  }
+  if (!pNode) {
+    return;
+  }
+  IXFA_DocLayout* pDocLayout = m_pDocument->GetDocLayout();
+  if (!pDocLayout) {
+    return;
+  }
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  CXFA_LayoutItem* pLayoutItem = pDocLayout->GetLayoutItem(pNode);
+  if (!pLayoutItem) {
+    FXJSE_Value_SetInteger(hValue, -1);
+    return;
+  }
+  int32_t iLast = pLayoutItem->GetLast()->GetPage()->GetPageIndex();
+  int32_t iFirst = pLayoutItem->GetFirst()->GetPage()->GetPageIndex();
+  int32_t iPageSpan = iLast - iFirst + 1;
+  if (hValue) {
+    FXJSE_Value_SetInteger(hValue, iPageSpan);
+  }
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Page(
+    CFXJSE_Arguments* pArguments) {
+  Script_LayoutPseudoModel_PageImp(pArguments, FALSE);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_GetObjArray(
+    IXFA_DocLayout* pDocLayout,
+    int32_t iPageNo,
+    const CFX_WideString& wsType,
+    FX_BOOL bOnPageArea,
+    CXFA_NodeArray& retArray) {
+  CXFA_ContainerLayoutItem* pLayoutPage =
+      (CXFA_ContainerLayoutItem*)pDocLayout->GetPage(iPageNo);
+  if (!pLayoutPage) {
+    return;
+  }
+  if (wsType == FX_WSTRC(L"pageArea")) {
+    if (CXFA_Node* pMasterPage = pLayoutPage->m_pFormNode) {
+      retArray.Add(pMasterPage);
+    }
+    return;
+  }
+  if (wsType == FX_WSTRC(L"contentArea")) {
+    for (CXFA_LayoutItem* pItem = pLayoutPage->m_pFirstChild; pItem;
+         pItem = pItem->m_pNextSibling) {
+      if (pItem->m_pFormNode->GetClassID() == XFA_ELEMENT_ContentArea) {
+        retArray.Add(pItem->m_pFormNode);
+      }
+    }
+    return;
+  }
+  CFX_MapPtrToPtr formItems;
+  formItems.InitHashTable(256, TRUE);
+  if (wsType.IsEmpty()) {
+    if (CXFA_Node* pMasterPage = pLayoutPage->m_pFormNode) {
+      retArray.Add(pMasterPage);
+    }
+    for (CXFA_LayoutItem* pItem = pLayoutPage->m_pFirstChild; pItem;
+         pItem = pItem->m_pNextSibling) {
+      if (pItem->m_pFormNode->GetClassID() == XFA_ELEMENT_ContentArea) {
+        retArray.Add(pItem->m_pFormNode);
+        if (!bOnPageArea) {
+          CXFA_NodeIteratorTemplate<CXFA_ContentLayoutItem,
+                                    CXFA_TraverseStrategy_ContentLayoutItem>
+          iterator((CXFA_ContentLayoutItem*)pItem->m_pFirstChild);
+          for (CXFA_ContentLayoutItem* pItemChild = iterator.GetCurrent();
+               pItemChild; pItemChild = iterator.MoveToNext()) {
+            if (!pItemChild->IsContentLayoutItem()) {
+              continue;
+            }
+            XFA_ELEMENT eElementType = pItemChild->m_pFormNode->GetClassID();
+            if (eElementType != XFA_ELEMENT_Field &&
+                eElementType != XFA_ELEMENT_Draw &&
+                eElementType != XFA_ELEMENT_Subform &&
+                eElementType != XFA_ELEMENT_Area) {
+              continue;
+            }
+            if (formItems.GetValueAt(pItemChild->m_pFormNode)) {
+              continue;
+            }
+            formItems.SetAt(pItemChild->m_pFormNode, this);
+            retArray.Add(pItemChild->m_pFormNode);
+          }
+        }
+      } else {
+        if (bOnPageArea) {
+          CXFA_NodeIteratorTemplate<CXFA_ContentLayoutItem,
+                                    CXFA_TraverseStrategy_ContentLayoutItem>
+          iterator((CXFA_ContentLayoutItem*)pItem);
+          for (CXFA_ContentLayoutItem* pItemChild = iterator.GetCurrent();
+               pItemChild; pItemChild = iterator.MoveToNext()) {
+            if (!pItemChild->IsContentLayoutItem()) {
+              continue;
+            }
+            XFA_ELEMENT eElementType = pItemChild->m_pFormNode->GetClassID();
+            if (eElementType != XFA_ELEMENT_Field &&
+                eElementType != XFA_ELEMENT_Draw &&
+                eElementType != XFA_ELEMENT_Subform &&
+                eElementType != XFA_ELEMENT_Area) {
+              continue;
+            }
+            if (formItems.GetValueAt(pItemChild->m_pFormNode)) {
+              continue;
+            }
+            formItems.SetAt(pItemChild->m_pFormNode, this);
+            retArray.Add(pItemChild->m_pFormNode);
+          }
+        }
+      }
+    }
+    return;
+  }
+  XFA_ELEMENT eType = XFA_ELEMENT_UNKNOWN;
+  if (wsType == FX_WSTRC(L"field")) {
+    eType = XFA_ELEMENT_Field;
+  } else if (wsType == FX_WSTRC(L"draw")) {
+    eType = XFA_ELEMENT_Draw;
+  } else if (wsType == FX_WSTRC(L"subform")) {
+    eType = XFA_ELEMENT_Subform;
+  } else if (wsType == FX_WSTRC(L"area")) {
+    eType = XFA_ELEMENT_Area;
+  }
+  if (eType != XFA_ELEMENT_UNKNOWN) {
+    for (CXFA_LayoutItem* pItem = pLayoutPage->m_pFirstChild; pItem;
+         pItem = pItem->m_pNextSibling) {
+      if (pItem->m_pFormNode->GetClassID() == XFA_ELEMENT_ContentArea) {
+        if (!bOnPageArea) {
+          CXFA_NodeIteratorTemplate<CXFA_ContentLayoutItem,
+                                    CXFA_TraverseStrategy_ContentLayoutItem>
+          iterator((CXFA_ContentLayoutItem*)pItem->m_pFirstChild);
+          for (CXFA_ContentLayoutItem* pItemChild = iterator.GetCurrent();
+               pItemChild; pItemChild = iterator.MoveToNext()) {
+            if (!pItemChild->IsContentLayoutItem()) {
+              continue;
+            }
+            if (pItemChild->m_pFormNode->GetClassID() != eType) {
+              continue;
+            }
+            if (formItems.GetValueAt(pItemChild->m_pFormNode)) {
+              continue;
+            }
+            formItems.SetAt(pItemChild->m_pFormNode, this);
+            retArray.Add(pItemChild->m_pFormNode);
+          }
+        }
+      } else {
+        if (bOnPageArea) {
+          CXFA_NodeIteratorTemplate<CXFA_ContentLayoutItem,
+                                    CXFA_TraverseStrategy_ContentLayoutItem>
+          iterator((CXFA_ContentLayoutItem*)pItem);
+          for (CXFA_ContentLayoutItem* pItemChild = iterator.GetCurrent();
+               pItemChild; pItemChild = iterator.MoveToNext()) {
+            if (!pItemChild->IsContentLayoutItem()) {
+              continue;
+            }
+            if (pItemChild->m_pFormNode->GetClassID() != eType) {
+              continue;
+            }
+            if (formItems.GetValueAt(pItemChild->m_pFormNode)) {
+              continue;
+            }
+            formItems.SetAt(pItemChild->m_pFormNode, this);
+            retArray.Add(pItemChild->m_pFormNode);
+          }
+        }
+      }
+    }
+    return;
+  }
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_PageContent(
+    CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength < 1 || iLength > 3) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"pageContent");
+    return;
+  }
+  int32_t iIndex = 0;
+  CFX_WideString wsType;
+  FX_BOOL bOnPageArea = FALSE;
+  if (iLength >= 1) {
+    iIndex = pArguments->GetInt32(0);
+  }
+  if (iLength >= 2) {
+    CFX_ByteString bsType = pArguments->GetUTF8String(1);
+    wsType = CFX_WideString::FromUTF8(bsType, bsType.GetLength());
+  }
+  if (iLength >= 3) {
+    bOnPageArea = pArguments->GetInt32(2) == 0 ? FALSE : TRUE;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_DocLayout* pDocLayout = m_pDocument->GetDocLayout();
+  if (!pDocLayout) {
+    return;
+  }
+  CXFA_NodeArray retArray;
+  Script_LayoutPseudoModel_GetObjArray(pDocLayout, iIndex, wsType, bOnPageArea,
+                                       retArray);
+  CXFA_ArrayNodeList* pArrayNodeList = new CXFA_ArrayNodeList(m_pDocument);
+  pArrayNodeList->SetArrayNodeList(retArray);
+  FXJSE_Value_SetObject(pArguments->GetReturnValue(),
+                        (CXFA_Object*)pArrayNodeList,
+                        m_pDocument->GetScriptContext()->GetJseNormalClass());
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPageCount(
+    CFXJSE_Arguments* pArguments) {
+  Script_LayoutPseudoModel_NumberedPageCount(pArguments, FALSE);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPageCountInBatch(
+    CFXJSE_Arguments* pArguments) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  int32_t iPageCount = pNotify->GetDocProvider()->AbsPageCountInBatch(hDoc);
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetInteger(hValue, iPageCount);
+  }
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_SheetCountInBatch(
+    CFXJSE_Arguments* pArguments) {
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  int32_t iPageCount = pNotify->GetDocProvider()->SheetCountInBatch(hDoc);
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetInteger(hValue, iPageCount);
+  }
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Relayout(
+    CFXJSE_Arguments* pArguments) {
+  CXFA_Node* pRootNode = m_pDocument->GetRoot();
+  CXFA_Node* pFormRoot = pRootNode->GetFirstChildByClass(XFA_ELEMENT_Form);
+  FXSYS_assert(pFormRoot);
+  CXFA_Node* pContentRootNode = pFormRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
+  CXFA_LayoutProcessor* pLayoutProcessor = m_pDocument->GetLayoutProcessor();
+  if (pContentRootNode) {
+    pLayoutProcessor->AddChangedContainer(pContentRootNode);
+  }
+  pLayoutProcessor->SetForceReLayout(TRUE);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPageSpan(
+    CFXJSE_Arguments* pArguments) {
+  Script_LayoutPseudoModel_PageSpan(pArguments);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPageInBatch(
+    CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"absPageInBatch");
+    return;
+  }
+  CXFA_Node* pNode = NULL;
+  if (iLength >= 1) {
+    pNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
+  }
+  if (!pNode) {
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_DocLayout* pDocLayout = m_pDocument->GetDocLayout();
+  if (!pDocLayout) {
+    return;
+  }
+  IXFA_Widget* hWidget = pNotify->GetHWidget(pDocLayout->GetLayoutItem(pNode));
+  if (!hWidget) {
+    return;
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  int32_t iPageCount = pNotify->GetDocProvider()->AbsPageInBatch(hDoc, hWidget);
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetInteger(hValue, iPageCount);
+  }
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_SheetInBatch(
+    CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 1) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD,
+                            L"sheetInBatch");
+    return;
+  }
+  CXFA_Node* pNode = NULL;
+  if (iLength >= 1) {
+    pNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
+  }
+  if (!pNode) {
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_DocLayout* pDocLayout = m_pDocument->GetDocLayout();
+  if (!pDocLayout) {
+    return;
+  }
+  IXFA_Widget* hWidget = pNotify->GetHWidget(pDocLayout->GetLayoutItem(pNode));
+  if (!hWidget) {
+    return;
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  int32_t iPageCount = pNotify->GetDocProvider()->SheetInBatch(hDoc, hWidget);
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetInteger(hValue, iPageCount);
+  }
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Sheet(
+    CFXJSE_Arguments* pArguments) {
+  Script_LayoutPseudoModel_PageImp(pArguments, TRUE);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_RelayoutPageArea(
+    CFXJSE_Arguments* pArguments) {}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_SheetCount(
+    CFXJSE_Arguments* pArguments) {
+  Script_LayoutPseudoModel_NumberedPageCount(pArguments, FALSE);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPage(
+    CFXJSE_Arguments* pArguments) {
+  Script_LayoutPseudoModel_PageImp(pArguments, TRUE);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_PageImp(
+    CFXJSE_Arguments* pArguments,
+    FX_BOOL bAbsPage) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 1) {
+    const FX_WCHAR* methodName;
+    if (bAbsPage) {
+      methodName = L"absPage";
+    } else {
+      methodName = L"page";
+    }
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, methodName);
+    return;
+  }
+  CXFA_Node* pNode = NULL;
+  if (iLength >= 1) {
+    pNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
+  }
+  int32_t iPage = 0;
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (!pNode && hValue) {
+    FXJSE_Value_SetInteger(hValue, iPage);
+  }
+  IXFA_DocLayout* pDocLayout = m_pDocument->GetDocLayout();
+  if (!pDocLayout) {
+    return;
+  }
+  CXFA_LayoutItem* pLayoutItem = pDocLayout->GetLayoutItem(pNode);
+  if (!pLayoutItem) {
+    FXJSE_Value_SetInteger(hValue, -1);
+    return;
+  }
+  iPage = pLayoutItem->GetFirst()->GetPage()->GetPageIndex();
+  if (hValue) {
+    FXJSE_Value_SetInteger(hValue, bAbsPage ? iPage : iPage + 1);
+  }
+}
diff --git a/xfa/fxfa/parser/xfa_script_layoutpseudomodel.h b/xfa/fxfa/parser/xfa_script_layoutpseudomodel.h
new file mode 100644
index 0000000..349a3cc
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script_layoutpseudomodel.h
@@ -0,0 +1,64 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_SCRIPT_LAYOUTPSEUDOMODEL_H_
+#define XFA_FXFA_PARSER_XFA_SCRIPT_LAYOUTPSEUDOMODEL_H_
+
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+
+enum XFA_LAYOUTMODEL_HWXY {
+  XFA_LAYOUTMODEL_H,
+  XFA_LAYOUTMODEL_W,
+  XFA_LAYOUTMODEL_X,
+  XFA_LAYOUTMODEL_Y
+};
+
+class CScript_LayoutPseudoModel : public CXFA_OrdinaryObject {
+ public:
+  explicit CScript_LayoutPseudoModel(CXFA_Document* pDocument);
+  ~CScript_LayoutPseudoModel();
+
+  void Script_LayoutPseudoModel_Ready(FXJSE_HVALUE hValue,
+                                      FX_BOOL bSetting,
+                                      XFA_ATTRIBUTE eAttribute);
+
+  void Script_LayoutPseudoModel_HWXY(CFXJSE_Arguments* pArguments,
+                                     XFA_LAYOUTMODEL_HWXY layoutModel);
+  void Script_LayoutPseudoModel_H(CFXJSE_Arguments* pArguments);
+  void Script_LayoutPseudoModel_W(CFXJSE_Arguments* pArguments);
+  void Script_LayoutPseudoModel_X(CFXJSE_Arguments* pArguments);
+  void Script_LayoutPseudoModel_Y(CFXJSE_Arguments* pArguments);
+  void Script_LayoutPseudoModel_NumberedPageCount(CFXJSE_Arguments* pArguments,
+                                                  FX_BOOL bNumbered);
+  void Script_LayoutPseudoModel_PageCount(CFXJSE_Arguments* pArguments);
+  void Script_LayoutPseudoModel_PageSpan(CFXJSE_Arguments* pArguments);
+  void Script_LayoutPseudoModel_Page(CFXJSE_Arguments* pArguments);
+  void Script_LayoutPseudoModel_PageContent(CFXJSE_Arguments* pArguments);
+  void Script_LayoutPseudoModel_AbsPageCount(CFXJSE_Arguments* pArguments);
+  void Script_LayoutPseudoModel_AbsPageCountInBatch(
+      CFXJSE_Arguments* pArguments);
+  void Script_LayoutPseudoModel_SheetCountInBatch(CFXJSE_Arguments* pArguments);
+  void Script_LayoutPseudoModel_Relayout(CFXJSE_Arguments* pArguments);
+  void Script_LayoutPseudoModel_AbsPageSpan(CFXJSE_Arguments* pArguments);
+  void Script_LayoutPseudoModel_AbsPageInBatch(CFXJSE_Arguments* pArguments);
+  void Script_LayoutPseudoModel_SheetInBatch(CFXJSE_Arguments* pArguments);
+  void Script_LayoutPseudoModel_Sheet(CFXJSE_Arguments* pArguments);
+  void Script_LayoutPseudoModel_RelayoutPageArea(CFXJSE_Arguments* pArguments);
+  void Script_LayoutPseudoModel_SheetCount(CFXJSE_Arguments* pArguments);
+  void Script_LayoutPseudoModel_AbsPage(CFXJSE_Arguments* pArguments);
+
+ protected:
+  void Script_LayoutPseudoModel_GetObjArray(IXFA_DocLayout* pDocLayout,
+                                            int32_t iPageNo,
+                                            const CFX_WideString& wsType,
+                                            FX_BOOL bOnPageArea,
+                                            CXFA_NodeArray& retArray);
+  void Script_LayoutPseudoModel_PageImp(CFXJSE_Arguments* pArguments,
+                                        FX_BOOL bAbsPage);
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_SCRIPT_LAYOUTPSEUDOMODEL_H_
diff --git a/xfa/fxfa/parser/xfa_script_logpseudomodel.cpp b/xfa/fxfa/parser/xfa_script_logpseudomodel.cpp
new file mode 100644
index 0000000..01f94c5
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script_logpseudomodel.cpp
@@ -0,0 +1,33 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_script_logpseudomodel.h"
+
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+CScript_LogPseudoModel::CScript_LogPseudoModel(CXFA_Document* pDocument)
+    : CXFA_OrdinaryObject(pDocument, XFA_ELEMENT_LogPseudoModel) {
+  m_uScriptHash = XFA_HASHCODE_Log;
+}
+CScript_LogPseudoModel::~CScript_LogPseudoModel() {}
+void CScript_LogPseudoModel::Script_LogPseudoModel_Message(
+    CFXJSE_Arguments* pArguments) {}
+void CScript_LogPseudoModel::Script_LogPseudoModel_TraceEnabled(
+    CFXJSE_Arguments* pArguments) {}
+void CScript_LogPseudoModel::Script_LogPseudoModel_TraceActivate(
+    CFXJSE_Arguments* pArguments) {}
+void CScript_LogPseudoModel::Script_LogPseudoModel_TraceDeactivate(
+    CFXJSE_Arguments* pArguments) {}
+void CScript_LogPseudoModel::Script_LogPseudoModel_Trace(
+    CFXJSE_Arguments* pArguments) {}
diff --git a/xfa/fxfa/parser/xfa_script_logpseudomodel.h b/xfa/fxfa/parser/xfa_script_logpseudomodel.h
new file mode 100644
index 0000000..8cd7c23
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script_logpseudomodel.h
@@ -0,0 +1,24 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_SCRIPT_LOGPSEUDOMODEL_H_
+#define XFA_FXFA_PARSER_XFA_SCRIPT_LOGPSEUDOMODEL_H_
+
+#include "xfa/fxfa/parser/xfa_object.h"
+
+class CScript_LogPseudoModel : public CXFA_OrdinaryObject {
+ public:
+  explicit CScript_LogPseudoModel(CXFA_Document* pDocument);
+  virtual ~CScript_LogPseudoModel();
+
+  void Script_LogPseudoModel_Message(CFXJSE_Arguments* pArguments);
+  void Script_LogPseudoModel_TraceEnabled(CFXJSE_Arguments* pArguments);
+  void Script_LogPseudoModel_TraceActivate(CFXJSE_Arguments* pArguments);
+  void Script_LogPseudoModel_TraceDeactivate(CFXJSE_Arguments* pArguments);
+  void Script_LogPseudoModel_Trace(CFXJSE_Arguments* pArguments);
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_SCRIPT_LOGPSEUDOMODEL_H_
diff --git a/xfa/fxfa/parser/xfa_script_nodehelper.cpp b/xfa/fxfa/parser/xfa_script_nodehelper.cpp
new file mode 100644
index 0000000..ba58430
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script_nodehelper.cpp
@@ -0,0 +1,429 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_script_nodehelper.h"
+
+#include "core/include/fxcrt/fx_ext.h"
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_script_imp.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+CXFA_NodeHelper::CXFA_NodeHelper(void)
+    : m_eLastCreateType(XFA_ELEMENT_DataValue),
+      m_pCreateParent(NULL),
+      m_iCreateCount(0),
+      m_iCreateFlag(XFA_RESOLVENODE_RSTYPE_CreateNodeOne),
+      m_iCurAllStart(-1),
+      m_pAllStartParent(NULL) {}
+CXFA_NodeHelper::~CXFA_NodeHelper(void) {}
+CXFA_Node* CXFA_NodeHelper::XFA_ResolveNodes_GetOneChild(
+    CXFA_Node* parent,
+    const FX_WCHAR* pwsName,
+    FX_BOOL bIsClassName) {
+  if (parent == NULL) {
+    return NULL;
+  }
+  CXFA_NodeArray siblings;
+  uint32_t uNameHash = FX_HashCode_String_GetW(pwsName, FXSYS_wcslen(pwsName));
+  XFA_NodeAcc_TraverseAnySiblings(parent, uNameHash, &siblings, bIsClassName);
+  if (siblings.GetSize() == 0) {
+    return NULL;
+  }
+  return siblings[0];
+}
+int32_t CXFA_NodeHelper::XFA_CountSiblings(CXFA_Node* pNode,
+                                           XFA_LOGIC_TYPE eLogicType,
+                                           CXFA_NodeArray* pSiblings,
+                                           FX_BOOL bIsClassName) {
+  if (!pNode)
+    return 0;
+  CXFA_Node* parent =
+      XFA_ResolveNodes_GetParent(pNode, XFA_LOGIC_NoTransparent);
+  if (!parent)
+    return 0;
+  const XFA_PROPERTY* pProperty = XFA_GetPropertyOfElement(
+      parent->GetClassID(), pNode->GetClassID(), XFA_XDPPACKET_UNKNOWN);
+  if (!pProperty && eLogicType == XFA_LOGIC_Transparent) {
+    parent = XFA_ResolveNodes_GetParent(pNode, XFA_LOGIC_Transparent);
+    if (parent == NULL) {
+      return 0;
+    }
+  }
+  if (bIsClassName) {
+    return XFA_NodeAcc_TraverseSiblings(parent, pNode->GetClassHashCode(),
+                                        pSiblings, eLogicType, bIsClassName);
+  } else {
+    return XFA_NodeAcc_TraverseSiblings(parent, pNode->GetNameHash(), pSiblings,
+                                        eLogicType, bIsClassName);
+  }
+}
+int32_t CXFA_NodeHelper::XFA_NodeAcc_TraverseAnySiblings(
+    CXFA_Node* parent,
+    FX_DWORD dNameHash,
+    CXFA_NodeArray* pSiblings,
+    FX_BOOL bIsClassName) {
+  if (parent == NULL || pSiblings == NULL) {
+    return 0;
+  }
+  int32_t nCount = 0;
+  int32_t i = 0;
+  CXFA_NodeArray properties;
+  parent->GetNodeList(properties, XFA_NODEFILTER_Properties);
+  int32_t nProperties = properties.GetSize();
+  for (i = 0; i < nProperties; ++i) {
+    CXFA_Node* child = properties[i];
+    if (bIsClassName) {
+      if (child->GetClassHashCode() == dNameHash) {
+        pSiblings->Add(child);
+        nCount++;
+      }
+    } else {
+      if (child->GetNameHash() == dNameHash) {
+        pSiblings->Add(child);
+        nCount++;
+      }
+    }
+    if (nCount > 0) {
+      return nCount;
+    }
+    nCount += XFA_NodeAcc_TraverseAnySiblings(child, dNameHash, pSiblings,
+                                              bIsClassName);
+  }
+  CXFA_NodeArray children;
+  parent->GetNodeList(children, XFA_NODEFILTER_Children);
+  int32_t nChildren = children.GetSize();
+  for (i = 0; i < nChildren; i++) {
+    CXFA_Node* child = children[i];
+    if (bIsClassName) {
+      if (child->GetClassHashCode() == dNameHash) {
+        if (pSiblings) {
+          pSiblings->Add(child);
+        }
+        nCount++;
+      }
+    } else {
+      if (child->GetNameHash() == dNameHash) {
+        if (pSiblings) {
+          pSiblings->Add(child);
+        }
+        nCount++;
+      }
+    }
+    if (nCount > 0) {
+      return nCount;
+    }
+    nCount += XFA_NodeAcc_TraverseAnySiblings(child, dNameHash, pSiblings,
+                                              bIsClassName);
+  }
+  return nCount;
+}
+int32_t CXFA_NodeHelper::XFA_NodeAcc_TraverseSiblings(CXFA_Node* parent,
+                                                      FX_DWORD dNameHash,
+                                                      CXFA_NodeArray* pSiblings,
+                                                      XFA_LOGIC_TYPE eLogicType,
+                                                      FX_BOOL bIsClassName,
+                                                      FX_BOOL bIsFindProperty) {
+  if (parent == NULL || pSiblings == NULL) {
+    return 0;
+  }
+  int32_t nCount = 0;
+  int32_t i = 0;
+  if (bIsFindProperty) {
+    CXFA_NodeArray properties;
+    parent->GetNodeList(properties, XFA_NODEFILTER_Properties);
+    int32_t nProperties = properties.GetSize();
+    for (i = 0; i < nProperties; ++i) {
+      CXFA_Node* child = properties[i];
+      if (bIsClassName) {
+        if (child->GetClassHashCode() == dNameHash) {
+          pSiblings->Add(child);
+          nCount++;
+        }
+      } else {
+        if (child->GetNameHash() == dNameHash) {
+          if (child->GetClassID() != XFA_ELEMENT_PageSet &&
+              child->GetClassID() != XFA_ELEMENT_Extras &&
+              child->GetClassID() != XFA_ELEMENT_Items) {
+            pSiblings->Add(child);
+            nCount++;
+          }
+        }
+      }
+      if (child->IsUnnamed() && child->GetClassID() == XFA_ELEMENT_PageSet) {
+        nCount += XFA_NodeAcc_TraverseSiblings(child, dNameHash, pSiblings,
+                                               eLogicType, bIsClassName, FALSE);
+      }
+    }
+    if (nCount > 0) {
+      return nCount;
+    }
+  }
+  CXFA_NodeArray children;
+  parent->GetNodeList(children, XFA_NODEFILTER_Children);
+  int32_t nChildren = children.GetSize();
+  for (i = 0; i < nChildren; i++) {
+    CXFA_Node* child = children[i];
+    if (child->GetClassID() == XFA_ELEMENT_Variables) {
+      continue;
+    }
+    if (bIsClassName) {
+      if (child->GetClassHashCode() == dNameHash) {
+        if (pSiblings) {
+          pSiblings->Add(child);
+        }
+        nCount++;
+      }
+    } else {
+      if (child->GetNameHash() == dNameHash) {
+        if (pSiblings) {
+          pSiblings->Add(child);
+        }
+        nCount++;
+      }
+    }
+    if (eLogicType == XFA_LOGIC_NoTransparent) {
+      continue;
+    }
+    if (XFA_NodeIsTransparent(child) &&
+        child->GetClassID() != XFA_ELEMENT_PageSet) {
+      nCount += XFA_NodeAcc_TraverseSiblings(child, dNameHash, pSiblings,
+                                             eLogicType, bIsClassName, FALSE);
+    }
+  }
+  return nCount;
+}
+CXFA_Node* CXFA_NodeHelper::XFA_ResolveNodes_GetParent(
+    CXFA_Node* pNode,
+    XFA_LOGIC_TYPE eLogicType) {
+  if (!pNode) {
+    return NULL;
+  }
+  if (eLogicType == XFA_LOGIC_NoTransparent) {
+    return pNode->GetNodeItem(XFA_NODEITEM_Parent);
+  }
+  CXFA_Node* parent;
+  CXFA_Node* node = pNode;
+  while (TRUE) {
+    parent = XFA_ResolveNodes_GetParent(node);
+    if (parent == NULL) {
+      break;
+    }
+    XFA_ELEMENT parentElement = parent->GetClassID();
+    if ((!parent->IsUnnamed() && parentElement != XFA_ELEMENT_SubformSet) ||
+        parentElement == XFA_ELEMENT_Variables) {
+      break;
+    }
+    node = parent;
+  }
+  return parent;
+}
+int32_t CXFA_NodeHelper::XFA_GetIndex(CXFA_Node* pNode,
+                                      XFA_LOGIC_TYPE eLogicType,
+                                      FX_BOOL bIsProperty,
+                                      FX_BOOL bIsClassIndex) {
+  CXFA_Node* parent =
+      XFA_ResolveNodes_GetParent(pNode, XFA_LOGIC_NoTransparent);
+  if (parent == NULL) {
+    return 0;
+  }
+  if (!bIsProperty && eLogicType == XFA_LOGIC_Transparent) {
+    parent = XFA_ResolveNodes_GetParent(pNode, XFA_LOGIC_Transparent);
+    if (parent == NULL) {
+      return 0;
+    }
+  }
+  FX_DWORD dwHashName = pNode->GetNameHash();
+  if (bIsClassIndex) {
+    dwHashName = pNode->GetClassHashCode();
+  }
+  CXFA_NodeArray siblings;
+  int32_t iSize = XFA_NodeAcc_TraverseSiblings(parent, dwHashName, &siblings,
+                                               eLogicType, bIsClassIndex);
+  for (int32_t i = 0; i < iSize; ++i) {
+    CXFA_Node* child = siblings[i];
+    if (child == pNode) {
+      return i;
+    }
+  }
+  return 0;
+}
+void CXFA_NodeHelper::XFA_GetNameExpression(CXFA_Node* refNode,
+                                            CFX_WideString& wsName,
+                                            FX_BOOL bIsAllPath,
+                                            XFA_LOGIC_TYPE eLogicType) {
+  wsName.Empty();
+  if (bIsAllPath) {
+    XFA_GetNameExpression(refNode, wsName, FALSE, eLogicType);
+    CFX_WideString wsParent;
+    CXFA_Node* parent =
+        XFA_ResolveNodes_GetParent(refNode, XFA_LOGIC_NoTransparent);
+    while (parent) {
+      XFA_GetNameExpression(parent, wsParent, FALSE, eLogicType);
+      wsParent += L".";
+      wsParent += wsName;
+      wsName = wsParent;
+      parent = XFA_ResolveNodes_GetParent(parent, XFA_LOGIC_NoTransparent);
+    }
+    return;
+  }
+
+  CFX_WideStringC wsTagName;
+  CFX_WideString ws;
+  FX_BOOL bIsProperty = XFA_NodeIsProperty(refNode);
+  if (refNode->IsUnnamed() ||
+      (bIsProperty && refNode->GetClassID() != XFA_ELEMENT_PageSet)) {
+    refNode->GetClassName(wsTagName);
+    ws = wsTagName;
+    wsName.Format(L"#%s[%d]", (const FX_WCHAR*)ws,
+                  XFA_GetIndex(refNode, eLogicType, bIsProperty, TRUE));
+    return;
+  }
+  ws = refNode->GetCData(XFA_ATTRIBUTE_Name);
+  ws.Replace(L".", L"\\.");
+  wsName.Format(L"%s[%d]", (const FX_WCHAR*)ws,
+                XFA_GetIndex(refNode, eLogicType, bIsProperty, FALSE));
+}
+
+FX_BOOL CXFA_NodeHelper::XFA_NodeIsTransparent(CXFA_Node* refNode) {
+  if (refNode == NULL) {
+    return FALSE;
+  }
+  XFA_ELEMENT eRefNode = refNode->GetClassID();
+  if ((refNode->IsUnnamed() && refNode->IsContainerNode()) ||
+      eRefNode == XFA_ELEMENT_SubformSet || eRefNode == XFA_ELEMENT_Area ||
+      eRefNode == XFA_ELEMENT_Proto) {
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_NodeHelper::XFA_CreateNode_ForCondition(
+    CFX_WideString& wsCondition) {
+  int32_t iLen = wsCondition.GetLength();
+  CFX_WideString wsIndex = FX_WSTRC(L"0");
+  FX_BOOL bAll = FALSE;
+
+  if (iLen == 0) {
+    m_iCreateFlag = XFA_RESOLVENODE_RSTYPE_CreateNodeOne;
+    return FALSE;
+  }
+  if (wsCondition.GetAt(0) == '[') {
+    int32_t i = 1;
+    for (; i < iLen; ++i) {
+      FX_WCHAR ch = wsCondition[i];
+      if (ch == ' ') {
+        continue;
+      }
+      if (ch == '+' || ch == '-') {
+        break;
+      } else if (ch == '*') {
+        bAll = TRUE;
+        break;
+      } else {
+        break;
+      }
+    }
+    if (bAll) {
+      wsIndex = FX_WSTRC(L"1");
+      m_iCreateFlag = XFA_RESOLVENODE_RSTYPE_CreateNodeAll;
+    } else {
+      m_iCreateFlag = XFA_RESOLVENODE_RSTYPE_CreateNodeOne;
+      wsIndex = wsCondition.Mid(i, iLen - 1 - i);
+    }
+    int32_t iIndex = wsIndex.GetInteger();
+    m_iCreateCount = iIndex;
+    return TRUE;
+  }
+  return FALSE;
+}
+FX_BOOL CXFA_NodeHelper::XFA_ResolveNodes_CreateNode(
+    CFX_WideString wsName,
+    CFX_WideString wsCondition,
+    FX_BOOL bLastNode,
+    CXFA_ScriptContext* pScriptContext) {
+  if (m_pCreateParent == NULL) {
+    return FALSE;
+  }
+  FX_BOOL bIsClassName = FALSE;
+  FX_BOOL bResult = FALSE;
+  if (wsName.GetAt(0) == '!') {
+    wsName = wsName.Right(wsName.GetLength() - 1);
+    m_pCreateParent = ToNode(
+        pScriptContext->GetDocument()->GetXFAObject(XFA_HASHCODE_Datasets));
+  }
+  if (wsName.GetAt(0) == '#') {
+    bIsClassName = TRUE;
+    wsName = wsName.Right(wsName.GetLength() - 1);
+  }
+  if (m_iCreateCount == 0) {
+    XFA_CreateNode_ForCondition(wsCondition);
+  }
+  if (bIsClassName) {
+    const XFA_ELEMENTINFO* lpElement = XFA_GetElementByName(wsName);
+    if (lpElement == NULL) {
+      return FALSE;
+    }
+    for (int32_t iIndex = 0; iIndex < m_iCreateCount; iIndex++) {
+      CXFA_Node* pNewNode =
+          m_pCreateParent->CreateSamePacketNode(lpElement->eName);
+      if (pNewNode) {
+        m_pCreateParent->InsertChild(pNewNode);
+        if (iIndex == m_iCreateCount - 1) {
+          m_pCreateParent = pNewNode;
+        }
+        bResult = TRUE;
+      }
+    }
+  } else {
+    XFA_ELEMENT eClassType = XFA_ELEMENT_DataGroup;
+    if (bLastNode) {
+      eClassType = m_eLastCreateType;
+    }
+    for (int32_t iIndex = 0; iIndex < m_iCreateCount; iIndex++) {
+      CXFA_Node* pNewNode = m_pCreateParent->CreateSamePacketNode(eClassType);
+      if (pNewNode) {
+        pNewNode->SetAttribute(XFA_ATTRIBUTE_Name, wsName);
+        pNewNode->CreateXMLMappingNode();
+        m_pCreateParent->InsertChild(pNewNode);
+        if (iIndex == m_iCreateCount - 1) {
+          m_pCreateParent = pNewNode;
+        }
+        bResult = TRUE;
+      }
+    }
+  }
+  if (!bResult) {
+    m_pCreateParent = NULL;
+  }
+  return bResult;
+}
+void CXFA_NodeHelper::XFA_SetCreateNodeType(CXFA_Node* refNode) {
+  if (refNode == NULL) {
+    return;
+  }
+  if (refNode->GetClassID() == XFA_ELEMENT_Subform) {
+    m_eLastCreateType = XFA_ELEMENT_DataGroup;
+  } else if (refNode->GetClassID() == XFA_ELEMENT_Field) {
+    m_eLastCreateType = XFA_FieldIsMultiListBox(refNode)
+                            ? XFA_ELEMENT_DataGroup
+                            : XFA_ELEMENT_DataValue;
+  } else if (refNode->GetClassID() == XFA_ELEMENT_ExclGroup) {
+    m_eLastCreateType = XFA_ELEMENT_DataValue;
+  }
+}
+FX_BOOL CXFA_NodeHelper::XFA_NodeIsProperty(CXFA_Node* refNode) {
+  CXFA_Node* parent =
+      XFA_ResolveNodes_GetParent(refNode, XFA_LOGIC_NoTransparent);
+  return parent && refNode &&
+         XFA_GetPropertyOfElement(parent->GetClassID(), refNode->GetClassID(),
+                                  XFA_XDPPACKET_UNKNOWN);
+}
diff --git a/xfa/fxfa/parser/xfa_script_nodehelper.h b/xfa/fxfa/parser/xfa_script_nodehelper.h
new file mode 100644
index 0000000..b52f681
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script_nodehelper.h
@@ -0,0 +1,72 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_SCRIPT_NODEHELPER_H_
+#define XFA_FXFA_PARSER_XFA_SCRIPT_NODEHELPER_H_
+
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+
+class CXFA_ScriptContext;
+
+enum XFA_LOGIC_TYPE {
+  XFA_LOGIC_NoTransparent,
+  XFA_LOGIC_Transparent,
+};
+
+class CXFA_NodeHelper {
+ public:
+  CXFA_NodeHelper(void);
+  ~CXFA_NodeHelper(void);
+  CXFA_Node* XFA_ResolveNodes_GetOneChild(CXFA_Node* parent,
+                                          const FX_WCHAR* pwsName,
+                                          FX_BOOL bIsClassName = FALSE);
+  CXFA_Node* XFA_ResolveNodes_GetParent(
+      CXFA_Node* pNode,
+      XFA_LOGIC_TYPE eLogicType = XFA_LOGIC_NoTransparent);
+
+  int32_t XFA_NodeAcc_TraverseSiblings(CXFA_Node* parent,
+                                       FX_DWORD dNameHash,
+                                       CXFA_NodeArray* pSiblings,
+                                       XFA_LOGIC_TYPE eLogicType,
+                                       FX_BOOL bIsClassName = FALSE,
+                                       FX_BOOL bIsFindProperty = TRUE);
+  int32_t XFA_NodeAcc_TraverseAnySiblings(CXFA_Node* parent,
+                                          FX_DWORD dNameHash,
+                                          CXFA_NodeArray* pSiblings,
+                                          FX_BOOL bIsClassName = FALSE);
+  int32_t XFA_CountSiblings(CXFA_Node* pNode,
+                            XFA_LOGIC_TYPE eLogicType,
+                            CXFA_NodeArray* pSiblings,
+                            FX_BOOL bIsClassName = FALSE);
+  int32_t XFA_GetIndex(CXFA_Node* pNode,
+                       XFA_LOGIC_TYPE eLogicType = XFA_LOGIC_NoTransparent,
+                       FX_BOOL bIsProperty = FALSE,
+                       FX_BOOL bIsClassIndex = FALSE);
+  void XFA_GetNameExpression(
+      CXFA_Node* refNode,
+      CFX_WideString& wsName,
+      FX_BOOL bIsAllPath,
+      XFA_LOGIC_TYPE eLogicType = XFA_LOGIC_NoTransparent);
+  FX_BOOL XFA_NodeIsTransparent(CXFA_Node* refNode);
+  FX_BOOL XFA_ResolveNodes_CreateNode(CFX_WideString wsName,
+                                      CFX_WideString wsCondition,
+                                      FX_BOOL bLastNode,
+                                      CXFA_ScriptContext* pScriptContext);
+  FX_BOOL XFA_CreateNode_ForCondition(CFX_WideString& wsCondition);
+  void XFA_SetCreateNodeType(CXFA_Node* refNode);
+  FX_BOOL XFA_NodeIsProperty(CXFA_Node* refNode);
+
+ public:
+  XFA_ELEMENT m_eLastCreateType;
+  CXFA_Node* m_pCreateParent;
+  int32_t m_iCreateCount;
+  XFA_RESOVENODE_RSTYPE m_iCreateFlag;
+  int32_t m_iCurAllStart;
+  CXFA_Node* m_pAllStartParent;
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_SCRIPT_NODEHELPER_H_
diff --git a/xfa/fxfa/parser/xfa_script_resolveprocessor.cpp b/xfa/fxfa/parser/xfa_script_resolveprocessor.cpp
new file mode 100644
index 0000000..b40d714
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script_resolveprocessor.cpp
@@ -0,0 +1,825 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_script_resolveprocessor.h"
+
+#include "core/include/fxcrt/fx_ext.h"
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_script_imp.h"
+#include "xfa/fxfa/parser/xfa_script_nodehelper.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+CXFA_ResolveProcessor::CXFA_ResolveProcessor(void)
+    : m_pNodeHelper(NULL), m_iCurStart(0) {
+  m_pNodeHelper = new CXFA_NodeHelper;
+}
+CXFA_ResolveProcessor::~CXFA_ResolveProcessor(void) {
+  if (m_pNodeHelper) {
+    delete m_pNodeHelper;
+    m_pNodeHelper = NULL;
+  }
+}
+int32_t CXFA_ResolveProcessor::XFA_ResolveNodes(CXFA_ResolveNodesData& rnd) {
+  if (rnd.m_CurNode == NULL) {
+    return -1;
+  }
+  if (!rnd.m_CurNode->IsNode()) {
+    if (rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) {
+      return XFA_ResolveNodes_ForAttributeRs(rnd.m_CurNode, rnd, rnd.m_wsName);
+    }
+    return 0;
+  }
+  if (rnd.m_dwStyles & XFA_RESOLVENODE_AnyChild) {
+    return XFA_ResolveNodes_AnyChild(rnd);
+  }
+  FX_WCHAR wch = rnd.m_wsName.GetAt(0);
+  switch (wch) {
+    case '$':
+      return XFA_ResolveNodes_Dollar(rnd);
+    case '!':
+      return XFA_ResolveNodes_Excalmatory(rnd);
+    case '#':
+      return XFA_ResolveNodes_NumberSign(rnd);
+    case '*':
+      return XFA_ResolveNodes_Asterisk(rnd);
+    case '.':
+      return XFA_ResolveNodes_AnyChild(rnd);
+    default:
+      break;
+  }
+  if (rnd.m_uHashName == XFA_HASHCODE_This && rnd.m_nLevel == 0) {
+    rnd.m_Nodes.Add(rnd.m_pSC->GetThisObject());
+    return 1;
+  } else if (rnd.m_CurNode->GetClassID() == XFA_ELEMENT_Xfa) {
+    CXFA_Object* pObjNode =
+        rnd.m_pSC->GetDocument()->GetXFAObject(rnd.m_uHashName);
+    if (pObjNode) {
+      rnd.m_Nodes.Add(pObjNode);
+    } else if (rnd.m_uHashName == XFA_HASHCODE_Xfa) {
+      rnd.m_Nodes.Add(rnd.m_CurNode);
+    } else if ((rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) &&
+               XFA_ResolveNodes_ForAttributeRs(rnd.m_CurNode, rnd,
+                                               rnd.m_wsName)) {
+      return 1;
+    }
+    if (rnd.m_Nodes.GetSize() > 0) {
+      XFA_ResolveNode_FilterCondition(rnd, rnd.m_wsCondition);
+    }
+    return rnd.m_Nodes.GetSize();
+  }
+  int32_t nRet = XFA_ResolveNodes_Normal(rnd);
+  if (nRet < 1 && rnd.m_uHashName == XFA_HASHCODE_Xfa) {
+    rnd.m_Nodes.Add(rnd.m_pSC->GetDocument()->GetRoot());
+  }
+  return rnd.m_Nodes.GetSize();
+}
+int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_AnyChild(
+    CXFA_ResolveNodesData& rnd) {
+  CFX_WideString wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1);
+  CFX_WideString wsCondition = rnd.m_wsCondition;
+  CXFA_Node* findNode = NULL;
+  CXFA_NodeArray siblings;
+  FX_BOOL bClassName = FALSE;
+  if (wsName.GetAt(0) == '#') {
+    bClassName = TRUE;
+    wsName = wsName.Right(wsName.GetLength() - 1);
+  }
+  findNode = m_pNodeHelper->XFA_ResolveNodes_GetOneChild(ToNode(rnd.m_CurNode),
+                                                         wsName, bClassName);
+  if (findNode == NULL) {
+    return 0;
+  }
+  if (wsCondition.IsEmpty()) {
+    rnd.m_Nodes.Add(findNode);
+    return rnd.m_Nodes.GetSize();
+  }
+  m_pNodeHelper->XFA_CountSiblings(findNode, XFA_LOGIC_Transparent,
+                                   (CXFA_NodeArray*)&rnd.m_Nodes, bClassName);
+  XFA_ResolveNode_FilterCondition(rnd, wsCondition);
+  return rnd.m_Nodes.GetSize();
+}
+int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_Dollar(
+    CXFA_ResolveNodesData& rnd) {
+  CXFA_ObjArray& nodes = rnd.m_Nodes;
+  CFX_WideString wsName = rnd.m_wsName;
+  CFX_WideString wsCondition = rnd.m_wsCondition;
+  int32_t iNameLen = wsName.GetLength();
+  if (iNameLen == 1) {
+    nodes.Add(rnd.m_CurNode);
+    return 1;
+  }
+  if (rnd.m_nLevel > 0) {
+    return -1;
+  }
+  FX_DWORD dwNameHash =
+      FX_HashCode_String_GetW((const FX_WCHAR*)wsName + 1, iNameLen - 1);
+  if (dwNameHash == XFA_HASHCODE_Xfa) {
+    nodes.Add(rnd.m_pSC->GetDocument()->GetRoot());
+  } else {
+    CXFA_Object* pObjNode = rnd.m_pSC->GetDocument()->GetXFAObject(dwNameHash);
+    if (pObjNode) {
+      rnd.m_Nodes.Add(pObjNode);
+    }
+  }
+  if (rnd.m_Nodes.GetSize() > 0) {
+    XFA_ResolveNode_FilterCondition(rnd, wsCondition);
+  }
+  return rnd.m_Nodes.GetSize();
+}
+int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_Excalmatory(
+    CXFA_ResolveNodesData& rnd) {
+  if (rnd.m_nLevel > 0) {
+    return 0;
+  }
+  CXFA_Node* datasets =
+      ToNode(rnd.m_pSC->GetDocument()->GetXFAObject(XFA_HASHCODE_Datasets));
+  if (!datasets) {
+    return 0;
+  }
+  CXFA_ResolveNodesData rndFind;
+  rndFind.m_pSC = rnd.m_pSC;
+  rndFind.m_CurNode = datasets;
+  rndFind.m_wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1);
+  rndFind.m_uHashName =
+      FX_HashCode_String_GetW(rndFind.m_wsName, rndFind.m_wsName.GetLength());
+  rndFind.m_nLevel = rnd.m_nLevel + 1;
+  rndFind.m_dwStyles = XFA_RESOLVENODE_Children;
+  rndFind.m_wsCondition = rnd.m_wsCondition;
+  XFA_ResolveNodes(rndFind);
+  if (rndFind.m_Nodes.GetSize() > 0) {
+    rnd.m_Nodes.Append(rndFind.m_Nodes);
+    rndFind.m_Nodes.RemoveAll();
+  }
+  return rnd.m_Nodes.GetSize();
+}
+int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_NumberSign(
+    CXFA_ResolveNodesData& rnd) {
+  CFX_WideString wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1);
+  CFX_WideString wsCondition = rnd.m_wsCondition;
+  CXFA_Node* curNode = ToNode(rnd.m_CurNode);
+  if (XFA_ResolveNodes_ForAttributeRs(curNode, rnd, wsName)) {
+    return 1;
+  }
+  CXFA_ResolveNodesData rndFind;
+  rndFind.m_pSC = rnd.m_pSC;
+  rndFind.m_nLevel = rnd.m_nLevel + 1;
+  rndFind.m_dwStyles = rnd.m_dwStyles;
+  rndFind.m_dwStyles |= XFA_RESOLVENODE_TagName;
+  rndFind.m_dwStyles &= ~XFA_RESOLVENODE_Attributes;
+  rndFind.m_wsName = wsName;
+  rndFind.m_uHashName =
+      FX_HashCode_String_GetW(rndFind.m_wsName, rndFind.m_wsName.GetLength());
+  rndFind.m_wsCondition = wsCondition;
+  rndFind.m_CurNode = curNode;
+  XFA_ResolveNodes_Normal(rndFind);
+  if (rndFind.m_Nodes.GetSize() > 0) {
+    if (wsCondition.GetLength() == 0 && rndFind.m_Nodes.Find(curNode) >= 0) {
+      rnd.m_Nodes.Add(curNode);
+    } else {
+      rnd.m_Nodes.Append(rndFind.m_Nodes);
+      rndFind.m_Nodes.RemoveAll();
+    }
+  }
+  return rnd.m_Nodes.GetSize();
+}
+int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_ForAttributeRs(
+    CXFA_Object* curNode,
+    CXFA_ResolveNodesData& rnd,
+    const CFX_WideStringC& strAttr) {
+  const XFA_SCRIPTATTRIBUTEINFO* lpScriptAttribute =
+      XFA_GetScriptAttributeByName(curNode->GetClassID(), strAttr);
+  if (lpScriptAttribute) {
+    rnd.m_pScriptAttribute = lpScriptAttribute;
+    rnd.m_Nodes.Add(curNode);
+    rnd.m_dwFlag = XFA_RESOVENODE_RSTYPE_Attribute;
+    return 1;
+  }
+  return 0;
+}
+int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_Normal(
+    CXFA_ResolveNodesData& rnd) {
+  if (rnd.m_nLevel > 32) {
+    return 0;
+  }
+  if (!rnd.m_CurNode->IsNode()) {
+    return 0;
+  }
+  CXFA_Node* curNode = ToNode(rnd.m_CurNode);
+  CXFA_ObjArray& nodes = rnd.m_Nodes;
+  int32_t nNum = nodes.GetSize();
+  FX_DWORD dwStyles = rnd.m_dwStyles;
+  CFX_WideString& wsName = rnd.m_wsName;
+  uint32_t uNameHash = rnd.m_uHashName;
+  CFX_WideString& wsCondition = rnd.m_wsCondition;
+  CXFA_ResolveNodesData rndFind;
+  rndFind.m_wsName = rnd.m_wsName;
+  rndFind.m_wsCondition = rnd.m_wsCondition;
+  rndFind.m_pSC = rnd.m_pSC;
+  rndFind.m_nLevel = rnd.m_nLevel + 1;
+  rndFind.m_uHashName = uNameHash;
+  CXFA_NodeArray children;
+  CXFA_NodeArray properties;
+  CXFA_Node* pVariablesNode = NULL;
+  CXFA_Node* pPageSetNode = NULL;
+  CXFA_Node* pChild = curNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+  while (pChild) {
+    if (pChild->GetClassID() == XFA_ELEMENT_Variables) {
+      pVariablesNode = pChild;
+      pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+      continue;
+    } else if (pChild->GetClassID() == XFA_ELEMENT_PageSet) {
+      pPageSetNode = pChild;
+      pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+      continue;
+    } else {
+      const XFA_PROPERTY* pPropert = XFA_GetPropertyOfElement(
+          curNode->GetClassID(), pChild->GetClassID(), XFA_XDPPACKET_UNKNOWN);
+      if (pPropert) {
+        properties.Add(pChild);
+      } else {
+        children.Add(pChild);
+      }
+    }
+    pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+  }
+  if ((dwStyles & XFA_RESOLVENODE_Properties) && pVariablesNode) {
+    uint32_t uPropHash = pVariablesNode->GetClassHashCode();
+    if (uPropHash == uNameHash) {
+      nodes.Add(pVariablesNode);
+    } else {
+      rndFind.m_CurNode = pVariablesNode;
+      XFA_ResolveNodes_SetStylesForChild(dwStyles, rndFind);
+      CFX_WideString wsSaveCondition = rndFind.m_wsCondition;
+      rndFind.m_wsCondition.Empty();
+      XFA_ResolveNodes_Normal(rndFind);
+      rndFind.m_wsCondition = wsSaveCondition;
+      if (rndFind.m_Nodes.GetSize() > 0) {
+        nodes.Append(rndFind.m_Nodes);
+        rndFind.m_Nodes.RemoveAll();
+      }
+    }
+    if (nodes.GetSize() > nNum) {
+      XFA_ResolveNode_FilterCondition(rnd, wsCondition);
+      if (nodes.GetSize() > 0) {
+        return 1;
+      }
+      return 0;
+    }
+  }
+  if (dwStyles & XFA_RESOLVENODE_Children) {
+    FX_BOOL bSetFlag = FALSE;
+    if (pPageSetNode && (dwStyles & XFA_RESOLVENODE_Properties)) {
+      children.Add(pPageSetNode);
+    }
+    for (int32_t i = 0; i < children.GetSize(); i++) {
+      CXFA_Node* child = children[i];
+      if (dwStyles & XFA_RESOLVENODE_TagName) {
+        if (child->GetClassHashCode() == uNameHash) {
+          nodes.Add(child);
+        }
+      } else if (child->GetNameHash() == uNameHash) {
+        nodes.Add(child);
+      }
+      if (m_pNodeHelper->XFA_NodeIsTransparent(child) &&
+          child->GetClassID() != XFA_ELEMENT_PageSet) {
+        if (!bSetFlag) {
+          XFA_ResolveNodes_SetStylesForChild(dwStyles, rndFind);
+          bSetFlag = TRUE;
+        }
+        rndFind.m_CurNode = child;
+        CFX_WideString wsSaveCondition = rndFind.m_wsCondition;
+        rndFind.m_wsCondition.Empty();
+        XFA_ResolveNodes_Normal(rndFind);
+        rndFind.m_wsCondition = wsSaveCondition;
+        if (rndFind.m_Nodes.GetSize() > 0) {
+          nodes.Append(rndFind.m_Nodes);
+          rndFind.m_Nodes.RemoveAll();
+        }
+      }
+    }
+    if (nodes.GetSize() > nNum) {
+      if (!(dwStyles & XFA_RESOLVENODE_ALL)) {
+        CXFA_NodeArray upArrayNodes;
+        if (m_pNodeHelper->XFA_NodeIsTransparent(ToNode(curNode))) {
+          m_pNodeHelper->XFA_CountSiblings(
+              ToNode(nodes[0]), XFA_LOGIC_Transparent, &upArrayNodes,
+              !!(dwStyles & XFA_RESOLVENODE_TagName));
+        }
+        if (upArrayNodes.GetSize() > nodes.GetSize()) {
+          upArrayNodes[0] = ToNode(nodes[0]);
+          nodes.RemoveAll();
+          nodes.Append((CXFA_ObjArray&)upArrayNodes);
+          upArrayNodes.RemoveAll();
+        }
+      }
+      XFA_ResolveNode_FilterCondition(rnd, wsCondition);
+      if (nodes.GetSize() > 0) {
+        return 1;
+      }
+      return 0;
+    }
+  }
+  if (dwStyles & XFA_RESOLVENODE_Attributes) {
+    if (XFA_ResolveNodes_ForAttributeRs(curNode, rnd, wsName)) {
+      return 1;
+    }
+  }
+  if (dwStyles & XFA_RESOLVENODE_Properties) {
+    for (int32_t i = 0; i < properties.GetSize(); i++) {
+      CXFA_Node* childProperty = properties[i];
+      if (childProperty->IsUnnamed()) {
+        uint32_t uPropHash = childProperty->GetClassHashCode();
+        if (uPropHash == uNameHash) {
+          nodes.Add(childProperty);
+        }
+      } else if (childProperty->GetNameHash() == uNameHash &&
+                 childProperty->GetClassID() != XFA_ELEMENT_Extras &&
+                 childProperty->GetClassID() != XFA_ELEMENT_Items) {
+        nodes.Add(childProperty);
+      }
+    }
+    if (nodes.GetSize() > nNum) {
+      XFA_ResolveNode_FilterCondition(rnd, wsCondition);
+      if (nodes.GetSize() > 0) {
+        return 1;
+      }
+      return 0;
+    }
+    CXFA_Node* pProp = NULL;
+    if (XFA_ELEMENT_Subform == curNode->GetClassID() &&
+        XFA_HASHCODE_Occur == uNameHash) {
+      CXFA_Node* pInstanceManager =
+          curNode->AsNode()->GetInstanceMgrOfSubform();
+      if (pInstanceManager) {
+        pProp = pInstanceManager->GetProperty(0, XFA_ELEMENT_Occur, TRUE);
+      }
+    } else {
+      const XFA_ELEMENTINFO* pElement = XFA_GetElementByName(wsName);
+      if (pElement) {
+        pProp = curNode->AsNode()->GetProperty(
+            0, pElement->eName, pElement->eName != XFA_ELEMENT_PageSet);
+      }
+    }
+    if (pProp) {
+      nodes.Add(pProp);
+      return nodes.GetSize();
+    }
+  }
+  CXFA_Node* parentNode = m_pNodeHelper->XFA_ResolveNodes_GetParent(
+      curNode->AsNode(), XFA_LOGIC_NoTransparent);
+  uint32_t uCurClassHash = curNode->GetClassHashCode();
+  if (!parentNode) {
+    if (uCurClassHash == uNameHash) {
+      nodes.Add(curNode->AsNode());
+      XFA_ResolveNode_FilterCondition(rnd, wsCondition);
+      if (nodes.GetSize() > 0) {
+        return 1;
+      }
+    }
+    return 0;
+  }
+  if (dwStyles & XFA_RESOLVENODE_Siblings) {
+    CXFA_Node* child = parentNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+    FX_DWORD dwSubStyles =
+        XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties;
+    if (dwStyles & XFA_RESOLVENODE_TagName) {
+      dwSubStyles |= XFA_RESOLVENODE_TagName;
+    }
+    if (dwStyles & XFA_RESOLVENODE_ALL) {
+      dwSubStyles |= XFA_RESOLVENODE_ALL;
+    }
+    rndFind.m_dwStyles = dwSubStyles;
+    while (child) {
+      if (child == curNode) {
+        if (dwStyles & XFA_RESOLVENODE_TagName) {
+          if (uCurClassHash == uNameHash) {
+            nodes.Add(curNode);
+          }
+        } else {
+          if (child->GetNameHash() == uNameHash) {
+            nodes.Add(curNode);
+            if (rnd.m_nLevel == 0 && wsCondition.GetLength() == 0) {
+              nodes.RemoveAll();
+              nodes.Add(curNode);
+              return 1;
+            }
+          }
+        }
+        child = child->GetNodeItem(XFA_NODEITEM_NextSibling);
+        continue;
+      }
+      if (dwStyles & XFA_RESOLVENODE_TagName) {
+        if (child->GetClassHashCode() == uNameHash) {
+          nodes.Add(child);
+        }
+      } else if (child->GetNameHash() == uNameHash) {
+        nodes.Add(child);
+      }
+      const XFA_PROPERTY* pPropert = XFA_GetPropertyOfElement(
+          parentNode->GetClassID(), child->GetClassID(), XFA_XDPPACKET_UNKNOWN);
+      FX_BOOL bInnerSearch = FALSE;
+      if (pPropert) {
+        if ((child->GetClassID() == XFA_ELEMENT_Variables ||
+             child->GetClassID() == XFA_ELEMENT_PageSet)) {
+          bInnerSearch = TRUE;
+        }
+      } else {
+        if (m_pNodeHelper->XFA_NodeIsTransparent(child)) {
+          bInnerSearch = TRUE;
+        }
+      }
+      if (bInnerSearch) {
+        rndFind.m_CurNode = child;
+        CFX_WideString wsOriginCondition = rndFind.m_wsCondition;
+        rndFind.m_wsCondition.Empty();
+        FX_DWORD dwOriginStyle = rndFind.m_dwStyles;
+        rndFind.m_dwStyles = dwOriginStyle | XFA_RESOLVENODE_ALL;
+        XFA_ResolveNodes_Normal(rndFind);
+        rndFind.m_dwStyles = dwOriginStyle;
+        rndFind.m_wsCondition = wsOriginCondition;
+        if (rndFind.m_Nodes.GetSize() > 0) {
+          nodes.Append(rndFind.m_Nodes);
+          rndFind.m_Nodes.RemoveAll();
+        }
+      }
+      child = child->GetNodeItem(XFA_NODEITEM_NextSibling);
+    }
+    if (nodes.GetSize() > nNum) {
+      if (m_pNodeHelper->XFA_NodeIsTransparent(parentNode)) {
+        CXFA_NodeArray upArrayNodes;
+        m_pNodeHelper->XFA_CountSiblings(
+            ToNode(nodes[0]), XFA_LOGIC_Transparent, &upArrayNodes,
+            !!(dwStyles & XFA_RESOLVENODE_TagName));
+        if (upArrayNodes.GetSize() > nodes.GetSize()) {
+          upArrayNodes[0] = ToNode(nodes[0]);
+          nodes.RemoveAll();
+          nodes.Append((CXFA_ObjArray&)upArrayNodes);
+          upArrayNodes.RemoveAll();
+        }
+      }
+      XFA_ResolveNode_FilterCondition(rnd, wsCondition);
+      if (nodes.GetSize() > 0) {
+        return 1;
+      }
+      return 0;
+    }
+  }
+  if (dwStyles & XFA_RESOLVENODE_Parent) {
+    FX_DWORD dwSubStyles = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent |
+                           XFA_RESOLVENODE_Properties;
+    if (dwStyles & XFA_RESOLVENODE_TagName) {
+      dwSubStyles |= XFA_RESOLVENODE_TagName;
+    }
+    if (dwStyles & XFA_RESOLVENODE_ALL) {
+      dwSubStyles |= XFA_RESOLVENODE_ALL;
+    }
+    rndFind.m_dwStyles = dwSubStyles;
+    rndFind.m_CurNode = parentNode;
+    CXFA_NodeArray& array = rnd.m_pSC->GetUpObjectArray();
+    array.Add(parentNode);
+    XFA_ResolveNodes_Normal(rndFind);
+    if (rndFind.m_Nodes.GetSize() > 0) {
+      nodes.Append(rndFind.m_Nodes);
+      rndFind.m_Nodes.RemoveAll();
+    }
+    if (nodes.GetSize() > nNum) {
+      return 1;
+    }
+  }
+  return 0;
+}
+int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_Asterisk(
+    CXFA_ResolveNodesData& rnd) {
+  CXFA_Node* curNode = ToNode(rnd.m_CurNode);
+  CXFA_ObjArray& nodes = rnd.m_Nodes;
+  CXFA_NodeArray array;
+  curNode->GetNodeList(array,
+                       XFA_NODEFILTER_Children | XFA_NODEFILTER_Properties);
+  nodes.Append((CXFA_ObjArray&)array);
+  return nodes.GetSize();
+}
+int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_PopStack(
+    CFX_Int32Array& stack) {
+  int32_t nType = -1;
+  int32_t iSize = stack.GetSize() - 1;
+  if (iSize > -1) {
+    nType = stack[iSize];
+    stack.RemoveAt(iSize, 1);
+  }
+  return nType;
+}
+int32_t CXFA_ResolveProcessor::XFA_ResolveNodes_GetFilter(
+    const CFX_WideStringC& wsExpression,
+    int32_t nStart,
+    CXFA_ResolveNodesData& rnd) {
+  FXSYS_assert(nStart > -1);
+  int32_t iLength = wsExpression.GetLength();
+  if (nStart >= iLength) {
+    return 0;
+  }
+  CFX_WideString& wsName = rnd.m_wsName;
+  CFX_WideString& wsCondition = rnd.m_wsCondition;
+  FX_WCHAR* pNameBuf = wsName.GetBuffer(iLength - nStart);
+  FX_WCHAR* pConditionBuf = wsCondition.GetBuffer(iLength - nStart);
+  int32_t nNameCount = 0;
+  int32_t nConditionCount = 0;
+  CFX_Int32Array stack;
+  int32_t nType = -1;
+  const FX_WCHAR* pSrc = wsExpression.GetPtr();
+  FX_WCHAR wPrev = 0, wCur;
+  FX_BOOL bIsCondition = FALSE;
+  while (nStart < iLength) {
+    wCur = pSrc[nStart++];
+    if (wCur == '.') {
+      if (wPrev == '\\') {
+        pNameBuf[nNameCount - 1] = wPrev = '.';
+        continue;
+      }
+      if (nNameCount == 0) {
+        pNameBuf[nNameCount++] = wCur;
+        continue;
+      }
+      FX_WCHAR wLookahead = nStart < iLength ? pSrc[nStart] : 0;
+      if (wLookahead != '[' && wLookahead != '(') {
+        if (nType < 0) {
+          break;
+        }
+      }
+    }
+    if (wCur == '[' || wCur == '(') {
+      bIsCondition = TRUE;
+    } else if (wCur == '.' && nStart < iLength &&
+               (pSrc[nStart] == '[' || pSrc[nStart] == '(')) {
+      bIsCondition = TRUE;
+    }
+    if (bIsCondition) {
+      pConditionBuf[nConditionCount++] = wCur;
+    } else {
+      pNameBuf[nNameCount++] = wCur;
+    }
+    FX_BOOL bRecursive = TRUE;
+    switch (nType) {
+      case 0:
+        if (wCur == ']') {
+          nType = XFA_ResolveNodes_PopStack(stack);
+          bRecursive = FALSE;
+        }
+        break;
+      case 1:
+        if (wCur == ')') {
+          nType = XFA_ResolveNodes_PopStack(stack);
+          bRecursive = FALSE;
+        }
+        break;
+      case 2:
+        if (wCur == '"') {
+          nType = XFA_ResolveNodes_PopStack(stack);
+          bRecursive = FALSE;
+        }
+        break;
+    }
+    if (bRecursive) {
+      switch (wCur) {
+        case '[':
+          stack.Add(nType);
+          nType = 0;
+          break;
+        case '(':
+          stack.Add(nType);
+          nType = 1;
+          break;
+        case '"':
+          stack.Add(nType);
+          nType = 2;
+          break;
+      }
+    }
+    wPrev = wCur;
+  }
+  if (stack.GetSize() > 0) {
+    return -1;
+  }
+  wsName.ReleaseBuffer(nNameCount);
+  wsName.TrimLeft();
+  wsName.TrimRight();
+  wsCondition.ReleaseBuffer(nConditionCount);
+  wsCondition.TrimLeft();
+  wsCondition.TrimRight();
+  rnd.m_uHashName = FX_HashCode_String_GetW(wsName, wsName.GetLength());
+  return nStart;
+}
+void CXFA_ResolveProcessor::XFA_ResolveNode_ConditionArray(
+    int32_t iCurIndex,
+    CFX_WideString wsCondition,
+    int32_t iFoundCount,
+    CXFA_ResolveNodesData& rnd) {
+  CXFA_NodeArray& findNodes = (CXFA_NodeArray&)rnd.m_Nodes;
+  int32_t iLen = wsCondition.GetLength();
+  FX_BOOL bRelative = FALSE;
+  FX_BOOL bAll = FALSE;
+  int32_t i = 1;
+  for (; i < iLen; ++i) {
+    FX_WCHAR ch = wsCondition[i];
+    if (ch == ' ') {
+      continue;
+    }
+    if (ch == '+' || ch == '-') {
+      bRelative = TRUE;
+      break;
+    } else if (ch == '*') {
+      bAll = TRUE;
+      break;
+    } else {
+      break;
+    }
+  }
+  if (bAll) {
+    if (rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) {
+      if (rnd.m_dwStyles & XFA_RESOLVENODE_Bind) {
+        m_pNodeHelper->m_pCreateParent = ToNode(rnd.m_CurNode);
+        m_pNodeHelper->m_iCreateCount = 1;
+        findNodes.RemoveAll();
+        m_pNodeHelper->m_iCurAllStart = -1;
+        m_pNodeHelper->m_pAllStartParent = NULL;
+      } else {
+        if (m_pNodeHelper->m_iCurAllStart == -1) {
+          m_pNodeHelper->m_iCurAllStart = m_iCurStart;
+          m_pNodeHelper->m_pAllStartParent = ToNode(rnd.m_CurNode);
+        }
+      }
+    } else if (rnd.m_dwStyles & XFA_RESOLVENODE_BindNew) {
+      if (m_pNodeHelper->m_iCurAllStart == -1) {
+        m_pNodeHelper->m_iCurAllStart = m_iCurStart;
+      }
+    }
+    return;
+  }
+  if (iFoundCount == 1 && !iLen) {
+    return;
+  }
+  CFX_WideString wsIndex;
+  wsIndex = wsCondition.Mid(i, iLen - 1 - i);
+  int32_t iIndex = wsIndex.GetInteger();
+  if (bRelative) {
+    iIndex += iCurIndex;
+  }
+  if (iFoundCount <= iIndex || iIndex < 0) {
+    if (rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) {
+      m_pNodeHelper->m_pCreateParent = ToNode(rnd.m_CurNode);
+      m_pNodeHelper->m_iCreateCount = iIndex - iFoundCount + 1;
+    }
+    findNodes.RemoveAll();
+  } else {
+    CXFA_Node* ret = findNodes[iIndex];
+    findNodes.RemoveAll();
+    findNodes.Add(ret);
+  }
+}
+void CXFA_ResolveProcessor::XFA_ResolveNode_DoPredicateFilter(
+    int32_t iCurIndex,
+    CFX_WideString wsCondition,
+    int32_t iFoundCount,
+    CXFA_ResolveNodesData& rnd) {
+  CXFA_NodeArray& findNodes = (CXFA_NodeArray&)rnd.m_Nodes;
+  FXSYS_assert(iFoundCount == findNodes.GetSize());
+  CFX_WideString wsExpression;
+  IXFA_ScriptContext* pContext = NULL;
+  XFA_SCRIPTLANGTYPE eLangType = XFA_SCRIPTLANGTYPE_Unkown;
+  if (wsCondition.Left(2) == FX_WSTRC(L".[") &&
+      wsCondition.Right(1) == FX_WSTRC(L"]")) {
+    eLangType = XFA_SCRIPTLANGTYPE_Formcalc;
+  } else if (wsCondition.Left(2) == FX_WSTRC(L".(") &&
+             wsCondition.Right(1) == FX_WSTRC(L")")) {
+    eLangType = XFA_SCRIPTLANGTYPE_Javascript;
+  } else {
+    return;
+  }
+  pContext = rnd.m_pSC;
+  wsExpression = wsCondition.Mid(2, wsCondition.GetLength() - 3);
+  for (int32_t i = iFoundCount - 1; i >= 0; i--) {
+    CXFA_Object* node = findNodes[i];
+    FX_BOOL bRet = FALSE;
+    FXJSE_HVALUE pRetValue = FXJSE_Value_Create(rnd.m_pSC->GetRuntime());
+    bRet = pContext->RunScript(eLangType, wsExpression, pRetValue, node);
+    if (!bRet || !FXJSE_Value_ToBoolean(pRetValue)) {
+      findNodes.RemoveAt(i);
+    }
+    FXJSE_Value_Release(pRetValue);
+  }
+}
+
+void CXFA_ResolveProcessor::XFA_ResolveNode_FilterCondition(
+    CXFA_ResolveNodesData& rnd,
+    CFX_WideString wsCondition) {
+  CXFA_NodeArray& findNodes = (CXFA_NodeArray&)rnd.m_Nodes;
+  int32_t iCurrIndex = 0;
+  const CXFA_NodeArray& array = rnd.m_pSC->GetUpObjectArray();
+  int32_t iSize = array.GetSize();
+  if (iSize) {
+    CXFA_Node* curNode = array[iSize - 1];
+    FX_BOOL bIsProperty = m_pNodeHelper->XFA_NodeIsProperty(curNode);
+    if (curNode->IsUnnamed() ||
+        (bIsProperty && curNode->GetClassID() != XFA_ELEMENT_PageSet)) {
+      iCurrIndex = m_pNodeHelper->XFA_GetIndex(curNode, XFA_LOGIC_Transparent,
+                                               bIsProperty, TRUE);
+    } else {
+      iCurrIndex = m_pNodeHelper->XFA_GetIndex(curNode, XFA_LOGIC_Transparent,
+                                               bIsProperty, FALSE);
+    }
+  }
+  int32_t iFoundCount = findNodes.GetSize();
+  wsCondition.TrimLeft();
+  wsCondition.TrimRight();
+  int32_t iLen = wsCondition.GetLength();
+  if (!iLen) {
+    if (rnd.m_dwStyles & XFA_RESOLVENODE_ALL) {
+      return;
+    }
+    if (iFoundCount == 1) {
+      return;
+    }
+    if (iFoundCount <= iCurrIndex) {
+      if (rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) {
+        m_pNodeHelper->m_pCreateParent = ToNode(rnd.m_CurNode);
+        m_pNodeHelper->m_iCreateCount = iCurrIndex - iFoundCount + 1;
+      }
+      findNodes.RemoveAll();
+      return;
+    } else {
+      CXFA_Node* ret = findNodes[iCurrIndex];
+      findNodes.RemoveAll();
+      findNodes.Add(ret);
+      return;
+    }
+  }
+  FX_WCHAR wTypeChar = wsCondition[0];
+  switch (wTypeChar) {
+    case '[':
+      XFA_ResolveNode_ConditionArray(iCurrIndex, wsCondition, iFoundCount, rnd);
+      return;
+    case '(':
+      return;
+    case '"':
+      return;
+    case '.':
+      if (iLen > 1 && (wsCondition[1] == '[' || wsCondition[1] == '(')) {
+        XFA_ResolveNode_DoPredicateFilter(iCurrIndex, wsCondition, iFoundCount,
+                                          rnd);
+      }
+    default:
+      return;
+  }
+}
+void CXFA_ResolveProcessor::XFA_ResolveNodes_SetStylesForChild(
+    FX_DWORD dwParentStyles,
+    CXFA_ResolveNodesData& rnd) {
+  FX_DWORD dwSubStyles = XFA_RESOLVENODE_Children;
+  if (dwParentStyles & XFA_RESOLVENODE_TagName) {
+    dwSubStyles |= XFA_RESOLVENODE_TagName;
+  }
+  dwSubStyles &= ~XFA_RESOLVENODE_Parent;
+  dwSubStyles &= ~XFA_RESOLVENODE_Siblings;
+  dwSubStyles &= ~XFA_RESOLVENODE_Properties;
+  dwSubStyles |= XFA_RESOLVENODE_ALL;
+  rnd.m_dwStyles = dwSubStyles;
+}
+int32_t CXFA_ResolveProcessor::XFA_ResolveNode_SetResultCreateNode(
+    XFA_RESOLVENODE_RS& resolveNodeRS,
+    CFX_WideString& wsLastCondition) {
+  if (m_pNodeHelper->m_pCreateParent) {
+    resolveNodeRS.nodes.Add(m_pNodeHelper->m_pCreateParent);
+  } else {
+    m_pNodeHelper->XFA_CreateNode_ForCondition(wsLastCondition);
+  }
+  resolveNodeRS.dwFlags = m_pNodeHelper->m_iCreateFlag;
+  if (resolveNodeRS.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeOne) {
+    if (m_pNodeHelper->m_iCurAllStart != -1) {
+      resolveNodeRS.dwFlags = XFA_RESOLVENODE_RSTYPE_CreateNodeMidAll;
+    }
+  }
+  return resolveNodeRS.nodes.GetSize();
+}
+void CXFA_ResolveProcessor::XFA_ResolveNode_SetIndexDataBind(
+    CFX_WideString& wsNextCondition,
+    int32_t& iIndex,
+    int32_t iCount) {
+  if (m_pNodeHelper->XFA_CreateNode_ForCondition(wsNextCondition)) {
+    if (m_pNodeHelper->m_eLastCreateType == XFA_ELEMENT_DataGroup) {
+      iIndex = 0;
+    } else {
+      iIndex = iCount - 1;
+    }
+  } else {
+    iIndex = iCount - 1;
+  }
+}
diff --git a/xfa/fxfa/parser/xfa_script_resolveprocessor.h b/xfa/fxfa/parser/xfa_script_resolveprocessor.h
new file mode 100644
index 0000000..fa34a88
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script_resolveprocessor.h
@@ -0,0 +1,86 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_SCRIPT_RESOLVEPROCESSOR_H_
+#define XFA_FXFA_PARSER_XFA_SCRIPT_RESOLVEPROCESSOR_H_
+
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/include/fxfa/fxfa_objectacc.h"
+
+class CXFA_NodeHelper;
+class CXFA_ScriptContext;
+
+class CXFA_ResolveNodesData {
+ public:
+  CXFA_ResolveNodesData(CXFA_ScriptContext* pSC = NULL)
+      : m_pSC(pSC),
+        m_CurNode(NULL),
+        m_wsName(),
+        m_uHashName(0),
+        m_wsCondition(),
+        m_nLevel(0),
+        m_Nodes(),
+        m_dwStyles(XFA_RESOLVENODE_Children),
+        m_pScriptAttribute(NULL),
+        m_dwFlag(XFA_RESOVENODE_RSTYPE_Nodes) {}
+  ~CXFA_ResolveNodesData() { m_Nodes.RemoveAll(); }
+  CXFA_ScriptContext* m_pSC;
+  CXFA_Object* m_CurNode;
+  CFX_WideString m_wsName;
+  uint32_t m_uHashName;
+  CFX_WideString m_wsCondition;
+  int32_t m_nLevel;
+  CXFA_ObjArray m_Nodes;
+  FX_DWORD m_dwStyles;
+  const XFA_SCRIPTATTRIBUTEINFO* m_pScriptAttribute;
+  XFA_RESOVENODE_RSTYPE m_dwFlag;
+};
+class CXFA_ResolveProcessor {
+ public:
+  CXFA_ResolveProcessor(void);
+  ~CXFA_ResolveProcessor(void);
+  int32_t XFA_ResolveNodes(CXFA_ResolveNodesData& rnd);
+  int32_t XFA_ResolveNodes_AnyChild(CXFA_ResolveNodesData& rnd);
+  int32_t XFA_ResolveNodes_Dollar(CXFA_ResolveNodesData& rnd);
+  int32_t XFA_ResolveNodes_Excalmatory(CXFA_ResolveNodesData& rnd);
+  int32_t XFA_ResolveNodes_NumberSign(CXFA_ResolveNodesData& rnd);
+  int32_t XFA_ResolveNodes_Asterisk(CXFA_ResolveNodesData& rnd);
+  int32_t XFA_ResolveNodes_Normal(CXFA_ResolveNodesData& rnd);
+  int32_t XFA_ResolveNodes_ForAttributeRs(CXFA_Object* curNode,
+                                          CXFA_ResolveNodesData& rnd,
+                                          const CFX_WideStringC& strAttr);
+  void XFA_ResolveNode_ConditionArray(int32_t iCurIndex,
+                                      CFX_WideString wsCondition,
+                                      int32_t iFoundCount,
+                                      CXFA_ResolveNodesData& rnd);
+  void XFA_ResolveNode_DoPredicateFilter(int32_t iCurIndex,
+                                         CFX_WideString wsCondition,
+                                         int32_t iFoundCount,
+                                         CXFA_ResolveNodesData& rnd);
+  int32_t XFA_ResolveNodes_GetFilter(const CFX_WideStringC& wsExpression,
+                                     int32_t nStart,
+                                     CXFA_ResolveNodesData& rnd);
+  void XFA_ResolveNode_FilterCondition(CXFA_ResolveNodesData& rnd,
+                                       CFX_WideString wsCondition);
+  int32_t XFA_ResolveNodes_PopStack(CFX_Int32Array& stack);
+  void XFA_ResolveNodes_SetStylesForChild(FX_DWORD dwParentStyles,
+                                          CXFA_ResolveNodesData& rnd);
+  int32_t XFA_ResolveNode_SetResultCreateNode(XFA_RESOLVENODE_RS& resolveNodeRS,
+                                              CFX_WideString& wsLastCondition);
+  void XFA_ResolveNode_SetIndexDataBind(CFX_WideString& wsNextCondition,
+                                        int32_t& iIndex,
+                                        int32_t iCount);
+  CXFA_NodeHelper* GetNodeHelper() { return m_pNodeHelper; }
+
+ private:
+  CXFA_NodeHelper* m_pNodeHelper;
+
+ public:
+  int32_t m_iCurStart;
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_SCRIPT_RESOLVEPROCESSOR_H_
diff --git a/xfa/fxfa/parser/xfa_script_signaturepseudomodel.cpp b/xfa/fxfa/parser/xfa_script_signaturepseudomodel.cpp
new file mode 100644
index 0000000..ee33eb2
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script_signaturepseudomodel.cpp
@@ -0,0 +1,124 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_script_signaturepseudomodel.h"
+
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+CScript_SignaturePseudoModel::CScript_SignaturePseudoModel(
+    CXFA_Document* pDocument)
+    : CXFA_OrdinaryObject(pDocument, XFA_ELEMENT_SignaturePseudoModel) {
+  m_uScriptHash = XFA_HASHCODE_Signature;
+}
+CScript_SignaturePseudoModel::~CScript_SignaturePseudoModel() {}
+void CScript_SignaturePseudoModel::Script_SignaturePseudoModel_Verify(
+    CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength < 1 || iLength > 4) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"verify");
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  CXFA_Node* pNode = NULL;
+  if (iLength >= 1) {
+    pNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
+  }
+  int32_t bVerify = pNotify->GetDocProvider()->Verify(hDoc, pNode);
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetInteger(hValue, bVerify);
+  }
+}
+void CScript_SignaturePseudoModel::Script_SignaturePseudoModel_Sign(
+    CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength < 3 || iLength > 7) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"sign");
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  CXFA_NodeList* pNodeList = NULL;
+  CFX_WideString wsExpression;
+  CFX_WideString wsXMLIdent;
+  if (iLength >= 1) {
+    pNodeList = (CXFA_NodeList*)pArguments->GetObject(0);
+  }
+  if (iLength >= 2) {
+    CFX_ByteString bsExpression = pArguments->GetUTF8String(1);
+    wsExpression =
+        CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+  }
+  if (iLength >= 3) {
+    CFX_ByteString bsXMLIdent = pArguments->GetUTF8String(2);
+    wsXMLIdent = CFX_WideString::FromUTF8(bsXMLIdent, bsXMLIdent.GetLength());
+  }
+  FX_BOOL bSign = pNotify->GetDocProvider()->Sign(hDoc, pNodeList, wsExpression,
+                                                  wsXMLIdent);
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetBoolean(hValue, bSign);
+  }
+}
+void CScript_SignaturePseudoModel::Script_SignaturePseudoModel_Enumerate(
+    CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength != 0) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"enumerate");
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  CXFA_NodeList* pList = pNotify->GetDocProvider()->Enumerate(hDoc);
+  if (!pList)
+    return;
+  FXJSE_Value_Set(pArguments->GetReturnValue(),
+                  m_pDocument->GetScriptContext()->GetJSValueFromMap(pList));
+}
+void CScript_SignaturePseudoModel::Script_SignaturePseudoModel_Clear(
+    CFXJSE_Arguments* pArguments) {
+  int32_t iLength = pArguments->GetLength();
+  if (iLength < 1 || iLength > 2) {
+    ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, L"clear");
+    return;
+  }
+  IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+  if (!pNotify) {
+    return;
+  }
+  IXFA_Doc* hDoc = pNotify->GetHDOC();
+  CXFA_Node* pNode = NULL;
+  FX_BOOL bClear = TRUE;
+  if (iLength >= 1) {
+    pNode = static_cast<CXFA_Node*>(pArguments->GetObject(0));
+  }
+  if (iLength >= 2) {
+    bClear = pArguments->GetInt32(1) == 0 ? FALSE : TRUE;
+  }
+  FX_BOOL bFlag = pNotify->GetDocProvider()->Clear(hDoc, pNode, bClear);
+  FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+  if (hValue) {
+    FXJSE_Value_SetBoolean(hValue, bFlag);
+  }
+}
diff --git a/xfa/fxfa/parser/xfa_script_signaturepseudomodel.h b/xfa/fxfa/parser/xfa_script_signaturepseudomodel.h
new file mode 100644
index 0000000..2591917
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_script_signaturepseudomodel.h
@@ -0,0 +1,22 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_SCRIPT_SIGNATUREPSEUDOMODEL_H_
+#define XFA_FXFA_PARSER_XFA_SCRIPT_SIGNATUREPSEUDOMODEL_H_
+
+#include "xfa/fxfa/parser/xfa_object.h"
+
+class CScript_SignaturePseudoModel : public CXFA_OrdinaryObject {
+ public:
+  CScript_SignaturePseudoModel(CXFA_Document* pDocument);
+  ~CScript_SignaturePseudoModel();
+  void Script_SignaturePseudoModel_Verify(CFXJSE_Arguments* pArguments);
+  void Script_SignaturePseudoModel_Sign(CFXJSE_Arguments* pArguments);
+  void Script_SignaturePseudoModel_Enumerate(CFXJSE_Arguments* pArguments);
+  void Script_SignaturePseudoModel_Clear(CFXJSE_Arguments* pArguments);
+};
+
+#endif  // XFA_FXFA_PARSER_XFA_SCRIPT_SIGNATUREPSEUDOMODEL_H_
diff --git a/xfa/fxfa/parser/xfa_utils.h b/xfa/fxfa/parser/xfa_utils.h
new file mode 100644
index 0000000..6cc17d9
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_utils.h
@@ -0,0 +1,219 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef XFA_FXFA_PARSER_XFA_UTILS_H_
+#define XFA_FXFA_PARSER_XFA_UTILS_H_
+
+#include "xfa/fde/xml/fde_xml.h"
+#include "xfa/include/fxfa/fxfa_basic.h"
+
+class CXFA_LocaleValue;
+
+FX_BOOL XFA_FDEExtension_ResolveNamespaceQualifier(
+    IFDE_XMLElement* pNode,
+    const CFX_WideStringC& wsQualifier,
+    CFX_WideString& wsNamespaceURI);
+template <class NodeType, class TraverseStrategy>
+class CXFA_NodeIteratorTemplate {
+ public:
+  CXFA_NodeIteratorTemplate(NodeType* pRootNode = NULL) : m_pRoot(pRootNode) {
+    if (pRootNode) {
+      m_NodeStack.Push(pRootNode);
+    }
+  }
+  FX_BOOL Init(NodeType* pRootNode) {
+    if (!pRootNode) {
+      return FALSE;
+    }
+    m_pRoot = pRootNode;
+    m_NodeStack.RemoveAll();
+    m_NodeStack.Push(pRootNode);
+    return TRUE;
+  }
+  void Clear() { m_NodeStack.RemoveAll(); }
+  void Reset() {
+    Clear();
+    if (m_pRoot) {
+      m_NodeStack.Push(m_pRoot);
+    }
+  }
+  FX_BOOL SetCurrent(NodeType* pCurNode) {
+    m_NodeStack.RemoveAll();
+    if (pCurNode) {
+      CFX_StackTemplate<NodeType*> revStack;
+      NodeType* pNode;
+      for (pNode = pCurNode; pNode && pNode != m_pRoot;
+           pNode = TraverseStrategy::GetParent(pNode)) {
+        revStack.Push(pNode);
+      }
+      if (!pNode) {
+        return FALSE;
+      }
+      revStack.Push(m_pRoot);
+      while (revStack.GetSize()) {
+        m_NodeStack.Push(*revStack.GetTopElement());
+        revStack.Pop();
+      }
+    }
+    return TRUE;
+  }
+  NodeType* GetCurrent() const {
+    return m_NodeStack.GetSize() ? *m_NodeStack.GetTopElement() : NULL;
+  }
+  NodeType* GetRoot() const { return m_pRoot; }
+  NodeType* MoveToPrev() {
+    int32_t nStackLength = m_NodeStack.GetSize();
+    if (nStackLength == 1) {
+      return NULL;
+    } else if (nStackLength > 1) {
+      NodeType* pCurItem = *m_NodeStack.GetTopElement();
+      m_NodeStack.Pop();
+      NodeType* pParentItem = *m_NodeStack.GetTopElement();
+      NodeType* pParentFirstChildItem =
+          TraverseStrategy::GetFirstChild(pParentItem);
+      if (pCurItem == pParentFirstChildItem) {
+        return pParentItem;
+      }
+      NodeType *pPrevItem = pParentFirstChildItem, *pPrevItemNext = NULL;
+      for (; pPrevItem; pPrevItem = pPrevItemNext) {
+        pPrevItemNext = TraverseStrategy::GetNextSibling(pPrevItem);
+        if (!pPrevItemNext || pPrevItemNext == pCurItem) {
+          break;
+        }
+      }
+      m_NodeStack.Push(pPrevItem);
+    } else {
+      m_NodeStack.RemoveAll();
+      if (m_pRoot) {
+        m_NodeStack.Push(m_pRoot);
+      }
+    }
+    if (m_NodeStack.GetSize() > 0) {
+      NodeType* pChildItem = *m_NodeStack.GetTopElement();
+      while ((pChildItem = TraverseStrategy::GetFirstChild(pChildItem)) !=
+             NULL) {
+        while (NodeType* pNextItem =
+                   TraverseStrategy::GetNextSibling(pChildItem)) {
+          pChildItem = pNextItem;
+        }
+        m_NodeStack.Push(pChildItem);
+      }
+      return *m_NodeStack.GetTopElement();
+    }
+    return NULL;
+  }
+  NodeType* MoveToNext() {
+    NodeType** ppNode = NULL;
+    NodeType* pCurrent = GetCurrent();
+    while (m_NodeStack.GetSize() > 0) {
+      while ((ppNode = m_NodeStack.GetTopElement())) {
+        if (pCurrent != *ppNode) {
+          return *ppNode;
+        }
+        NodeType* pChild = TraverseStrategy::GetFirstChild(*ppNode);
+        if (pChild == NULL) {
+          break;
+        }
+        m_NodeStack.Push(pChild);
+      }
+      while ((ppNode = m_NodeStack.GetTopElement())) {
+        NodeType* pNext = TraverseStrategy::GetNextSibling(*ppNode);
+        m_NodeStack.Pop();
+        if (m_NodeStack.GetSize() == 0) {
+          break;
+        }
+        if (pNext) {
+          m_NodeStack.Push(pNext);
+          break;
+        }
+      }
+    }
+    return NULL;
+  }
+  NodeType* SkipChildrenAndMoveToNext() {
+    NodeType** ppNode = NULL;
+    while ((ppNode = m_NodeStack.GetTopElement())) {
+      NodeType* pNext = TraverseStrategy::GetNextSibling(*ppNode);
+      m_NodeStack.Pop();
+      if (m_NodeStack.GetSize() == 0) {
+        break;
+      }
+      if (pNext) {
+        m_NodeStack.Push(pNext);
+        break;
+      }
+    }
+    return GetCurrent();
+  }
+
+ protected:
+  NodeType* m_pRoot;
+  CFX_StackTemplate<NodeType*> m_NodeStack;
+};
+template <class KeyType>
+class CXFA_PtrSetTemplate : private CFX_MapPtrToPtr {
+ public:
+  CXFA_PtrSetTemplate() : CFX_MapPtrToPtr(10) {}
+
+  int GetCount() const { return CFX_MapPtrToPtr::GetCount(); }
+
+  FX_BOOL IsEmpty() const { return CFX_MapPtrToPtr::IsEmpty(); }
+
+  FX_BOOL Lookup(KeyType key) const {
+    void* pValue = NULL;
+    return CFX_MapPtrToPtr::Lookup((void*)key, pValue);
+  }
+
+  FX_BOOL operator[](KeyType key) { return Lookup(key); }
+
+  void Add(KeyType key) { CFX_MapPtrToPtr::SetAt((void*)key, (void*)key); }
+
+  FX_BOOL RemoveKey(KeyType key) {
+    return CFX_MapPtrToPtr::RemoveKey((void*)key);
+  }
+
+  void RemoveAll() { CFX_MapPtrToPtr::RemoveAll(); }
+
+  FX_POSITION GetStartPosition() const {
+    return CFX_MapPtrToPtr::GetStartPosition();
+  }
+
+  void GetNextAssoc(FX_POSITION& rNextPosition, KeyType& rKey) const {
+    void* pKey = NULL;
+    void* pValue = NULL;
+    CFX_MapPtrToPtr::GetNextAssoc(rNextPosition, pKey, pValue);
+    rKey = (KeyType)(uintptr_t)pKey;
+  }
+};
+class CXFA_Node;
+class CXFA_WidgetData;
+
+CXFA_Node* XFA_CreateUIChild(CXFA_Node* pNode, XFA_ELEMENT& eWidgetType);
+CXFA_LocaleValue XFA_GetLocaleValue(CXFA_WidgetData* pWidgetData);
+CFX_WideString XFA_NumericLimit(const CFX_WideString& wsValue,
+                                int32_t iLead,
+                                int32_t iTread);
+FX_DOUBLE XFA_WideStringToDouble(const CFX_WideString& wsStringVal);
+FX_DOUBLE XFA_ByteStringToDouble(const CFX_ByteStringC& szStringVal);
+int32_t XFA_MapRotation(int32_t nRotation);
+
+FX_BOOL XFA_RecognizeRichText(IFDE_XMLElement* pRichTextXMLNode);
+void XFA_GetPlainTextFromRichText(IFDE_XMLNode* pXMLNode,
+                                  CFX_WideString& wsPlainText);
+FX_BOOL XFA_FieldIsMultiListBox(CXFA_Node* pFieldNode);
+IFX_Stream* XFA_CreateWideTextRead(const CFX_WideString& wsBuffer);
+FX_BOOL XFA_IsLayoutElement(XFA_ELEMENT eElement,
+                            FX_BOOL bLayoutContainer = FALSE);
+FX_BOOL XFA_IsTakingupSpace(XFA_ATTRIBUTEENUM ePresence);
+FX_BOOL XFA_IsFlowingLayout(XFA_ATTRIBUTEENUM eLayout);
+FX_BOOL XFA_IsHorizontalFlow(XFA_ATTRIBUTEENUM eLayout);
+void XFA_DataExporter_DealWithDataGroupNode(CXFA_Node* pDataNode);
+void XFA_DataExporter_RegenerateFormFile(CXFA_Node* pNode,
+                                         IFX_Stream* pStream,
+                                         const FX_CHAR* pChecksum = NULL,
+                                         FX_BOOL bSaveXML = FALSE);
+
+#endif  // XFA_FXFA_PARSER_XFA_UTILS_H_
diff --git a/xfa/fxfa/parser/xfa_utils_imp.cpp b/xfa/fxfa/parser/xfa_utils_imp.cpp
new file mode 100644
index 0000000..c043e7c
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_utils_imp.cpp
@@ -0,0 +1,403 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+#include "core/include/fxcrt/fx_ext.h"
+#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
+#include "xfa/fxfa/parser/xfa_docdata.h"
+#include "xfa/fxfa/parser/xfa_doclayout.h"
+#include "xfa/fxfa/parser/xfa_document.h"
+#include "xfa/fxfa/parser/xfa_localemgr.h"
+#include "xfa/fxfa/parser/xfa_localevalue.h"
+#include "xfa/fxfa/parser/xfa_object.h"
+#include "xfa/fxfa/parser/xfa_parser.h"
+#include "xfa/fxfa/parser/xfa_script.h"
+
+CXFA_Node* XFA_CreateUIChild(CXFA_Node* pNode, XFA_ELEMENT& eWidgetType) {
+  XFA_ELEMENT eType = pNode->GetClassID();
+  eWidgetType = eType;
+  if (eType != XFA_ELEMENT_Field && eType != XFA_ELEMENT_Draw) {
+    return NULL;
+  }
+  eWidgetType = XFA_ELEMENT_UNKNOWN;
+  XFA_ELEMENT eUIType = XFA_ELEMENT_UNKNOWN;
+  CXFA_Value defValue(pNode->GetProperty(0, XFA_ELEMENT_Value, TRUE));
+  XFA_ELEMENT eValueType = (XFA_ELEMENT)defValue.GetChildValueClassID();
+  switch (eValueType) {
+    case XFA_ELEMENT_Boolean:
+      eUIType = XFA_ELEMENT_CheckButton;
+      break;
+    case XFA_ELEMENT_Integer:
+    case XFA_ELEMENT_Decimal:
+    case XFA_ELEMENT_Float:
+      eUIType = XFA_ELEMENT_NumericEdit;
+      break;
+    case XFA_ELEMENT_ExData:
+    case XFA_ELEMENT_Text:
+      eUIType = XFA_ELEMENT_TextEdit;
+      eWidgetType = XFA_ELEMENT_Text;
+      break;
+    case XFA_ELEMENT_Date:
+    case XFA_ELEMENT_Time:
+    case XFA_ELEMENT_DateTime:
+      eUIType = XFA_ELEMENT_DateTimeEdit;
+      break;
+    case XFA_ELEMENT_Image:
+      eUIType = XFA_ELEMENT_ImageEdit;
+      eWidgetType = XFA_ELEMENT_Image;
+      break;
+    case XFA_ELEMENT_Arc:
+    case XFA_ELEMENT_Line:
+    case XFA_ELEMENT_Rectangle:
+      eUIType = XFA_ELEMENT_DefaultUi;
+      eWidgetType = eValueType;
+      break;
+    default:
+      break;
+  }
+  CXFA_Node* pUIChild = NULL;
+  CXFA_Node* pUI = pNode->GetProperty(0, XFA_ELEMENT_Ui, TRUE);
+  CXFA_Node* pChild = pUI->GetNodeItem(XFA_NODEITEM_FirstChild);
+  for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+    XFA_ELEMENT eChild = pChild->GetClassID();
+    if (eChild == XFA_ELEMENT_Extras || eChild == XFA_ELEMENT_Picture) {
+      continue;
+    }
+    const XFA_PROPERTY* pProperty =
+        XFA_GetPropertyOfElement(XFA_ELEMENT_Ui, eChild, XFA_XDPPACKET_Form);
+    if (pProperty && (pProperty->uFlags & XFA_PROPERTYFLAG_OneOf)) {
+      pUIChild = pChild;
+      break;
+    }
+  }
+  if (eType == XFA_ELEMENT_Draw) {
+    XFA_ELEMENT eDraw = pUIChild ? pUIChild->GetClassID() : XFA_ELEMENT_UNKNOWN;
+    switch (eDraw) {
+      case XFA_ELEMENT_TextEdit:
+        eWidgetType = XFA_ELEMENT_Text;
+        break;
+      case XFA_ELEMENT_ImageEdit:
+        eWidgetType = XFA_ELEMENT_Image;
+        break;
+      default:
+        eWidgetType =
+            eWidgetType == XFA_ELEMENT_UNKNOWN ? XFA_ELEMENT_Text : eWidgetType;
+        break;
+    }
+  } else {
+    if (pUIChild && pUIChild->GetClassID() == XFA_ELEMENT_DefaultUi) {
+      eWidgetType = XFA_ELEMENT_TextEdit;
+    } else {
+      eWidgetType = pUIChild
+                        ? pUIChild->GetClassID()
+                        : (eUIType == XFA_ELEMENT_UNKNOWN ? XFA_ELEMENT_TextEdit
+                                                          : eUIType);
+    }
+  }
+  if (!pUIChild) {
+    if (eUIType == XFA_ELEMENT_UNKNOWN) {
+      eUIType = XFA_ELEMENT_TextEdit;
+      defValue.GetNode()->GetProperty(0, XFA_ELEMENT_Text, TRUE);
+    }
+    pUIChild = pUI->GetProperty(0, eUIType, TRUE);
+  } else if (eUIType == XFA_ELEMENT_UNKNOWN) {
+    switch (pUIChild->GetClassID()) {
+      case XFA_ELEMENT_CheckButton: {
+        eValueType = XFA_ELEMENT_Text;
+        if (CXFA_Node* pItems = pNode->GetChild(0, XFA_ELEMENT_Items)) {
+          if (CXFA_Node* pItem = pItems->GetChild(0, XFA_ELEMENT_UNKNOWN)) {
+            eValueType = pItem->GetClassID();
+          }
+        }
+      } break;
+      case XFA_ELEMENT_DateTimeEdit:
+        eValueType = XFA_ELEMENT_DateTime;
+        break;
+      case XFA_ELEMENT_ImageEdit:
+        eValueType = XFA_ELEMENT_Image;
+        break;
+      case XFA_ELEMENT_NumericEdit:
+        eValueType = XFA_ELEMENT_Float;
+        break;
+      case XFA_ELEMENT_ChoiceList: {
+        eValueType = (pUIChild->GetEnum(XFA_ATTRIBUTE_Open) ==
+                      XFA_ATTRIBUTEENUM_MultiSelect)
+                         ? XFA_ELEMENT_ExData
+                         : XFA_ELEMENT_Text;
+      } break;
+      case XFA_ELEMENT_Barcode:
+      case XFA_ELEMENT_Button:
+      case XFA_ELEMENT_PasswordEdit:
+      case XFA_ELEMENT_Signature:
+      case XFA_ELEMENT_TextEdit:
+      default:
+        eValueType = XFA_ELEMENT_Text;
+        break;
+    }
+    defValue.GetNode()->GetProperty(0, eValueType, TRUE);
+  }
+  return pUIChild;
+}
+CXFA_LocaleValue XFA_GetLocaleValue(CXFA_WidgetData* pWidgetData) {
+  CXFA_Node* pNodeValue =
+      pWidgetData->GetNode()->GetChild(0, XFA_ELEMENT_Value);
+  if (!pNodeValue) {
+    return CXFA_LocaleValue();
+  }
+  CXFA_Node* pValueChild = pNodeValue->GetNodeItem(XFA_NODEITEM_FirstChild);
+  if (!pValueChild) {
+    return CXFA_LocaleValue();
+  }
+  int32_t iVTType = XFA_VT_NULL;
+  XFA_ELEMENT eType = pValueChild->GetClassID();
+  switch (eType) {
+    case XFA_ELEMENT_Decimal:
+      iVTType = XFA_VT_DECIMAL;
+      break;
+    case XFA_ELEMENT_Float:
+      iVTType = XFA_VT_FLOAT;
+      break;
+    case XFA_ELEMENT_Date:
+      iVTType = XFA_VT_DATE;
+      break;
+    case XFA_ELEMENT_Time:
+      iVTType = XFA_VT_TIME;
+      break;
+    case XFA_ELEMENT_DateTime:
+      iVTType = XFA_VT_DATETIME;
+      break;
+    case XFA_ELEMENT_Boolean:
+      iVTType = XFA_VT_BOOLEAN;
+      break;
+    case XFA_ELEMENT_Integer:
+      iVTType = XFA_VT_INTEGER;
+      break;
+    case XFA_ELEMENT_Text:
+      iVTType = XFA_VT_TEXT;
+      break;
+    default:
+      iVTType = XFA_VT_NULL;
+      break;
+  }
+  return CXFA_LocaleValue(iVTType, pWidgetData->GetRawValue(),
+                          pWidgetData->GetNode()->GetDocument()->GetLocalMgr());
+}
+void XFA_GetPlainTextFromRichText(IFDE_XMLNode* pXMLNode,
+                                  CFX_WideString& wsPlainText) {
+  if (pXMLNode == NULL) {
+    return;
+  }
+  switch (pXMLNode->GetType()) {
+    case FDE_XMLNODE_Element: {
+      IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLNode;
+      CFX_WideString wsTag;
+      pXMLElement->GetLocalTagName(wsTag);
+      uint32_t uTag = FX_HashCode_String_GetW(wsTag, wsTag.GetLength(), TRUE);
+      if (uTag == 0x0001f714) {
+        wsPlainText += L"\n";
+      } else if (uTag == 0x00000070) {
+        if (!wsPlainText.IsEmpty()) {
+          wsPlainText += L"\n";
+        }
+      } else if (uTag == 0xa48ac63) {
+        if (!wsPlainText.IsEmpty() &&
+            wsPlainText[wsPlainText.GetLength() - 1] != '\n') {
+          wsPlainText += L"\n";
+        }
+      }
+    } break;
+    case FDE_XMLNODE_Text: {
+      CFX_WideString wsContent;
+      ((IFDE_XMLText*)pXMLNode)->GetText(wsContent);
+      wsPlainText += wsContent;
+    } break;
+    case FDE_XMLNODE_CharData: {
+      CFX_WideString wsCharData;
+      ((IFDE_XMLCharData*)pXMLNode)->GetCharData(wsCharData);
+      wsPlainText += wsCharData;
+    } break;
+    default:
+      break;
+  }
+  for (IFDE_XMLNode* pChildXML =
+           pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild);
+       pChildXML;
+       pChildXML = pChildXML->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+    XFA_GetPlainTextFromRichText(pChildXML, wsPlainText);
+  }
+}
+FX_BOOL XFA_FieldIsMultiListBox(CXFA_Node* pFieldNode) {
+  FX_BOOL bRet = FALSE;
+  if (!pFieldNode) {
+    return bRet;
+  }
+  CXFA_Node* pUIChild = pFieldNode->GetChild(0, XFA_ELEMENT_Ui);
+  if (pUIChild) {
+    CXFA_Node* pFirstChild = pUIChild->GetNodeItem(XFA_NODEITEM_FirstChild);
+    if (pFirstChild && pFirstChild->GetClassID() == XFA_ELEMENT_ChoiceList) {
+      bRet = pFirstChild->GetEnum(XFA_ATTRIBUTE_Open) ==
+             XFA_ATTRIBUTEENUM_MultiSelect;
+    }
+  }
+  return bRet;
+}
+FX_BOOL XFA_IsLayoutElement(XFA_ELEMENT eElement, FX_BOOL bLayoutContainer) {
+  switch (eElement) {
+    case XFA_ELEMENT_Draw:
+    case XFA_ELEMENT_Field:
+    case XFA_ELEMENT_InstanceManager:
+      return !bLayoutContainer;
+    case XFA_ELEMENT_Area:
+    case XFA_ELEMENT_Subform:
+    case XFA_ELEMENT_ExclGroup:
+    case XFA_ELEMENT_SubformSet:
+      return TRUE;
+    case XFA_ELEMENT_PageArea:
+    case XFA_ELEMENT_Form:
+      return TRUE;
+    default:
+      return FALSE;
+  }
+  return FALSE;
+}
+FX_BOOL XFA_IsTakingupSpace(XFA_ATTRIBUTEENUM ePresence) {
+  switch (ePresence) {
+    case XFA_ATTRIBUTEENUM_Visible:
+    case XFA_ATTRIBUTEENUM_Invisible:
+      return TRUE;
+    default:
+      return FALSE;
+  }
+  return FALSE;
+}
+FX_BOOL XFA_IsFlowingLayout(XFA_ATTRIBUTEENUM eLayout) {
+  switch (eLayout) {
+    case XFA_ATTRIBUTEENUM_Tb:
+    case XFA_ATTRIBUTEENUM_Lr_tb:
+    case XFA_ATTRIBUTEENUM_Rl_tb:
+      return TRUE;
+    default:
+      return FALSE;
+  }
+  return FALSE;
+}
+FX_BOOL XFA_IsHorizontalFlow(XFA_ATTRIBUTEENUM eLayout) {
+  switch (eLayout) {
+    case XFA_ATTRIBUTEENUM_Lr_tb:
+    case XFA_ATTRIBUTEENUM_Rl_tb:
+      return TRUE;
+    default:
+      return FALSE;
+  }
+  return FALSE;
+}
+static const FX_DOUBLE fraction_scales[] = {0.1,
+                                            0.01,
+                                            0.001,
+                                            0.0001,
+                                            0.00001,
+                                            0.000001,
+                                            0.0000001,
+                                            0.00000001,
+                                            0.000000001,
+                                            0.0000000001,
+                                            0.00000000001,
+                                            0.000000000001,
+                                            0.0000000000001,
+                                            0.00000000000001,
+                                            0.000000000000001,
+                                            0.0000000000000001};
+FX_DOUBLE XFA_WideStringToDouble(const CFX_WideString& wsStringVal) {
+  CFX_WideString wsValue = wsStringVal;
+  wsValue.TrimLeft();
+  wsValue.TrimRight();
+  int64_t nIntegral = 0;
+  FX_DWORD dwFractional = 0;
+  int32_t nExponent = 0;
+  int32_t cc = 0;
+  FX_BOOL bNegative = FALSE, bExpSign = FALSE;
+  const FX_WCHAR* str = (const FX_WCHAR*)wsValue;
+  int32_t len = wsValue.GetLength();
+  if (str[0] == '+') {
+    cc++;
+  } else if (str[0] == '-') {
+    bNegative = TRUE;
+    cc++;
+  }
+  int32_t nIntegralLen = 0;
+  while (cc < len) {
+    if (str[cc] == '.' || str[cc] == 'E' || str[cc] == 'e' ||
+        nIntegralLen > 17) {
+      break;
+    }
+    if (!XFA_IsDigit(str[cc])) {
+      return 0;
+    }
+    nIntegral = nIntegral * 10 + str[cc] - '0';
+    cc++;
+    nIntegralLen++;
+  }
+  nIntegral = bNegative ? -nIntegral : nIntegral;
+  int32_t scale = 0;
+  FX_DOUBLE fraction = 0.0;
+  if (cc < len && str[cc] == '.') {
+    cc++;
+    while (cc < len) {
+      fraction += fraction_scales[scale] * (str[cc] - '0');
+      scale++;
+      cc++;
+      if (cc == len) {
+        break;
+      }
+      if (scale == sizeof(fraction_scales) / sizeof(FX_DOUBLE) ||
+          str[cc] == 'E' || str[cc] == 'e') {
+        break;
+      }
+      if (!XFA_IsDigit(str[cc])) {
+        return 0;
+      }
+    }
+    dwFractional = (FX_DWORD)(fraction * 4294967296.0);
+  }
+  if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) {
+    cc++;
+    if (cc < len) {
+      if (str[cc] == '+') {
+        cc++;
+      } else if (str[cc] == '-') {
+        bExpSign = TRUE;
+        cc++;
+      }
+    }
+    while (cc < len) {
+      if (str[cc] == '.' || !XFA_IsDigit(str[cc])) {
+        return 0;
+      }
+      nExponent = nExponent * 10 + str[cc] - '0';
+      cc++;
+    }
+    nExponent = bExpSign ? -nExponent : nExponent;
+  }
+  FX_DOUBLE dValue = (dwFractional / 4294967296.0);
+  dValue = nIntegral + (nIntegral >= 0 ? dValue : -dValue);
+  if (nExponent != 0) {
+    dValue *= FXSYS_pow(10, (FX_FLOAT)nExponent);
+  }
+  return dValue;
+}
+
+FX_DOUBLE XFA_ByteStringToDouble(const CFX_ByteStringC& szStringVal) {
+  CFX_WideString wsValue =
+      CFX_WideString::FromUTF8(szStringVal.GetCStr(), szStringVal.GetLength());
+  return XFA_WideStringToDouble(wsValue);
+}
+
+int32_t XFA_MapRotation(int32_t nRotation) {
+  nRotation = nRotation % 360;
+  nRotation = nRotation < 0 ? nRotation + 360 : nRotation;
+  return nRotation;
+}
diff --git a/xfa/fxfa/parser/xfa_utils_imp_unittest.cpp b/xfa/fxfa/parser/xfa_utils_imp_unittest.cpp
new file mode 100644
index 0000000..93ee3b9
--- /dev/null
+++ b/xfa/fxfa/parser/xfa_utils_imp_unittest.cpp
@@ -0,0 +1,22 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "xfa/fxfa/parser/xfa_utils.h"
+
+TEST(XfaUtilsImp, XFA_MapRotation) {
+  struct TestCase {
+    int input;
+    int expected_output;
+  } TestCases[] = {{-1000000, 80}, {-361, 359}, {-360, 0},  {-359, 1},
+                   {-91, 269},     {-90, 270},  {-89, 271}, {-1, 359},
+                   {0, 0},         {1, 1},      {89, 89},   {90, 90},
+                   {91, 91},       {359, 359},  {360, 0},   {361, 1},
+                   {100000, 280}};
+
+  for (size_t i = 0; i < FX_ArraySize(TestCases); ++i) {
+    EXPECT_EQ(TestCases[i].expected_output,
+              XFA_MapRotation(TestCases[i].input));
+  }
+}