Add Python script for generating Natvis file and update file for 3.11.2 (#3697)

diff --git a/nlohmann_json.natvis b/nlohmann_json.natvis
index 5577176..b101771 100644
--- a/nlohmann_json.natvis
+++ b/nlohmann_json.natvis
@@ -1,5 +1,9 @@
+<!-- * * * * * * * * AUTO-GENERATED FILE  * * * * * * * * -->
+<!-- Edit ./tools/generate_natvis/nlohmann_json.natvis.j2 -->
+<!-- * * * * * * * * AUTO-GENERATED FILE  * * * * * * * * -->
 <?xml version="1.0" encoding="utf-8"?>
 <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+    <!-- Namespace nlohmann -->
     <Type Name="nlohmann::basic_json&lt;*&gt;">
         <DisplayString Condition="m_type == nlohmann::detail::value_t::null">null</DisplayString>
         <DisplayString Condition="m_type == nlohmann::detail::value_t::object">{*(m_value.object)}</DisplayString>
@@ -20,8 +24,8 @@
         </Expand>
     </Type>
 
-    <!--    skip the pair first/second members in the treeview while traversing a map.
-            Only works in VS 2015 Update 2 and beyond using the new visualization -->
+    <!-- Skip the pair first/second members in the treeview while traversing a map.
+         Only works in VS 2015 Update 2 and beyond using the new visualization -->
     <Type Name="std::pair&lt;*, nlohmann::basic_json&lt;*&gt;&gt;" IncludeView="MapHelper">
         <DisplayString>{second}</DisplayString>
         <Expand>
@@ -29,4 +33,244 @@
         </Expand>
     </Type>
 
+    <!-- Namespace nlohmann::json_abi -->
+    <Type Name="nlohmann::json_abi::basic_json&lt;*&gt;">
+        <DisplayString Condition="m_type == nlohmann::json_abi::detail::value_t::null">null</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi::detail::value_t::object">{*(m_value.object)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi::detail::value_t::array">{*(m_value.array)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi::detail::value_t::string">{*(m_value.string)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi::detail::value_t::boolean">{m_value.boolean}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi::detail::value_t::number_integer">{m_value.number_integer}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi::detail::value_t::number_unsigned">{m_value.number_unsigned}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi::detail::value_t::number_float">{m_value.number_float}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi::detail::value_t::discarded">discarded</DisplayString>
+        <Expand>
+            <ExpandedItem Condition="m_type == nlohmann::json_abi::detail::value_t::object">
+                *(m_value.object),view(simple)
+            </ExpandedItem>
+            <ExpandedItem Condition="m_type == nlohmann::json_abi::detail::value_t::array">
+                *(m_value.array),view(simple)
+            </ExpandedItem>
+        </Expand>
+    </Type>
+
+    <!-- Skip the pair first/second members in the treeview while traversing a map.
+         Only works in VS 2015 Update 2 and beyond using the new visualization -->
+    <Type Name="std::pair&lt;*, nlohmann::json_abi::basic_json&lt;*&gt;&gt;" IncludeView="MapHelper">
+        <DisplayString>{second}</DisplayString>
+        <Expand>
+            <ExpandedItem>second</ExpandedItem>
+        </Expand>
+    </Type>
+
+    <!-- Namespace nlohmann::json_abi_v3_11_2 -->
+    <Type Name="nlohmann::json_abi_v3_11_2::basic_json&lt;*&gt;">
+        <DisplayString Condition="m_type == nlohmann::json_abi_v3_11_2::detail::value_t::null">null</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_v3_11_2::detail::value_t::object">{*(m_value.object)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_v3_11_2::detail::value_t::array">{*(m_value.array)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_v3_11_2::detail::value_t::string">{*(m_value.string)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_v3_11_2::detail::value_t::boolean">{m_value.boolean}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_v3_11_2::detail::value_t::number_integer">{m_value.number_integer}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_v3_11_2::detail::value_t::number_unsigned">{m_value.number_unsigned}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_v3_11_2::detail::value_t::number_float">{m_value.number_float}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_v3_11_2::detail::value_t::discarded">discarded</DisplayString>
+        <Expand>
+            <ExpandedItem Condition="m_type == nlohmann::json_abi_v3_11_2::detail::value_t::object">
+                *(m_value.object),view(simple)
+            </ExpandedItem>
+            <ExpandedItem Condition="m_type == nlohmann::json_abi_v3_11_2::detail::value_t::array">
+                *(m_value.array),view(simple)
+            </ExpandedItem>
+        </Expand>
+    </Type>
+
+    <!-- Skip the pair first/second members in the treeview while traversing a map.
+         Only works in VS 2015 Update 2 and beyond using the new visualization -->
+    <Type Name="std::pair&lt;*, nlohmann::json_abi_v3_11_2::basic_json&lt;*&gt;&gt;" IncludeView="MapHelper">
+        <DisplayString>{second}</DisplayString>
+        <Expand>
+            <ExpandedItem>second</ExpandedItem>
+        </Expand>
+    </Type>
+
+    <!-- Namespace nlohmann::json_abi_diag -->
+    <Type Name="nlohmann::json_abi_diag::basic_json&lt;*&gt;">
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag::detail::value_t::null">null</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag::detail::value_t::object">{*(m_value.object)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag::detail::value_t::array">{*(m_value.array)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag::detail::value_t::string">{*(m_value.string)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag::detail::value_t::boolean">{m_value.boolean}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag::detail::value_t::number_integer">{m_value.number_integer}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag::detail::value_t::number_unsigned">{m_value.number_unsigned}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag::detail::value_t::number_float">{m_value.number_float}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag::detail::value_t::discarded">discarded</DisplayString>
+        <Expand>
+            <ExpandedItem Condition="m_type == nlohmann::json_abi_diag::detail::value_t::object">
+                *(m_value.object),view(simple)
+            </ExpandedItem>
+            <ExpandedItem Condition="m_type == nlohmann::json_abi_diag::detail::value_t::array">
+                *(m_value.array),view(simple)
+            </ExpandedItem>
+        </Expand>
+    </Type>
+
+    <!-- Skip the pair first/second members in the treeview while traversing a map.
+         Only works in VS 2015 Update 2 and beyond using the new visualization -->
+    <Type Name="std::pair&lt;*, nlohmann::json_abi_diag::basic_json&lt;*&gt;&gt;" IncludeView="MapHelper">
+        <DisplayString>{second}</DisplayString>
+        <Expand>
+            <ExpandedItem>second</ExpandedItem>
+        </Expand>
+    </Type>
+
+    <!-- Namespace nlohmann::json_abi_diag_v3_11_2 -->
+    <Type Name="nlohmann::json_abi_diag_v3_11_2::basic_json&lt;*&gt;">
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_v3_11_2::detail::value_t::null">null</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_v3_11_2::detail::value_t::object">{*(m_value.object)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_v3_11_2::detail::value_t::array">{*(m_value.array)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_v3_11_2::detail::value_t::string">{*(m_value.string)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_v3_11_2::detail::value_t::boolean">{m_value.boolean}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_v3_11_2::detail::value_t::number_integer">{m_value.number_integer}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_v3_11_2::detail::value_t::number_unsigned">{m_value.number_unsigned}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_v3_11_2::detail::value_t::number_float">{m_value.number_float}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_v3_11_2::detail::value_t::discarded">discarded</DisplayString>
+        <Expand>
+            <ExpandedItem Condition="m_type == nlohmann::json_abi_diag_v3_11_2::detail::value_t::object">
+                *(m_value.object),view(simple)
+            </ExpandedItem>
+            <ExpandedItem Condition="m_type == nlohmann::json_abi_diag_v3_11_2::detail::value_t::array">
+                *(m_value.array),view(simple)
+            </ExpandedItem>
+        </Expand>
+    </Type>
+
+    <!-- Skip the pair first/second members in the treeview while traversing a map.
+         Only works in VS 2015 Update 2 and beyond using the new visualization -->
+    <Type Name="std::pair&lt;*, nlohmann::json_abi_diag_v3_11_2::basic_json&lt;*&gt;&gt;" IncludeView="MapHelper">
+        <DisplayString>{second}</DisplayString>
+        <Expand>
+            <ExpandedItem>second</ExpandedItem>
+        </Expand>
+    </Type>
+
+    <!-- Namespace nlohmann::json_abi_ldvcmp -->
+    <Type Name="nlohmann::json_abi_ldvcmp::basic_json&lt;*&gt;">
+        <DisplayString Condition="m_type == nlohmann::json_abi_ldvcmp::detail::value_t::null">null</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_ldvcmp::detail::value_t::object">{*(m_value.object)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_ldvcmp::detail::value_t::array">{*(m_value.array)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_ldvcmp::detail::value_t::string">{*(m_value.string)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_ldvcmp::detail::value_t::boolean">{m_value.boolean}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_ldvcmp::detail::value_t::number_integer">{m_value.number_integer}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_ldvcmp::detail::value_t::number_unsigned">{m_value.number_unsigned}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_ldvcmp::detail::value_t::number_float">{m_value.number_float}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_ldvcmp::detail::value_t::discarded">discarded</DisplayString>
+        <Expand>
+            <ExpandedItem Condition="m_type == nlohmann::json_abi_ldvcmp::detail::value_t::object">
+                *(m_value.object),view(simple)
+            </ExpandedItem>
+            <ExpandedItem Condition="m_type == nlohmann::json_abi_ldvcmp::detail::value_t::array">
+                *(m_value.array),view(simple)
+            </ExpandedItem>
+        </Expand>
+    </Type>
+
+    <!-- Skip the pair first/second members in the treeview while traversing a map.
+         Only works in VS 2015 Update 2 and beyond using the new visualization -->
+    <Type Name="std::pair&lt;*, nlohmann::json_abi_ldvcmp::basic_json&lt;*&gt;&gt;" IncludeView="MapHelper">
+        <DisplayString>{second}</DisplayString>
+        <Expand>
+            <ExpandedItem>second</ExpandedItem>
+        </Expand>
+    </Type>
+
+    <!-- Namespace nlohmann::json_abi_ldvcmp_v3_11_2 -->
+    <Type Name="nlohmann::json_abi_ldvcmp_v3_11_2::basic_json&lt;*&gt;">
+        <DisplayString Condition="m_type == nlohmann::json_abi_ldvcmp_v3_11_2::detail::value_t::null">null</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_ldvcmp_v3_11_2::detail::value_t::object">{*(m_value.object)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_ldvcmp_v3_11_2::detail::value_t::array">{*(m_value.array)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_ldvcmp_v3_11_2::detail::value_t::string">{*(m_value.string)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_ldvcmp_v3_11_2::detail::value_t::boolean">{m_value.boolean}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_ldvcmp_v3_11_2::detail::value_t::number_integer">{m_value.number_integer}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_ldvcmp_v3_11_2::detail::value_t::number_unsigned">{m_value.number_unsigned}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_ldvcmp_v3_11_2::detail::value_t::number_float">{m_value.number_float}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_ldvcmp_v3_11_2::detail::value_t::discarded">discarded</DisplayString>
+        <Expand>
+            <ExpandedItem Condition="m_type == nlohmann::json_abi_ldvcmp_v3_11_2::detail::value_t::object">
+                *(m_value.object),view(simple)
+            </ExpandedItem>
+            <ExpandedItem Condition="m_type == nlohmann::json_abi_ldvcmp_v3_11_2::detail::value_t::array">
+                *(m_value.array),view(simple)
+            </ExpandedItem>
+        </Expand>
+    </Type>
+
+    <!-- Skip the pair first/second members in the treeview while traversing a map.
+         Only works in VS 2015 Update 2 and beyond using the new visualization -->
+    <Type Name="std::pair&lt;*, nlohmann::json_abi_ldvcmp_v3_11_2::basic_json&lt;*&gt;&gt;" IncludeView="MapHelper">
+        <DisplayString>{second}</DisplayString>
+        <Expand>
+            <ExpandedItem>second</ExpandedItem>
+        </Expand>
+    </Type>
+
+    <!-- Namespace nlohmann::json_abi_diag_ldvcmp -->
+    <Type Name="nlohmann::json_abi_diag_ldvcmp::basic_json&lt;*&gt;">
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_ldvcmp::detail::value_t::null">null</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_ldvcmp::detail::value_t::object">{*(m_value.object)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_ldvcmp::detail::value_t::array">{*(m_value.array)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_ldvcmp::detail::value_t::string">{*(m_value.string)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_ldvcmp::detail::value_t::boolean">{m_value.boolean}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_ldvcmp::detail::value_t::number_integer">{m_value.number_integer}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_ldvcmp::detail::value_t::number_unsigned">{m_value.number_unsigned}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_ldvcmp::detail::value_t::number_float">{m_value.number_float}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_ldvcmp::detail::value_t::discarded">discarded</DisplayString>
+        <Expand>
+            <ExpandedItem Condition="m_type == nlohmann::json_abi_diag_ldvcmp::detail::value_t::object">
+                *(m_value.object),view(simple)
+            </ExpandedItem>
+            <ExpandedItem Condition="m_type == nlohmann::json_abi_diag_ldvcmp::detail::value_t::array">
+                *(m_value.array),view(simple)
+            </ExpandedItem>
+        </Expand>
+    </Type>
+
+    <!-- Skip the pair first/second members in the treeview while traversing a map.
+         Only works in VS 2015 Update 2 and beyond using the new visualization -->
+    <Type Name="std::pair&lt;*, nlohmann::json_abi_diag_ldvcmp::basic_json&lt;*&gt;&gt;" IncludeView="MapHelper">
+        <DisplayString>{second}</DisplayString>
+        <Expand>
+            <ExpandedItem>second</ExpandedItem>
+        </Expand>
+    </Type>
+
+    <!-- Namespace nlohmann::json_abi_diag_ldvcmp_v3_11_2 -->
+    <Type Name="nlohmann::json_abi_diag_ldvcmp_v3_11_2::basic_json&lt;*&gt;">
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_ldvcmp_v3_11_2::detail::value_t::null">null</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_ldvcmp_v3_11_2::detail::value_t::object">{*(m_value.object)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_ldvcmp_v3_11_2::detail::value_t::array">{*(m_value.array)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_ldvcmp_v3_11_2::detail::value_t::string">{*(m_value.string)}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_ldvcmp_v3_11_2::detail::value_t::boolean">{m_value.boolean}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_ldvcmp_v3_11_2::detail::value_t::number_integer">{m_value.number_integer}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_ldvcmp_v3_11_2::detail::value_t::number_unsigned">{m_value.number_unsigned}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_ldvcmp_v3_11_2::detail::value_t::number_float">{m_value.number_float}</DisplayString>
+        <DisplayString Condition="m_type == nlohmann::json_abi_diag_ldvcmp_v3_11_2::detail::value_t::discarded">discarded</DisplayString>
+        <Expand>
+            <ExpandedItem Condition="m_type == nlohmann::json_abi_diag_ldvcmp_v3_11_2::detail::value_t::object">
+                *(m_value.object),view(simple)
+            </ExpandedItem>
+            <ExpandedItem Condition="m_type == nlohmann::json_abi_diag_ldvcmp_v3_11_2::detail::value_t::array">
+                *(m_value.array),view(simple)
+            </ExpandedItem>
+        </Expand>
+    </Type>
+
+    <!-- Skip the pair first/second members in the treeview while traversing a map.
+         Only works in VS 2015 Update 2 and beyond using the new visualization -->
+    <Type Name="std::pair&lt;*, nlohmann::json_abi_diag_ldvcmp_v3_11_2::basic_json&lt;*&gt;&gt;" IncludeView="MapHelper">
+        <DisplayString>{second}</DisplayString>
+        <Expand>
+            <ExpandedItem>second</ExpandedItem>
+        </Expand>
+    </Type>
+
 </AutoVisualizer>
diff --git a/tools/generate_natvis/README.md b/tools/generate_natvis/README.md
new file mode 100644
index 0000000..b4d3a7d
--- /dev/null
+++ b/tools/generate_natvis/README.md
@@ -0,0 +1,10 @@
+generate_natvis.py
+==================
+
+Generate the Natvis debugger visualization file for all supported namespace combinations.
+
+## Usage
+
+```
+./generate_natvis.py --version X.Y.Z output_directory/
+```
diff --git a/tools/generate_natvis/generate_natvis.py b/tools/generate_natvis/generate_natvis.py
new file mode 100755
index 0000000..e3d6a00
--- /dev/null
+++ b/tools/generate_natvis/generate_natvis.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python3
+
+import argparse
+import itertools
+import jinja2
+import os
+import sys
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--version', required=True, help='Library version number')
+    parser.add_argument('output', help='Output directory for nlohmann_json.natvis')
+    args = parser.parse_args()
+
+    namespaces = ['nlohmann']
+    abi_prefix = 'json_abi'
+    abi_tags = ['_diag', '_ldvcmp']
+    version = '_v' + args.version.replace('.', '_')
+    inline_namespaces = []
+
+    for n in range(0, len(abi_tags) + 1):
+        for tags in itertools.combinations(abi_tags, n):
+            ns = abi_prefix + ''.join(tags)
+            inline_namespaces += [ns]
+            inline_namespaces += [ns + version]
+
+    namespaces += [f'{namespaces[0]}::{ns}' for ns in inline_namespaces]
+
+    env = jinja2.Environment(loader=jinja2.FileSystemLoader(searchpath=sys.path[0]), autoescape=True, trim_blocks=True,
+                                                            lstrip_blocks=True, keep_trailing_newline=True)
+    template = env.get_template('nlohmann_json.natvis.j2')
+    natvis = template.render(namespaces=namespaces)
+
+    with open(os.path.join(args.output, 'nlohmann_json.natvis'), 'w') as f:
+        f.write(natvis)
diff --git a/tools/generate_natvis/nlohmann_json.natvis.j2 b/tools/generate_natvis/nlohmann_json.natvis.j2
new file mode 100644
index 0000000..0a9ee2c
--- /dev/null
+++ b/tools/generate_natvis/nlohmann_json.natvis.j2
@@ -0,0 +1,38 @@
+<!-- * * * * * * * * AUTO-GENERATED FILE  * * * * * * * * -->
+<!-- Edit ./tools/generate_natvis/nlohmann_json.natvis.j2 -->
+<!-- * * * * * * * * AUTO-GENERATED FILE  * * * * * * * * -->
+<?xml version="1.0" encoding="utf-8"?>
+<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+{% for ns in namespaces %}
+    <!-- Namespace {{ ns }} -->
+    <Type Name="{{ ns }}::basic_json&lt;*&gt;">
+        <DisplayString Condition="m_type == {{ ns }}::detail::value_t::null">null</DisplayString>
+        <DisplayString Condition="m_type == {{ ns }}::detail::value_t::object">{*(m_value.object)}</DisplayString>
+        <DisplayString Condition="m_type == {{ ns }}::detail::value_t::array">{*(m_value.array)}</DisplayString>
+        <DisplayString Condition="m_type == {{ ns }}::detail::value_t::string">{*(m_value.string)}</DisplayString>
+        <DisplayString Condition="m_type == {{ ns }}::detail::value_t::boolean">{m_value.boolean}</DisplayString>
+        <DisplayString Condition="m_type == {{ ns }}::detail::value_t::number_integer">{m_value.number_integer}</DisplayString>
+        <DisplayString Condition="m_type == {{ ns }}::detail::value_t::number_unsigned">{m_value.number_unsigned}</DisplayString>
+        <DisplayString Condition="m_type == {{ ns }}::detail::value_t::number_float">{m_value.number_float}</DisplayString>
+        <DisplayString Condition="m_type == {{ ns }}::detail::value_t::discarded">discarded</DisplayString>
+        <Expand>
+            <ExpandedItem Condition="m_type == {{ ns }}::detail::value_t::object">
+                *(m_value.object),view(simple)
+            </ExpandedItem>
+            <ExpandedItem Condition="m_type == {{ ns }}::detail::value_t::array">
+                *(m_value.array),view(simple)
+            </ExpandedItem>
+        </Expand>
+    </Type>
+
+    <!-- Skip the pair first/second members in the treeview while traversing a map.
+         Only works in VS 2015 Update 2 and beyond using the new visualization -->
+    <Type Name="std::pair&lt;*, {{ ns }}::basic_json&lt;*&gt;&gt;" IncludeView="MapHelper">
+        <DisplayString>{second}</DisplayString>
+        <Expand>
+            <ExpandedItem>second</ExpandedItem>
+        </Expand>
+    </Type>
+
+{% endfor %}
+</AutoVisualizer>