← Back to team overview

ubuntu-touch-coreapps-reviewers team mailing list archive

[Merge] lp:~qqworini/ubuntu-rssreader-app/new-settings-help into lp:ubuntu-rssreader-app

 

Joey Chan has proposed merging lp:~qqworini/ubuntu-rssreader-app/new-settings-help into lp:ubuntu-rssreader-app.

Commit message:
0. replace U1DB with QSettings
1. add a help page
2. add an info page

To all reviewers,  in those new added pages, some words, sentences or statements may NOT right or NOT accurate, pls help me to correct them before merge  :)

Requested reviews:
  Ubuntu Shorts Developers (ubuntu-shorts-dev)
Related bugs:
  Bug #1553740 in Ubuntu Shorts App: "Typo in Shorts"
  https://bugs.launchpad.net/ubuntu-rssreader-app/+bug/1553740

For more details, see:
https://code.launchpad.net/~qqworini/ubuntu-rssreader-app/new-settings-help/+merge/289180

0. replace U1DB with QSettings
1. add a help page
2. add an info page
-- 
Your team Ubuntu Shorts Developers is requested to review the proposed merge of lp:~qqworini/ubuntu-rssreader-app/new-settings-help into lp:ubuntu-rssreader-app.
=== modified file 'shorts/CMakeLists.txt'
--- shorts/CMakeLists.txt	2015-12-02 17:03:41 +0000
+++ shorts/CMakeLists.txt	2016-03-16 12:38:32 +0000
@@ -5,7 +5,7 @@
     main.cpp
     CachingNetworkManagerFactory.cpp
     shorts.qrc
-    xml2json/utilities.cpp
+    utilities.cpp
 
     )
 

=== modified file 'shorts/main.cpp'
--- shorts/main.cpp	2015-12-02 17:03:41 +0000
+++ shorts/main.cpp	2016-03-16 12:38:32 +0000
@@ -3,7 +3,7 @@
 #include <QtQuick>
 
 #include "CachingNetworkManagerFactory.h"
-#include "xml2json/utilities.h"
+#include "utilities.h"
 
 int main(int argc, char *argv[])
 {

=== modified file 'shorts/po/com.ubuntu.shorts.pot'
--- shorts/po/com.ubuntu.shorts.pot	2016-03-11 21:32:19 +0000
+++ shorts/po/com.ubuntu.shorts.pot	2016-03-16 12:38:32 +0000
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-14 22:46+0800\n"
+"POT-Creation-Date: 2016-03-11 20:54+0800\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@xxxxxx>\n"
@@ -65,8 +65,8 @@
 msgstr ""
 
 #: ../qml/nongoogle/AppendNGFeedPage.qml:30 ../qml/pages/AppendFeedPage.qml:31
-#: ../qml/shorts-app.qml:255 ../qml/shorts-app.qml:390
-#: ../qml/shorts-app.qml:398
+#: ../qml/shorts-app.qml:265 ../qml/shorts-app.qml:403
+#: ../qml/shorts-app.qml:411
 msgid "Add feeds"
 msgstr ""
 
@@ -90,7 +90,7 @@
 
 #: ../qml/nongoogle/AppendNGFeedPage.qml:197
 #: ../qml/pages/AppendFeedPage.qml:243 ../qml/pages/CreateTopicPage.qml:38
-#: ../qml/pages/TopicManagement.qml:239 ../qml/shorts-app.qml:481
+#: ../qml/pages/TopicManagement.qml:239 ../qml/shorts-app.qml:494
 msgid "Cancel"
 msgstr ""
 
@@ -157,7 +157,6 @@
 
 #: ../qml/pages/ChooseTopicPage.qml:109 ../qml/pages/ChooseTopicPage.qml:122
 #: ../qml/pages/CreateTopicPage.qml:66 ../qml/pages/CreateTopicPage.qml:78
-#: ../qml/shorts-app.qml:568
 msgid "Warning"
 msgstr ""
 
@@ -201,32 +200,159 @@
 msgid "Topic: "
 msgstr ""
 
-#: ../qml/pages/PageSettings.qml:9 ../qml/shorts-app.qml:239
+#: ../qml/pages/PageHelp.qml:15
+msgid "Welcome to Shorts"
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:17
+msgid "View Articles"
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:19
+msgid "Search RSS"
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:21
+msgid "Manage topics and feeds"
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:23
+msgid "Location"
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:25
+msgid "Enjoy"
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:105
+msgid "Shorts is an RSS reader app developed by Canonical & Ubuntu Comunity."
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:110
+msgid ""
+"Shorts provides most primary features which also can be seen in other RSS "
+"reader apps, with a beautiful Ubuntu style user interface."
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:117
+msgid "Swipe left to continue."
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:136
+msgid "Scroll left/right in grid mode or scroll up/down in list mode."
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:163
+msgid ""
+"Swipe up will enter this search page, just type any simple words, or paste a "
+"link."
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:190
+msgid ""
+"Every feed must belong to one topic, swipe one item to delete feed/topic."
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:223
+msgid "Seems you are living in: "
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:232
+msgid ""
+"Some regions/countries(e.g. China) may block Google service, if you're "
+"living there or plan to go there, we suggest to trun off the build-in Google "
+"RSS service in settings page, or nothing you should care."
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:239
+msgid ""
+"We detect that you're living in some region/country(e.g. China) which blocks "
+"Google service, so Shorts disable the build-in Google RSS service by "
+"default. You still can turn it on here or in settings page."
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:250
+msgid "Use Google RSS engine: "
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:287
+msgid "Enjoy !"
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:297
+msgid "Do not show this help page again "
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:316
+msgid "Start using Shorts !"
+msgstr ""
+
+#: ../qml/pages/PageHelp.qml:340
+msgid "Skip"
+msgstr ""
+
+#: ../qml/pages/PageInfo.qml:10
+msgid "About Shorts"
+msgstr ""
+
+#: ../qml/pages/PageInfo.qml:39
+msgid "Author"
+msgstr ""
+
+#: ../qml/pages/PageInfo.qml:53
+msgid "Copyleft"
+msgstr ""
+
+#: ../qml/pages/PageInfo.qml:57
+msgid "License with GPLv3"
+msgstr ""
+
+#: ../qml/pages/PageInfo.qml:62
+msgid ""
+"Ubuntu Shorts App is the official rss reader app for Ubuntu Touch. We follow "
+"an open source model where the code is available to anyone to branch and "
+"hack on. The ubuntu shorts app follows a test driven development (TDD) where "
+"tests are written in parallel to feature implementation to help spot "
+"regressions easier."
+msgstr ""
+
+#: ../qml/pages/PageInfo.qml:68
+msgid "Click here to report a bug"
+msgstr ""
+
+#: ../qml/pages/PageSettings.qml:9 ../qml/shorts-app.qml:249
 msgid "Settings"
 msgstr ""
 
-#: ../qml/pages/PageSettings.qml:38
+#: ../qml/pages/PageSettings.qml:15
+msgid "Help"
+msgstr ""
+
+#: ../qml/pages/PageSettings.qml:20
+msgid "Info"
+msgstr ""
+
+#: ../qml/pages/PageSettings.qml:51
 msgid ""
-"For those who living in some special regions cannot access Google, the "
-"switch below can disable Google RSS engine, Shorts will directly gets data "
-"from RSS sources."
+"Some special regions/countries block Google service, we suggest to turn off "
+"the switch below if living in there."
 msgstr ""
 
-#: ../qml/pages/PageSettings.qml:46
+#: ../qml/pages/PageSettings.qml:59
 msgid "Use Google Search: "
 msgstr ""
 
-#: ../qml/pages/PageSettings.qml:71
+#: ../qml/pages/PageSettings.qml:84
 msgid ""
 "For those users, who want to import their RSS feeds from other sources, "
 "please press the button below."
 msgstr ""
 
-#: ../qml/pages/PageSettings.qml:81
-msgid "Import OMPL"
+#: ../qml/pages/PageSettings.qml:94
+msgid "Import OPML"
 msgstr ""
 
-#: ../qml/pages/TopicManagement.qml:13 ../qml/shorts-app.qml:219
+#: ../qml/pages/TopicManagement.qml:13 ../qml/shorts-app.qml:229
 msgid "Edit topics"
 msgstr ""
 
@@ -234,88 +360,50 @@
 msgid "Add Feed"
 msgstr ""
 
-#: ../qml/shorts-app.qml:186
+#: ../qml/shorts-app.qml:196
 msgid "Refresh"
 msgstr ""
 
-#: ../qml/shorts-app.qml:193
+#: ../qml/shorts-app.qml:203
 msgid "Grid View"
 msgstr ""
 
-#: ../qml/shorts-app.qml:193
+#: ../qml/shorts-app.qml:203
 msgid "List view"
 msgstr ""
 
-#: ../qml/shorts-app.qml:229
+#: ../qml/shorts-app.qml:239
 msgid "Disable night mode"
 msgstr ""
 
-#: ../qml/shorts-app.qml:229
+#: ../qml/shorts-app.qml:239
 msgid "Enable night mode"
 msgstr ""
 
-#: ../qml/shorts-app.qml:321
+#: ../qml/shorts-app.qml:334
 msgid "Saved"
 msgstr ""
 
-#: ../qml/shorts-app.qml:329 shorts.desktop.in.in.h:1
+#: ../qml/shorts-app.qml:342 shorts.desktop.in.in.h:1
 msgid "Shorts"
 msgstr ""
 
-#: ../qml/shorts-app.qml:473
+#: ../qml/shorts-app.qml:486
 msgid "Checking for new articles"
 msgstr ""
 
-#: ../qml/shorts-app.qml:497
+#: ../qml/shorts-app.qml:510
 msgid "Perhaps some of the channels have not been updated."
 msgstr ""
 
-#: ../qml/shorts-app.qml:498
+#: ../qml/shorts-app.qml:511
 msgid "Errors occurred during the update"
 msgstr ""
 
-#: ../qml/shorts-app.qml:516
-msgid "+ Add feeds"
-msgstr ""
-
-#: ../qml/shorts-app.qml:528
-msgid "Add online accounts"
-msgstr ""
-
-#: ../qml/shorts-app.qml:531
-msgid "Online accounts are not available for now"
-msgstr ""
-
-#: ../qml/shorts-app.qml:532 ../qml/shorts-app.qml:541
-msgid "We are sorry"
-msgstr ""
-
-#: ../qml/shorts-app.qml:537
-msgid "Import subscriptions"
-msgstr ""
-
-#: ../qml/shorts-app.qml:540
-msgid "Importing subscriptions is not available for now"
-msgstr ""
-
-#: ../qml/shorts-app.qml:555
+#: ../qml/shorts-app.qml:525
 msgid "Ok"
 msgstr ""
 
-#: ../qml/shorts-app.qml:569
-msgid ""
-"Shorts detects that you're located in an area which blocks Google's IP."
-"<br><br>"
-msgstr ""
-
-#: ../qml/shorts-app.qml:574
-msgid "Yes, please."
-msgstr ""
-
-#: ../qml/shorts-app.qml:584
-msgid "No, thanks."
-msgstr ""
-
 #: ../qml/tabs/BaseTab.qml:153
 msgid "There are no articles to show"
 msgstr ""

=== modified file 'shorts/qml/components/NetworkManager.qml'
--- shorts/qml/components/NetworkManager.qml	2016-01-16 10:55:38 +0000
+++ shorts/qml/components/NetworkManager.qml	2016-03-16 12:38:32 +0000
@@ -183,7 +183,7 @@
         property var googleFeedApi: GoogleFeedApi {
             onLoadResult: {
                 if (result.responseStatus !== 200) {
-                    console.log("XML NETWORK GFA:", JSON.stringify(result))
+//                    console.log("XML NETWORK GFA:", JSON.stringify(result))
                     if (operationStatus == "success")
                         operationStatus = "withErrors"
                 } else d.updateFeedInfo(d.currentFeed.id, d.currentFeed.link, result.responseData)
@@ -195,7 +195,7 @@
         property var nonGoogleFeedApi: XmlNetwork {
             onLoadResult: {
                 if (!result.rss) {
-                    console.log("XML NETWORK NGA:", JSON.stringify(result))
+//                    console.log("XML NETWORK NGA:", JSON.stringify(result))
                     if (operationStatus == "success")
                         operationStatus = "withErrors"
                 } else d.updateFeedInfoNg(d.currentFeed.id, d.currentFeed.link, result.rss.channel)

=== modified file 'shorts/qml/components/OptionsKeeper.qml'
--- shorts/qml/components/OptionsKeeper.qml	2016-01-04 11:46:35 +0000
+++ shorts/qml/components/OptionsKeeper.qml	2016-03-16 12:38:32 +0000
@@ -3,6 +3,10 @@
 
 /* New interface for options.
  * Currently it is just facade on U1DB.
+ *
+ * ******* New changes, since 27.Feb.2016
+ * We decide to replace U1DB with QSettings, which is more reliable & light weight
+ * properties & functions remain the same
  */
 Item {
 
@@ -11,70 +15,91 @@
     property bool useListMode
     property bool useGoogleSearch
 
+    property bool needPopup
+
     Component.onCompleted: {
+        // initial first use of QSettings
+        if (utilities.getSetting("firstSetting") == "") {
+            utilities.setSetting("firstSetting", "used!")
+            utilities.setSetting("needPopup", "true")
+            utilities.setSetting("dbVersion", "1.2")
+            utilities.setSetting("fontSize", String(settingsDocument.contents.fontSize))
+            utilities.setSetting("useDarkTheme", String(settingsDocument.contents.useDarkTheme))
+            utilities.setSetting("useListMode", String(settingsDocument.contents.useListMode))
+            utilities.setSetting("useGoogleSearch", "true")
+        }
+
         fontSize = getFontSize()
         useDarkTheme = getUseDarkTheme()
         useListMode = getUseListMode()
         useGoogleSearch = getUseGoogleSearch()
+        needPopup = getNeedPopup()
     }
 
     onFontSizeChanged: setFontSize(fontSize)
     onUseDarkThemeChanged: setUseDarkTheme(useDarkTheme)
     onUseListModeChanged: setUseListMode(useListMode)
     onUseGoogleSearchChanged: setUseGoogleSearch(useGoogleSearch)
+    onNeedPopupChanged: setNeedPopup(needPopup)
+
+    function getNeedPopup() {
+        var tmp = utilities.getSetting("needPopup")
+        if (tmp == "true") return true
+        if (tmp == "false") return false
+    }
+
+    function setNeedPopup(value) {
+        utilities.setSetting("needPopup", String(value))
+    }
 
     function getFontSize() {
-        return settingsDocument.contents.fontSize
+        return Number(utilities.getSetting("fontSize"))
     }
 
     function setFontSize(value) {
-        var cont = settingsDocument.contents
-        cont.fontSize = value
-        settingsDocument.contents = cont
+        utilities.setSetting("fontSize", String(value))
     }
 
     function getUseDarkTheme() {
-        return settingsDocument.contents.useDarkTheme
+        var tmp = utilities.getSetting("useDarkTheme")
+        if (tmp == "true") return true
+        if (tmp == "false") return false
     }
 
     function setUseDarkTheme(value) {
-        var cont = settingsDocument.contents
-        cont.useDarkTheme = value
-        settingsDocument.contents = cont
+        utilities.setSetting("useDarkTheme", String(value))
     }
 
     function getUseListMode() {
-        return settingsDocument.contents.useListMode
+        var tmp = utilities.getSetting("useListMode")
+        if (tmp == "true") return true
+        if (tmp == "false") return false
     }
 
     function setUseListMode(value) {
-        var cont = settingsDocument.contents
-        cont.useListMode = value
-        settingsDocument.contents = cont
+        utilities.setSetting("useListMode", String(value))
     }
 
     function dbVersion() {
-        return settingsDocument.contents.dbVersion
+        return utilities.getSetting("dbVersion")
     }
 
     function setDbVersion(value) {
-        var cont = settingsDocument.contents
-        cont.dbVersion = value
-        settingsDocument.contents = cont
+        utilities.setSetting("dbVersion", String(value))
     }
 
     function dbLastUpdate() {
-        return settingsDocument.contents.dbLastUpdate
+//        return settingsDocument.contents.dbLastUpdate
     }
 
     function getUseGoogleSearch() {
-        return settingsDocument.contents.useGoogleSearch
+        var tmp = utilities.getSetting("useGoogleSearch")
+        if (tmp == "true") return true
+        if (tmp == "false") return false
     }
 
     function setUseGoogleSearch(value) {
-        var cont = settingsDocument.contents
-        cont.useGoogleSearch = value
-        settingsDocument.contents = cont
+        utilities.setSetting("useGoogleSearch", String(value))
     }
 
     U1db.Database {
@@ -88,7 +113,7 @@
         docId: 'settingsDocument'
         create: true
         defaults: { "useDarkTheme" : false, "fontSize" : 1,
-                    "useListMode" : false, "dbVersion" : 1.2,
+                    "useListMode" : false, "dbVersion" : "1.2",
                     "useGoogleSearch" : true
         }
     }

=== added file 'shorts/qml/components/SettingsItem.qml'
--- shorts/qml/components/SettingsItem.qml	1970-01-01 00:00:00 +0000
+++ shorts/qml/components/SettingsItem.qml	2016-03-16 12:38:32 +0000
@@ -0,0 +1,120 @@
+/*
+ * Flashback - Entertainment app for Ubuntu
+ * Copyright (C) 2013, 2014 Nekhelesh Ramananthan <nik90@xxxxxxxxxx>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+import QtQuick 2.2
+import Ubuntu.Components 1.1
+import Ubuntu.Components.ListItems 1.0 as ListItem
+
+UbuntuShape {
+    id: settingsItem
+
+    // Property to set the contents of the settings item
+    property alias contents: _contents.data
+
+    // Property to set the header of the settings item
+    property string title: "Default"
+
+    // Property to set the icon of the settings item header
+    property alias icon: _icon.source
+
+    // Property to set the vertical spacing in the contents column
+    property alias contentSpacing: _contents.spacing
+
+    radius: "medium"
+    color: Qt.rgba(0,0,0,0.15)
+    height: _titleContainer.height + _contentsContainer.height + units.gu(2)
+
+    anchors {
+        left: parent.left
+        right: parent.right
+    }
+
+    Item {
+        id: _titleContainer
+
+        clip: true
+        height: _title.height + units.gu(3)
+        anchors {
+            top: parent.top
+            left: parent.left
+            right: parent.right
+        }
+
+        UbuntuShape {
+            id: _header
+            radius: "medium"
+            color: Qt.rgba(0,0,0,0.2)
+            height: _title.height + units.gu(5)
+            anchors {
+                top: parent.top
+                left: parent.left
+                right: parent.right
+            }
+        }
+        
+        Row {
+            spacing: units.gu(1)
+            anchors {
+                left: parent.left
+                leftMargin: units.gu(2)
+                top: parent.top
+                topMargin: units.gu(1.5)
+            }
+
+            Image {
+                id: _icon
+                source: ""
+                height: _title.height
+                fillMode: Image.PreserveAspectFit
+                visible: source == "" ? false : true
+            }
+
+            Label {
+                id: _title
+                text: title
+                font.pixelSize: units.dp(17)
+            }
+        }
+    }
+
+    Rectangle {
+        id: customDivider
+        anchors .top: _titleContainer.bottom
+        width: parent.width
+        height: units.gu(0.1)
+        color: UbuntuColors.orange
+    }
+
+    Column {
+        id: _contentsContainer
+
+        anchors {
+            bottomMargin: units.gu(1)
+            bottom: parent.bottom
+            left: parent.left
+            right: parent.right
+        }
+
+        Column {
+            id: _contents
+            spacing: units.gu(1)
+            width: parent.width
+            clip: true
+        }
+    }
+}

=== modified file 'shorts/qml/icons/CMakeLists.txt'
--- shorts/qml/icons/CMakeLists.txt	2015-07-17 14:42:42 +0000
+++ shorts/qml/icons/CMakeLists.txt	2016-03-16 12:38:32 +0000
@@ -1,4 +1,4 @@
-file(GLOB ICONS *.svg)
+file(GLOB ICONS *.svg *.png)
 
 # make the files visible in the qtcreator tree
 add_custom_target(ubuntu-rssreader-app_icons_QMlFiles ALL SOURCES ${ICONS})

=== added file 'shorts/qml/icons/help1.png'
Binary files shorts/qml/icons/help1.png	1970-01-01 00:00:00 +0000 and shorts/qml/icons/help1.png	2016-03-16 12:38:32 +0000 differ
=== added file 'shorts/qml/icons/help2.png'
Binary files shorts/qml/icons/help2.png	1970-01-01 00:00:00 +0000 and shorts/qml/icons/help2.png	2016-03-16 12:38:32 +0000 differ
=== added file 'shorts/qml/icons/help3.png'
Binary files shorts/qml/icons/help3.png	1970-01-01 00:00:00 +0000 and shorts/qml/icons/help3.png	2016-03-16 12:38:32 +0000 differ
=== added file 'shorts/qml/icons/shorts.png'
Binary files shorts/qml/icons/shorts.png	1970-01-01 00:00:00 +0000 and shorts/qml/icons/shorts.png	2016-03-16 12:38:32 +0000 differ
=== modified file 'shorts/qml/nongoogle/Positioner.qml'
--- shorts/qml/nongoogle/Positioner.qml	2016-01-04 11:46:35 +0000
+++ shorts/qml/nongoogle/Positioner.qml	2016-03-16 12:38:32 +0000
@@ -32,6 +32,8 @@
     // Property to keep track of app cold start status
     property string countryCode: ""
 
+    signal locationDetected(var location)
+
     Component.onCompleted: {
     }
 
@@ -94,12 +96,13 @@
 
                     countryCode = resObj.countryName
                     print("countryCode", resObj)
+                    locationDetected(countryCode)
 
-                    if (countryCode == "China") {
-                        if (optionsKeeper.useGoogleSearch) {
-                            PopupUtils.open(componentDialogNG, tabstabs)
-                        }
-                    }
+//                    if (countryCode == "China") {
+//                        if (optionsKeeper.useGoogleSearch) {
+//                            PopupUtils.open(componentDialogNG, tabstabs)
+//                        }
+//                    }
                 }
             }
 

=== modified file 'shorts/qml/nongoogle/XmlNetwork.qml'
--- shorts/qml/nongoogle/XmlNetwork.qml	2016-01-04 11:13:30 +0000
+++ shorts/qml/nongoogle/XmlNetwork.qml	2016-03-16 12:38:32 +0000
@@ -1,4 +1,5 @@
 import QtQuick 2.4
+import "../utils/xml2json.js" as XJ
 
 QtObject {
     id: rootObject
@@ -28,13 +29,18 @@
             if (doc.readyState === XMLHttpRequest.DONE) {
 
                 var resObj
+//                print ("status & text: ", doc.status, doc.statusText, doc.responseText)
                 if (doc.status == 200) {
-                    resObj = utilities.xmlToJson(doc.responseText)
+                                        resObj = utilities.xmlToJson(doc.responseText)
+//                    resObj = utilities.xmlToJson(doc.responseText)
+//                    var x2js = new XJ.X2JS();
+//                    resObj = XJ.xmlToJSON.parseString(doc.responseText)    //x2js.xml_str2json( doc.responseText );
                 } else { // Error
                     resObj = {"responseDetails" : doc.statusText,
                         "responseStatus" : doc.status}
                 }
 
+                print ("resObj: ", resObj.rss )
                 __doc = null
                 loadResult(resObj)
             }

=== added file 'shorts/qml/pages/PageHelp.qml'
--- shorts/qml/pages/PageHelp.qml	1970-01-01 00:00:00 +0000
+++ shorts/qml/pages/PageHelp.qml	2016-03-16 12:38:32 +0000
@@ -0,0 +1,371 @@
+import QtQuick 2.4
+//import QtQml.Models 2.1
+import Ubuntu.Components 1.3
+import Ubuntu.Components.ListItems 1.3 as ListItem
+
+import "../nongoogle"
+
+
+
+Page {
+    id: pageHelp
+    title: {
+        switch (view.currentIndex) {
+        case 0 :
+            return i18n.tr("Welcome to Shorts")
+        case 1 :
+            return i18n.tr("View Articles")
+        case 2 :
+            return i18n.tr("Search RSS")
+        case 3 :
+            return i18n.tr("Manage topics and feeds")
+        case 4 :
+            return i18n.tr("Location")
+        case 5 :
+            return i18n.tr("Enjoy")
+        }
+    }
+
+    flickable: null
+//    head.visible: false
+    head.backAction:
+        Action { // just replace the default one
+        visible: false
+        iconName: "close"
+    }
+
+    // property to log who push me to stack ..
+    property var pushOwner
+
+    property bool dontShowAgain: true
+    property alias useGoogleRSS: swUseGfa.checked
+
+    function backToPushOwner(isSkip) {
+        if (isSkip) {
+            optionsKeeper.needPopup = true
+        }
+        else {
+            if (dontShowAgain) {
+                optionsKeeper.needPopup = false
+            }
+            else {
+                optionsKeeper.needPopup = true
+            }
+
+//            if (positionDetector.countryCode == "China") {
+//                optionsKeeper.useGoogleSearch = false
+//            }
+            optionsKeeper.useGoogleSearch = useGoogleRSS
+        }
+
+        // call startup function in MainView, do nothing when other pages push this page
+        try {
+            pushOwner.startup()
+        }
+        catch (er) {
+            // TODO show error
+        }
+        pageStack.pop()
+    }
+
+    // Positioner to detect current position
+    Positioner {
+        id: positionDetector
+    }
+
+    VisualItemModel {
+        id: itemModel
+
+        //////////////////////////////////////////////////             tutorial 1       welcome screen, show what this app can do
+        Item {
+            width: view.width; height: view.height
+            Column {
+                anchors.fill: parent
+                anchors.margins: units.gu(2)
+                spacing: units.gu(1)
+
+//                Label {
+//                    anchors { left: parent.left; right: parent.right }
+//                    text: i18n.tr("xxxxxxxxxxxxxxxxx")
+//                    fontSize: "large"
+//                    font.bold: true
+//                    horizontalAlignment: Text.AlignHCenter
+//                    wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+//                }
+                Image {
+                    anchors.horizontalCenter: parent.horizontalCenter
+                    source: "../icons/shorts.png"
+                    width: units.gu(15); height: width
+                    fillMode: Image.PreserveAspectFit
+                }
+
+                Item { width: units.gu(2); height: width }
+                Label {
+                    anchors { left: parent.left; right: parent.right }
+                    text: i18n.tr("Shorts is an RSS reader app developed by Canonical & Ubuntu Comunity.")
+                    wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+                }
+                Label {
+                    anchors { left: parent.left; right: parent.right }
+                    text: i18n.tr("Shorts provides most primary features which also can be seen in other RSS reader apps, with a beautiful Ubuntu style user interface.")
+                    wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+//                    font.bold: true
+                }
+                Item { width: units.gu(11); height: width }
+                Label {
+                    anchors { left: parent.left; right: parent.right }
+                    text: i18n.tr("Swipe left to continue.")
+                    font.italic: true
+                    horizontalAlignment: Text.AlignHCenter
+                    wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+                }
+
+            }
+        }
+
+        //////////////////////////////////////////////////             tutorial 2     rss screen
+        Item {
+            width: view.width; height: view.height
+            Column {
+                anchors.fill: parent
+                anchors.margins: units.gu(2)
+                spacing: units.gu(1)
+
+                Label {
+                    anchors { left: parent.left; right: parent.right }
+                    text: i18n.tr("Scroll left/right in grid mode or scroll up/down in list mode.")
+//                    fontSize: "large"
+//                    font.bold: true
+                    horizontalAlignment: Text.AlignHCenter
+                    wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+                }
+                Image {
+                    anchors.horizontalCenter: parent.horizontalCenter
+                    source: "../icons/help1.png"
+                    anchors { left: parent.left; right: parent.right }
+                    height: width
+                    fillMode: Image.PreserveAspectFit
+                }
+
+            }
+        }
+
+        //////////////////////////////////////////////////             tutorial 3       search screen
+        Item {
+            width: view.width; height: view.height
+            Column {
+                anchors.fill: parent
+                anchors.margins: units.gu(2)
+                spacing: units.gu(1)
+
+                Label {
+                    anchors { left: parent.left; right: parent.right }
+                    text: i18n.tr("Swipe up will enter this search page, just type any simple words, or paste a link.")
+//                    fontSize: "large"
+//                    font.bold: true
+                    horizontalAlignment: Text.AlignHCenter
+                    wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+                }
+                Image {
+                    anchors.horizontalCenter: parent.horizontalCenter
+                    source: "../icons/help2.png"
+                    anchors { left: parent.left; right: parent.right }
+                    height: width
+                    fillMode: Image.PreserveAspectFit
+                }
+
+            }
+        }
+
+        //////////////////////////////////////////////////             tutorial 4        topic screen
+        Item {
+            width: view.width; height: view.height
+            Column {
+                anchors.fill: parent
+                anchors.margins: units.gu(2)
+                spacing: units.gu(1)
+
+                Label {
+                    anchors { left: parent.left; right: parent.right }
+                    text: i18n.tr("Every feed must belong to one topic, swipe one item to delete feed/topic.")
+//                    fontSize: "large"
+//                    font.bold: true
+                    horizontalAlignment: Text.AlignHCenter
+                    wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+                }
+//                Label {
+//                    anchors { left: parent.left; right: parent.right }
+//                    text: i18n.tr("1. Normally, users are no need to care about their settings, default setting will work fine for most cases.")
+//                    wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+//                }
+                Image {
+                    anchors.horizontalCenter: parent.horizontalCenter
+                    source: "../icons/help3.png"
+                    anchors { left: parent.left; right: parent.right }
+                    height: width
+                    fillMode: Image.PreserveAspectFit
+                }
+
+
+            }
+        }
+
+        //////////////////////////////////////////////////             tutorial 5     location screen & tips about non-google setting
+        Item {
+            width: view.width; height: view.height
+            Column {
+                anchors.fill: parent
+                anchors.margins: units.gu(2)
+                spacing: units.gu(1)
+
+                Label {
+                    anchors { left: parent.left; right: parent.right }
+                    text: i18n.tr("Seems you are living in: ") + positionDetector.countryCode
+//                    fontSize: "large"
+//                    font.bold: true
+                    horizontalAlignment: Text.AlignHCenter
+                    wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+                }
+
+                Label {
+                    anchors { left: parent.left; right: parent.right }
+                    text: i18n.tr("Some regions/countries(e.g. China) may block Google service, if you're living there or plan to go there, we suggest to trun off the build-in Google RSS service in settings page, or nothing you should care.")
+                    wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+                    visible: positionDetector.countryCode != "China"
+                }
+
+                Label {
+                    anchors { left: parent.left; right: parent.right }
+                    text: i18n.tr("We detect that you're living in some region/country(e.g. China) which blocks Google service, so Shorts disable the build-in Google RSS service by default. You still can turn it on here or in settings page.")
+                    wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+                    visible: positionDetector.countryCode == "China"
+                }
+
+                Item { width: 10; height: units.gu(1); } // just a separator
+
+                ListItem.ThinDivider{ }
+
+                ListItem.Standard {
+                    visible: positionDetector.countryCode == "China"
+                    text: i18n.tr("Use Google RSS engine: ")
+                    control:
+                        Switch {
+                        id: swUseGfa
+                        anchors.right: parent.right
+                        checked: true
+
+                        Connections {
+                            target: positionDetector
+                            onLocationDetected: {
+                                if (location == "China") {
+                                    swUseGfa.checked = false
+                                }
+                                else swUseGfa.checked = true
+                            }
+                        }
+
+                        onCheckedChanged: {
+                            //
+                        }
+                    }
+                }
+
+
+            }
+        }
+
+        //////////////////////////////////////////////////             tutorial 6     end screen & do not show this again
+        Item {
+            width: view.width; height: view.height
+            Column {
+                anchors.fill: parent
+                anchors.margins: units.gu(2)
+                spacing: units.gu(1)
+
+                Label {
+                    anchors { left: parent.left; right: parent.right }
+                    text: i18n.tr("Enjoy !")
+                    fontSize: "large"
+                    font.bold: true
+                    horizontalAlignment: Text.AlignHCenter
+                    wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+                }
+
+                ListItem.ThinDivider{ }
+
+                ListItem.Standard {
+                    text: i18n.tr("Do not show this help page again ")
+                    control:
+                        Switch {
+                        id: xxxxxxxxxx
+                        anchors.right: parent.right
+                        checked: true
+
+                        onCheckedChanged: {
+                            dontShowAgain = checked
+                        }
+                    }
+                }
+
+
+            }
+
+            Button {
+                anchors { centerIn: parent }
+                color: UbuntuColors.orange
+                text: i18n.tr("Start using Shorts !")
+                onClicked: { backToPushOwner(false) }
+            }
+        }
+    }
+
+    ListView {
+        id: view
+        anchors { fill: parent; bottomMargin: units.gu(6); topMargin: units.gu(1) }
+        model: itemModel
+        preferredHighlightBegin: 0; preferredHighlightEnd: 0
+        highlightRangeMode: ListView.StrictlyEnforceRange
+        orientation: ListView.Horizontal
+        snapMode: ListView.SnapOneItem;
+        cacheBuffer: 999999
+    }
+
+    MouseArea {
+        width: units.gu(8); height: units.gu(7)
+        anchors.bottom: parent.bottom
+        onClicked: { backToPushOwner(true) }
+
+        Label{ /*anchors.horizontalCenter: parent.horizontalCenter;*/
+            anchors.centerIn: parent
+            text: i18n.tr("Skip")
+            font.italic: true
+        }
+    }
+
+    // bottom indicator
+    Item {
+        width: pageHelp.width; height: units.gu(6) 
+        anchors { top: view.bottom; bottom: parent.bottom }
+
+        Row {
+            anchors.centerIn: parent
+            spacing: units.gu(1.8)
+
+            Repeater {
+                model: itemModel.count
+
+                Rectangle {
+                    width: units.gu(1) ; height: width
+                    radius: width
+                    color: view.currentIndex == index ? "blue" : "white"
+
+                    MouseArea {
+                        width: units.gu(2); height: width
+                        anchors.centerIn: parent
+                        onClicked: view.currentIndex = index
+                    }
+                }
+            }
+        }
+    }
+}

=== added file 'shorts/qml/pages/PageInfo.qml'
--- shorts/qml/pages/PageInfo.qml	1970-01-01 00:00:00 +0000
+++ shorts/qml/pages/PageInfo.qml	2016-03-16 12:38:32 +0000
@@ -0,0 +1,79 @@
+import QtQuick 2.4
+import Ubuntu.Components 1.3
+import Ubuntu.Components.ListItems 1.3 as ListItem
+import "../components"
+
+Page {
+    id: pageInfo
+
+    flickable: null
+    title: i18n.tr("About Shorts")
+
+    /////////////////////////////     main content
+    Flickable {
+        id: scrollArea
+        boundsBehavior: (contentHeight > height) ? Flickable.DragAndOvershootBounds : Flickable.StopAtBounds
+        anchors.fill: parent
+        contentWidth: width
+        contentHeight: columnInnerArea.height + units.gu(3)
+        clip: true
+
+        Column {
+            id: columnInnerArea
+            spacing: units.gu(2)
+            anchors {
+                top: parent.top;
+                margins: units.gu(1)
+                left: parent.left; right: parent.right
+            }
+            height: childrenRect.height
+
+            Image {
+                anchors.horizontalCenter: parent.horizontalCenter
+                source: "../icons/shorts.png"
+                width: units.gu(15); height: width
+                fillMode: Image.PreserveAspectFit
+            }
+
+            SettingsItem {
+                title: i18n.tr("Author")
+                contents: [
+
+                    ListItem.Standard {
+                        text: "Roman Shchekin <mrqtros@xxxxxxxxx>"
+                    },
+
+                    ListItem.Standard {
+                        text: "Joey Chan <joeychan.ubuntu@xxxxxxxxx>"
+                    }
+                ]
+            }
+
+            SettingsItem {
+                title: i18n.tr("Copyleft")
+                contents: [
+                    //
+                    ListItem.Standard {
+                        text: i18n.tr("License with GPLv3")
+                        showDivider: false
+                    },
+
+                    Label {
+                        text: i18n.tr("Ubuntu Shorts App is the official rss reader app for Ubuntu Touch. We follow an open source model where the code is available to anyone to branch and hack on. The ubuntu shorts app follows a test driven development (TDD) where tests are written in parallel to feature implementation to help spot regressions easier.")
+                        anchors { left: parent.left; right: parent.right; margins: units.gu(2) }
+                        wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+                    },
+
+                    ListItem.Standard {
+                        text: "<b>" + i18n.tr("Click here to report a bug") + "</b>"
+                        showDivider: false
+                        MouseArea {
+                            anchors.fill: parent
+                            onClicked: Qt.openUrlExternally("https://bugs.launchpad.net/ubuntu-rssreader-app/+filebug";)
+                        }
+                    }
+                ]
+            }
+        }
+    }
+}

=== modified file 'shorts/qml/pages/PageSettings.qml'
--- shorts/qml/pages/PageSettings.qml	2016-01-14 15:35:31 +0000
+++ shorts/qml/pages/PageSettings.qml	2016-03-16 12:38:32 +0000
@@ -9,6 +9,19 @@
     title: i18n.tr("Settings")
     flickable: null
 
+    head.actions: [
+        Action {
+            iconName: "help"
+            text: i18n.tr("Help")
+            onTriggered: pageStack.push(Qt.resolvedUrl("./PageHelp.qml")/*, {pushOwner: pageSettings }*/)
+        },
+        Action {
+            iconName: "info"
+            text: i18n.tr("Info")
+            onTriggered: pageStack.push(Qt.resolvedUrl("./PageInfo.qml")/*, {pushOwner: pageSettings }*/)
+        }
+    ]
+
     property bool preventSave: false
 
     Component.onCompleted: updateInfoFromOptions()
@@ -35,7 +48,7 @@
             anchors { left: parent.left; right: parent.right; margins: units.gu(2) }
             horizontalAlignment: Text.AlignHCenter
             wrapMode: Text.WrapAtWordBoundaryOrAnywhere
-            text: i18n.tr("For those who living in some special regions cannot access Google, the switch below can disable Google RSS engine, Shorts will directly gets data from RSS sources.")
+            text: i18n.tr("Some special regions/countries block Google service, we suggest to turn off the switch below if living in there.")
         }
 
         Item { width: 10; height: units.gu(1); } // just a separator
@@ -78,7 +91,7 @@
         Button {
             anchors { left: parent.left; right: parent.right; margins: units.gu(2) }
             anchors.horizontalCenter: parent.horizontalCenter
-            text: i18n.tr("Import OMPL")
+            text: i18n.tr("Import OPML")
 
             onClicked: {
                 pageStack.push(Qt.resolvedUrl("../content/ImportFeeds.qml")) ;

=== modified file 'shorts/qml/shorts-app.qml'
--- shorts/qml/shorts-app.qml	2016-01-16 10:55:38 +0000
+++ shorts/qml/shorts-app.qml	2016-03-16 12:38:32 +0000
@@ -31,7 +31,20 @@
     backgroundColor: "#F5F5F5"
 
     Component.onCompleted: {
-
+        // show help page in first use
+        if (optionsKeeper.needPopup) {
+            pageStack.push(Qt.resolvedUrl("./pages/PageHelp.qml"), {pushOwner: mainView })
+            // the help page will call the startup() function by using the pushOwner property
+        }
+        else {
+            startup()
+        }
+
+
+    }
+
+    // seperate following code to a "startup" function from Component.onCompleted above
+    function startup() {
         var dbParams = {"isRefreshRequired" : false,
             "oldDbVersion" : optionsKeeper.dbVersion(),
             "newDbVersion" : ""
@@ -457,9 +470,9 @@
     }
 
     // Positioner to detect current position
-    Positioner {
-        id: positionDetector
-    }
+//    Positioner {
+//        id: positionDetector
+//    }
 
     /* -------------------------- Components ---------------------------- */
 
@@ -517,33 +530,33 @@
     } // Component
 
     ////////////////////////////////////////////////////////  a dialog to ask user if she/he wants to turn off the google search
-    Component {
-        id: componentDialogNG
-
-        Dialog {
-            id: dialogNG
-            title: i18n.tr("Warning")
-            text: i18n.tr("Shorts detects that you're located in an area which blocks Google's IP.<br><br>"
-                          + "We strongly reconmend you to turn off the Google search funtion."
-                          + "Or you can do it in the settings page manually.")
-
-            Button {
-                text: i18n.tr("Yes, please.")
-                color: UbuntuColors.orange
-                objectName: "dialogNGButtonYes"
-                onClicked: {
-                    optionsKeeper.setUseGoogleSearch(false)
-                    PopupUtils.close(dialogNG)
-                }
-            }
-
-            Button {
-                text: i18n.tr("No, thanks.")
-                objectName: "dialogNGButtonNo"
-                onClicked: PopupUtils.close(dialogNG)
-            }
-        }
-    } // Component
+//    Component {
+//        id: componentDialogNG
+
+//        Dialog {
+//            id: dialogNG
+//            title: i18n.tr("Warning")
+//            text: i18n.tr("Shorts detects that you're located in an area which blocks Google's IP.<br><br>"
+//                          + "We strongly reconmend you to turn off the Google search funtion."
+//                          + "Or you can do it in the settings page manually.")
+
+//            Button {
+//                text: i18n.tr("Yes, please.")
+//                color: UbuntuColors.orange
+//                objectName: "dialogNGButtonYes"
+//                onClicked: {
+//                    optionsKeeper.setUseGoogleSearch(false)
+//                    PopupUtils.close(dialogNG)
+//                }
+//            }
+
+//            Button {
+//                text: i18n.tr("No, thanks.")
+//                objectName: "dialogNGButtonNo"
+//                onClicked: PopupUtils.close(dialogNG)
+//            }
+//        }
+//    } // Component
 
     /* -------------------------- Connections ---------------------------- */
 

=== modified file 'shorts/qml/utils/databasemodule_v2.js'
--- shorts/qml/utils/databasemodule_v2.js	2016-01-10 09:04:00 +0000
+++ shorts/qml/utils/databasemodule_v2.js	2016-03-16 12:38:32 +0000
@@ -40,9 +40,9 @@
                 dbResult = tx.executeSql("alter table article add author text")
                 console.log("Database updated: ", JSON.stringify(dbResult))
             })
-            dbParams.newDbVersion = 1.1
-        case 1.2:
-            dbParams.newDbVersion = 1.2
+            dbParams.newDbVersion = "1.1"
+        case "1.2":
+            dbParams.newDbVersion = "1.2"
     }
 
     var tagCount = 0

=== added file 'shorts/qml/utils/xml2json.js'
--- shorts/qml/utils/xml2json.js	1970-01-01 00:00:00 +0000
+++ shorts/qml/utils/xml2json.js	2016-03-16 12:38:32 +0000
@@ -0,0 +1,242 @@
+/* Copyright 2015 William Summers, MetaTribal LLC
+ * adapted from https://developer.mozilla.org/en-US/docs/JXON
+ *
+ * Licensed under the MIT License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://opensource.org/licenses/MIT
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author William Summers
+ *
+ */
+ 
+var xmlToJSON = (function () {
+
+    this.version = "1.3";
+
+    var options = { // set up the default options
+        mergeCDATA: true, // extract cdata and merge with text
+        grokAttr: true, // convert truthy attributes to boolean, etc
+        grokText: true, // convert truthy text/attr to boolean, etc
+        normalize: true, // collapse multiple spaces to single space
+        xmlns: true, // include namespaces as attribute in output
+        namespaceKey: '_ns', // tag name for namespace objects
+        textKey: '_text', // tag name for text nodes
+        valueKey: '_value', // tag name for attribute values
+        attrKey: '_attr', // tag for attr groups
+        cdataKey: '_cdata', // tag for cdata nodes (ignored if mergeCDATA is true)
+        attrsAsObject: true, // if false, key is used as prefix to name, set prefix to '' to merge children and attrs.
+        stripAttrPrefix: true, // remove namespace prefixes from attributes
+        stripElemPrefix: true, // for elements of same name in diff namespaces, you can enable namespaces and access the nskey property
+        childrenAsArray: true // force children into arrays
+    };
+
+    var prefixMatch = new RegExp(/(?!xmlns)^.*:/);
+    var trimMatch = new RegExp(/^\s+|\s+$/g);
+
+    this.grokType = function (sValue) {
+        if (/^\s*$/.test(sValue)) {
+            return null;
+        }
+        if (/^(?:true|false)$/i.test(sValue)) {
+            return sValue.toLowerCase() === "true";
+        }
+        if (isFinite(sValue)) {
+            return parseFloat(sValue);
+        }
+        return sValue;
+    };
+
+    this.parseString = function (xmlString, opt) {
+        return this.parseXML(this.stringToXML(xmlString), opt);
+    }
+
+    this.parseXML = function (oXMLParent, opt) {
+
+        // initialize options
+        for (var key in opt) {
+            options[key] = opt[key];
+        }
+
+        var vResult = {},
+            nLength = 0,
+            sCollectedTxt = "";
+
+        // parse namespace information
+        if (options.xmlns && oXMLParent.namespaceURI) {
+            vResult[options.namespaceKey] = oXMLParent.namespaceURI;
+        }
+
+        // parse attributes
+        // using attributes property instead of hasAttributes method to support older browsers
+        if (oXMLParent.attributes && oXMLParent.attributes.length > 0) {
+            var vAttribs = {};
+
+            for (nLength; nLength < oXMLParent.attributes.length; nLength++) {
+                var oAttrib = oXMLParent.attributes.item(nLength);
+                vContent = {};
+                var attribName = '';
+
+                if (options.stripAttrPrefix) {
+                    attribName = oAttrib.name.replace(prefixMatch, '');
+
+                } else {
+                    attribName = oAttrib.name;
+                }
+
+                if (options.grokAttr) {
+                    vContent[options.valueKey] = this.grokType(oAttrib.value.replace(trimMatch, ''));
+                } else {
+                    vContent[options.valueKey] = oAttrib.value.replace(trimMatch, '');
+                }
+
+                if (options.xmlns && oAttrib.namespaceURI) {
+                    vContent[options.namespaceKey] = oAttrib.namespaceURI;
+                }
+
+                if (options.attrsAsObject) { // attributes with same local name must enable prefixes
+                    vAttribs[attribName] = vContent;
+                } else {
+                    vResult[options.attrKey + attribName] = vContent;
+                }
+            }
+
+            if (options.attrsAsObject) {
+                vResult[options.attrKey] = vAttribs;
+            } else {}
+        }
+
+        // iterate over the children
+        if (oXMLParent.hasChildNodes()) {
+            for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {
+                oNode = oXMLParent.childNodes.item(nItem);
+
+                if (oNode.nodeType === 4) {
+                    if (options.mergeCDATA) {
+                        sCollectedTxt += oNode.nodeValue;
+                    } else {
+                        if (vResult.hasOwnProperty(options.cdataKey)) {
+                            if (vResult[options.cdataKey].constructor !== Array) {
+                                vResult[options.cdataKey] = [vResult[options.cdataKey]];
+                            }
+                            vResult[options.cdataKey].push(oNode.nodeValue);
+
+                        } else {
+                            if (options.childrenAsArray) {
+                                vResult[options.cdataKey] = [];
+                                vResult[options.cdataKey].push(oNode.nodeValue);
+                            } else {
+                                vResult[options.cdataKey] = oNode.nodeValue;
+                            }
+                        }
+                    }
+                } /* nodeType is "CDATASection" (4) */
+                else if (oNode.nodeType === 3) {
+                    sCollectedTxt += oNode.nodeValue;
+                } /* nodeType is "Text" (3) */
+                else if (oNode.nodeType === 1) { /* nodeType is "Element" (1) */
+
+                    if (nLength === 0) {
+                        vResult = {};
+                    }
+
+                    // using nodeName to support browser (IE) implementation with no 'localName' property
+                    if (options.stripElemPrefix) {
+                        sProp = oNode.nodeName.replace(prefixMatch, '');
+                    } else {
+                        sProp = oNode.nodeName;
+                    }
+
+                    vContent = xmlToJSON.parseXML(oNode);
+
+                    if (vResult.hasOwnProperty(sProp)) {
+                        if (vResult[sProp].constructor !== Array) {
+                            vResult[sProp] = [vResult[sProp]];
+                        }
+                        vResult[sProp].push(vContent);
+
+                    } else {
+                        if (options.childrenAsArray) {
+                            vResult[sProp] = [];
+                            vResult[sProp].push(vContent);
+                        } else {
+                            vResult[sProp] = vContent;
+                        }
+                        nLength++;
+                    }
+                }
+            }
+        } else if (!sCollectedTxt) { // no children and no text, return null
+            if (options.childrenAsArray) {
+                vResult[options.textKey] = [];
+                vResult[options.textKey].push(null);
+            } else {
+                vResult[options.textKey] = null;
+            }
+        }
+
+        if (sCollectedTxt) {
+            if (options.grokText) {
+                var value = this.grokType(sCollectedTxt.replace(trimMatch, ''));
+                if (value !== null && value !== undefined) {
+                    vResult[options.textKey] = value;
+                }
+            } else if (options.normalize) {
+                vResult[options.textKey] = sCollectedTxt.replace(trimMatch, '').replace(/\s+/g, " ");
+            } else {
+                vResult[options.textKey] = sCollectedTxt.replace(trimMatch, '');
+            }
+        }
+
+        return vResult;
+    }
+
+
+    // Convert xmlDocument to a string
+    // Returns null on failure
+    this.xmlToString = function (xmlDoc) {
+        try {
+            var xmlString = xmlDoc.xml ? xmlDoc.xml : (new XMLSerializer()).serializeToString(xmlDoc);
+            return xmlString;
+        } catch (err) {
+            return null;
+        }
+    }
+
+    // Convert a string to XML Node Structure
+    // Returns null on failure
+    this.stringToXML = function (xmlString) {
+        try {
+            var xmlDoc = null;
+
+            if (window.DOMParser) {
+
+                var parser = new DOMParser();
+                xmlDoc = parser.parseFromString(xmlString, "text/xml");
+
+                return xmlDoc;
+            } else {
+                xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
+                xmlDoc.async = false;
+                xmlDoc.loadXML(xmlString);
+
+                return xmlDoc;
+            }
+        } catch (e) {
+            return null;
+        }
+    }
+
+    return this;
+}).call({});
+
+if (typeof module != "undefined" && module !== null && module.exports) module.exports = xmlToJSON;
+else if (typeof define === "function" && define.amd) define(function() {return xmlToJSON});

=== modified file 'shorts/shorts.qrc'
--- shorts/shorts.qrc	2016-01-10 09:04:00 +0000
+++ shorts/shorts.qrc	2016-03-16 12:38:32 +0000
@@ -39,6 +39,14 @@
         <file>qml/content/OpmlParser.qml</file>
         <file>qml/content/ImportFeeds.qml</file>
         <file>qml/content/ContentPickerDialog.qml</file>
+        <file>qml/utils/xml2json.js</file>
+        <file>qml/pages/PageHelp.qml</file>
+        <file>qml/icons/help1.png</file>
+        <file>qml/icons/help2.png</file>
+        <file>qml/icons/help3.png</file>
+        <file>qml/icons/shorts.png</file>
+        <file>qml/pages/PageInfo.qml</file>
+        <file>qml/components/SettingsItem.qml</file>
     </qresource>
     <qresource prefix="/img">
         <file>qml/icons/add.svg</file>

=== added file 'shorts/utilities.cpp'
--- shorts/utilities.cpp	1970-01-01 00:00:00 +0000
+++ shorts/utilities.cpp	2016-03-16 12:38:32 +0000
@@ -0,0 +1,68 @@
+#include "utilities.h"
+#include "xml2json/xml2json.hpp"
+
+Utilities::Utilities(QObject *parent) :
+    QObject(parent)
+{
+//    qDebug() << "path: " << QDir::currentPath() ;
+//    QFile xmlFile("xml");
+//    xmlFile.open(QIODevice::ReadOnly | QIODevice::Text);
+
+//    qDebug() << "json: " << xmlToJson(QString(xmlFile.readAll())).size();
+}
+
+QJsonObject Utilities::xmlToJson(const QString &xml)
+{
+    QByteArray ba = xml.toLocal8Bit();
+    char* ch = ba.data();
+    std::string json = "";
+    try
+    {
+        json = xml2json(ch);
+    }
+    catch (char* err)
+    {
+        Q_UNUSED(err);
+        json = "";
+    }
+
+//    qDebug() << "json: " << QString::fromStdString(json) ;
+    return QJsonDocument::fromJson(QString::fromStdString(json).toLocal8Bit()).object();
+}
+
+QStringList Utilities::htmlGetImg(const QString &html)
+{
+    QRegExp imgTagRegex("\\<img[^\\>]*src\\s*=\\s*\"([^\"]*)\"[^\\>]*\\>", Qt::CaseInsensitive);
+    imgTagRegex.setMinimal(true);
+    QStringList urlmatches;
+    QStringList imgmatches;
+    int offset = 0;
+    while( (offset = imgTagRegex.indexIn(html, offset)) != -1)
+    {
+        offset += imgTagRegex.matchedLength();
+        imgmatches.append(imgTagRegex.cap(0)); // Should hold complete img tag
+        urlmatches.append(imgTagRegex.cap(1)); // Should hold only src property
+    }
+    return urlmatches;
+}
+
+QString Utilities::getSetting(const QString &key)
+{
+    QSettings settings;
+    return settings.value(key).toString();
+}
+
+void Utilities::setSetting(const QString &key, const QString &value)
+{
+    QSettings settings;
+    settings.setValue(key, value);
+}
+
+// QJsonObject Utilities::test()
+// {
+//     QFile xmlFile("xml");
+//     xmlFile.open(QIODevice::ReadOnly | QIODevice::Text);
+// 
+//     QJsonObject obj = xmlToJson(QString(xmlFile.readAll()));
+//     return obj;
+// }

=== added file 'shorts/utilities.h'
--- shorts/utilities.h	1970-01-01 00:00:00 +0000
+++ shorts/utilities.h	2016-03-16 12:38:32 +0000
@@ -0,0 +1,28 @@
+#ifndef UTILITIES_H
+#define UTILITIES_H
+
+#include <QtCore>
+
+class Utilities : public QObject
+{
+    Q_OBJECT
+public:
+    explicit Utilities(QObject *parent = 0);
+
+    Q_INVOKABLE QJsonObject xmlToJson(const QString &xml);
+    Q_INVOKABLE QStringList htmlGetImg(const QString &html);
+
+    // get & set settings' values
+    Q_INVOKABLE QString getSetting(const QString &key);
+    Q_INVOKABLE void setSetting(const QString &key, const QString &value);
+
+    // test only
+//     Q_INVOKABLE QJsonObject test();
+
+signals:
+
+public slots:
+
+};
+
+#endif // UTILITIES_H

=== modified file 'shorts/xml2json/rapidjson/allocators.h'
--- shorts/xml2json/rapidjson/allocators.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/allocators.h	2016-03-16 12:38:32 +0000
@@ -1,22 +1,16 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_ALLOCATORS_H_
 #define RAPIDJSON_ALLOCATORS_H_
@@ -68,8 +62,20 @@
 class CrtAllocator {
 public:
     static const bool kNeedFree = true;
-    void* Malloc(size_t size) { return std::malloc(size); }
-    void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { (void)originalSize; return std::realloc(originalPtr, newSize); }
+    void* Malloc(size_t size) { 
+        if (size) //  behavior of malloc(0) is implementation defined.
+            return std::malloc(size);
+        else
+            return NULL; // standardize to returning NULL.
+    }
+    void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
+        (void)originalSize;
+        if (newSize == 0) {
+            std::free(originalPtr);
+            return NULL;
+        }
+        return std::realloc(originalPtr, newSize);
+    }
     static void Free(void *ptr) { std::free(ptr); }
 };
 
@@ -137,11 +143,13 @@
 
     //! Deallocates all memory chunks, excluding the user-supplied buffer.
     void Clear() {
-        while(chunkHead_ != 0 && chunkHead_ != userBuffer_) {
+        while (chunkHead_ && chunkHead_ != userBuffer_) {
             ChunkHeader* next = chunkHead_->next;
             baseAllocator_->Free(chunkHead_);
             chunkHead_ = next;
         }
+        if (chunkHead_ && chunkHead_ == userBuffer_)
+            chunkHead_->size = 0; // Clear user buffer
     }
 
     //! Computes the total capacity of allocated memory chunks.
@@ -166,11 +174,14 @@
 
     //! Allocates a memory block. (concept Allocator)
     void* Malloc(size_t size) {
+        if (!size)
+            return NULL;
+
         size = RAPIDJSON_ALIGN(size);
         if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity)
             AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size);
 
-        void *buffer = reinterpret_cast<char *>(chunkHead_ + 1) + chunkHead_->size;
+        void *buffer = reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size;
         chunkHead_->size += size;
         return buffer;
     }
@@ -180,12 +191,15 @@
         if (originalPtr == 0)
             return Malloc(newSize);
 
+        if (newSize == 0)
+            return NULL;
+
         // Do not shrink if new size is smaller than original
         if (originalSize >= newSize)
             return originalPtr;
 
         // Simply expand it if it is the last allocation and there is sufficient space
-        if (originalPtr == (char *)(chunkHead_ + 1) + chunkHead_->size - originalSize) {
+        if (originalPtr == reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) {
             size_t increment = static_cast<size_t>(newSize - originalSize);
             increment = RAPIDJSON_ALIGN(increment);
             if (chunkHead_->size + increment <= chunkHead_->capacity) {
@@ -197,7 +211,9 @@
         // Realloc process: allocate and copy memory, do not free original buffer.
         void* newBuffer = Malloc(newSize);
         RAPIDJSON_ASSERT(newBuffer != 0);   // Do not handle out-of-memory explicitly.
-        return std::memcpy(newBuffer, originalPtr, originalSize);
+        if (originalSize)
+            std::memcpy(newBuffer, originalPtr, originalSize);
+        return newBuffer;
     }
 
     //! Frees a memory block (concept Allocator)
@@ -215,7 +231,7 @@
     void AddChunk(size_t capacity) {
         if (!baseAllocator_)
             ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator());
-        ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity));
+        ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity));
         chunk->capacity = capacity;
         chunk->size = 0;
         chunk->next = chunkHead_;

=== modified file 'shorts/xml2json/rapidjson/document.h'
--- shorts/xml2json/rapidjson/document.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/document.h	2016-03-16 12:38:32 +0000
@@ -1,22 +1,16 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_DOCUMENT_H_
 #define RAPIDJSON_DOCUMENT_H_
@@ -31,33 +25,19 @@
 #ifdef _MSC_VER
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
-#elif defined(__GNUC__)
+#endif
+
+#ifdef __clang__
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(padded)
+RAPIDJSON_DIAG_OFF(switch-enum)
+#endif
+
+#ifdef __GNUC__
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_OFF(effc++)
 #endif
 
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_HAS_STDSTRING
-
-#ifndef RAPIDJSON_HAS_STDSTRING
-#ifdef RAPIDJSON_DOXYGEN_RUNNING
-#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation
-#else
-#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default
-#endif
-/*! \def RAPIDJSON_HAS_STDSTRING
-    \ingroup RAPIDJSON_CONFIG
-    \brief Enable RapidJSON support for \c std::string
-
-    By defining this preprocessor symbol to \c 1, several convenience functions for using
-    \ref rapidjson::GenericValue with \c std::string are enabled, especially
-    for construction and comparison.
-
-    \hideinitializer
-*/
-#include <string>
-#endif // RAPIDJSON_HAS_STDSTRING
-
 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
 #include <iterator> // std::iterator, std::random_access_iterator_tag
 #endif
@@ -72,6 +52,9 @@
 template <typename Encoding, typename Allocator>
 class GenericValue;
 
+template <typename Encoding, typename Allocator, typename StackAllocator>
+class GenericDocument;
+
 //! Name-value pair in a JSON object value.
 /*!
     This class was internal to GenericValue. It used to be a inner struct.
@@ -260,6 +243,7 @@
     typedef CharType Ch; //!< character type of the string
 
     //! Create string reference from \c const character array
+#ifndef __clang__ // -Wdocumentation
     /*!
         This constructor implicitly creates a constant string reference from
         a \c const character array.  It has better performance than
@@ -282,11 +266,13 @@
             In such cases, the referenced string should be \b copied to the
             GenericValue instead.
      */
+#endif
     template<SizeType N>
     GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
         : s(str), length(N-1) {}
 
     //! Explicitly create string reference from \c const character pointer
+#ifndef __clang__ // -Wdocumentation
     /*!
         This constructor can be used to \b explicitly  create a reference to
         a constant string pointer.
@@ -305,16 +291,19 @@
             In such cases, the referenced string should be \b copied to the
             GenericValue instead.
      */
+#endif
     explicit GenericStringRef(const CharType* str)
         : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != NULL); }
 
     //! Create constant string reference from pointer and length
+#ifndef __clang__ // -Wdocumentation
     /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
         \param len length of the string, excluding the trailing NULL terminator
 
         \post \ref s == str && \ref length == len
         \note Constant complexity.
      */
+#endif
     GenericStringRef(const CharType* str, SizeType len)
         : s(str), length(len) { RAPIDJSON_ASSERT(s != NULL); }
 
@@ -430,6 +419,7 @@
     typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterator ConstMemberIterator;  //!< Constant member iterator for iterating in object.
     typedef GenericValue* ValueIterator;            //!< Value iterator for iterating in array.
     typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.
+    typedef GenericValue<Encoding, Allocator> ValueType;    //!< Value type of itself.
 
     //!@name Constructors and destructor.
     //@{
@@ -448,6 +438,16 @@
     //! Copy constructor is not permitted.
     GenericValue(const GenericValue& rhs);
 
+#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
+    //! Moving from a GenericDocument is not permitted.
+    template <typename StackAllocator>
+    GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
+
+    //! Move assignment from a GenericDocument is not permitted.
+    template <typename StackAllocator>
+    GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
+#endif
+
 public:
 
     //! Constructor with JSON value type.
@@ -643,7 +643,7 @@
      */
     template <typename SourceAllocator>
     GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator) {
-        RAPIDJSON_ASSERT((void*)this != (void const*)&rhs);
+        RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
         this->~GenericValue();
         new (this) GenericValue(rhs, allocator);
         return *this;
@@ -662,6 +662,20 @@
         return *this;
     }
 
+    //! free-standing swap function helper
+    /*!
+        Helper function to enable support for common swap implementation pattern based on \c std::swap:
+        \code
+        void swap(MyClass& a, MyClass& b) {
+            using std::swap;
+            swap(a.value, b.value);
+            // ...
+        }
+        \endcode
+        \see Swap()
+     */
+    friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
+
     //! Prepare Value for move semantics
     /*! \return *this */
     GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
@@ -703,12 +717,15 @@
             return StringEqual(rhs);
 
         case kNumberType:
-            if (IsDouble() || rhs.IsDouble())
-                return GetDouble() == rhs.GetDouble(); // May convert one operand from integer to double.
+            if (IsDouble() || rhs.IsDouble()) {
+                double a = GetDouble();     // May convert from integer to double.
+                double b = rhs.GetDouble(); // Ditto
+                return a >= b && a <= b;    // Prevent -Wfloat-equal
+            }
             else
                 return data_.n.u64 == rhs.data_.n.u64;
 
-        default: // kTrueType, kFalseType, kNullType
+        default:
             return true;
         }
     }
@@ -836,13 +853,25 @@
             return member->value;
         else {
             RAPIDJSON_ASSERT(false);    // see above note
-            static GenericValue NullValue;
-            return NullValue;
+
+            // This will generate -Wexit-time-destructors in clang
+            // static GenericValue NullValue;
+            // return NullValue;
+
+            // Use static buffer and placement-new to prevent destruction
+            static char buffer[sizeof(GenericValue)];
+            return *new (buffer) GenericValue();
         }
     }
     template <typename SourceAllocator>
     const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
 
+#if RAPIDJSON_HAS_STDSTRING
+    //! Get a value from an object associated with name (string object).
+    GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
+    const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
+#endif
+
     //! Const member iterator
     /*! \pre IsObject() == true */
     ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(data_.o.members); }
@@ -866,6 +895,18 @@
     */
     bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
 
+#if RAPIDJSON_HAS_STDSTRING
+    //! Check whether a member exists in the object with string object.
+    /*!
+        \param name Member name to be searched.
+        \pre IsObject() == true
+        \return Whether a member with that name exists.
+        \note It is better to use FindMember() directly if you need the obtain the value as well.
+        \note Linear time complexity.
+    */
+    bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
+#endif
+
     //! Check whether a member exists in the object with GenericValue name.
     /*!
         This version is faster because it does not need a StrLen(). It can also handle string with null character.
@@ -922,6 +963,18 @@
     }
     template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
 
+#if RAPIDJSON_HAS_STDSTRING
+    //! Find member by string object name.
+    /*!
+        \param name Member name to be searched.
+        \pre IsObject() == true
+        \return Iterator to member, if it exists.
+            Otherwise returns \ref MemberEnd().
+    */
+    MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(StringRef(name)); }
+    ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(StringRef(name)); }
+#endif
+
     //! Add a member (name-value pair) to the object.
     /*! \param name A string value as name of member.
         \param value Value of any type.
@@ -968,6 +1021,22 @@
         return AddMember(name, v, allocator);
     }
 
+#if RAPIDJSON_HAS_STDSTRING
+    //! Add a string object as member (name-value pair) to the object.
+    /*! \param name A string value as name of member.
+        \param value constant string reference as value of member.
+        \param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
+        \return The value itself for fluent API.
+        \pre  IsObject()
+        \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below.
+        \note Amortized Constant time complexity.
+    */
+    GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
+        GenericValue v(value, allocator);
+        return AddMember(name, v, allocator);
+    }
+#endif
+
     //! Add any primitive value as member (name-value pair) to the object.
     /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
         \param name A string value as name of member.
@@ -1086,6 +1155,10 @@
         return RemoveMember(n);
     }
 
+#if RAPIDJSON_HAS_STDSTRING
+    bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
+#endif
+
     template <typename SourceAllocator>
     bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
         MemberIterator m = FindMember(name);
@@ -1157,11 +1230,36 @@
         MemberIterator pos = MemberBegin() + (first - MemberBegin());
         for (MemberIterator itr = pos; itr != last; ++itr)
             itr->~Member();
-        std::memmove(&*pos, &*last, (MemberEnd() - last) * sizeof(Member));
-        data_.o.size -= (last - first);
+        std::memmove(&*pos, &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
+        data_.o.size -= static_cast<SizeType>(last - first);
         return pos;
     }
 
+    //! Erase a member in object by its name.
+    /*! \param name Name of member to be removed.
+        \return Whether the member existed.
+        \note Linear time complexity.
+    */
+    bool EraseMember(const Ch* name) {
+        GenericValue n(StringRef(name));
+        return EraseMember(n);
+    }
+
+#if RAPIDJSON_HAS_STDSTRING
+    bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }
+#endif
+
+    template <typename SourceAllocator>
+    bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {
+        MemberIterator m = FindMember(name);
+        if (m != MemberEnd()) {
+            EraseMember(m);
+            return true;
+        }
+        else
+            return false;
+    }
+
     //@}
 
     //!@name Array
@@ -1225,7 +1323,7 @@
     GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
         RAPIDJSON_ASSERT(IsArray());
         if (newCapacity > data_.a.capacity) {
-            data_.a.elements = (GenericValue*)allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue));
+            data_.a.elements = static_cast<GenericValue*>(allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)));
             data_.a.capacity = newCapacity;
         }
         return *this;
@@ -1332,8 +1430,8 @@
         ValueIterator pos = Begin() + (first - Begin());
         for (ValueIterator itr = pos; itr != last; ++itr)
             itr->~GenericValue();       
-        std::memmove(pos, last, (End() - last) * sizeof(GenericValue));
-        data_.a.size -= (last - first);
+        std::memmove(pos, last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
+        data_.a.size -= static_cast<SizeType>(last - first);
         return pos;
     }
 
@@ -1352,8 +1450,8 @@
         if ((flags_ & kDoubleFlag) != 0)                return data_.n.d;   // exact type, no conversion.
         if ((flags_ & kIntFlag) != 0)                   return data_.n.i.i; // int -> double
         if ((flags_ & kUintFlag) != 0)                  return data_.n.u.u; // unsigned -> double
-        if ((flags_ & kInt64Flag) != 0)                 return (double)data_.n.i64; // int64_t -> double (may lose precision)
-        RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0);  return (double)data_.n.u64; // uint64_t -> double (may lose precision)
+        if ((flags_ & kInt64Flag) != 0)                 return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
+        RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0);  return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
     }
 
     GenericValue& SetInt(int i)             { this->~GenericValue(); new (this) GenericValue(i);    return *this; }
@@ -1417,7 +1515,7 @@
         \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size()
         \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
     */
-    GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(s.data(), s.size(), allocator); }
+    GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(s.data(), SizeType(s.size()), allocator); }
 #endif
 
     //@}
@@ -1459,17 +1557,14 @@
         case kStringType:
             return handler.String(GetString(), GetStringLength(), (flags_ & kCopyFlag) != 0);
     
-        case kNumberType:
+        default:
+            RAPIDJSON_ASSERT(GetType() == kNumberType);
             if (IsInt())            return handler.Int(data_.n.i.i);
             else if (IsUint())      return handler.Uint(data_.n.u.u);
             else if (IsInt64())     return handler.Int64(data_.n.i64);
             else if (IsUint64())    return handler.Uint64(data_.n.u64);
             else                    return handler.Double(data_.n.d);
-    
-        default:
-            RAPIDJSON_ASSERT(false);
         }
-        return false;
     }
 
 private:
@@ -1528,9 +1623,9 @@
         enum { MaxChars = sizeof(String) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
         Ch str[MaxChars];
 
-        inline static bool Usable(SizeType len) { return            (MaxSize >= len); }
-        inline void     SetLength(SizeType len) { str[LenPos] = (Ch)(MaxSize -  len); }
-        inline SizeType GetLength() const       { return  (SizeType)(MaxSize -  str[LenPos]); }
+        inline static bool Usable(SizeType len) { return                       (MaxSize >= len); }
+        inline void     SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize -  len); }
+        inline SizeType GetLength() const       { return  static_cast<SizeType>(MaxSize -  str[LenPos]); }
     };  // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
 
     // By using proper binary layout, retrieval of different integer types do not need conversions.
@@ -1582,16 +1677,24 @@
     // Initialize this value as array with initial data, without calling destructor.
     void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
         flags_ = kArrayFlag;
-        data_.a.elements = (GenericValue*)allocator.Malloc(count * sizeof(GenericValue));
-        std::memcpy(data_.a.elements, values, count * sizeof(GenericValue));
+        if (count) {
+            data_.a.elements = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
+            std::memcpy(data_.a.elements, values, count * sizeof(GenericValue));
+        }
+        else
+            data_.a.elements = NULL;
         data_.a.size = data_.a.capacity = count;
     }
 
     //! Initialize this value as object with initial data, without calling destructor.
     void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
         flags_ = kObjectFlag;
-        data_.o.members = (Member*)allocator.Malloc(count * sizeof(Member));
-        std::memcpy(data_.o.members, members, count * sizeof(Member));
+        if (count) {
+            data_.o.members = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
+            std::memcpy(data_.o.members, members, count * sizeof(Member));
+        }
+        else
+            data_.o.members = NULL;
         data_.o.size = data_.o.capacity = count;
     }
 
@@ -1612,7 +1715,7 @@
         } else {
             flags_ = kCopyStringFlag;
             data_.s.length = s.length;
-            str = (Ch *)allocator.Malloc((s.length + 1) * sizeof(Ch));
+            str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
             data_.s.str = str;
         }
         std::memcpy(str, s, s.length * sizeof(Ch));
@@ -1668,7 +1771,22 @@
     typedef Allocator AllocatorType;                        //!< Allocator type from template parameter.
 
     //! Constructor
-    /*! \param allocator        Optional allocator for allocating memory.
+    /*! Creates an empty document of specified type.
+        \param type             Mandatory type of object to create.
+        \param allocator        Optional allocator for allocating memory.
+        \param stackCapacity    Optional initial capacity of stack in bytes.
+        \param stackAllocator   Optional allocator for allocating memory for stack.
+    */
+    explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
+        GenericValue<Encoding, Allocator>(type),  allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
+    {
+        if (!allocator_)
+            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
+    }
+
+    //! Constructor
+    /*! Creates an empty document which type is Null. 
+        \param allocator        Optional allocator for allocating memory.
         \param stackCapacity    Optional initial capacity of stack in bytes.
         \param stackAllocator   Optional allocator for allocating memory for stack.
     */
@@ -1682,7 +1800,7 @@
 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
     //! Move constructor in C++11
     GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
-        : ValueType(std::move(rhs)),
+        : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
           allocator_(rhs.allocator_),
           ownAllocator_(rhs.ownAllocator_),
           stack_(std::move(rhs.stack_)),
@@ -1722,6 +1840,35 @@
     }
 #endif
 
+    //! Exchange the contents of this document with those of another.
+    /*!
+        \param rhs Another document.
+        \note Constant complexity.
+        \see GenericValue::Swap
+    */
+    GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {
+        ValueType::Swap(rhs);
+        stack_.Swap(rhs.stack_);
+        internal::Swap(allocator_, rhs.allocator_);
+        internal::Swap(ownAllocator_, rhs.ownAllocator_);
+        internal::Swap(parseResult_, rhs.parseResult_);
+        return *this;
+    }
+
+    //! free-standing swap function helper
+    /*!
+        Helper function to enable support for common swap implementation pattern based on \c std::swap:
+        \code
+        void swap(MyClass& a, MyClass& b) {
+            using std::swap;
+            swap(a.doc, b.doc);
+            // ...
+        }
+        \endcode
+        \see Swap()
+     */
+    friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
+
     //!@name Parse from stream
     //!@{
 
@@ -1734,13 +1881,13 @@
     */
     template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
     GenericDocument& ParseStream(InputStream& is) {
-        ValueType::SetNull(); // Remove existing root if exist
-        GenericReader<SourceEncoding, Encoding, Allocator> reader(&GetAllocator());
+        GenericReader<SourceEncoding, Encoding, StackAllocator> reader(
+            stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
         ClearStackOnExit scope(*this);
         parseResult_ = reader.template Parse<parseFlags>(is, *this);
         if (parseResult_) {
             RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
-            this->RawAssign(*stack_.template Pop<ValueType>(1));    // Add this-> to prevent issue 13.
+            ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
         }
         return *this;
     }
@@ -1753,7 +1900,7 @@
     */
     template <unsigned parseFlags, typename InputStream>
     GenericDocument& ParseStream(InputStream& is) {
-        return ParseStream<parseFlags,Encoding,InputStream>(is);
+        return ParseStream<parseFlags, Encoding, InputStream>(is);
     }
 
     //! Parse JSON text from an input stream (with \ref kParseDefaultFlags)
@@ -1770,26 +1917,15 @@
     //!@name Parse in-place from mutable string
     //!@{
 
-    //! Parse JSON text from a mutable string (with Encoding conversion)
+    //! Parse JSON text from a mutable string
     /*! \tparam parseFlags Combination of \ref ParseFlag.
-        \tparam SourceEncoding Transcoding from input Encoding
         \param str Mutable zero-terminated string to be parsed.
         \return The document itself for fluent API.
     */
-    template <unsigned parseFlags, typename SourceEncoding>
+    template <unsigned parseFlags>
     GenericDocument& ParseInsitu(Ch* str) {
         GenericInsituStringStream<Encoding> s(str);
-        return ParseStream<parseFlags | kParseInsituFlag, SourceEncoding>(s);
-    }
-
-    //! Parse JSON text from a mutable string
-    /*! \tparam parseFlags Combination of \ref ParseFlag.
-        \param str Mutable zero-terminated string to be parsed.
-        \return The document itself for fluent API.
-    */
-    template <unsigned parseFlags>
-    GenericDocument& ParseInsitu(Ch* str) {
-        return ParseInsitu<parseFlags, Encoding>(str);
+        return ParseStream<parseFlags | kParseInsituFlag>(s);
     }
 
     //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags)
@@ -1797,7 +1933,7 @@
         \return The document itself for fluent API.
     */
     GenericDocument& ParseInsitu(Ch* str) {
-        return ParseInsitu<kParseDefaultFlags, Encoding>(str);
+        return ParseInsitu<kParseDefaultFlags>(str);
     }
     //!@}
 
@@ -1810,7 +1946,7 @@
         \param str Read-only zero-terminated string to be parsed.
     */
     template <unsigned parseFlags, typename SourceEncoding>
-    GenericDocument& Parse(const Ch* str) {
+    GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
         RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
         GenericStringStream<SourceEncoding> s(str);
         return ParseStream<parseFlags, SourceEncoding>(s);
@@ -1845,10 +1981,26 @@
     //! Get the position of last parsing error in input, 0 otherwise.
     size_t GetErrorOffset() const { return parseResult_.Offset(); }
 
+    //! Implicit conversion to get the last parse result
+#ifndef __clang // -Wdocumentation
+    /*! \return \ref ParseResult of the last parse operation
+
+        \code
+          Document doc;
+          ParseResult ok = doc.Parse(json);
+          if (!ok)
+            printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset());
+        \endcode
+     */
+#endif
+    operator ParseResult() const { return parseResult_; }
     //!@}
 
     //! Get the allocator of this document.
-    Allocator& GetAllocator() { return *allocator_; }
+    Allocator& GetAllocator() {
+        RAPIDJSON_ASSERT(allocator_);
+        return *allocator_;
+    }
 
     //! Get the capacity of stack in bytes.
     size_t GetStackCapacity() const { return stack_.GetCapacity(); }
@@ -1891,7 +2043,7 @@
 
     bool EndObject(SizeType memberCount) {
         typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
-        stack_.template Top<ValueType>()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator());
+        stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
         return true;
     }
 
@@ -1954,15 +2106,24 @@
             SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
         }
         break;
-    default: // kNumberType, kTrueType, kFalseType, kNullType
+    default:
         flags_ = rhs.flags_;
         data_  = *reinterpret_cast<const Data*>(&rhs.data_);
+        break;
     }
 }
 
 RAPIDJSON_NAMESPACE_END
 
-#if defined(_MSC_VER) || defined(__GNUC__)
+#ifdef _MSC_VER
+RAPIDJSON_DIAG_POP
+#endif
+
+#ifdef __clang__
+RAPIDJSON_DIAG_POP
+#endif
+
+#ifdef __GNUC__
 RAPIDJSON_DIAG_POP
 #endif
 

=== modified file 'shorts/xml2json/rapidjson/encodedstream.h'
--- shorts/xml2json/rapidjson/encodedstream.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/encodedstream.h	2016-03-16 12:38:32 +0000
@@ -1,22 +1,16 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_ENCODEDSTREAM_H_
 #define RAPIDJSON_ENCODEDSTREAM_H_
@@ -28,6 +22,11 @@
 RAPIDJSON_DIAG_OFF(effc++)
 #endif
 
+#ifdef __clang__
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(padded)
+#endif
+
 RAPIDJSON_NAMESPACE_BEGIN
 
 //! Input byte stream wrapper with a statically bound encoding.
@@ -66,7 +65,7 @@
 //! Output byte stream wrapper with statically bound encoding.
 /*!
     \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.
-    \tparam InputByteStream Type of input byte stream. For example, FileWriteStream.
+    \tparam OutputByteStream Type of input byte stream. For example, FileWriteStream.
 */
 template <typename Encoding, typename OutputByteStream>
 class EncodedOutputStream {
@@ -83,8 +82,8 @@
     void Flush() { os_.Flush(); }
 
     // Not implemented
-    Ch Peek() const { RAPIDJSON_ASSERT(false); }
-    Ch Take() { RAPIDJSON_ASSERT(false);  }
+    Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}
+    Ch Take() { RAPIDJSON_ASSERT(false); return 0;}
     size_t Tell() const { RAPIDJSON_ASSERT(false);  return 0; }
     Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
     size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
@@ -115,6 +114,7 @@
         \param type UTF encoding type if it is not detected from the stream.
     */
     AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) {
+        RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE);        
         DetectType();
         static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) };
         takeFunc_ = f[type_];
@@ -147,11 +147,11 @@
         // FF FE        UTF-16LE
         // EF BB BF     UTF-8
 
-        const unsigned char* c = (const unsigned char *)is_->Peek4();
+        const unsigned char* c = reinterpret_cast<const unsigned char *>(is_->Peek4());
         if (!c)
             return;
 
-        unsigned bom = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
+        unsigned bom = static_cast<unsigned>(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24));
         hasBOM_ = false;
         if (bom == 0xFFFE0000)                  { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
         else if (bom == 0x0000FEFF)             { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
@@ -183,21 +183,8 @@
         }
 
         // Runtime check whether the size of character type is sufficient. It only perform checks with assertion.
-        switch (type_) {
-        case kUTF8:
-            // Do nothing
-            break;
-        case kUTF16LE:
-        case kUTF16BE:
-            RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
-            break;
-        case kUTF32LE:
-        case kUTF32BE:
-            RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
-            break;
-        default:
-            RAPIDJSON_ASSERT(false);    // Invalid type
-        }
+        if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
+        if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
     }
 
     typedef Ch (*TakeFunc)(InputByteStream& is);
@@ -211,7 +198,7 @@
 //! Output stream wrapper with dynamically bound encoding and automatic encoding detection.
 /*!
     \tparam CharType Type of character for writing.
-    \tparam InputByteStream type of output byte stream to be wrapped.
+    \tparam OutputByteStream type of output byte stream to be wrapped.
 */
 template <typename CharType, typename OutputByteStream>
 class AutoUTFOutputStream {
@@ -226,22 +213,11 @@
         \param putBOM Whether to write BOM at the beginning of the stream.
     */
     AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) {
-        // RUntime check whether the size of character type is sufficient. It only perform checks with assertion.
-        switch (type_) {
-        case kUTF16LE:
-        case kUTF16BE:
-            RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
-            break;
-        case kUTF32LE:
-        case kUTF32BE:
-            RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
-            break;
-        case kUTF8:
-            // Do nothing
-            break;
-        default:
-            RAPIDJSON_ASSERT(false);    // Invalid UTFType
-        }
+        RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE);
+
+        // Runtime check whether the size of character type is sufficient. It only perform checks with assertion.
+        if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
+        if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
 
         static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) };
         putFunc_ = f[type_];
@@ -256,8 +232,8 @@
     void Flush() { os_->Flush(); } 
 
     // Not implemented
-    Ch Peek() const { RAPIDJSON_ASSERT(false); }
-    Ch Take() { RAPIDJSON_ASSERT(false); }
+    Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}
+    Ch Take() { RAPIDJSON_ASSERT(false); return 0;}
     size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
     Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
     size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
@@ -283,6 +259,10 @@
 
 RAPIDJSON_NAMESPACE_END
 
+#ifdef __clang__
+RAPIDJSON_DIAG_POP
+#endif
+
 #ifdef __GNUC__
 RAPIDJSON_DIAG_POP
 #endif

=== modified file 'shorts/xml2json/rapidjson/encodings.h'
--- shorts/xml2json/rapidjson/encodings.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/encodings.h	2016-03-16 12:38:32 +0000
@@ -1,22 +1,16 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_ENCODINGS_H_
 #define RAPIDJSON_ENCODINGS_H_
@@ -30,6 +24,7 @@
 #elif defined(__GNUC__)
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_OFF(effc++)
+RAPIDJSON_DIAG_OFF(overflow)
 #endif
 
 RAPIDJSON_NAMESPACE_BEGIN
@@ -127,17 +122,17 @@
 
     template <typename InputStream>
     static bool Decode(InputStream& is, unsigned* codepoint) {
-#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | ((unsigned char)c & 0x3Fu)
-#define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0)
+#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)
+#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
 #define TAIL() COPY(); TRANS(0x70)
-        Ch c = is.Take();
+        typename InputStream::Ch c = is.Take();
         if (!(c & 0x80)) {
-            *codepoint = (unsigned char)c;
+            *codepoint = static_cast<unsigned char>(c);
             return true;
         }
 
-        unsigned char type = GetRange((unsigned char)c);
-        *codepoint = (0xFF >> type) & (unsigned char)c;
+        unsigned char type = GetRange(static_cast<unsigned char>(c));
+        *codepoint = (0xFF >> type) & static_cast<unsigned char>(c);
         bool result = true;
         switch (type) {
         case 2: TAIL(); return result;
@@ -157,7 +152,7 @@
     template <typename InputStream, typename OutputStream>
     static bool Validate(InputStream& is, OutputStream& os) {
 #define COPY() os.Put(c = is.Take())
-#define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0)
+#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
 #define TAIL() COPY(); TRANS(0x70)
         Ch c;
         COPY();
@@ -165,7 +160,7 @@
             return true;
 
         bool result = true;
-        switch (GetRange((unsigned char)c)) {
+        switch (GetRange(static_cast<unsigned char>(c))) {
         case 2: TAIL(); return result;
         case 3: TAIL(); TAIL(); return result;
         case 4: COPY(); TRANS(0x50); TAIL(); return result;
@@ -201,12 +196,12 @@
     template <typename InputByteStream>
     static CharType TakeBOM(InputByteStream& is) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
-        Ch c = Take(is);
-        if ((unsigned char)c != 0xEFu) return c;
-        c = is.Take();
-        if ((unsigned char)c != 0xBBu) return c;
-        c = is.Take();
-        if ((unsigned char)c != 0xBFu) return c;
+        typename InputByteStream::Ch c = Take(is);
+        if (static_cast<unsigned char>(c) != 0xEFu) return c;
+        c = is.Take();
+        if (static_cast<unsigned char>(c) != 0xBBu) return c;
+        c = is.Take();
+        if (static_cast<unsigned char>(c) != 0xBFu) return c;
         c = is.Take();
         return c;
     }
@@ -214,13 +209,15 @@
     template <typename InputByteStream>
     static Ch Take(InputByteStream& is) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
-        return is.Take();
+        return static_cast<Ch>(is.Take());
     }
 
     template <typename OutputByteStream>
     static void PutBOM(OutputByteStream& os) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
-        os.Put(0xEFu); os.Put(0xBBu); os.Put(0xBFu);
+        os.Put(static_cast<typename OutputByteStream::Ch>(0xEFu));
+        os.Put(static_cast<typename OutputByteStream::Ch>(0xBBu));
+        os.Put(static_cast<typename OutputByteStream::Ch>(0xBFu));
     }
 
     template <typename OutputByteStream>
@@ -267,15 +264,15 @@
     template <typename InputStream>
     static bool Decode(InputStream& is, unsigned* codepoint) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
-        Ch c = is.Take();
+        typename InputStream::Ch c = is.Take();
         if (c < 0xD800 || c > 0xDFFF) {
-            *codepoint = c;
+            *codepoint = static_cast<unsigned>(c);
             return true;
         }
         else if (c <= 0xDBFF) {
-            *codepoint = (c & 0x3FF) << 10;
+            *codepoint = (static_cast<unsigned>(c) & 0x3FF) << 10;
             c = is.Take();
-            *codepoint |= (c & 0x3FF);
+            *codepoint |= (static_cast<unsigned>(c) & 0x3FF);
             *codepoint += 0x10000;
             return c >= 0xDC00 && c <= 0xDFFF;
         }
@@ -286,8 +283,8 @@
     static bool Validate(InputStream& is, OutputStream& os) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
         RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
-        Ch c;
-        os.Put(c = is.Take());
+        typename InputStream::Ch c;
+        os.Put(static_cast<typename OutputStream::Ch>(c = is.Take()));
         if (c < 0xD800 || c > 0xDFFF)
             return true;
         else if (c <= 0xDBFF) {
@@ -305,28 +302,29 @@
     static CharType TakeBOM(InputByteStream& is) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
         CharType c = Take(is);
-        return (unsigned short)c == 0xFEFFu ? Take(is) : c;
+        return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c;
     }
 
     template <typename InputByteStream>
     static CharType Take(InputByteStream& is) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
-        CharType c = (unsigned char)is.Take();
-        c |= (unsigned char)is.Take() << 8;
-        return c;
+        unsigned c = static_cast<uint8_t>(is.Take());
+        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
+        return static_cast<CharType>(c);
     }
 
     template <typename OutputByteStream>
     static void PutBOM(OutputByteStream& os) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
-        os.Put(0xFFu); os.Put(0xFEu);
+        os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
+        os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
     }
 
     template <typename OutputByteStream>
     static void Put(OutputByteStream& os, CharType c) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
-        os.Put(c & 0xFFu);
-        os.Put((c >> 8) & 0xFFu);
+        os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu));
+        os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu));
     }
 };
 
@@ -337,28 +335,29 @@
     static CharType TakeBOM(InputByteStream& is) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
         CharType c = Take(is);
-        return (unsigned short)c == 0xFEFFu ? Take(is) : c;
+        return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c;
     }
 
     template <typename InputByteStream>
     static CharType Take(InputByteStream& is) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
-        CharType c = (unsigned char)is.Take() << 8;
-        c |= (unsigned char)is.Take();
-        return c;
+        unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
+        c |= static_cast<uint8_t>(is.Take());
+        return static_cast<CharType>(c);
     }
 
     template <typename OutputByteStream>
     static void PutBOM(OutputByteStream& os) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
-        os.Put(0xFEu); os.Put(0xFFu);
+        os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
+        os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
     }
 
     template <typename OutputByteStream>
     static void Put(OutputByteStream& os, CharType c) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
-        os.Put((c >> 8) & 0xFFu);
-        os.Put(c & 0xFFu);
+        os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu));
+        os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu));
     }
 };
 
@@ -411,32 +410,35 @@
     static CharType TakeBOM(InputByteStream& is) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
         CharType c = Take(is);
-        return (unsigned)c == 0x0000FEFFu ? Take(is) : c;
+        return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c;
     }
 
     template <typename InputByteStream>
     static CharType Take(InputByteStream& is) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
-        CharType c = (unsigned char)is.Take();
-        c |= (unsigned char)is.Take() << 8;
-        c |= (unsigned char)is.Take() << 16;
-        c |= (unsigned char)is.Take() << 24;
-        return c;
+        unsigned c = static_cast<uint8_t>(is.Take());
+        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
+        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16;
+        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24;
+        return static_cast<CharType>(c);
     }
 
     template <typename OutputByteStream>
     static void PutBOM(OutputByteStream& os) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
-        os.Put(0xFFu); os.Put(0xFEu); os.Put(0x00u); os.Put(0x00u);
+        os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
+        os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
+        os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
+        os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
     }
 
     template <typename OutputByteStream>
     static void Put(OutputByteStream& os, CharType c) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
-        os.Put(c & 0xFFu);
-        os.Put((c >> 8) & 0xFFu);
-        os.Put((c >> 16) & 0xFFu);
-        os.Put((c >> 24) & 0xFFu);
+        os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu));
+        os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu));
+        os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu));
+        os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu));
     }
 };
 
@@ -447,32 +449,35 @@
     static CharType TakeBOM(InputByteStream& is) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
         CharType c = Take(is);
-        return (unsigned)c == 0x0000FEFFu ? Take(is) : c; 
+        return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c; 
     }
 
     template <typename InputByteStream>
     static CharType Take(InputByteStream& is) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
-        CharType c = (unsigned char)is.Take() << 24;
-        c |= (unsigned char)is.Take() << 16;
-        c |= (unsigned char)is.Take() << 8;
-        c |= (unsigned char)is.Take();
-        return c;
+        unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24;
+        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16;
+        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
+        c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take()));
+        return static_cast<CharType>(c);
     }
 
     template <typename OutputByteStream>
     static void PutBOM(OutputByteStream& os) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
-        os.Put(0x00u); os.Put(0x00u); os.Put(0xFEu); os.Put(0xFFu);
+        os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
+        os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
+        os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
+        os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
     }
 
     template <typename OutputByteStream>
     static void Put(OutputByteStream& os, CharType c) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
-        os.Put((c >> 24) & 0xFFu);
-        os.Put((c >> 16) & 0xFFu);
-        os.Put((c >> 8) & 0xFFu);
-        os.Put(c & 0xFFu);
+        os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu));
+        os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu));
+        os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu));
+        os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu));
     }
 };
 
@@ -498,29 +503,29 @@
 
     template <typename InputStream>
     static bool Decode(InputStream& is, unsigned* codepoint) {
-        unsigned char c = static_cast<unsigned char>(is.Take());
+        uint8_t c = static_cast<uint8_t>(is.Take());
         *codepoint = c;
         return c <= 0X7F;
     }
 
     template <typename InputStream, typename OutputStream>
     static bool Validate(InputStream& is, OutputStream& os) {
-        unsigned char c = is.Take();
-        os.Put(c);
+        uint8_t c = static_cast<uint8_t>(is.Take());
+        os.Put(static_cast<typename OutputStream::Ch>(c));
         return c <= 0x7F;
     }
 
     template <typename InputByteStream>
     static CharType TakeBOM(InputByteStream& is) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
-        Ch c = Take(is);
-        return c;
+        uint8_t c = static_cast<uint8_t>(Take(is));
+        return static_cast<Ch>(c);
     }
 
     template <typename InputByteStream>
     static Ch Take(InputByteStream& is) {
         RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
-        return is.Take();
+        return static_cast<Ch>(is.Take());
     }
 
     template <typename OutputByteStream>
@@ -623,7 +628,7 @@
 
 RAPIDJSON_NAMESPACE_END
 
-#if defined(__GNUC__) || defined(_MSV_VER)
+#if defined(__GNUC__) || defined(_MSC_VER)
 RAPIDJSON_DIAG_POP
 #endif
 

=== modified file 'shorts/xml2json/rapidjson/error/en.h'
--- shorts/xml2json/rapidjson/error/en.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/error/en.h	2016-03-16 12:38:32 +0000
@@ -1,28 +1,28 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
-#ifndef RAPIDJSON_ERROR_EN_H__
-#define RAPIDJSON_ERROR_EN_H__
+#ifndef RAPIDJSON_ERROR_EN_H_
+#define RAPIDJSON_ERROR_EN_H_
 
 #include "error.h"
 
+#ifdef __clang__
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(switch-enum)
+RAPIDJSON_DIAG_OFF(covered-switch-default)
+#endif
+
 RAPIDJSON_NAMESPACE_BEGIN
 
 //! Maps error code of parsing into error message.
@@ -61,11 +61,14 @@
         case kParseErrorTermination:                    return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error.");
         case kParseErrorUnspecificSyntaxError:          return RAPIDJSON_ERROR_STRING("Unspecific syntax error.");
 
-        default:
-            return RAPIDJSON_ERROR_STRING("Unknown error.");
+        default:                                        return RAPIDJSON_ERROR_STRING("Unknown error.");
     }
 }
 
 RAPIDJSON_NAMESPACE_END
 
-#endif // RAPIDJSON_ERROR_EN_H__
+#ifdef __clang__
+RAPIDJSON_DIAG_POP
+#endif
+
+#endif // RAPIDJSON_ERROR_EN_H_

=== modified file 'shorts/xml2json/rapidjson/error/error.h'
--- shorts/xml2json/rapidjson/error/error.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/error/error.h	2016-03-16 12:38:32 +0000
@@ -1,25 +1,26 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#ifndef RAPIDJSON_ERROR_ERROR_H__
-#define RAPIDJSON_ERROR_ERROR_H__
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
+
+#ifndef RAPIDJSON_ERROR_ERROR_H_
+#define RAPIDJSON_ERROR_ERROR_H_
+
+#include "../rapidjson.h"
+
+#ifdef __clang__
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(padded)
+#endif
 
 /*! \file error.h */
 
@@ -103,7 +104,7 @@
     \see GenericReader::Parse, GenericDocument::Parse
 */
 struct ParseResult {
-
+public:
     //! Default constructor, no error.
     ParseResult() : code_(kParseErrorNone), offset_(0) {}
     //! Constructor to set an error.
@@ -147,4 +148,8 @@
 
 RAPIDJSON_NAMESPACE_END
 
-#endif // RAPIDJSON_ERROR_ERROR_H__
+#ifdef __clang__
+RAPIDJSON_DIAG_POP
+#endif
+
+#endif // RAPIDJSON_ERROR_ERROR_H_

=== modified file 'shorts/xml2json/rapidjson/filereadstream.h'
--- shorts/xml2json/rapidjson/filereadstream.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/filereadstream.h	2016-03-16 12:38:32 +0000
@@ -1,22 +1,16 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_FILEREADSTREAM_H_
 #define RAPIDJSON_FILEREADSTREAM_H_
@@ -24,6 +18,13 @@
 #include "rapidjson.h"
 #include <cstdio>
 
+#ifdef __clang__
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(padded)
+RAPIDJSON_DIAG_OFF(unreachable-code)
+RAPIDJSON_DIAG_OFF(missing-noreturn)
+#endif
+
 RAPIDJSON_NAMESPACE_BEGIN
 
 //! File byte stream for input using fread().
@@ -91,4 +92,8 @@
 
 RAPIDJSON_NAMESPACE_END
 
+#ifdef __clang__
+RAPIDJSON_DIAG_POP
+#endif
+
 #endif // RAPIDJSON_FILESTREAM_H_

=== modified file 'shorts/xml2json/rapidjson/filewritestream.h'
--- shorts/xml2json/rapidjson/filewritestream.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/filewritestream.h	2016-03-16 12:38:32 +0000
@@ -1,22 +1,16 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_FILEWRITESTREAM_H_
 #define RAPIDJSON_FILEWRITESTREAM_H_
@@ -24,6 +18,11 @@
 #include "rapidjson.h"
 #include <cstdio>
 
+#ifdef __clang__
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(unreachable-code)
+#endif
+
 RAPIDJSON_NAMESPACE_BEGIN
 
 //! Wrapper of C file stream for input using fread().
@@ -63,7 +62,11 @@
 
     void Flush() {
         if (current_ != buffer_) {
-            fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
+            size_t result = fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
+            if (result < static_cast<size_t>(current_ - buffer_)) {
+                // failure deliberately ignored at this time
+                // added to avoid warn_unused_result build errors
+            }
             current_ = buffer_;
         }
     }
@@ -94,4 +97,8 @@
 
 RAPIDJSON_NAMESPACE_END
 
+#ifdef __clang__
+RAPIDJSON_DIAG_POP
+#endif
+
 #endif // RAPIDJSON_FILESTREAM_H_

=== modified file 'shorts/xml2json/rapidjson/internal/biginteger.h'
--- shorts/xml2json/rapidjson/internal/biginteger.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/internal/biginteger.h	2016-03-16 12:38:32 +0000
@@ -1,22 +1,16 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_BIGINTEGER_H_
 #define RAPIDJSON_BIGINTEGER_H_
@@ -25,6 +19,7 @@
 
 #if defined(_MSC_VER) && defined(_M_AMD64)
 #include <intrin.h> // for _umul128
+#pragma intrinsic(_umul128)
 #endif
 
 RAPIDJSON_NAMESPACE_BEGIN
@@ -56,7 +51,16 @@
         if (length > 0)
             AppendDecimal64(decimals + i, decimals + i + length);
     }
-
+    
+    BigInteger& operator=(const BigInteger &rhs)
+    {
+        if (this != &rhs) {
+            count_ = rhs.count_;
+            std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type));
+        }
+        return *this;
+    }
+    
     BigInteger& operator=(uint64_t u) {
         digits_[0] = u;            
         count_ = 1;
@@ -103,7 +107,7 @@
         if (u == 1) return *this;
         if (*this == 1) return *this = u;
 
-        uint32_t k = 0;
+        uint64_t k = 0;
         for (size_t i = 0; i < count_; i++) {
             const uint64_t c = digits_[i] >> 32;
             const uint64_t d = digits_[i] & 0xFFFFFFFF;
@@ -178,13 +182,10 @@
     }
 
     // Compute absolute difference of this and rhs.
-    // Return false if this < rhs
+    // Assume this != rhs
     bool Difference(const BigInteger& rhs, BigInteger* out) const {
         int cmp = Compare(rhs);
-        if (cmp == 0) {
-            *out = BigInteger(0);
-            return false;
-        }
+        RAPIDJSON_ASSERT(cmp != 0);
         const BigInteger *a, *b;  // Makes a > b
         bool ret;
         if (cmp < 0) { a = &rhs; b = this; ret = true; }
@@ -239,7 +240,7 @@
         uint64_t r = 0;
         for (const char* p = begin; p != end; ++p) {
             RAPIDJSON_ASSERT(*p >= '0' && *p <= '9');
-            r = r * 10 + (*p - '0');
+            r = r * 10u + static_cast<unsigned>(*p - '0');
         }
         return r;
     }
@@ -252,9 +253,10 @@
             (*outHigh)++;
         return low;
 #elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
-        unsigned __int128 p = static_cast<unsigned __int128>(a) * static_cast<unsigned __int128>(b);
+        __extension__ typedef unsigned __int128 uint128;
+        uint128 p = static_cast<uint128>(a) * static_cast<uint128>(b);
         p += k;
-        *outHigh = p >> 64;
+        *outHigh = static_cast<uint64_t>(p >> 64);
         return static_cast<uint64_t>(p);
 #else
         const uint64_t a0 = a & 0xFFFFFFFF, a1 = a >> 32, b0 = b & 0xFFFFFFFF, b1 = b >> 32;
@@ -274,12 +276,6 @@
 #endif
     }
 
-    static Type FullAdd(Type a, Type b, bool inCarry, bool* outCarry) {
-        Type c = a + b + (inCarry ? 1 : 0);
-        *outCarry = c < a;
-        return c;
-    }
-
     static const size_t kBitCount = 3328;  // 64bit * 54 > 10^1000
     static const size_t kCapacity = kBitCount / sizeof(Type);
     static const size_t kTypeBit = sizeof(Type) * 8;

=== modified file 'shorts/xml2json/rapidjson/internal/diyfp.h'
--- shorts/xml2json/rapidjson/internal/diyfp.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/internal/diyfp.h	2016-03-16 12:38:32 +0000
@@ -1,22 +1,16 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 // This is a C++ header-only implementation of Grisu2 algorithm from the publication:
 // Loitsch, Florian. "Printing floating-point numbers quickly and accurately with
@@ -25,11 +19,12 @@
 #ifndef RAPIDJSON_DIYFP_H_
 #define RAPIDJSON_DIYFP_H_
 
-#if defined(_MSC_VER)
+#include "../rapidjson.h"
+
+#if defined(_MSC_VER) && defined(_M_AMD64)
 #include <intrin.h>
-#if defined(_M_AMD64)
 #pragma intrinsic(_BitScanReverse64)
-#endif
+#pragma intrinsic(_umul128)
 #endif
 
 RAPIDJSON_NAMESPACE_BEGIN
@@ -40,6 +35,11 @@
 RAPIDJSON_DIAG_OFF(effc++)
 #endif
 
+#ifdef __clang__
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(padded)
+#endif
+
 struct DiyFp {
     DiyFp() {}
 
@@ -51,7 +51,7 @@
             uint64_t u64;
         } u = { d };
 
-        int biased_e = (u.u64 & kDpExponentMask) >> kDpSignificandSize;
+        int biased_e = static_cast<int>((u.u64 & kDpExponentMask) >> kDpSignificandSize);
         uint64_t significand = (u.u64 & kDpSignificandMask);
         if (biased_e != 0) {
             f = significand + kDpHiddenBit;
@@ -75,8 +75,9 @@
             h++;
         return DiyFp(h, e + rhs.e + 64);
 #elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
-        unsigned __int128 p = static_cast<unsigned __int128>(f) * static_cast<unsigned __int128>(rhs.f);
-        uint64_t h = p >> 64;
+        __extension__ typedef unsigned __int128 uint128;
+        uint128 p = static_cast<uint128>(f) * static_cast<uint128>(rhs.f);
+        uint64_t h = static_cast<uint64_t>(p >> 64);
         uint64_t l = static_cast<uint64_t>(p);
         if (l & (uint64_t(1) << 63)) // rounding
             h++;
@@ -140,25 +141,9 @@
             double d;
             uint64_t u64;
         }u;
-        uint64_t significand = f;
-        int exponent = e;
-        while (significand > kDpHiddenBit + kDpSignificandMask) {
-            significand >>= 1;
-            exponent++;
-        }
-        while (exponent > kDpDenormalExponent && (significand & kDpHiddenBit) == 0) {
-            significand <<= 1;
-            exponent--;
-        }
-        if (exponent >= kDpMaxExponent) {
-            u.u64 = kDpExponentMask;    // Infinity
-            return u.d;
-        }
-        else if (exponent < kDpDenormalExponent)
-            return 0.0;
-        const uint64_t be = (exponent == kDpDenormalExponent && (significand & kDpHiddenBit) == 0) ? 0 : 
-            static_cast<uint64_t>(exponent + kDpExponentBias);
-        u.u64 = (significand & kDpSignificandMask) | (be << kDpSignificandSize);
+        const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 : 
+            static_cast<uint64_t>(e + kDpExponentBias);
+        u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize);
         return u.d;
     }
 
@@ -243,7 +228,7 @@
     //int k = static_cast<int>(ceil((-61 - e) * 0.30102999566398114)) + 374;
     double dk = (-61 - e) * 0.30102999566398114 + 347;  // dk must be positive, so can do ceiling in positive
     int k = static_cast<int>(dk);
-    if (k != dk)
+    if (dk - k > 0.0)
         k++;
 
     unsigned index = static_cast<unsigned>((k >> 3) + 1);
@@ -253,8 +238,8 @@
 }
 
 inline DiyFp GetCachedPower10(int exp, int *outExp) {
-     unsigned index = (exp + 348) / 8;
-     *outExp = -348 + index * 8;
+     unsigned index = (static_cast<unsigned>(exp) + 348u) / 8u;
+     *outExp = -348 + static_cast<int>(index) * 8;
      return GetCachedPowerByIndex(index);
  }
 
@@ -262,6 +247,11 @@
 RAPIDJSON_DIAG_POP
 #endif
 
+#ifdef __clang__
+RAPIDJSON_DIAG_POP
+RAPIDJSON_DIAG_OFF(padded)
+#endif
+
 } // namespace internal
 RAPIDJSON_NAMESPACE_END
 

=== modified file 'shorts/xml2json/rapidjson/internal/dtoa.h'
--- shorts/xml2json/rapidjson/internal/dtoa.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/internal/dtoa.h	2016-03-16 12:38:32 +0000
@@ -1,22 +1,16 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 // This is a C++ header-only implementation of Grisu2 algorithm from the publication:
 // Loitsch, Florian. "Printing floating-point numbers quickly and accurately with
@@ -27,6 +21,7 @@
 
 #include "itoa.h" // GetDigitsLut()
 #include "diyfp.h"
+#include "ieee754.h"
 
 RAPIDJSON_NAMESPACE_BEGIN
 namespace internal {
@@ -55,8 +50,10 @@
     if (n < 1000000) return 6;
     if (n < 10000000) return 7;
     if (n < 100000000) return 8;
-    if (n < 1000000000) return 9;
-    return 10;
+    // Will not reach 10 digits in DigitGen()
+    //if (n < 1000000000) return 9;
+    //return 10;
+    return 9;
 }
 
 inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {
@@ -65,13 +62,12 @@
     const DiyFp wp_w = Mp - W;
     uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
     uint64_t p2 = Mp.f & (one.f - 1);
-    int kappa = CountDecimalDigit32(p1);
+    unsigned kappa = CountDecimalDigit32(p1); // kappa in [0, 9]
     *len = 0;
 
     while (kappa > 0) {
-        uint32_t d;
+        uint32_t d = 0;
         switch (kappa) {
-            case 10: d = p1 / 1000000000; p1 %= 1000000000; break;
             case  9: d = p1 /  100000000; p1 %=  100000000; break;
             case  8: d = p1 /   10000000; p1 %=   10000000; break;
             case  7: d = p1 /    1000000; p1 %=    1000000; break;
@@ -81,14 +77,7 @@
             case  3: d = p1 /        100; p1 %=        100; break;
             case  2: d = p1 /         10; p1 %=         10; break;
             case  1: d = p1;              p1 =           0; break;
-            default: 
-#if defined(_MSC_VER)
-                __assume(0);
-#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
-                __builtin_unreachable();
-#else
-                d = 0;
-#endif
+            default:;
         }
         if (d || *len)
             buffer[(*len)++] = static_cast<char>('0' + static_cast<char>(d));
@@ -112,7 +101,7 @@
         kappa--;
         if (p2 < delta) {
             *K += kappa;
-            GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * kPow10[-kappa]);
+            GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * kPow10[-static_cast<int>(kappa)]);
             return;
         }
     }
@@ -169,14 +158,14 @@
     }
     else if (0 < kk && kk <= 21) {
         // 1234e-2 -> 12.34
-        std::memmove(&buffer[kk + 1], &buffer[kk], length - kk);
+        std::memmove(&buffer[kk + 1], &buffer[kk], static_cast<size_t>(length - kk));
         buffer[kk] = '.';
         return &buffer[length + 1];
     }
     else if (-6 < kk && kk <= 0) {
         // 1234e-6 -> 0.001234
         const int offset = 2 - kk;
-        std::memmove(&buffer[offset], &buffer[0], length);
+        std::memmove(&buffer[offset], &buffer[0], static_cast<size_t>(length));
         buffer[0] = '0';
         buffer[1] = '.';
         for (int i = 2; i < offset; i++)
@@ -190,7 +179,7 @@
     }
     else {
         // 1234e30 -> 1.234e33
-        std::memmove(&buffer[2], &buffer[1], length - 1);
+        std::memmove(&buffer[2], &buffer[1], static_cast<size_t>(length - 1));
         buffer[1] = '.';
         buffer[length + 1] = 'e';
         return WriteExponent(kk - 1, &buffer[0 + length + 2]);
@@ -198,7 +187,10 @@
 }
 
 inline char* dtoa(double value, char* buffer) {
-    if (value == 0) {
+    Double d(value);
+    if (d.IsZero()) {
+        if (d.Sign())
+            *buffer++ = '-';     // -0.0, Issue #289
         buffer[0] = '0';
         buffer[1] = '.';
         buffer[2] = '0';

=== modified file 'shorts/xml2json/rapidjson/internal/ieee754.h'
--- shorts/xml2json/rapidjson/internal/ieee754.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/internal/ieee754.h	2016-03-16 12:38:32 +0000
@@ -1,22 +1,16 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_IEEE754_
 #define RAPIDJSON_IEEE754_
@@ -29,36 +23,29 @@
 class Double {
 public:
     Double() {}
-    Double(double d) : d(d) {}
-    Double(uint64_t u) : u(u) {}
+    Double(double d) : d_(d) {}
+    Double(uint64_t u) : u_(u) {}
 
-    double Value() const { return d; }
-    uint64_t Uint64Value() const { return u; }
+    double Value() const { return d_; }
+    uint64_t Uint64Value() const { return u_; }
 
     double NextPositiveDouble() const {
         RAPIDJSON_ASSERT(!Sign());
-        return Double(u + 1).Value();
-    }
-
-    double PreviousPositiveDouble() const {
-        RAPIDJSON_ASSERT(!Sign());
-        if (d == 0.0)
-            return 0.0;
-        else
-            return Double(u - 1).Value();
-    }
-
-    bool Sign() const { return (u & kSignMask) != 0; }
-    uint64_t Significand() const { return u & kSignificandMask; }
-    int Exponent() const { return ((u & kExponentMask) >> kSignificandSize) - kExponentBias; }
-
-    bool IsNan() const { return (u & kExponentMask) == kExponentMask && Significand() != 0; }
-    bool IsInf() const { return (u & kExponentMask) == kExponentMask && Significand() == 0; }
-    bool IsNormal() const { return (u & kExponentMask) != 0 || Significand() == 0; }
+        return Double(u_ + 1).Value();
+    }
+
+    bool Sign() const { return (u_ & kSignMask) != 0; }
+    uint64_t Significand() const { return u_ & kSignificandMask; }
+    int Exponent() const { return static_cast<int>(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); }
+
+    bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; }
+    bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; }
+    bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; }
+    bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; }
 
     uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); }
     int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; }
-    uint64_t ToBias() const { return (u & kSignMask) ? ~u + 1 : u | kSignMask; }
+    uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; }
 
     static unsigned EffectiveSignificandSize(int order) {
         if (order >= -1021)
@@ -66,7 +53,7 @@
         else if (order <= -1074)
             return 0;
         else
-            return order + 1074;
+            return static_cast<unsigned>(order) + 1074;
     }
 
 private:
@@ -79,8 +66,8 @@
     static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000);
 
     union {
-        double d;
-        uint64_t u;
+        double d_;
+        uint64_t u_;
     };
 };
 

=== modified file 'shorts/xml2json/rapidjson/internal/itoa.h'
--- shorts/xml2json/rapidjson/internal/itoa.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/internal/itoa.h	2016-03-16 12:38:32 +0000
@@ -1,26 +1,22 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_ITOA_
 #define RAPIDJSON_ITOA_
 
+#include "../rapidjson.h"
+
 RAPIDJSON_NAMESPACE_BEGIN
 namespace internal {
 
@@ -115,12 +111,13 @@
 }
 
 inline char* i32toa(int32_t value, char* buffer) {
+    uint32_t u = static_cast<uint32_t>(value);
     if (value < 0) {
         *buffer++ = '-';
-        value = -value;
+        u = ~u + 1;
     }
 
-    return u32toa(static_cast<uint32_t>(value), buffer);
+    return u32toa(u, buffer);
 }
 
 inline char* u64toa(uint64_t value, char* buffer) {
@@ -292,12 +289,13 @@
 }
 
 inline char* i64toa(int64_t value, char* buffer) {
+    uint64_t u = static_cast<uint64_t>(value);
     if (value < 0) {
         *buffer++ = '-';
-        value = -value;
+        u = ~u + 1;
     }
 
-    return u64toa(static_cast<uint64_t>(value), buffer);
+    return u64toa(u, buffer);
 }
 
 } // namespace internal

=== modified file 'shorts/xml2json/rapidjson/internal/meta.h'
--- shorts/xml2json/rapidjson/internal/meta.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/internal/meta.h	2016-03-16 12:38:32 +0000
@@ -1,29 +1,21 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_INTERNAL_META_H_
 #define RAPIDJSON_INTERNAL_META_H_
 
-#ifndef RAPIDJSON_RAPIDJSON_H_
-#error <rapidjson.h> not yet included. Do not include this file directly.
-#endif
+#include "../rapidjson.h"
 
 #ifdef __GNUC__
 RAPIDJSON_DIAG_PUSH

=== modified file 'shorts/xml2json/rapidjson/internal/pow10.h'
--- shorts/xml2json/rapidjson/internal/pow10.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/internal/pow10.h	2016-03-16 12:38:32 +0000
@@ -1,26 +1,22 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_POW10_
 #define RAPIDJSON_POW10_
 
+#include "../rapidjson.h"
+
 RAPIDJSON_NAMESPACE_BEGIN
 namespace internal {
 

=== modified file 'shorts/xml2json/rapidjson/internal/stack.h'
--- shorts/xml2json/rapidjson/internal/stack.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/internal/stack.h	2016-03-16 12:38:32 +0000
@@ -1,26 +1,23 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_INTERNAL_STACK_H_
 #define RAPIDJSON_INTERNAL_STACK_H_
 
+#include "../rapidjson.h"
+#include "swap.h"
+
 RAPIDJSON_NAMESPACE_BEGIN
 namespace internal {
 
@@ -85,6 +82,15 @@
     }
 #endif
 
+    void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT {
+        internal::Swap(allocator_, rhs.allocator_);
+        internal::Swap(ownAllocator_, rhs.ownAllocator_);
+        internal::Swap(stack_, rhs.stack_);
+        internal::Swap(stackTop_, rhs.stackTop_);
+        internal::Swap(stackEnd_, rhs.stackEnd_);
+        internal::Swap(initialCapacity_, rhs.initialCapacity_);
+    }
+
     void Clear() { stackTop_ = stack_; }
 
     void ShrinkToFit() { 
@@ -126,9 +132,16 @@
     }
 
     template<typename T>
-    T* Bottom() { return (T*)stack_; }
-
-    Allocator& GetAllocator() { return *allocator_; }
+    T* Bottom() { return reinterpret_cast<T*>(stack_); }
+
+    bool HasAllocator() const {
+        return allocator_ != 0;
+    }
+
+    Allocator& GetAllocator() {
+        RAPIDJSON_ASSERT(allocator_);
+        return *allocator_;
+    }
     bool Empty() const { return stackTop_ == stack_; }
     size_t GetSize() const { return static_cast<size_t>(stackTop_ - stack_); }
     size_t GetCapacity() const { return static_cast<size_t>(stackEnd_ - stack_); }
@@ -155,7 +168,7 @@
 
     void Resize(size_t newCapacity) {
         const size_t size = GetSize();  // Backup the current size
-        stack_ = (char*)allocator_->Realloc(stack_, GetCapacity(), newCapacity);
+        stack_ = static_cast<char*>(allocator_->Realloc(stack_, GetCapacity(), newCapacity));
         stackTop_ = stack_ + size;
         stackEnd_ = stack_ + newCapacity;
     }

=== modified file 'shorts/xml2json/rapidjson/internal/strfunc.h'
--- shorts/xml2json/rapidjson/internal/strfunc.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/internal/strfunc.h	2016-03-16 12:38:32 +0000
@@ -1,26 +1,22 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_INTERNAL_STRFUNC_H_
 #define RAPIDJSON_INTERNAL_STRFUNC_H_
 
+#include "../rapidjson.h"
+
 RAPIDJSON_NAMESPACE_BEGIN
 namespace internal {
 

=== modified file 'shorts/xml2json/rapidjson/internal/strtod.h'
--- shorts/xml2json/rapidjson/internal/strtod.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/internal/strtod.h	2016-03-16 12:38:32 +0000
@@ -1,22 +1,16 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_STRTOD_
 #define RAPIDJSON_STRTOD_
@@ -58,7 +52,7 @@
     return m;
 }
 
-inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp, bool* adjustToNegative) {
+inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) {
     const Double db(b);
     const uint64_t bInt = db.IntegerSignificand();
     const int bExp = db.IntegerExponent();
@@ -101,28 +95,18 @@
     hS_Exp2 -= common_Exp2;
 
     BigInteger dS = d;
-    dS.MultiplyPow5(dS_Exp5) <<= dS_Exp2;
+    dS.MultiplyPow5(static_cast<unsigned>(dS_Exp5)) <<= static_cast<unsigned>(dS_Exp2);
 
     BigInteger bS(bInt);
-    bS.MultiplyPow5(bS_Exp5) <<= bS_Exp2;
+    bS.MultiplyPow5(static_cast<unsigned>(bS_Exp5)) <<= static_cast<unsigned>(bS_Exp2);
 
     BigInteger hS(1);
-    hS.MultiplyPow5(hS_Exp5) <<= hS_Exp2;
+    hS.MultiplyPow5(static_cast<unsigned>(hS_Exp5)) <<= static_cast<unsigned>(hS_Exp2);
 
     BigInteger delta(0);
-    *adjustToNegative = dS.Difference(bS, &delta);
+    dS.Difference(bS, &delta);
 
-    int cmp = delta.Compare(hS);
-    // If delta is within 1/2 ULP, check for special case when significand is power of two.
-    // In this case, need to compare with 1/2h in the lower bound.
-    if (cmp < 0 && *adjustToNegative && // within and dS < bS
-        db.IsNormal() && (bInt & (bInt - 1)) == 0 && // Power of 2
-        db.Uint64Value() != RAPIDJSON_UINT64_C2(0x00100000, 0x00000000)) // minimum normal number must not do this
-    {
-        delta <<= 1;
-        return delta.Compare(hS);
-    }
-    return cmp;
+    return delta.Compare(hS);
 }
 
 inline bool StrtodFast(double d, int p, double* result) {
@@ -150,7 +134,7 @@
         if (significand  >  RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) ||
             (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5'))
             break;
-        significand = significand * 10 + (decimals[i] - '0');
+        significand = significand * 10u + static_cast<unsigned>(decimals[i] - '0');
     }
     
     if (i < length && decimals[i] >= '5') // Rounding
@@ -165,7 +149,7 @@
     v = v.Normalize();
     error <<= -v.e;
 
-    const int dExp = (int)decimalPosition - (int)i + exp;
+    const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(i) + exp;
 
     int actualExp;
     DiyFp cachedPower = GetCachedPower10(dExp, &actualExp);
@@ -179,10 +163,10 @@
             DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 00000000), -44),  // 10^6
             DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 00000000), -40)   // 10^7
         };
-        int adjustment = dExp - actualExp - 1;
+        int  adjustment = dExp - actualExp - 1;
         RAPIDJSON_ASSERT(adjustment >= 0 && adjustment < 7);
         v = v * kPow10[adjustment];
-        if (length + adjustment > 19) // has more digits than decimal digits in 64-bit
+        if (length + static_cast<unsigned>(adjustment)> 19u) // has more digits than decimal digits in 64-bit
             error += kUlp / 2;
     }
 
@@ -200,43 +184,42 @@
         unsigned scaleExp = (precisionSize + kUlpShift) - 63;
         v.f >>= scaleExp;
         v.e += scaleExp; 
-        error = (error >> scaleExp) + 1 + kUlp;
+        error = (error >> scaleExp) + 1 + static_cast<int>(kUlp);
         precisionSize -= scaleExp;
     }
 
-    DiyFp rounded(v.f >> precisionSize, v.e + precisionSize);
+    DiyFp rounded(v.f >> precisionSize, v.e + static_cast<int>(precisionSize));
     const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp;
     const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp;
-    if (precisionBits >= halfWay + error)
+    if (precisionBits >= halfWay + static_cast<unsigned>(error)) {
         rounded.f++;
+        if (rounded.f & (DiyFp::kDpHiddenBit << 1)) { // rounding overflows mantissa (issue #340)
+            rounded.f >>= 1;
+            rounded.e++;
+        }
+    }
 
     *result = rounded.ToDouble();
 
-    return halfWay - error >= precisionBits || precisionBits >= halfWay + error;
+    return halfWay - static_cast<unsigned>(error) >= precisionBits || precisionBits >= halfWay + static_cast<unsigned>(error);
 }
 
 inline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) {
     const BigInteger dInt(decimals, length);
-    const int dExp = (int)decimalPosition - (int)length + exp;
+    const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(length) + exp;
     Double a(approx);
-    for (int i = 0; i < 10; i++) {
-        bool adjustToNegative;
-        int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp, &adjustToNegative);
-        if (cmp < 0)
-            return a.Value();  // within half ULP
-        else if (cmp == 0) {
-            // Round towards even
-            if (a.Significand() & 1)
-                return adjustToNegative ? a.PreviousPositiveDouble() : a.NextPositiveDouble();
-            else
-                return a.Value();
-        }
-        else // adjustment
-            a = adjustToNegative ? a.PreviousPositiveDouble() : a.NextPositiveDouble();
+    int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp);
+    if (cmp < 0)
+        return a.Value();  // within half ULP
+    else if (cmp == 0) {
+        // Round towards even
+        if (a.Significand() & 1)
+            return a.NextPositiveDouble();
+        else
+            return a.Value();
     }
-
-    // This should not happen, but in case there is really a bug, break the infinite-loop
-    return a.Value();
+    else // adjustment
+        return a.NextPositiveDouble();
 }
 
 inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) {
@@ -263,8 +246,10 @@
 
     // Trim right-most digits
     const int kMaxDecimalDigit = 780;
-    if ((int)length > kMaxDecimalDigit) {
-        exp += (int(length) - kMaxDecimalDigit);
+    if (static_cast<int>(length) > kMaxDecimalDigit) {
+        int delta = (static_cast<int>(length) - kMaxDecimalDigit);
+        exp += delta;
+        decimalPosition -= static_cast<unsigned>(delta);
         length = kMaxDecimalDigit;
     }
 

=== added file 'shorts/xml2json/rapidjson/internal/swap.h'
--- shorts/xml2json/rapidjson/internal/swap.h	1970-01-01 00:00:00 +0000
+++ shorts/xml2json/rapidjson/internal/swap.h	2016-03-16 12:38:32 +0000
@@ -0,0 +1,37 @@
+// Tencent is pleased to support the open source community by making RapidJSON available.
+//
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+
+#ifndef RAPIDJSON_INTERNAL_SWAP_H_
+#define RAPIDJSON_INTERNAL_SWAP_H_
+
+#include "../rapidjson.h"
+
+RAPIDJSON_NAMESPACE_BEGIN
+namespace internal {
+
+//! Custom swap() to avoid dependency on C++ <algorithm> header
+/*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only.
+    \note This has the same semantics as std::swap().
+*/
+template <typename T>
+inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT {
+    T tmp = a;
+        a = b;
+        b = tmp;
+}
+
+} // namespace internal
+RAPIDJSON_NAMESPACE_END
+
+#endif // RAPIDJSON_INTERNAL_SWAP_H_

=== modified file 'shorts/xml2json/rapidjson/memorybuffer.h'
--- shorts/xml2json/rapidjson/memorybuffer.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/memorybuffer.h	2016-03-16 12:38:32 +0000
@@ -1,22 +1,16 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_MEMORYBUFFER_H_
 #define RAPIDJSON_MEMORYBUFFER_H_

=== modified file 'shorts/xml2json/rapidjson/memorystream.h'
--- shorts/xml2json/rapidjson/memorystream.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/memorystream.h	2016-03-16 12:38:32 +0000
@@ -1,28 +1,28 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_MEMORYSTREAM_H_
 #define RAPIDJSON_MEMORYSTREAM_H_
 
 #include "rapidjson.h"
 
+#ifdef __clang__
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(unreachable-code)
+RAPIDJSON_DIAG_OFF(missing-noreturn)
+#endif
+
 RAPIDJSON_NAMESPACE_BEGIN
 
 //! Represents an in-memory input byte stream.
@@ -64,4 +64,8 @@
 
 RAPIDJSON_NAMESPACE_END
 
+#ifdef __clang__
+RAPIDJSON_DIAG_POP
+#endif
+
 #endif // RAPIDJSON_MEMORYBUFFER_H_

=== modified file 'shorts/xml2json/rapidjson/msinttypes/inttypes.h'
--- shorts/xml2json/rapidjson/msinttypes/inttypes.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/msinttypes/inttypes.h	2016-03-16 12:38:32 +0000
@@ -30,6 +30,10 @@
 // 
 ///////////////////////////////////////////////////////////////////////////////
 
+// The above software in this distribution may have been modified by 
+// THL A29 Limited ("Tencent Modifications"). 
+// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited.
+
 #ifndef _MSC_VER // [
 #error "Use this header only with Microsoft Visual C++ compilers!"
 #endif // _MSC_VER ]

=== modified file 'shorts/xml2json/rapidjson/msinttypes/stdint.h'
--- shorts/xml2json/rapidjson/msinttypes/stdint.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/msinttypes/stdint.h	2016-03-16 12:38:32 +0000
@@ -30,6 +30,10 @@
 // 
 ///////////////////////////////////////////////////////////////////////////////
 
+// The above software in this distribution may have been modified by 
+// THL A29 Limited ("Tencent Modifications"). 
+// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited.
+
 #ifndef _MSC_VER // [
 #error "Use this header only with Microsoft Visual C++ compilers!"
 #endif // _MSC_VER ]
@@ -85,14 +89,14 @@
 #include <limits.h>
 
 // For Visual Studio 6 in C++ mode and for many Visual Studio versions when
-// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
-// or compiler give many errors like this:
+// compiling for ARM we have to wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler would give many errors like this:
 //   error C2733: second C linkage of overloaded function 'wmemchr' not allowed
-#ifdef __cplusplus
+#if defined(__cplusplus) && !defined(_M_ARM)
 extern "C" {
 #endif
 #  include <wchar.h>
-#ifdef __cplusplus
+#if defined(__cplusplus) && !defined(_M_ARM)
 }
 #endif
 

=== added file 'shorts/xml2json/rapidjson/pointer.h'
--- shorts/xml2json/rapidjson/pointer.h	1970-01-01 00:00:00 +0000
+++ shorts/xml2json/rapidjson/pointer.h	2016-03-16 12:38:32 +0000
@@ -0,0 +1,1326 @@
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
+
+#ifndef RAPIDJSON_POINTER_H_
+#define RAPIDJSON_POINTER_H_
+
+#include "document.h"
+#include "internal/itoa.h"
+
+#ifdef __clang__
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(switch-enum)
+#endif
+
+RAPIDJSON_NAMESPACE_BEGIN
+
+static const SizeType kPointerInvalidIndex = ~SizeType(0);  //!< Represents an invalid index in GenericPointer::Token
+
+//! Error code of parsing.
+/*! \ingroup RAPIDJSON_ERRORS
+    \see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode
+*/
+enum PointerParseErrorCode {
+    kPointerParseErrorNone = 0,                     //!< The parse is successful
+
+    kPointerParseErrorTokenMustBeginWithSolidus,    //!< A token must begin with a '/'
+    kPointerParseErrorInvalidEscape,                //!< Invalid escape
+    kPointerParseErrorInvalidPercentEncoding,       //!< Invalid percent encoding in URI fragment
+    kPointerParseErrorCharacterMustPercentEncode    //!< A character must percent encoded in URI fragment
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// GenericPointer
+
+//! Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
+/*!
+    This class implements RFC 6901 "JavaScript Object Notation (JSON) Pointer" 
+    (https://tools.ietf.org/html/rfc6901).
+
+    A JSON pointer is for identifying a specific value in a JSON document
+    (GenericDocument). It can simplify coding of DOM tree manipulation, because it
+    can access multiple-level depth of DOM tree with single API call.
+
+    After it parses a string representation (e.g. "/foo/0" or URI fragment 
+    representation (e.g. "#/foo/0") into its internal representation (tokens),
+    it can be used to resolve a specific value in multiple documents, or sub-tree 
+    of documents.
+
+    Contrary to GenericValue, Pointer can be copy constructed and copy assigned.
+    Apart from assignment, a Pointer cannot be modified after construction.
+
+    Although Pointer is very convenient, please aware that constructing Pointer
+    involves parsing and dynamic memory allocation. A special constructor with user-
+    supplied tokens eliminates these.
+
+    GenericPointer depends on GenericDocument and GenericValue.
+    
+    \tparam ValueType The value type of the DOM tree. E.g. GenericValue<UTF8<> >
+    \tparam Allocator The allocator type for allocating memory for internal representation.
+    
+    \note GenericPointer uses same encoding of ValueType.
+    However, Allocator of GenericPointer is independent of Allocator of Value.
+*/
+template <typename ValueType, typename Allocator = CrtAllocator>
+class GenericPointer {
+public:
+    typedef typename ValueType::EncodingType EncodingType;  //!< Encoding type from Value
+    typedef typename ValueType::Ch Ch;                      //!< Character type from Value
+
+    //! A token is the basic units of internal representation.
+    /*!
+        A JSON pointer string representation "/foo/123" is parsed to two tokens: 
+        "foo" and 123. 123 will be represented in both numeric form and string form.
+        They are resolved according to the actual value type (object or array).
+
+        For token that are not numbers, or the numeric value is out of bound
+        (greater than limits of SizeType), they are only treated as string form
+        (i.e. the token's index will be equal to kPointerInvalidIndex).
+
+        This struct is public so that user can create a Pointer without parsing and 
+        allocation, using a special constructor.
+    */
+    struct Token {
+        const Ch* name;             //!< Name of the token. It has null character at the end but it can contain null character.
+        SizeType length;            //!< Length of the name.
+        SizeType index;             //!< A valid array index, if it is not equal to kPointerInvalidIndex.
+    };
+
+    //!@name Constructors and destructor.
+    //@{
+
+    //! Default constructor.
+    GenericPointer() : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
+
+    //! Constructor that parses a string or URI fragment representation.
+    /*!
+        \param source A null-terminated, string or URI fragment representation of JSON pointer.
+        \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.
+    */
+    explicit GenericPointer(const Ch* source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
+        Parse(source, internal::StrLen(source));
+    }
+
+#if RAPIDJSON_HAS_STDSTRING
+    //! Constructor that parses a string or URI fragment representation.
+    /*!
+        \param source A string or URI fragment representation of JSON pointer.
+        \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.
+        \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
+    */
+    explicit GenericPointer(const std::basic_string<Ch>& source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
+        Parse(source.c_str(), source.size());
+    }
+#endif
+
+    //! Constructor that parses a string or URI fragment representation, with length of the source string.
+    /*!
+        \param source A string or URI fragment representation of JSON pointer.
+        \param length Length of source.
+        \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.
+        \note Slightly faster than the overload without length.
+    */
+    GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
+        Parse(source, length);
+    }
+
+    //! Constructor with user-supplied tokens.
+    /*!
+        This constructor let user supplies const array of tokens.
+        This prevents the parsing process and eliminates allocation.
+        This is preferred for memory constrained environments.
+
+        \param tokens An constant array of tokens representing the JSON pointer.
+        \param tokenCount Number of tokens.
+
+        \b Example
+        \code
+        #define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex }
+        #define INDEX(i) { #i, sizeof(#i) - 1, i }
+
+        static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(123) };
+        static const Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
+        // Equivalent to static const Pointer p("/foo/123");
+
+        #undef NAME
+        #undef INDEX
+        \endcode
+    */
+    GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
+
+    //! Copy constructor.
+    GenericPointer(const GenericPointer& rhs) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
+        *this = rhs;
+    }
+
+    //! Destructor.
+    ~GenericPointer() {
+        if (nameBuffer_)    // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated.
+            Allocator::Free(tokens_);
+        RAPIDJSON_DELETE(ownAllocator_);
+    }
+
+    //! Assignment operator.
+    GenericPointer& operator=(const GenericPointer& rhs) {
+        if (this != &rhs) {
+            // Do not delete ownAllcator
+            if (nameBuffer_)
+                Allocator::Free(tokens_);
+
+            tokenCount_ = rhs.tokenCount_;
+            parseErrorOffset_ = rhs.parseErrorOffset_;
+            parseErrorCode_ = rhs.parseErrorCode_;
+
+            if (rhs.nameBuffer_)
+                CopyFromRaw(rhs); // Normally parsed tokens.
+            else {
+                tokens_ = rhs.tokens_; // User supplied const tokens.
+                nameBuffer_ = 0;
+            }
+        }
+        return *this;
+    }
+
+    //@}
+
+    //!@name Append token
+    //@{
+
+    //! Append a token and return a new Pointer
+    /*!
+        \param token Token to be appended.
+        \param allocator Allocator for the newly return Pointer.
+        \return A new Pointer with appended token.
+    */
+    GenericPointer Append(const Token& token, Allocator* allocator = 0) const {
+        GenericPointer r;
+        r.allocator_ = allocator;
+        Ch *p = r.CopyFromRaw(*this, 1, token.length + 1);
+        std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch));
+        r.tokens_[tokenCount_].name = p;
+        r.tokens_[tokenCount_].length = token.length;
+        r.tokens_[tokenCount_].index = token.index;
+        return r;
+    }
+
+    //! Append a name token with length, and return a new Pointer
+    /*!
+        \param name Name to be appended.
+        \param length Length of name.
+        \param allocator Allocator for the newly return Pointer.
+        \return A new Pointer with appended token.
+    */
+    GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const {
+        Token token = { name, length, kPointerInvalidIndex };
+        return Append(token, allocator);
+    }
+
+    //! Append a name token without length, and return a new Pointer
+    /*!
+        \param name Name (const Ch*) to be appended.
+        \param allocator Allocator for the newly return Pointer.
+        \return A new Pointer with appended token.
+    */
+    template <typename T>
+    RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >), (GenericPointer))
+    Append(T* name, Allocator* allocator = 0) const {
+        return Append(name, StrLen(name), allocator);
+    }
+
+#if RAPIDJSON_HAS_STDSTRING
+    //! Append a name token, and return a new Pointer
+    /*!
+        \param name Name to be appended.
+        \param allocator Allocator for the newly return Pointer.
+        \return A new Pointer with appended token.
+    */
+    GenericPointer Append(const std::basic_string<Ch>& name, Allocator* allocator = 0) const {
+        return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator);
+    }
+#endif
+
+    //! Append a index token, and return a new Pointer
+    /*!
+        \param index Index to be appended.
+        \param allocator Allocator for the newly return Pointer.
+        \return A new Pointer with appended token.
+    */
+    GenericPointer Append(SizeType index, Allocator* allocator = 0) const {
+        char buffer[21];
+        char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
+        SizeType length = static_cast<SizeType>(end - buffer);
+        buffer[length] = '\0';
+
+        if (sizeof(Ch) == 1) {
+            Token token = { reinterpret_cast<Ch*>(buffer), length, index };
+            return Append(token, allocator);
+        }
+        else {
+            Ch name[21];
+            for (size_t i = 0; i <= length; i++)
+                name[i] = buffer[i];
+            Token token = { name, length, index };
+            return Append(token, allocator);
+        }
+    }
+
+    //! Append a token by value, and return a new Pointer
+    /*!
+        \param token token to be appended.
+        \param allocator Allocator for the newly return Pointer.
+        \return A new Pointer with appended token.
+    */
+    GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const {
+        if (token.IsString())
+            return Append(token.GetString(), token.GetStringLength(), allocator);
+        else {
+            RAPIDJSON_ASSERT(token.IsUint64());
+            RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0));
+            return Append(static_cast<SizeType>(token.GetUint64()), allocator);
+        }
+    }
+
+    //!@name Handling Parse Error
+    //@{
+
+    //! Check whether this is a valid pointer.
+    bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; }
+
+    //! Get the parsing error offset in code unit.
+    size_t GetParseErrorOffset() const { return parseErrorOffset_; }
+
+    //! Get the parsing error code.
+    PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }
+
+    //@}
+
+    //!@name Tokens
+    //@{
+
+    //! Get the token array (const version only).
+    const Token* GetTokens() const { return tokens_; }
+
+    //! Get the number of tokens.
+    size_t GetTokenCount() const { return tokenCount_; }
+
+    //@}
+
+    //!@name Equality/inequality operators
+    //@{
+
+    //! Equality operator.
+    /*!
+        \note When any pointers are invalid, always returns false.
+    */
+    bool operator==(const GenericPointer& rhs) const {
+        if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)
+            return false;
+
+        for (size_t i = 0; i < tokenCount_; i++) {
+            if (tokens_[i].index != rhs.tokens_[i].index ||
+                tokens_[i].length != rhs.tokens_[i].length || 
+                (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0))
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    //! Inequality operator.
+    /*!
+        \note When any pointers are invalid, always returns true.
+    */
+    bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
+
+    //@}
+
+    //!@name Stringify
+    //@{
+
+    //! Stringify the pointer into string representation.
+    /*!
+        \tparam OutputStream Type of output stream.
+        \param os The output stream.
+    */
+    template<typename OutputStream>
+    bool Stringify(OutputStream& os) const {
+        return Stringify<false, OutputStream>(os);
+    }
+
+    //! Stringify the pointer into URI fragment representation.
+    /*!
+        \tparam OutputStream Type of output stream.
+        \param os The output stream.
+    */
+    template<typename OutputStream>
+    bool StringifyUriFragment(OutputStream& os) const {
+        return Stringify<true, OutputStream>(os);
+    }
+
+    //@}
+
+    //!@name Create value
+    //@{
+
+    //! Create a value in a subtree.
+    /*!
+        If the value is not exist, it creates all parent values and a JSON Null value.
+        So it always succeed and return the newly created or existing value.
+
+        Remind that it may change types of parents according to tokens, so it 
+        potentially removes previously stored values. For example, if a document 
+        was an array, and "/foo" is used to create a value, then the document 
+        will be changed to an object, and all existing array elements are lost.
+
+        \param root Root value of a DOM subtree to be resolved. It can be any value other than document root.
+        \param allocator Allocator for creating the values if the specified value or its parents are not exist.
+        \param alreadyExist If non-null, it stores whether the resolved value is already exist.
+        \return The resolved newly created (a JSON Null value), or already exists value.
+    */
+    ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const {
+        RAPIDJSON_ASSERT(IsValid());
+        ValueType* v = &root;
+        bool exist = true;
+        for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
+            if (v->IsArray() && t->name[0] == '-' && t->length == 1) {
+                v->PushBack(ValueType().Move(), allocator);
+                v = &((*v)[v->Size() - 1]);
+                exist = false;
+            }
+            else {
+                if (t->index == kPointerInvalidIndex) { // must be object name
+                    if (!v->IsObject())
+                        v->SetObject(); // Change to Object
+                }
+                else { // object name or array index
+                    if (!v->IsArray() && !v->IsObject())
+                        v->SetArray(); // Change to Array
+                }
+
+                if (v->IsArray()) {
+                    if (t->index >= v->Size()) {
+                        v->Reserve(t->index + 1, allocator);
+                        while (t->index >= v->Size())
+                            v->PushBack(ValueType().Move(), allocator);
+                        exist = false;
+                    }
+                    v = &((*v)[t->index]);
+                }
+                else {
+                    typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
+                    if (m == v->MemberEnd()) {
+                        v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
+                        v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end
+                        exist = false;
+                    }
+                    else
+                        v = &m->value;
+                }
+            }
+        }
+
+        if (alreadyExist)
+            *alreadyExist = exist;
+
+        return *v;
+    }
+
+    //! Creates a value in a document.
+    /*!
+        \param document A document to be resolved.
+        \param alreadyExist If non-null, it stores whether the resolved value is already exist.
+        \return The resolved newly created, or already exists value.
+    */
+    template <typename stackAllocator>
+    ValueType& Create(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, bool* alreadyExist = 0) const {
+        return Create(document, document.GetAllocator(), alreadyExist);
+    }
+
+    //@}
+
+    //!@name Query value
+    //@{
+
+    //! Query a value in a subtree.
+    /*!
+        \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
+        \return Pointer to the value if it can be resolved. Otherwise null.
+    */
+    ValueType* Get(ValueType& root) const {
+        RAPIDJSON_ASSERT(IsValid());
+        ValueType* v = &root;
+        for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
+            switch (v->GetType()) {
+            case kObjectType:
+                {
+                    typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
+                    if (m == v->MemberEnd())
+                        return 0;
+                    v = &m->value;
+                }
+                break;
+            case kArrayType:
+                if (t->index == kPointerInvalidIndex || t->index >= v->Size())
+                    return 0;
+                v = &((*v)[t->index]);
+                break;
+            default:
+                return 0;
+            }
+        }
+        return v;
+    }
+
+    //! Query a const value in a const subtree.
+    /*!
+        \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
+        \return Pointer to the value if it can be resolved. Otherwise null.
+    */
+    const ValueType* Get(const ValueType& root) const { return Get(const_cast<ValueType&>(root)); }
+
+    //@}
+
+    //!@name Query a value with default
+    //@{
+
+    //! Query a value in a subtree with default value.
+    /*!
+        Similar to Get(), but if the specified value do not exists, it creates all parents and clone the default value.
+        So that this function always succeed.
+
+        \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
+        \param defaultValue Default value to be cloned if the value was not exists.
+        \param allocator Allocator for creating the values if the specified value or its parents are not exist.
+        \see Create()
+    */
+    ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {
+        bool alreadyExist;
+        Value& v = Create(root, allocator, &alreadyExist);
+        return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
+    }
+
+    //! Query a value in a subtree with default null-terminated string.
+    ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {
+        bool alreadyExist;
+        Value& v = Create(root, allocator, &alreadyExist);
+        return alreadyExist ? v : v.SetString(defaultValue, allocator);
+    }
+
+#if RAPIDJSON_HAS_STDSTRING
+    //! Query a value in a subtree with default std::basic_string.
+    ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {
+        bool alreadyExist;
+        Value& v = Create(root, allocator, &alreadyExist);
+        return alreadyExist ? v : v.SetString(defaultValue, allocator);
+    }
+#endif
+
+    //! Query a value in a subtree with default primitive value.
+    /*!
+        \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
+    */
+    template <typename T>
+    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
+    GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const {
+        return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
+    }
+
+    //! Query a value in a document with default value.
+    template <typename stackAllocator>
+    ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& defaultValue) const {
+        return GetWithDefault(document, defaultValue, document.GetAllocator());
+    }
+
+    //! Query a value in a document with default null-terminated string.
+    template <typename stackAllocator>
+    ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* defaultValue) const {
+        return GetWithDefault(document, defaultValue, document.GetAllocator());
+    }
+    
+#if RAPIDJSON_HAS_STDSTRING
+    //! Query a value in a document with default std::basic_string.
+    template <typename stackAllocator>
+    ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& defaultValue) const {
+        return GetWithDefault(document, defaultValue, document.GetAllocator());
+    }
+#endif
+
+    //! Query a value in a document with default primitive value.
+    /*!
+        \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
+    */
+    template <typename T, typename stackAllocator>
+    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
+    GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T defaultValue) const {
+        return GetWithDefault(document, defaultValue, document.GetAllocator());
+    }
+
+    //@}
+
+    //!@name Set a value
+    //@{
+
+    //! Set a value in a subtree, with move semantics.
+    /*!
+        It creates all parents if they are not exist or types are different to the tokens.
+        So this function always succeeds but potentially remove existing values.
+
+        \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
+        \param value Value to be set.
+        \param allocator Allocator for creating the values if the specified value or its parents are not exist.
+        \see Create()
+    */
+    ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
+        return Create(root, allocator) = value;
+    }
+
+    //! Set a value in a subtree, with copy semantics.
+    ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const {
+        return Create(root, allocator).CopyFrom(value, allocator);
+    }
+
+    //! Set a null-terminated string in a subtree.
+    ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const {
+        return Create(root, allocator) = ValueType(value, allocator).Move();
+    }
+
+#if RAPIDJSON_HAS_STDSTRING
+    //! Set a std::basic_string in a subtree.
+    ValueType& Set(ValueType& root, const std::basic_string<Ch>& value, typename ValueType::AllocatorType& allocator) const {
+        return Create(root, allocator) = ValueType(value, allocator).Move();
+    }
+#endif
+
+    //! Set a primitive value in a subtree.
+    /*!
+        \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
+    */
+    template <typename T>
+    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
+    Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const {
+        return Create(root, allocator) = ValueType(value).Move();
+    }
+
+    //! Set a value in a document, with move semantics.
+    template <typename stackAllocator>
+    ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {
+        return Create(document) = value;
+    }
+
+    //! Set a value in a document, with copy semantics.
+    template <typename stackAllocator>
+    ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& value) const {
+        return Create(document).CopyFrom(value, document.GetAllocator());
+    }
+
+    //! Set a null-terminated string in a document.
+    template <typename stackAllocator>
+    ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* value) const {
+        return Create(document) = ValueType(value, document.GetAllocator()).Move();
+    }
+
+#if RAPIDJSON_HAS_STDSTRING
+    //! Sets a std::basic_string in a document.
+    template <typename stackAllocator>
+    ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& value) const {
+        return Create(document) = ValueType(value, document.GetAllocator()).Move();
+    }
+#endif
+
+    //! Set a primitive value in a document.
+    /*!
+    \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
+    */
+    template <typename T, typename stackAllocator>
+    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
+        Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T value) const {
+            return Create(document) = value;
+    }
+
+    //@}
+
+    //!@name Swap a value
+    //@{
+
+    //! Swap a value with a value in a subtree.
+    /*!
+        It creates all parents if they are not exist or types are different to the tokens.
+        So this function always succeeds but potentially remove existing values.
+
+        \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
+        \param value Value to be swapped.
+        \param allocator Allocator for creating the values if the specified value or its parents are not exist.
+        \see Create()
+    */
+    ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
+        return Create(root, allocator).Swap(value);
+    }
+
+    //! Swap a value with a value in a document.
+    template <typename stackAllocator>
+    ValueType& Swap(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {
+        return Create(document).Swap(value);
+    }
+
+    //@}
+
+    //! Erase a value in a subtree.
+    /*!
+        \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
+        \return Whether the resolved value is found and erased.
+
+        \note Erasing with an empty pointer \c Pointer(""), i.e. the root, always fail and return false.
+    */
+    bool Erase(ValueType& root) const {
+        RAPIDJSON_ASSERT(IsValid());
+        if (tokenCount_ == 0) // Cannot erase the root
+            return false;
+
+        ValueType* v = &root;
+        const Token* last = tokens_ + (tokenCount_ - 1);
+        for (const Token *t = tokens_; t != last; ++t) {
+            switch (v->GetType()) {
+            case kObjectType:
+                {
+                    typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
+                    if (m == v->MemberEnd())
+                        return false;
+                    v = &m->value;
+                }
+                break;
+            case kArrayType:
+                if (t->index == kPointerInvalidIndex || t->index >= v->Size())
+                    return false;
+                v = &((*v)[t->index]);
+                break;
+            default:
+                return false;
+            }
+        }
+
+        switch (v->GetType()) {
+        case kObjectType:
+            return v->EraseMember(GenericStringRef<Ch>(last->name, last->length));
+        case kArrayType:
+            if (last->index == kPointerInvalidIndex || last->index >= v->Size())
+                return false;
+            v->Erase(v->Begin() + last->index);
+            return true;
+        default:
+            return false;
+        }
+    }
+
+private:
+    //! Clone the content from rhs to this.
+    /*!
+        \param rhs Source pointer.
+        \param extraToken Extra tokens to be allocated.
+        \param extraNameBufferSize Extra name buffer size (in number of Ch) to be allocated.
+        \return Start of non-occupied name buffer, for storing extra names.
+    */
+    Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) {
+        if (!allocator_) // allocator is independently owned.
+            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
+
+        size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens
+        for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
+            nameBufferSize += t->length;
+
+        tokenCount_ = rhs.tokenCount_ + extraToken;
+        tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));
+        nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
+        std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));
+        std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
+
+        // Adjust pointers to name buffer
+        std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
+        for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)
+            t->name += diff;
+
+        return nameBuffer_ + nameBufferSize;
+    }
+
+    //! Check whether a character should be percent-encoded.
+    /*!
+        According to RFC 3986 2.3 Unreserved Characters.
+        \param c The character (code unit) to be tested.
+    */
+    bool NeedPercentEncode(Ch c) const {
+        return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~');
+    }
+
+    //! Parse a JSON String or its URI fragment representation into tokens.
+#ifndef __clang__ // -Wdocumentation
+    /*!
+        \param source Either a JSON Pointer string, or its URI fragment representation. Not need to be null terminated.
+        \param length Length of the source string.
+        \note Source cannot be JSON String Representation of JSON Pointer, e.g. In "/\u0000", \u0000 will not be unescaped.
+    */
+#endif
+    void Parse(const Ch* source, size_t length) {
+        RAPIDJSON_ASSERT(source != NULL);
+        RAPIDJSON_ASSERT(nameBuffer_ == 0);
+        RAPIDJSON_ASSERT(tokens_ == 0);
+
+        // Create own allocator if user did not supply.
+        if (!allocator_)
+            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
+
+        // Count number of '/' as tokenCount
+        tokenCount_ = 0;
+        for (const Ch* s = source; s != source + length; s++) 
+            if (*s == '/')
+                tokenCount_++;
+
+        Token* token = tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch)));
+        Ch* name = nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
+        size_t i = 0;
+
+        // Detect if it is a URI fragment
+        bool uriFragment = false;
+        if (source[i] == '#') {
+            uriFragment = true;
+            i++;
+        }
+
+        if (i != length && source[i] != '/') {
+            parseErrorCode_ = kPointerParseErrorTokenMustBeginWithSolidus;
+            goto error;
+        }
+
+        while (i < length) {
+            RAPIDJSON_ASSERT(source[i] == '/');
+            i++; // consumes '/'
+
+            token->name = name;
+            bool isNumber = true;
+
+            while (i < length && source[i] != '/') {
+                Ch c = source[i];
+                if (uriFragment) {
+                    // Decoding percent-encoding for URI fragment
+                    if (c == '%') {
+                        PercentDecodeStream is(&source[i], source + length);
+                        GenericInsituStringStream<EncodingType> os(name);
+                        Ch* begin = os.PutBegin();
+                        if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {
+                            parseErrorCode_ = kPointerParseErrorInvalidPercentEncoding;
+                            goto error;
+                        }
+                        size_t len = os.PutEnd(begin);
+                        i += is.Tell() - 1;
+                        if (len == 1)
+                            c = *name;
+                        else {
+                            name += len;
+                            isNumber = false;
+                            i++;
+                            continue;
+                        }
+                    }
+                    else if (NeedPercentEncode(c)) {
+                        parseErrorCode_ = kPointerParseErrorCharacterMustPercentEncode;
+                        goto error;
+                    }
+                }
+
+                i++;
+                
+                // Escaping "~0" -> '~', "~1" -> '/'
+                if (c == '~') {
+                    if (i < length) {
+                        c = source[i];
+                        if (c == '0')       c = '~';
+                        else if (c == '1')  c = '/';
+                        else {
+                            parseErrorCode_ = kPointerParseErrorInvalidEscape;
+                            goto error;
+                        }
+                        i++;
+                    }
+                    else {
+                        parseErrorCode_ = kPointerParseErrorInvalidEscape;
+                        goto error;
+                    }
+                }
+
+                // First check for index: all of characters are digit
+                if (c < '0' || c > '9')
+                    isNumber = false;
+
+                *name++ = c;
+            }
+            token->length = static_cast<SizeType>(name - token->name);
+            if (token->length == 0)
+                isNumber = false;
+            *name++ = '\0'; // Null terminator
+
+            // Second check for index: more than one digit cannot have leading zero
+            if (isNumber && token->length > 1 && token->name[0] == '0')
+                isNumber = false;
+
+            // String to SizeType conversion
+            SizeType n = 0;
+            if (isNumber) {
+                for (size_t j = 0; j < token->length; j++) {
+                    SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0');
+                    if (m < n) {   // overflow detection
+                        isNumber = false;
+                        break;
+                    }
+                    n = m;
+                }
+            }
+
+            token->index = isNumber ? n : kPointerInvalidIndex;
+            token++;
+        }
+
+        RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer
+        parseErrorCode_ = kPointerParseErrorNone;
+        return;
+
+    error:
+        Allocator::Free(tokens_);
+        nameBuffer_ = 0;
+        tokens_ = 0;
+        tokenCount_ = 0;
+        parseErrorOffset_ = i;
+        return;
+    }
+
+    //! Stringify to string or URI fragment representation.
+    /*!
+        \tparam uriFragment True for stringifying to URI fragment representation. False for string representation.
+        \tparam OutputStream type of output stream.
+        \param os The output stream.
+    */
+    template<bool uriFragment, typename OutputStream>
+    bool Stringify(OutputStream& os) const {
+        RAPIDJSON_ASSERT(IsValid());
+
+        if (uriFragment)
+            os.Put('#');
+
+        for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
+            os.Put('/');
+            for (size_t j = 0; j < t->length; j++) {
+                Ch c = t->name[j];
+                if (c == '~') {
+                    os.Put('~');
+                    os.Put('0');
+                }
+                else if (c == '/') {
+                    os.Put('~');
+                    os.Put('1');
+                }
+                else if (uriFragment && NeedPercentEncode(c)) { 
+                    // Transcode to UTF8 sequence
+                    GenericStringStream<typename ValueType::EncodingType> source(&t->name[j]);
+                    PercentEncodeStream<OutputStream> target(os);
+                    if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))
+                        return false;
+                    j += source.Tell() - 1;
+                }
+                else
+                    os.Put(c);
+            }
+        }
+        return true;
+    }
+
+    //! A helper stream for decoding a percent-encoded sequence into code unit.
+    /*!
+        This stream decodes %XY triplet into code unit (0-255).
+        If it encounters invalid characters, it sets output code unit as 0 and 
+        mark invalid, and to be checked by IsValid().
+    */
+    class PercentDecodeStream {
+    public:
+        typedef typename ValueType::Ch Ch;
+
+        //! Constructor
+        /*!
+            \param source Start of the stream
+            \param end Past-the-end of the stream.
+        */
+        PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}
+
+        Ch Take() {
+            if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet
+                valid_ = false;
+                return 0;
+            }
+            src_++;
+            Ch c = 0;
+            for (int j = 0; j < 2; j++) {
+                c <<= 4;
+                Ch h = *src_;
+                if      (h >= '0' && h <= '9') c += h - '0';
+                else if (h >= 'A' && h <= 'F') c += h - 'A' + 10;
+                else if (h >= 'a' && h <= 'f') c += h - 'a' + 10;
+                else {
+                    valid_ = false;
+                    return 0;
+                }
+                src_++;
+            }
+            return c;
+        }
+
+        size_t Tell() const { return static_cast<size_t>(src_ - head_); }
+        bool IsValid() const { return valid_; }
+
+    private:
+        const Ch* src_;     //!< Current read position.
+        const Ch* head_;    //!< Original head of the string.
+        const Ch* end_;     //!< Past-the-end position.
+        bool valid_;        //!< Whether the parsing is valid.
+    };
+
+    //! A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.
+    template <typename OutputStream>
+    class PercentEncodeStream {
+    public:
+        PercentEncodeStream(OutputStream& os) : os_(os) {}
+        void Put(char c) { // UTF-8 must be byte
+            unsigned char u = static_cast<unsigned char>(c);
+            static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+            os_.Put('%');
+            os_.Put(hexDigits[u >> 4]);
+            os_.Put(hexDigits[u & 15]);
+        }
+    private:
+        OutputStream& os_;
+    };
+
+    Allocator* allocator_;                  //!< The current allocator. It is either user-supplied or equal to ownAllocator_.
+    Allocator* ownAllocator_;               //!< Allocator owned by this Pointer.
+    Ch* nameBuffer_;                        //!< A buffer containing all names in tokens.
+    Token* tokens_;                         //!< A list of tokens.
+    size_t tokenCount_;                     //!< Number of tokens in tokens_.
+    size_t parseErrorOffset_;               //!< Offset in code unit when parsing fail.
+    PointerParseErrorCode parseErrorCode_;  //!< Parsing error code.
+};
+
+//! GenericPointer for Value (UTF-8, default allocator).
+typedef GenericPointer<Value> Pointer;
+
+//!@name Helper functions for GenericPointer
+//@{
+
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename T>
+typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::AllocatorType& a) {
+    return pointer.Create(root, a);
+}
+
+template <typename T, typename CharType, size_t N>
+typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) {
+    return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
+}
+
+// No allocator parameter
+
+template <typename DocumentType>
+typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer) {
+    return pointer.Create(document);
+}
+
+template <typename DocumentType, typename CharType, size_t N>
+typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) {
+    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename T>
+typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer) {
+    return pointer.Get(root);
+}
+
+template <typename T>
+const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer) {
+    return pointer.Get(root);
+}
+
+template <typename T, typename CharType, size_t N>
+typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N]) {
+    return GenericPointer<typename T::ValueType>(source, N - 1).Get(root);
+}
+
+template <typename T, typename CharType, size_t N>
+const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N]) {
+    return GenericPointer<typename T::ValueType>(source, N - 1).Get(root);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename T>
+typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
+    return pointer.GetWithDefault(root, defaultValue, a);
+}
+
+template <typename T>
+typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
+    return pointer.GetWithDefault(root, defaultValue, a);
+}
+
+#if RAPIDJSON_HAS_STDSTRING
+template <typename T>
+typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
+    return pointer.GetWithDefault(root, defaultValue, a);
+}
+#endif
+
+template <typename T, typename T2>
+RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
+GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue, typename T::AllocatorType& a) {
+    return pointer.GetWithDefault(root, defaultValue, a);
+}
+
+template <typename T, typename CharType, size_t N>
+typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
+    return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
+}
+
+template <typename T, typename CharType, size_t N>
+typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
+    return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
+}
+
+#if RAPIDJSON_HAS_STDSTRING
+template <typename T, typename CharType, size_t N>
+typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
+    return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
+}
+#endif
+
+template <typename T, typename CharType, size_t N, typename T2>
+RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
+GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) {
+    return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
+}
+
+// No allocator parameter
+
+template <typename DocumentType>
+typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& defaultValue) {
+    return pointer.GetWithDefault(document, defaultValue);
+}
+
+template <typename DocumentType>
+typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* defaultValue) {
+    return pointer.GetWithDefault(document, defaultValue);
+}
+
+#if RAPIDJSON_HAS_STDSTRING
+template <typename DocumentType>
+typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& defaultValue) {
+    return pointer.GetWithDefault(document, defaultValue);
+}
+#endif
+
+template <typename DocumentType, typename T2>
+RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
+GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) {
+    return pointer.GetWithDefault(document, defaultValue);
+}
+
+template <typename DocumentType, typename CharType, size_t N>
+typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) {
+    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
+}
+
+template <typename DocumentType, typename CharType, size_t N>
+typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) {
+    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
+}
+
+#if RAPIDJSON_HAS_STDSTRING
+template <typename DocumentType, typename CharType, size_t N>
+typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& defaultValue) {
+    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
+}
+#endif
+
+template <typename DocumentType, typename CharType, size_t N, typename T2>
+RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
+GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) {
+    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename T>
+typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
+    return pointer.Set(root, value, a);
+}
+
+template <typename T>
+typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) {
+    return pointer.Set(root, value, a);
+}
+
+template <typename T>
+typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* value, typename T::AllocatorType& a) {
+    return pointer.Set(root, value, a);
+}
+
+#if RAPIDJSON_HAS_STDSTRING
+template <typename T>
+typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
+    return pointer.Set(root, value, a);
+}
+#endif
+
+template <typename T, typename T2>
+RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
+SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a) {
+    return pointer.Set(root, value, a);
+}
+
+template <typename T, typename CharType, size_t N>
+typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
+    return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
+}
+
+template <typename T, typename CharType, size_t N>
+typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) {
+    return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
+}
+
+template <typename T, typename CharType, size_t N>
+typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) {
+    return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
+}
+
+#if RAPIDJSON_HAS_STDSTRING
+template <typename T, typename CharType, size_t N>
+typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
+    return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
+}
+#endif
+
+template <typename T, typename CharType, size_t N, typename T2>
+RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
+SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) {
+    return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
+}
+
+// No allocator parameter
+
+template <typename DocumentType>
+typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
+    return pointer.Set(document, value);
+}
+
+template <typename DocumentType>
+typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& value) {
+    return pointer.Set(document, value);
+}
+
+template <typename DocumentType>
+typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* value) {
+    return pointer.Set(document, value);
+}
+
+#if RAPIDJSON_HAS_STDSTRING
+template <typename DocumentType>
+typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& value) {
+    return pointer.Set(document, value);
+}
+#endif
+
+template <typename DocumentType, typename T2>
+RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
+SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) {
+    return pointer.Set(document, value);
+}
+
+template <typename DocumentType, typename CharType, size_t N>
+typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
+    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
+}
+
+template <typename DocumentType, typename CharType, size_t N>
+typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) {
+    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
+}
+
+template <typename DocumentType, typename CharType, size_t N>
+typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) {
+    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
+}
+
+#if RAPIDJSON_HAS_STDSTRING
+template <typename DocumentType, typename CharType, size_t N>
+typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& value) {
+    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
+}
+#endif
+
+template <typename DocumentType, typename CharType, size_t N, typename T2>
+RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
+SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) {
+    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename T>
+typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
+    return pointer.Swap(root, value, a);
+}
+
+template <typename T, typename CharType, size_t N>
+typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
+    return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);
+}
+
+template <typename DocumentType>
+typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
+    return pointer.Swap(document, value);
+}
+
+template <typename DocumentType, typename CharType, size_t N>
+typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
+    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+template <typename T>
+bool EraseValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer) {
+    return pointer.Erase(root);
+}
+
+template <typename T, typename CharType, size_t N>
+bool EraseValueByPointer(T& root, const CharType(&source)[N]) {
+    return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
+}
+
+//@}
+
+RAPIDJSON_NAMESPACE_END
+
+#ifdef __clang__
+RAPIDJSON_DIAG_POP
+#endif
+
+#endif // RAPIDJSON_POINTER_H_

=== modified file 'shorts/xml2json/rapidjson/prettywriter.h'
--- shorts/xml2json/rapidjson/prettywriter.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/prettywriter.h	2016-03-16 12:38:32 +0000
@@ -1,22 +1,16 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_PRETTYWRITER_H_
 #define RAPIDJSON_PRETTYWRITER_H_
@@ -84,7 +78,7 @@
 
 #if RAPIDJSON_HAS_STDSTRING
     bool String(const std::basic_string<Ch>& str) {
-      return String(str.data(), SizeType(str.size()));
+        return String(str.data(), SizeType(str.size()));
     }
 #endif
 
@@ -106,8 +100,9 @@
             Base::os_->Put('\n');
             WriteIndent();
         }
-        if (!Base::WriteEndObject())
-            return false;
+        bool ret = Base::WriteEndObject();
+        (void)ret;
+        RAPIDJSON_ASSERT(ret == true);
         if (Base::level_stack_.Empty()) // end of json text
             Base::os_->Flush();
         return true;
@@ -129,8 +124,9 @@
             Base::os_->Put('\n');
             WriteIndent();
         }
-        if (!Base::WriteEndArray())
-            return false;
+        bool ret = Base::WriteEndArray();
+        (void)ret;
+        RAPIDJSON_ASSERT(ret == true);
         if (Base::level_stack_.Empty()) // end of json text
             Base::os_->Flush();
         return true;
@@ -190,7 +186,7 @@
 
     void WriteIndent()  {
         size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;
-        PutN(*Base::os_, indentChar_, count);
+        PutN(*Base::os_, static_cast<typename TargetEncoding::Ch>(indentChar_), count);
     }
 
     Ch indentChar_;

=== modified file 'shorts/xml2json/rapidjson/rapidjson.h'
--- shorts/xml2json/rapidjson/rapidjson.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/rapidjson.h	2016-03-16 12:38:32 +0000
@@ -1,32 +1,23 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_RAPIDJSON_H_
 #define RAPIDJSON_RAPIDJSON_H_
 
-// Copyright (c) 2011 Milo Yip (miloyip@xxxxxxxxx)
-// Version 0.1
-
 /*!\file rapidjson.h
     \brief common definitions and configuration
-
+    
     \see RAPIDJSON_CONFIG
  */
 
@@ -49,6 +40,40 @@
 #include <cstring>  // memset(), memcpy(), memmove(), memcmp()
 
 ///////////////////////////////////////////////////////////////////////////////
+// RAPIDJSON_VERSION_STRING
+//
+// ALWAYS synchronize the following 3 macros with corresponding variables in /CMakeLists.txt.
+//
+
+//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
+// token stringification
+#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x)
+#define RAPIDJSON_DO_STRINGIFY(x) #x
+//!@endcond
+
+/*! \def RAPIDJSON_MAJOR_VERSION
+    \ingroup RAPIDJSON_CONFIG
+    \brief Major version of RapidJSON in integer.
+*/
+/*! \def RAPIDJSON_MINOR_VERSION
+    \ingroup RAPIDJSON_CONFIG
+    \brief Minor version of RapidJSON in integer.
+*/
+/*! \def RAPIDJSON_PATCH_VERSION
+    \ingroup RAPIDJSON_CONFIG
+    \brief Patch version of RapidJSON in integer.
+*/
+/*! \def RAPIDJSON_VERSION_STRING
+    \ingroup RAPIDJSON_CONFIG
+    \brief Version of RapidJSON in "<major>.<minor>.<patch>" string format.
+*/
+#define RAPIDJSON_MAJOR_VERSION 1
+#define RAPIDJSON_MINOR_VERSION 0
+#define RAPIDJSON_PATCH_VERSION 2
+#define RAPIDJSON_VERSION_STRING \
+    RAPIDJSON_STRINGIFY(RAPIDJSON_MAJOR_VERSION.RAPIDJSON_MINOR_VERSION.RAPIDJSON_PATCH_VERSION)
+
+///////////////////////////////////////////////////////////////////////////////
 // RAPIDJSON_NAMESPACE_(BEGIN|END)
 /*! \def RAPIDJSON_NAMESPACE
     \ingroup RAPIDJSON_CONFIG
@@ -95,6 +120,31 @@
 #endif
 
 ///////////////////////////////////////////////////////////////////////////////
+// RAPIDJSON_HAS_STDSTRING
+
+#ifndef RAPIDJSON_HAS_STDSTRING
+#ifdef RAPIDJSON_DOXYGEN_RUNNING
+#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation
+#else
+#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default
+#endif
+/*! \def RAPIDJSON_HAS_STDSTRING
+    \ingroup RAPIDJSON_CONFIG
+    \brief Enable RapidJSON support for \c std::string
+
+    By defining this preprocessor symbol to \c 1, several convenience functions for using
+    \ref rapidjson::GenericValue with \c std::string are enabled, especially
+    for construction and comparison.
+
+    \hideinitializer
+*/
+#endif // !defined(RAPIDJSON_HAS_STDSTRING)
+
+#if RAPIDJSON_HAS_STDSTRING
+#include <string>
+#endif // RAPIDJSON_HAS_STDSTRING
+
+///////////////////////////////////////////////////////////////////////////////
 // RAPIDJSON_NO_INT64DEFINE
 
 /*! \def RAPIDJSON_NO_INT64DEFINE
@@ -128,9 +178,9 @@
 
 #ifndef RAPIDJSON_FORCEINLINE
 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && !defined(NDEBUG)
 #define RAPIDJSON_FORCEINLINE __forceinline
-#elif defined(__GNUC__) && __GNUC__ >= 4
+#elif defined(__GNUC__) && __GNUC__ >= 4 && !defined(NDEBUG)
 #define RAPIDJSON_FORCEINLINE __attribute__((always_inline))
 #else
 #define RAPIDJSON_FORCEINLINE
@@ -186,6 +236,8 @@
 #    define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
 #  elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__)
 #    define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
+#  elif defined(_MSC_VER) && defined(_M_ARM)
+#    define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
 #  elif defined(RAPIDJSON_DOXYGEN_RUNNING)
 #    define RAPIDJSON_ENDIAN
 #  else
@@ -198,7 +250,7 @@
 
 //! Whether using 64-bit architecture
 #ifndef RAPIDJSON_64BIT
-#if defined(__LP64__) || defined(_WIN64)
+#if defined(__LP64__) || defined(_WIN64) || defined(__EMSCRIPTEN__)
 #define RAPIDJSON_64BIT 1
 #else
 #define RAPIDJSON_64BIT 0
@@ -213,10 +265,14 @@
     \param x pointer to align
 
     Some machines require strict data alignment. Currently the default uses 4 bytes
-    alignment. User can customize by defining the RAPIDJSON_ALIGN function macro.,
+    alignment. User can customize by defining the RAPIDJSON_ALIGN function macro.
 */
 #ifndef RAPIDJSON_ALIGN
-#define RAPIDJSON_ALIGN(x) ((x + 3u) & ~3u)
+#if RAPIDJSON_64BIT == 1
+#define RAPIDJSON_ALIGN(x) (((x) + static_cast<uint64_t>(7u)) & ~static_cast<uint64_t>(7u))
+#else
+#define RAPIDJSON_ALIGN(x) (((x) + 3u) & ~3u)
+#endif
 #endif
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -320,7 +376,9 @@
 
 // Adopt from boost
 #ifndef RAPIDJSON_STATIC_ASSERT
+#ifndef __clang__
 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
+#endif
 RAPIDJSON_NAMESPACE_BEGIN
 template <bool x> struct STATIC_ASSERTION_FAILURE;
 template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
@@ -336,7 +394,9 @@
 #else
 #define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE 
 #endif
+#ifndef __clang__
 //!@endcond
+#endif
 
 /*! \def RAPIDJSON_STATIC_ASSERT
     \brief (Internal) macro to check for conditions at compile-time
@@ -362,10 +422,6 @@
 #define RAPIDJSON_VERSION_CODE(x,y,z) \
   (((x)*100000) + ((y)*100) + (z))
 
-// token stringification
-#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x)
-#define RAPIDJSON_DO_STRINGIFY(x) #x
-
 ///////////////////////////////////////////////////////////////////////////////
 // RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF
 

=== modified file 'shorts/xml2json/rapidjson/reader.h'
--- shorts/xml2json/rapidjson/reader.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/reader.h	2016-03-16 12:38:32 +0000
@@ -1,22 +1,16 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_READER_H_
 #define RAPIDJSON_READER_H_
@@ -45,6 +39,12 @@
 RAPIDJSON_DIAG_OFF(4702)  // unreachable code
 #endif
 
+#ifdef __clang__
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(padded)
+RAPIDJSON_DIAG_OFF(switch-enum)
+#endif
+
 #ifdef __GNUC__
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_OFF(effc++)
@@ -146,6 +146,7 @@
     kParseIterativeFlag = 4,        //!< Iterative(constant complexity in terms of function call stack size) parsing.
     kParseStopWhenDoneFlag = 8,     //!< After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error.
     kParseFullPrecisionFlag = 16,   //!< Parse number in full precision (but slower).
+    kParseCommentsFlag = 32,        //!< Allow one-line (//) and multi-line (/**/) comments.
     kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS  //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS
 };
 
@@ -261,27 +262,27 @@
 #ifdef RAPIDJSON_SSE42
 //! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once.
 inline const char *SkipWhitespace_SIMD(const char* p) {
-	// Fast return for single non-whitespace
-	if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
-		++p;
-	else
-		return p;
+    // Fast return for single non-whitespace
+    if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
+        ++p;
+    else
+        return p;
 
-	// 16-byte align to the next boundary
-	const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & ~15);
-	while (p != nextAligned)
-		if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
-			++p;
-		else
-			return p;
+    // 16-byte align to the next boundary
+    const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
+    while (p != nextAligned)
+        if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
+            ++p;
+        else
+            return p;
 
     // The rest of string using SIMD
-	static const char whitespace[16] = " \n\r\t";
-	const __m128i w = _mm_load_si128((const __m128i *)&whitespace[0]);
+    static const char whitespace[16] = " \n\r\t";
+    const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));
 
     for (;; p += 16) {
-        const __m128i s = _mm_load_si128((const __m128i *)p);
-        const unsigned r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
+        const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
+        const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
         if (r != 0) {   // some of characters is non-whitespace
 #ifdef _MSC_VER         // Find the index of first non-whitespace
             unsigned long offset;
@@ -298,39 +299,39 @@
 
 //! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once.
 inline const char *SkipWhitespace_SIMD(const char* p) {
-	// Fast return for single non-whitespace
-	if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
-		++p;
-	else
-		return p;
+    // Fast return for single non-whitespace
+    if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
+        ++p;
+    else
+        return p;
 
     // 16-byte align to the next boundary
-	const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & ~15);
-	while (p != nextAligned)
-		if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
-			++p;
-		else
-			return p;
+    const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
+    while (p != nextAligned)
+        if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
+            ++p;
+        else
+            return p;
 
     // The rest of string
-	static const char whitespaces[4][17] = {
-		"                ",
-		"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",
-		"\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r",
-		"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"};
+    static const char whitespaces[4][17] = {
+        "                ",
+        "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",
+        "\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r",
+        "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"};
 
-		const __m128i w0 = _mm_loadu_si128((const __m128i *)&whitespaces[0][0]);
-		const __m128i w1 = _mm_loadu_si128((const __m128i *)&whitespaces[1][0]);
-		const __m128i w2 = _mm_loadu_si128((const __m128i *)&whitespaces[2][0]);
-		const __m128i w3 = _mm_loadu_si128((const __m128i *)&whitespaces[3][0]);
+        const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
+        const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
+        const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
+        const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
 
     for (;; p += 16) {
-        const __m128i s = _mm_load_si128((const __m128i *)p);
+        const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
         __m128i x = _mm_cmpeq_epi8(s, w0);
         x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
         x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
         x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
-        unsigned short r = (unsigned short)~_mm_movemask_epi8(x);
+        unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));
         if (r != 0) {   // some of characters may be non-whitespace
 #ifdef _MSC_VER         // Find the index of first non-whitespace
             unsigned long offset;
@@ -404,7 +405,8 @@
 
         ClearStackOnExit scope(*this);
 
-        SkipWhitespace(is);
+        SkipWhitespaceAndComments<parseFlags>(is);
+        RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
 
         if (is.Peek() == '\0') {
             RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell());
@@ -415,7 +417,8 @@
             RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
 
             if (!(parseFlags & kParseStopWhenDoneFlag)) {
-                SkipWhitespace(is);
+                SkipWhitespaceAndComments<parseFlags>(is);
+                RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
 
                 if (is.Peek() != '\0') {
                     RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell());
@@ -468,6 +471,40 @@
         ClearStackOnExit& operator=(const ClearStackOnExit&);
     };
 
+    template<unsigned parseFlags, typename InputStream>
+    void SkipWhitespaceAndComments(InputStream& is) {
+        SkipWhitespace(is);
+
+        if (parseFlags & kParseCommentsFlag) {
+            while (is.Peek() == '/') {
+                is.Take();
+
+                if (is.Peek() == '*') {
+                    is.Take();
+                    while (true) {
+                        if (is.Peek() == '\0')
+                            RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
+
+                        if (is.Take() == '*') {
+                            if (is.Peek() == '\0')
+                                RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
+
+                            if (is.Take() == '/')
+                                break;
+                        }
+                    }
+                } else if (is.Peek() == '/') {
+                    is.Take();
+                    while (is.Peek() != '\0' && is.Take() != '\n') { }
+                } else {
+                    RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
+                }
+
+                SkipWhitespace(is);
+            }
+        }
+    }
+
     // Parse object: { string : value, ... }
     template<unsigned parseFlags, typename InputStream, typename Handler>
     void ParseObject(InputStream& is, Handler& handler) {
@@ -477,7 +514,8 @@
         if (!handler.StartObject())
             RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
 
-        SkipWhitespace(is);
+        SkipWhitespaceAndComments<parseFlags>(is);
+        RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 
         if (is.Peek() == '}') {
             is.Take();
@@ -493,27 +531,35 @@
             ParseString<parseFlags>(is, handler, true);
             RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 
-            SkipWhitespace(is);
+            SkipWhitespaceAndComments<parseFlags>(is);
+            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 
             if (is.Take() != ':')
                 RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
 
-            SkipWhitespace(is);
+            SkipWhitespaceAndComments<parseFlags>(is);
+            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 
             ParseValue<parseFlags>(is, handler);
             RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 
-            SkipWhitespace(is);
+            SkipWhitespaceAndComments<parseFlags>(is);
+            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 
             ++memberCount;
 
             switch (is.Take()) {
-                case ',': SkipWhitespace(is); break;
+                case ',':
+                    SkipWhitespaceAndComments<parseFlags>(is);
+                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
+                    break;
                 case '}': 
                     if (!handler.EndObject(memberCount))
                         RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
                     return;
-                default:  RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell());
+                default:  
+                    RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell());
+                    break;
             }
         }
     }
@@ -527,7 +573,8 @@
         if (!handler.StartArray())
             RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
         
-        SkipWhitespace(is);
+        SkipWhitespaceAndComments<parseFlags>(is);
+        RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 
         if (is.Peek() == ']') {
             is.Take();
@@ -541,15 +588,21 @@
             RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 
             ++elementCount;
-            SkipWhitespace(is);
+            SkipWhitespaceAndComments<parseFlags>(is);
+            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 
             switch (is.Take()) {
-                case ',': SkipWhitespace(is); break;
+                case ',':
+                    SkipWhitespaceAndComments<parseFlags>(is);
+                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
+                    break;
                 case ']': 
                     if (!handler.EndArray(elementCount))
                         RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
                     return;
-                default:  RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
+                default:  
+                    RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
+                    break;
             }
         }
     }
@@ -651,7 +704,7 @@
             RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
             size_t length = s.PutEnd(head) - 1;
             RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
-            const typename TargetEncoding::Ch* const str = (typename TargetEncoding::Ch*)head;
+            const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
             success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false));
         }
         else {
@@ -690,16 +743,17 @@
             if (c == '\\') {    // Escape
                 is.Take();
                 Ch e = is.Take();
-                if ((sizeof(Ch) == 1 || unsigned(e) < 256) && escape[(unsigned char)e]) {
-                    os.Put(escape[(unsigned char)e]);
-                }
+                if ((sizeof(Ch) == 1 || unsigned(e) < 256) && escape[static_cast<unsigned char>(e)])
+                    os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
                 else if (e == 'u') {    // Unicode
                     unsigned codepoint = ParseHex4(is);
+                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
                     if (codepoint >= 0xD800 && codepoint <= 0xDBFF) {
                         // Handle UTF-16 surrogate pair
                         if (is.Take() != '\\' || is.Take() != 'u')
                             RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, is.Tell() - 2);
                         unsigned codepoint2 = ParseHex4(is);
+                        RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
                         if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF)
                             RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, is.Tell() - 2);
                         codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
@@ -716,7 +770,7 @@
             }
             else if (c == '\0')
                 RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell() - 1);
-            else if ((unsigned)c < 0x20) // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
+            else if (static_cast<unsigned>(c) < 0x20) // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
                 RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell() - 1);
             else {
                 if (parseFlags & kParseValidateEncodingFlag ? 
@@ -757,7 +811,7 @@
         ~NumberStream() {}
 
         RAPIDJSON_FORCEINLINE Ch TakePush() {
-            stackStream.Put((char)Base::is.Peek());
+            stackStream.Put(static_cast<char>(Base::is.Peek()));
             return Base::is.Take();
         }
 
@@ -888,10 +942,10 @@
                     }
                 }
 
-                d = (double)i64;
+                d = static_cast<double>(i64);
 #else
                 // Use double to store significand in 32-bit architecture
-                d = use64bit ? (double)i64 : (double)i;
+                d = static_cast<double>(use64bit ? i64 : i);
 #endif
                 useDouble = true;
             }
@@ -900,7 +954,7 @@
                 if (significandDigit < 17) {
                     d = d * 10.0 + (s.TakePush() - '0');
                     --expFrac;
-                    if (d != 0.0)
+                    if (d > 0.0)
                         significandDigit++;
                 }
                 else
@@ -928,11 +982,23 @@
             }
 
             if (s.Peek() >= '0' && s.Peek() <= '9') {
-                exp = s.Take() - '0';
-                while (s.Peek() >= '0' && s.Peek() <= '9') {
-                    exp = exp * 10 + (s.Take() - '0');
-                    if (exp > 308 && !expMinus) // exp > 308 should be rare, so it should be checked first.
-                        RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, s.Tell());
+                exp = static_cast<int>(s.Take() - '0');
+                if (expMinus) {
+                    while (s.Peek() >= '0' && s.Peek() <= '9') {
+                        exp = exp * 10 + static_cast<int>(s.Take() - '0');
+                        if (exp >= 214748364) {                         // Issue #313: prevent overflow exponent
+                            while (s.Peek() >= '0' && s.Peek() <= '9')  // Consume the rest of exponent
+                                s.Take();
+                        }
+                    }
+                }
+                else {  // positive exp
+                    int maxExp = 308 - expFrac;
+                    while (s.Peek() >= '0' && s.Peek() <= '9') {
+                        exp = exp * 10 + static_cast<int>(s.Take() - '0');
+                        if (exp > maxExp)
+                            RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, s.Tell());
+                    }
                 }
             }
             else
@@ -959,13 +1025,13 @@
         else {
             if (use64bit) {
                 if (minus)
-                    cont = handler.Int64(-(int64_t)i64);
+                    cont = handler.Int64(static_cast<int64_t>(~i64 + 1));
                 else
                     cont = handler.Uint64(i64);
             }
             else {
                 if (minus)
-                    cont = handler.Int(-(int)i);
+                    cont = handler.Int(static_cast<int32_t>(~i + 1));
                 else
                     cont = handler.Uint(i);
             }
@@ -984,7 +1050,10 @@
             case '"': ParseString<parseFlags>(is, handler); break;
             case '{': ParseObject<parseFlags>(is, handler); break;
             case '[': ParseArray <parseFlags>(is, handler); break;
-            default : ParseNumber<parseFlags>(is, handler);
+            default : 
+                      ParseNumber<parseFlags>(is, handler);
+                      break;
+                      
         }
     }
 
@@ -1011,11 +1080,11 @@
         IterativeParsingArrayFinishState,
 
         // Single value state
-        IterativeParsingValueState,
-
-        cIterativeParsingStateCount
+        IterativeParsingValueState
     };
 
+    enum { cIterativeParsingStateCount = IterativeParsingValueState + 1 };
+
     // Tokens
     enum Token {
         LeftBracketToken = 0,
@@ -1057,8 +1126,8 @@
 #undef N16
 //!@endcond
         
-        if (sizeof(Ch) == 1 || unsigned(c) < 256)
-            return (Token)tokenMap[(unsigned char)c];
+        if (sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256)
+            return static_cast<Token>(tokenMap[static_cast<unsigned char>(c)]);
         else
             return NumberToken;
     }
@@ -1224,21 +1293,16 @@
             }
         }; // End of G
 
-        return (IterativeParsingState)G[state][token];
+        return static_cast<IterativeParsingState>(G[state][token]);
     }
 
     // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit().
     // May return a new state on state pop.
     template <unsigned parseFlags, typename InputStream, typename Handler>
     RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) {
+        (void)token;
+
         switch (dst) {
-        case IterativeParsingStartState:
-            RAPIDJSON_ASSERT(false);
-            return IterativeParsingErrorState;
-
-        case IterativeParsingFinishState:
-            return dst;
-
         case IterativeParsingErrorState:
             return dst;
 
@@ -1277,12 +1341,9 @@
                 return dst;
 
         case IterativeParsingKeyValueDelimiterState:
-            if (token == ColonToken) {
-                is.Take();
-                return dst;
-            }
-            else
-                return IterativeParsingErrorState;
+            RAPIDJSON_ASSERT(token == ColonToken);
+            is.Take();
+            return dst;
 
         case IterativeParsingMemberValueState:
             // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
@@ -1357,17 +1418,25 @@
             }
         }
 
-        case IterativeParsingValueState:
+        default:
+            // This branch is for IterativeParsingValueState actually.
+            // Use `default:` rather than
+            // `case IterativeParsingValueState:` is for code coverage.
+
+            // The IterativeParsingStartState is not enumerated in this switch-case.
+            // It is impossible for that case. And it can be caught by following assertion.
+
+            // The IterativeParsingFinishState is not enumerated in this switch-case either.
+            // It is a "derivative" state which cannot triggered from Predict() directly.
+            // Therefore it cannot happen here. And it can be caught by following assertion.
+            RAPIDJSON_ASSERT(dst == IterativeParsingValueState);
+
             // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
             ParseValue<parseFlags>(is, handler);
             if (HasParseError()) {
                 return IterativeParsingErrorState;
             }
             return IterativeParsingFinishState;
-
-        default:
-            RAPIDJSON_ASSERT(false);
-            return IterativeParsingErrorState;
         }
     }
 
@@ -1379,14 +1448,14 @@
         }
         
         switch (src) {
-        case IterativeParsingStartState:            RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell());
-        case IterativeParsingFinishState:           RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell());
+        case IterativeParsingStartState:            RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return;
+        case IterativeParsingFinishState:           RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return;
         case IterativeParsingObjectInitialState:
-        case IterativeParsingMemberDelimiterState:  RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());
-        case IterativeParsingMemberKeyState:        RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
-        case IterativeParsingMemberValueState:      RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell());
-        case IterativeParsingElementState:          RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
-        default:                                    RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
+        case IterativeParsingMemberDelimiterState:  RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return;
+        case IterativeParsingMemberKeyState:        RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return;
+        case IterativeParsingMemberValueState:      RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return;
+        case IterativeParsingElementState:          RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return;
+        default:                                    RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); return;
         }       
     }
 
@@ -1396,7 +1465,8 @@
         ClearStackOnExit scope(*this);
         IterativeParsingState state = IterativeParsingStartState;
 
-        SkipWhitespace(is);
+        SkipWhitespaceAndComments<parseFlags>(is);
+        RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
         while (is.Peek() != '\0') {
             Token t = Tokenize(is.Peek());
             IterativeParsingState n = Predict(state, t);
@@ -1413,7 +1483,8 @@
             if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
                 break;
 
-            SkipWhitespace(is);
+            SkipWhitespaceAndComments<parseFlags>(is);
+            RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
         }
 
         // Handle the end of file.
@@ -1433,6 +1504,11 @@
 
 RAPIDJSON_NAMESPACE_END
 
+#ifdef __clang__
+RAPIDJSON_DIAG_POP
+#endif
+
+
 #ifdef __GNUC__
 RAPIDJSON_DIAG_POP
 #endif

=== modified file 'shorts/xml2json/rapidjson/stringbuffer.h'
--- shorts/xml2json/rapidjson/stringbuffer.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/stringbuffer.h	2016-03-16 12:38:32 +0000
@@ -1,22 +1,16 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_STRINGBUFFER_H_
 #define RAPIDJSON_STRINGBUFFER_H_

=== modified file 'shorts/xml2json/rapidjson/writer.h'
--- shorts/xml2json/rapidjson/writer.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/rapidjson/writer.h	2016-03-16 12:38:32 +0000
@@ -1,22 +1,16 @@
-// Copyright (C) 2011 Milo Yip
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// Tencent is pleased to support the open source community by making RapidJSON available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed 
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+// specific language governing permissions and limitations under the License.
 
 #ifndef RAPIDJSON_WRITER_H_
 #define RAPIDJSON_WRITER_H_
@@ -29,15 +23,16 @@
 #include "stringbuffer.h"
 #include <new>      // placement new
 
-#if RAPIDJSON_HAS_STDSTRING
-#include <string>
-#endif
-
 #ifdef _MSC_VER
 RAPIDJSON_DIAG_PUSH
 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
 #endif
 
+#ifdef __clang__
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(padded)
+#endif
+
 RAPIDJSON_NAMESPACE_BEGIN
 
 //! JSON writer
@@ -133,7 +128,7 @@
 
 #if RAPIDJSON_HAS_STDSTRING
     bool String(const std::basic_string<Ch>& str) {
-      return String(str.data(), SizeType(str.size()));
+        return String(str.data(), SizeType(str.size()));
     }
 #endif
 
@@ -211,7 +206,7 @@
         char buffer[11];
         const char* end = internal::i32toa(i, buffer);
         for (const char* p = buffer; p != end; ++p)
-            os_->Put(*p);
+            os_->Put(static_cast<typename TargetEncoding::Ch>(*p));
         return true;
     }
 
@@ -219,7 +214,7 @@
         char buffer[10];
         const char* end = internal::u32toa(u, buffer);
         for (const char* p = buffer; p != end; ++p)
-            os_->Put(*p);
+            os_->Put(static_cast<typename TargetEncoding::Ch>(*p));
         return true;
     }
 
@@ -227,7 +222,7 @@
         char buffer[21];
         const char* end = internal::i64toa(i64, buffer);
         for (const char* p = buffer; p != end; ++p)
-            os_->Put(*p);
+            os_->Put(static_cast<typename TargetEncoding::Ch>(*p));
         return true;
     }
 
@@ -235,7 +230,7 @@
         char buffer[20];
         char* end = internal::u64toa(u64, buffer);
         for (char* p = buffer; p != end; ++p)
-            os_->Put(*p);
+            os_->Put(static_cast<typename TargetEncoding::Ch>(*p));
         return true;
     }
 
@@ -243,12 +238,12 @@
         char buffer[25];
         char* end = internal::dtoa(d, buffer);
         for (char* p = buffer; p != end; ++p)
-            os_->Put(*p);
+            os_->Put(static_cast<typename TargetEncoding::Ch>(*p));
         return true;
     }
 
     bool WriteString(const Ch* str, SizeType length)  {
-        static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+        static const typename TargetEncoding::Ch hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
         static const char escape[256] = {
 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
             //0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
@@ -265,7 +260,7 @@
         GenericStringStream<SourceEncoding> is(str);
         while (is.Tell() < length) {
             const Ch c = is.Peek();
-            if (!TargetEncoding::supportUnicode && (unsigned)c >= 0x80) {
+            if (!TargetEncoding::supportUnicode && static_cast<unsigned>(c) >= 0x80) {
                 // Unicode escaping
                 unsigned codepoint;
                 if (!SourceEncoding::Decode(is, &codepoint))
@@ -278,7 +273,8 @@
                     os_->Put(hexDigits[(codepoint >>  4) & 15]);
                     os_->Put(hexDigits[(codepoint      ) & 15]);
                 }
-                else if (codepoint >= 0x010000 && codepoint <= 0x10FFFF)    {
+                else {
+                    RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF);
                     // Surrogate pair
                     unsigned s = codepoint - 0x010000;
                     unsigned lead = (s >> 10) + 0xD800;
@@ -294,22 +290,21 @@
                     os_->Put(hexDigits[(trail >>  4) & 15]);
                     os_->Put(hexDigits[(trail      ) & 15]);                    
                 }
-                else
-                    return false;   // invalid code point
             }
-            else if ((sizeof(Ch) == 1 || (unsigned)c < 256) && escape[(unsigned char)c])  {
+            else if ((sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256) && escape[static_cast<unsigned char>(c)])  {
                 is.Take();
                 os_->Put('\\');
-                os_->Put(escape[(unsigned char)c]);
-                if (escape[(unsigned char)c] == 'u') {
-                    os_->Put('0');
-                    os_->Put('0');
-                    os_->Put(hexDigits[(unsigned char)c >> 4]);
-                    os_->Put(hexDigits[(unsigned char)c & 0xF]);
+                os_->Put(static_cast<typename TargetEncoding::Ch>(escape[static_cast<unsigned char>(c)]));
+                if (escape[static_cast<unsigned char>(c)] == 'u') {
+                    os_->Put('0');
+                    os_->Put('0');
+                    os_->Put(hexDigits[static_cast<unsigned char>(c) >> 4]);
+                    os_->Put(hexDigits[static_cast<unsigned char>(c) & 0xF]);
                 }
             }
             else
-                Transcoder<SourceEncoding, TargetEncoding>::Transcode(is, *os_);
+                if (!Transcoder<SourceEncoding, TargetEncoding>::Transcode(is, *os_))
+                    return false;
         }
         os_->Put('\"');
         return true;
@@ -356,7 +351,7 @@
 inline bool Writer<StringBuffer>::WriteInt(int i) {
     char *buffer = os_->Push(11);
     const char* end = internal::i32toa(i, buffer);
-    os_->Pop(11 - (end - buffer));
+    os_->Pop(static_cast<size_t>(11 - (end - buffer)));
     return true;
 }
 
@@ -364,7 +359,7 @@
 inline bool Writer<StringBuffer>::WriteUint(unsigned u) {
     char *buffer = os_->Push(10);
     const char* end = internal::u32toa(u, buffer);
-    os_->Pop(10 - (end - buffer));
+    os_->Pop(static_cast<size_t>(10 - (end - buffer)));
     return true;
 }
 
@@ -372,7 +367,7 @@
 inline bool Writer<StringBuffer>::WriteInt64(int64_t i64) {
     char *buffer = os_->Push(21);
     const char* end = internal::i64toa(i64, buffer);
-    os_->Pop(21 - (end - buffer));
+    os_->Pop(static_cast<size_t>(21 - (end - buffer)));
     return true;
 }
 
@@ -380,7 +375,7 @@
 inline bool Writer<StringBuffer>::WriteUint64(uint64_t u) {
     char *buffer = os_->Push(20);
     const char* end = internal::u64toa(u, buffer);
-    os_->Pop(20 - (end - buffer));
+    os_->Pop(static_cast<size_t>(20 - (end - buffer)));
     return true;
 }
 
@@ -388,7 +383,7 @@
 inline bool Writer<StringBuffer>::WriteDouble(double d) {
     char *buffer = os_->Push(25);
     char* end = internal::dtoa(d, buffer);
-    os_->Pop(25 - (end - buffer));
+    os_->Pop(static_cast<size_t>(25 - (end - buffer)));
     return true;
 }
 
@@ -398,4 +393,8 @@
 RAPIDJSON_DIAG_POP
 #endif
 
+#ifdef __clang__
+RAPIDJSON_DIAG_POP
+#endif
+
 #endif // RAPIDJSON_RAPIDJSON_H_

=== removed file 'shorts/xml2json/utilities.cpp'
--- shorts/xml2json/utilities.cpp	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/utilities.cpp	1970-01-01 00:00:00 +0000
@@ -1,46 +0,0 @@
-#include "utilities.h"
-#include "xml2json.hpp"
-
-Utilities::Utilities(QObject *parent) :
-    QObject(parent)
-{
-//    qDebug() << "path: " << QDir::currentPath() ;
-//    QFile xmlFile("xml");
-//    xmlFile.open(QIODevice::ReadOnly | QIODevice::Text);
-
-//    qDebug() << "json: " << xmlToJson(QString(xmlFile.readAll())).size();
-}
-
-QJsonObject Utilities::xmlToJson(const QString &xml)
-{
-    QByteArray ba = xml.toLocal8Bit();
-    char* ch = ba.data();
-    const std::string json = xml2json(ch);
-//    qDebug() << "json: " << QString::fromStdString(json) ;
-    return QJsonDocument::fromJson(QString::fromStdString(json).toLocal8Bit()).object();
-}
-
-QStringList Utilities::htmlGetImg(const QString &html)
-{
-    QRegExp imgTagRegex("\\<img[^\\>]*src\\s*=\\s*\"([^\"]*)\"[^\\>]*\\>", Qt::CaseInsensitive);
-    imgTagRegex.setMinimal(true);
-    QStringList urlmatches;
-    QStringList imgmatches;
-    int offset = 0;
-    while( (offset = imgTagRegex.indexIn(html, offset)) != -1)
-    {
-        offset += imgTagRegex.matchedLength();
-        imgmatches.append(imgTagRegex.cap(0)); // Should hold complete img tag
-        urlmatches.append(imgTagRegex.cap(1)); // Should hold only src property
-    }
-    return urlmatches;
-}
-
-QJsonObject Utilities::test()
-{
-    QFile xmlFile("xml");
-    xmlFile.open(QIODevice::ReadOnly | QIODevice::Text);
-
-    QJsonObject obj = xmlToJson(QString(xmlFile.readAll()));
-    return obj;
-}

=== removed file 'shorts/xml2json/utilities.h'
--- shorts/xml2json/utilities.h	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/utilities.h	1970-01-01 00:00:00 +0000
@@ -1,24 +0,0 @@
-#ifndef UTILITIES_H
-#define UTILITIES_H
-
-#include <QtCore>
-
-class Utilities : public QObject
-{
-    Q_OBJECT
-public:
-    explicit Utilities(QObject *parent = 0);
-
-    Q_INVOKABLE QJsonObject xmlToJson(const QString &xml);
-    Q_INVOKABLE QStringList htmlGetImg(const QString &html);
-
-    // test only
-    Q_INVOKABLE QJsonObject test();
-
-signals:
-
-public slots:
-
-};
-
-#endif // UTILITIES_H

=== modified file 'shorts/xml2json/xml2json.hpp'
--- shorts/xml2json/xml2json.hpp	2015-12-02 17:03:41 +0000
+++ shorts/xml2json/xml2json.hpp	2016-03-16 12:38:32 +0000
@@ -22,34 +22,7 @@
 #include "rapidjson/filewritestream.h"
 #include "rapidjson/error/en.h"
 
-//using namespace std;
-//using namespace rapidxml;
-
-/*
-void to_array_form_node(rapidxml::xml_node<> *xmlnode_chd, rapidjson::Value &jsvalue, rapidjson::Value &jsvalue_chd, rapidjson::Document::AllocatorType& allocator)
-{
-    // This function is obsolete. Just remain it here waiting for the future APIs of rapidjson that can minimize the data copy (if with existence guarantees).
-    rapidjson::Value jsvalue_target;
-
-    jsvalue_target = jsvalue.FindMember(xmlnode_chd->name())->value;
-    if (jsvalue_target.IsArray())
-    {
-        jsvalue_target.PushBack(jsvalue_chd, allocator);
-        jsvalue.RemoveMember(xmlnode_chd->name());
-        jsvalue.AddMember(rapidjson::StringRef(xmlnode_chd->name()), jsvalue_target, allocator);
-    }
-    else
-    {
-        rapidjson::Value jsvalue_array;
-        //jsvalue_array = jsvalue_target;
-        jsvalue_array.SetArray();
-        jsvalue_array.PushBack(jsvalue_target, allocator);
-        jsvalue_array.PushBack(jsvalue_chd, allocator);
-        jsvalue.RemoveMember(xmlnode_chd->name());
-        jsvalue.AddMember(rapidjson::StringRef(xmlnode_chd->name()), jsvalue_array, allocator);
-    }
-}
-*/
+// Avoided any namespace pollution.
 
 void to_array_form(const char *name, rapidjson::Value &jsvalue, rapidjson::Value &jsvalue_chd, rapidjson::Document::AllocatorType& allocator)
 {
@@ -57,7 +30,7 @@
     rapidjson::Value jn;             // this is a must, partially because of the latest version of rapidjson
     jn.SetString(name, allocator);
     jsvalue_target = jsvalue.FindMember(name)->value;
-    if (jsvalue_target.IsArray())
+    if(jsvalue_target.IsArray())
     {
         jsvalue_target.PushBack(jsvalue_chd, allocator);
         jsvalue.RemoveMember(name);
@@ -78,7 +51,7 @@
 void add_attributes(rapidxml::xml_node<> *xmlnode, rapidjson::Value &jsvalue, rapidjson::Document::AllocatorType& allocator)
 {
     rapidxml::xml_attribute<> *myattr;
-    for (myattr = xmlnode->first_attribute(); myattr; myattr = myattr->next_attribute())
+    for(myattr = xmlnode->first_attribute(); myattr; myattr = myattr->next_attribute())
     {
         rapidjson::Value jn, jv;
         jn.SetString((std::string("@") + myattr->name()).c_str(), allocator);
@@ -97,16 +70,16 @@
     rapidxml::xml_node<> *xmlnode_chd;
 
     // classified discussion:
-    if ((xmlnode->type() == rapidxml::node_data || xmlnode->type() == rapidxml::node_cdata) && xmlnode->value())
+    if((xmlnode->type() == rapidxml::node_data || xmlnode->type() == rapidxml::node_cdata) && xmlnode->value())
     {
         // case: pure_text
-        jsvalue.SetString(xmlnode->value(), allocator); // then addmember("#text" , jsvalue, allocator)
+        jsvalue.SetString(xmlnode->value(), allocator);  // then addmember("#text" , jsvalue, allocator)
     }
-    else if (xmlnode->type() == rapidxml::node_element)
+    else if(xmlnode->type() == rapidxml::node_element)
     {
-        if (xmlnode->first_attribute())
+        if(xmlnode->first_attribute())
         {
-            if (xmlnode->first_node() && xmlnode->first_node()->type() == rapidxml::node_data && count_children(xmlnode) == 1)
+            if(xmlnode->first_node() && xmlnode->first_node()->type() == rapidxml::node_data && count_children(xmlnode) == 1)
             {
                 // case: <e attr="xxx">text</e>
                 rapidjson::Value jn, jv;
@@ -124,43 +97,43 @@
         }
         else
         {
-            if (!xmlnode->first_node())
+            if(!xmlnode->first_node())
             {
                 // case: <e />
                 jsvalue.SetNull();
                 return;
             }
-            else if (xmlnode->first_node()->type() == rapidxml::node_data && count_children(xmlnode) == 1)
+            else if(xmlnode->first_node()->type() == rapidxml::node_data && count_children(xmlnode) == 1)
             {
                 // case: <e>text</e>
                 jsvalue.SetString(rapidjson::StringRef(xmlnode->first_node()->value()), allocator);
                 return;
             }
         }
-        if (xmlnode->first_node())
+        if(xmlnode->first_node())
         {
             // case: complex else...
             std::map<std::string, int> name_count;
-            for (xmlnode_chd = xmlnode->first_node(); xmlnode_chd; xmlnode_chd = xmlnode_chd->next_sibling())
+            for(xmlnode_chd = xmlnode->first_node(); xmlnode_chd; xmlnode_chd = xmlnode_chd->next_sibling())
             {
                 std::string current_name;
                 const char *name_ptr = NULL;
                 rapidjson::Value jn, jv;
-                if (xmlnode_chd->type() == rapidxml::node_data || xmlnode_chd->type() == rapidxml::node_cdata)
+                if(xmlnode_chd->type() == rapidxml::node_data || xmlnode_chd->type() == rapidxml::node_cdata)
                 {
                     current_name = "#text";
                     name_count[current_name]++;
                     jv.SetString("#text", allocator);
                     name_ptr = jv.GetString();
                 }
-                else if (xmlnode_chd->type() == rapidxml::node_element)
+                else if(xmlnode_chd->type() == rapidxml::node_element)
                 {
                     current_name = xmlnode_chd->name();
                     name_count[current_name]++;
                     name_ptr = xmlnode_chd->name();
                 }
                 traverse_node(xmlnode_chd, jsvalue_chd, allocator);
-                if (name_count[current_name] > 1 && name_ptr)
+                if(name_count[current_name] > 1 && name_ptr)
                     to_array_form(name_ptr, jsvalue, jsvalue_chd, allocator);
                 else
                 {
@@ -178,27 +151,28 @@
 
 std::string xml2json(const char *xml_str)
 {
-    //file<> fdoc("track_orig.xml");
-    rapidxml::xml_document<> doc;
-    doc.parse<0>(const_cast<char *>(xml_str));
+    //file<> fdoc("track_orig.xml"); // could serve another use case
+    rapidxml::xml_document<> *xml_doc = new rapidxml::xml_document<>();
+    xml_doc->parse<0> (const_cast<char *>(xml_str));
 
-    rapidjson::Document document;
-    document.SetObject();
-    rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
+    rapidjson::Document js_doc;
+    js_doc.SetObject();
+    rapidjson::Document::AllocatorType& allocator = js_doc.GetAllocator();
 
     rapidxml::xml_node<> *xmlnode_chd;
 
-    for (xmlnode_chd = doc.first_node(); xmlnode_chd; xmlnode_chd = xmlnode_chd->next_sibling())
+    for(xmlnode_chd = xml_doc->first_node(); xmlnode_chd; xmlnode_chd = xmlnode_chd->next_sibling())
     {
-        //cout << xmlnode_chd->name() << endl;
         rapidjson::Value jsvalue_chd;
         jsvalue_chd.SetObject();
         traverse_node(xmlnode_chd, jsvalue_chd, allocator);
-        document.AddMember(rapidjson::StringRef(xmlnode_chd->name()), jsvalue_chd, allocator);
+        js_doc.AddMember(rapidjson::StringRef(xmlnode_chd->name()), jsvalue_chd, allocator);
     }
+
+    delete xml_doc;
     rapidjson::StringBuffer buffer;
     rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
-    document.Accept(writer);
+    js_doc.Accept(writer);
     return buffer.GetString();
 }
 


Follow ups